mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-10-19 12:43:39 +00:00
15 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
46bf492d05
|
feat(managed-agent): bound half-open Hosted event streams behind a keepalive capability (#14135) (#14512)
* feat(managed-agent): bound half-open Hosted event streams behind a keepalive capability (#14135) The Harness advertises its events-route keepalive as event-keepalive/1, and the Java client arms the idle watchdog only against a Harness that advertises it, so a rolling upgrade never aborts the quiet streams of an older Harness. The abort is now the typed HostedHarnessStreamIdleException: the coordinator retries it through the existing re-attach path and never settles or cancels the Turn on silence alone. The watchdog ticks every tenth of the bound, so an abort lands 45 to 49.5 s after the last byte. HostedEventStreamLivenessIT runs the probes on the packaged chain behind a TCP relay that holds the events connection half-open or stalls it, and the hosted-harness-mysql fork budget grows to 4793 s. A design note records the numbers, the capability, the outcome and the other Hosted streams. Closes #14135 * test(managed-agent): frame relayed requests and see virtual-thread readers in the liveness gate The event-stream relay classified a connection, rewrote its Host header and matched keepalives within single reads, so a request or a keepalive split across TCP segments escaped the stall and half-open injection or the cadence count. It now buffers each request head, forwards the body by its Content-Length, matches keepalives across reads, and records and resets a request it cannot frame. HostedEventStreamRelayTest pins each split. The half-open probe checked reader release with Thread.getAllStackTraces(), which leaves out the virtual threads Turn readers run on. It now reads a JDK thread dump, and first requires that dump to show the parked reader. * test(managed-agent): count each keepalive one relay read carries (#14135) The relay recorded one stamp per read that held a keepalive, so two keepalives in one read counted once, and the split-keepalive case could report a size of 1 whenever the pieces happened to land together. It now counts every match in the read window; the carried tail is a byte shorter than a keepalive, so none counts twice. A new case sends two keepalives in one write. * test(sdk-java): park the published-window probe mid-interval (#14135) The watchdog's ticks run from the stream's creation, and the probe parked right after it. A 2000 ms bound is a whole number of half-budget 1000 ms ticks, so that park sat on a tick of the mutant too, and wherever the scheduler ran a few ms late (macOS) the mutant aborted at ~2000 ms and passed. Parking 300 ms in puts the park mid-interval for both ticks: the shipped 200 ms tick aborts at 2100 ms and a 1000 ms tick at 2700 ms, so the limit drops to 2400 ms. |
||
|
|
d565d7463d
|
fix(sdk-java): Close Hosted Harness review criticals from #12654 (#13314)
* fix(sdk-java): Close Hosted Harness review criticals from #12654 #12654 merged before its second review round was processed. This closes the 11 Critical and 2 Minor findings, each re-verified against main and pinned by a new HostedHarnessClientTest case whose mutation witness was run (reverting the fix reddens the test): - HarnessEventStream close() no longer parks behind a next() blocked in the socket read: the closed flag is atomic, the raw input is closed without any stream monitor, and HostedHarnessClient.close() completes; the blocked consumer fails with DaemonTransportException (R1-1). - The hosted SSE transport gains the idle watchdog its stdio sibling has: Builder.sseIdleTimeout defaults to 45s, and a silent peer makes next() fail with "Hosted Harness SSE idle timeout" (R1-43). - submitTurn releases the active-prompt slot on a definitive 409 and throws PromptAlreadyActiveException; retaining a marker keyed by the rejected promptId wedged the session client-side (R1-2). A definitive non-409 failure on a same-identity retry releases that slot too (F2). - getStatus() snapshots the entry before the remote read and removes only that registration, so a stale hasActivePrompt:false cannot delete a different prompt admitted in flight (R1-4). - Responses missing the X-Qwen-Harness-Boot-Id fence header on mutation paths are classified outcome-unknown (create/prompt/mutation/delete) instead of a bare DaemonProtocolException (R1-5). - A local executor rejection (saturated or terminated pool) surfaces as DaemonTransportException instead of claiming the request may have reached the daemon (R1-45). - closeSession(ref) and detachSession treat a definitive 404 as done and tear down the heartbeat timer (R1-3, R1-46). - streamEvents falls back to the session ref's validated watermark when the builder omits the resume pair, so the epoch fence actually applies (R1-44). - The shared SSE parser accepts the id-less session_snapshot frame, so StreamHarnessEvents.snapshot(true) works (R1-47). - computePayloadDigest hashes a sorted-key canonical form, so the wire dedup key is reproducible across JVM processes (R1-6). - HarnessRuntimeExecutionRecovery requires status for known outcomes at construction instead of NPE-ing in isContinuationReady() (F1). Test: HostedHarnessClientTest 34/34 (15 new); full module 181 green with 9 env-gated skips on JDK 17 and clean test green on JDK 11; 14 mutation witness arms all red. The remaining 49 Suggestion-level findings are dispositioned in their review threads and tracked in #13313. * fix: Close second-round review criticals on the Hosted Harness client Addresses the CHANGES_REQUESTED round on #13314, which execution-proved one real regression in the first commit plus five more critical defects around it: - R1-1 (the regression CI confirmed on the fault-gates lane): the digest was canonicalized but the wire `prompt` member was not, and the hosted route re-derives the digest from the received bytes — every addText submission drew `400 invalid_hosted_prompt`. toJson() now emits the canonical form, the digest reuses the JsonSupport.encode facade over that same value, and the test asserts the wire bytes and the digest are literally the same value. - R1-3: the 45s idle watchdog was inherited from the stdio transport, whose server heartbeats; the hosted events route wrote nothing while no event was committed, so healthy silent streams (tool calls, the 10-minute approval wait) were aborted. The hosted route now mirrors the primary route's keepalive comment every 15s, and Builder.sseIdleTimeout accepts Duration.ZERO for callers that own the deadline. A keepalive-only peer is covered by a new test (consumer parked in read for three idle budgets). - R1-4: an idle abort while the consumer was between next() calls surfaced IllegalStateException (not the DaemonException family). The closed guard now distinguishes who closed the stream: idle abort -> DaemonTransportException("Hosted Harness SSE idle timeout"), caller close -> IllegalStateException, matching the javadoc. - R1-5: the cause-chain scan certified any rejection-shaped IOException as "never dispatched", but delivery also runs on the caller executor, so a rejection after the server accepted the prompt dropped the active-prompt marker for an admitted turn. Only the bare RejectedExecutionException (submit-time) and the terminated-executor case now classify as saturated/known; everything mid-flight stays outcome-unknown. A deterministic delivery-phase test drives this via a package-private executor seam (park the worker, fill the queue, then answer 202). - R1-6: the missing-boot-header wrap reclassified every unfenced response as outcome-unknown, including definitive 4xx the server emits itself before the fencing middleware (413, 429). All four sites now re-derive: ambiguous (408/5xx) keeps outcome-unknown, definitive unfenced statuses surface as DaemonHttpException with their status preserved. - R1-7 (suggestion folded in, same hunk family): detachSession tears the local attachment down for every definitive answer, not just 204 and 404 — a 403/400/410 no longer leaks a heartbeat timer. - R1-13 (suggestion, adjacent): a caller queued on cursorLock when the stream closes re-checks inside the lock and gets the closed-stream signal instead of a transport error. Also: the snapshot frame comment now names the actual producer (the bridge's withSnapshot on the primary events route — never the hosted route); the StreamHarnessEvents builder javadoc documents the lastEventId fallback precedence and that snapshot(true) is a primary-transport option; the README retry section and both design-doc languages now state the canonical digest as a cross-language wire contract and record that changing the digest algorithm requires quiescing or rewriting in-flight turn rows (R1-2's deployment note); the two 10ms heartbeat tests assert liveness instead of comparing zeros; and an explicit-cursor-wins case plus a definitive boot-headerless DELETE case close the two remaining unpinned arms. Test: HostedHarnessClientTest 42/42 (full module 189 green, 9 env-gated skips) on JDK 17; clean test green on JDK 11 (2 additional version-gated skips: JDK 11 parks such sends instead of surfacing the rejection); hosted-harness-session.test.ts 181/181. Nine mutation witness arms all red (revert toJson canonicalization, forget idle signal in the closed guard, drop the in-lock re-check, unbounded cause-walk, blanket boot-header wrap at prompt and DELETE sites, detach without finally, watchdog removed with the keepalive arm staying green, ref-only resume fallback). * fix(sdk-java): close third-round review criticals on the Hosted Harness client (#13314) - submitTurn: a definitive unfenced refusal (a response without a valid boot header that is not an ambiguous 408/5xx) now releases only the active-prompt marker the call owns, in both the validateGeneration arm and the post-consume arm; a refusal produced before the route's promptId lookup can no longer delete an earlier same-identity entry whose outcome is unknown, and a refused fresh submission no longer wedges the session. - send: snapshot the executor termination state before dispatch so a close() racing an in-flight send keeps its outcome-unknown classification instead of certifying non-dispatch. - StreamHarnessEvents: an explicit lastEventId cursor now always wins, including a deliberate 0 (replay from the beginning), which HarnessCoordinator passes for turn rows without a recorded watermark; only an omitted cursor falls back to the session ref's watermark. - HarnessEventStream: the idle watchdog now measures peer silence only while a consumer is parked in next(), so time between calls (a blocking queue handoff, a slow event handler) no longer aborts a healthy keepalived stream. - docs: the payload digest is re-derived by the server from its own re-serialization of the parsed prompt member (JSON.stringify form), not from the received bytes; the README qualifies cross-release digest stability and the keepalive floor for a custom idle timeout. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(sdk-java): close fourth-round review findings on the Hosted Harness client (#13314) - Carry the wire status and machine-readable code through PromptAlreadyActiveException instead of collapsing every 409 into a fixed message - Keep a prompt marker whose submission is still in flight from being cleared by a status answer that predates the admission - Map a watchdog scheduling rejection to DaemonTransportException and drop the stranded stream registration - Document the enforced idle-abort window (budget to 1.5x) and the peer-side backpressure limit on consumer pauses - Pin the fenced definitive-refusal release, the Duration.ZERO watchdog opt-out, the next() entry stamp, and the terminated-executor release with dedicated regression tests * fix(sdk-java): close fifth-round review findings on the Hosted Harness client (#13314) - Retain the active-prompt marker when a fenced 409 carries hosted_prompt_recovery_required: that code proves the promptId is in the durable input log, so releasing the marker would admit a second identity into a session with two unsettled inputs and fail every recovery entrance closed; every other 409 code still releases it - Clear the hosted events keepalive from stop() as well as from the close handler, and send X-Accel-Buffering: no so a buffering intermediary cannot swallow the keepalives the client watchdog relies on - Pin the settled status-read clearing, the failed-close unregister, and the disabled watchdog's empty scheduler queue with positive witnesses, and extract the shared fenced-SSE response prelude in the client tests - Correct the documented idle-abort window with the 100 ms poll floor, state the digest's sha256: wire encoding in the README, and narrow the PromptAlreadyActiveException javadoc to what the code does * fix(sdk-java): lifecycle teardown runs only on definitive answers Close the corridor the next-round review's close/detach receipts queued: local attachments (and their heartbeat timers) must not survive a definitive refusal, and must NOT be torn down on outcome-unknown. - detachSession: the unconditional `finally { removeAttachment }` also ran when requireMutationStatus surfaced unexpected-success as MutationOutcomeUnknownException — a state where the server's answer is not decided and the lease must keep beating. Teardown now runs on the definitive limb (204 or tolerated 404) and inside the DaemonHttpException arm only; outcome-unknown surfaces keep the attachment (anUnexpectedDetachAnswerKeepsTheAttachment). - closeSession(HarnessSessionRef) and closeSession(String): mirror the same try/catch — a definitive DELETE refusal (e.g. 403) now also retires the attachment and the active-prompt ledger instead of leaking the timer until close(), while ambiguous answers keep them (aRefusedCloseStillTearsDownTheHeartbeat ×2 overloads, anUnexpectedCloseAnswerKeepsTheAttachment, aBootHeaderlessCloseKeepsTheAttachment for the gateway-502 shape). - closeSession(String) gains the ensureOpen() guard every other public entry has (a deferral receipt plus #13313's R1-50): the closed-client path is JVM-independent again, so aLocalExecutorRejectionIsNotReported AsOutcomeUnknown becomes closeSessionByIdFailsFastAfterClientClose — IllegalStateException on every JDK — and the saturated/terminated taxonomy stays pinned by aTerminatedHttpExecutorReleasesTheOwnedMarker. - closeByRefTreatsAnAbsentHarnessSessionAsClosed now also counts the DELETE request (dropping the remote call reddens assertEquals(1)). - Housekeeping of the takeover branch: aRecoveryRequiredRefusalKeepsThe OwnedMarker's stub never incremented its promptCalls counter, so its trailing assertion could never pass once it ran (CI never reached it through the verify-checkout race) — fixed by counting in the handler. Witnesses: full module 214/214 green on JDK 17 (clean test green on JDK 11, 13 skips = 9 env + 4 version-gated); corridor mutation arms all red — detach with an unconditional finally flattens the keep-beating assertion, removing either close-mirror makes refused-close heartbeats keep growing (9→14, 10→16), and removing ensureOpen flips the fail-fast test from IllegalStateException back to the transport exception. * fix(sdk-java): settle registered admission markers and align lifecycle teardown Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(sdk-java): retire hosted admission state on proven restart and scope the settle latch per attempt (#13314) A proven harness generation change now retires every local record for that peer at all three entrances: the submitTurn fence catch releases the admission ledger entry, the scheduled heartbeat retires the attachment and ledger instead of swallowing the mismatch, and detachSession mirrors closeSession for the generation branch while keeping the ledger across definitive refusals. The admission settle latch is per-attempt and outcome-scoped: only the owning call's concluded send settles it, every attempt re-arms it, and a same-identity retry's 202 publishes a fresh settled entry so a status read holding a stale snapshot cannot clear the marker that is live now. Pre-dispatch unchecked escapes release the owned marker via a dispatch boundary flag in send() instead of settle-and-keep. The SSE idle watchdog merges the parked flag and activity stamp into one volatile waitingSince write, so a tick can never pair a fresh flag with a stale stamp; keepalive refills still refresh the budget. Docs correct the persisted-digest claim: a form change invalidates rows whose stored key order was not already canonical, not every row. * fix(cli): drop ambient QWEN_HOME from the cli test setup (#13314) A run from inside a Qwen Code session always exports QWEN_HOME, which outranks the homedir() mocks the settings suite anchors on: the module-load getUserSettingsPath() then resolves to the ambient home, the mocked user-settings file is never found, and 13 settings.test.ts tests fail. The verification gate runs in exactly such an environment. Delete the variable in test-setup.ts, mirroring the existing QWEN_RUNTIME_DIR sanitization; tests that exercise QWEN_HOME set it in-body. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(sdk-java): close hosted harness ledger wedges from review (#13314) Unfenced 2xx/3xx mutation answers are now outcome-unknown instead of definitive, unfenced refusals carry the peer's buffered body, the per-attempt settle latch is owner-gated, close/detach retire only the records they observed, and wire 409s stay reachable through DaemonHttpException. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(sdk-java): close hosted harness review criticals on digest recovery, refusal typing, and ledger identity (#13314) - SubmitHarnessTurn accepts a persisted pre-canonicalization payload digest and re-sends the prompt in the exact as-built key order that digest covers, so recovering an older turn row reaches the route's replay path instead of failing the self-check before any request is sent. - An unfenced 4xx on the generic mutation channel surfaces as the protocol failure it is rather than DaemonHttpException, whose status consumers key terminal verdicts on; only submitTurn keeps the typed refusal its admission-marker release keys on. - ActivePrompt records the submitting client id and replaces the shared settle latch with a per-attempt send counter: lifecycle teardowns retire only markers whose identity proved stale, and a status read clears a marker only while no send attempt is in flight. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(sdk-java): close hosted harness round-10 review criticals on close/detach retirement (#13314) - README: correct the digest-migration paragraph — the client re-sends the shape its digest covers and accepts a pre-canonicalization as-built digest, so upgrades do not quiesce or rewrite in-flight turn rows - closeSession(String): a successful headerless DELETE deleted the session outright, so retire every attachment for the id, including one registered while the DELETE was in flight - submitTurn: gate all six owning-release arms on no send attempt still open, so a definitive refusal cannot strand a same-identity retry's 202 with no ledger entry - detachLifecycle: retire the observed admission marker even when no attachment remains (a refused close drops the attachment first), in both overloads - closeSession(HarnessSessionRef): a 204 proves identity-matched deletion, so retire every marker for the id; keep identity-matched retirement only for the tolerated identity-scoped 404 * fix(cli): wait out the record watcher's backoff in the unrecorded-reply squad test (#13314) The deterministic verification gate rejected the previous commit on "wakes the leader with the error when a member reply is never recorded" (default 1s vi.waitFor timed out waiting for the leader's wake). The give-up that wakes the leader is eligible the moment the test bumps its virtual clock, but it fires on the watcher's next real-timer check, and that chain backs off geometrically (recordWatchMs doubling to a 15s cap) — under full-suite load the next tick lands past the 1s default. The sibling restart-recovery test already guards the identical pattern with timeout: 3_000 and the comment "The watcher backs off; its next check may be a while."; apply the same bound here. Assertion-preserving. Probe: with the watcher's initial interval raised to 1.5s, the unmodified test fails with the gate's exact assertion at the same line; with the timeout it passes. * fix(sdk-java): close HostedHarnessClient admission-ledger fences found in review (#13314) Round-14 review found the admission-ledger fencing still open in eight places: - detachLifecycle(HarnessSessionRef) retired the pre-send snapshot even on a tolerated 404, wiping the marker the session's current owner planted through a re-issued identity; it now retires through the same identity-matched retireLedger detachSession uses, which also covers a marker this identity replanted while the detach was in flight. - detachSession collapsed a deleting 204 and a tolerated 404 into one identity-matched retirement, so a proven deletion kept a marker from an older identity; the 204 arm now retires unconditionally. - Both closeSession overloads applied the observed-snapshot rule to a generation change, so a marker published while the DELETE was in flight survived a proven restart; both now retire unconditionally on HostedHarnessGenerationException. - The sendMutation channel and the streamEvents fence observed a generation change without retiring local state; both now discard it, and sendMutation threads the session id from every caller. - The unfenced definitive-4xx arm released without reading the refusal code; an unfenced 409 is now narrowed by code like the fenced arm, so a boot-header-stripped hosted_prompt_recovery_required retains the marker and surfaces as PromptAlreadyActiveException. - When both the owning attempt and a joined same-identity retry were definitively refused, neither released the marker; an owning release refused by an open sibling send is now owed and discharged at the last concluded attempt, while outcome-unknown or durably admitted conclusions block it. - A non-owning retry's send window closed before its 202 republish, so an owning release landing in between dropped the joined entry and the replace silently no-oped; the window now closes after the ledger decision. - The dispatch guard probed the executor, so a saturated-but-running pool was misclassified outcome-unknown; send() now dispatches with sendAsync and maps the synchronous RejectedExecutionException to a known-outcome DaemonTransportException, keeping post-dispatch rejections outcome-unknown. Each fix carries a pinning test, and the three pre-dispatch escape tests move their injection seam from the removed executor-state probe to the executor's execute(). * test(cli): settle fresh process rows before identity-judged ledger sweeps (#13314) The deterministic gate rejected the previous round on managed-runtime-ledger.test.ts: on some hosts ps reports a just-born process with the negative-elapsed wraparound (e.g. 441077234-00:18:40, which parsePsElapsed rightly rejects) until it ages past the glitch, so an unwitnessed sweep judged the live fixture 'unknown' and held it unproven instead of killing it. settledGroupTable now also waits for the leader's row to carry a datable elapsed column, and the five live-spawn sweep tests that never settled now settle before sweeping. Assertions unchanged. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(sdk-java): report a close-aborted parked SSE read as a transport failure (#13314) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * chore(sdk-java): re-verify #13314 on a tree clean of generated Maven artifacts The deterministic gate rejected |
||
|
|
008c0de746
|
docs(sdk): clarify empty core-tool allowlists across SDKs (#13949)
Co-authored-by: Zhangchenhao-111 <285911435+Zhangchenhao-111@users.noreply.github.com> |
||
|
|
585466c646
|
feat(sdk-java): Add the Hosted Harness private client (#12654)
Add the Java control-plane transport for the hosted Harness private protocol from #12409. Construction performs capability negotiation, validates the advertised capability digest against the configured deployment digest, and pins the process boot identifier; every later request then carries the protocol and boot-ID fencing automatically, and a generation mismatch surfaces as a non-retryable conflict rather than a retry against a restarted Harness. Sessions are created, loaded, heartbeated, prompted, streamed, and cancelled through typed request objects; turn submissions carry a precomputed payload digest, and event streams reuse the daemon SSE reader with replay cursors. The client has no production caller yet: it is the transport the Spring control plane will wire in a later slice, in the same pattern as the attestation client before process adoption. Related to #12380. |
||
|
|
8b72f4d456
|
fix(java): make SDK worker threads daemon (#9925)
* fix(java): make SDK worker threads daemon Use daemon threads for the Java SDK default executors so background helper pools do not keep example or short-lived JVM processes alive after work completes. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com * fix(java): document and test daemon pool lifecycle Keep examples and docs aligned with daemon executors, and ensure the client module actually discovers its JUnit 5 regression test. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com * fix(java): reuse the custom example executor Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com * test(java): isolate SDK integration cases Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com --------- Co-authored-by: zhangyu.34 <zhangyu.34@bytedance.com> |
||
|
|
8104071260
|
docs(java): correct closed session exception (#9859)
* docs(java): correct closed session exception * docs(java): clarify session control exceptions Clarify which Java SDK entry points throw SessionControlException directly and pin closed-session behavior with a lightweight unit test. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com * test(java): pin unavailable session exceptions Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com * test(java): pin session exception wrapping Add coverage for direct session initialization failures and both QwenCodeCli.newSession wrapping paths so the Java SDK docs stay aligned with the exception contract. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com --------- Co-authored-by: zhangyu.34 <zhangyu.34@bytedance.com> |
||
|
|
867ded5bd5
|
fix(sdk): support "auto" permission mode (#9003)
* fix(sdk-python): support "auto" permission mode * refactor(sdk-python): derive permission-mode validation from PermissionMode type * fix(sdk-java): support "auto" permission mode * refactor(sdk-python): derive auth-type and effort validation from type aliases * chore: rerun CI |
||
|
|
e09399e0fb
|
feat(core): make list_directory opt-in (disabled by default) (#9424)
* feat(core): make list_directory opt-in (disabled by default) glob covers directory listing in most cases, so list_directory is now disabled by default to keep the tool surface lean. Enable it with tools.listDirectory.enabled=true or by listing it in the coreTools allowlist (--core-tools / tools.core). The plan-mode reminder no longer steers the model toward the tool. * fix(core): align list_directory opt-in gate with prompts and allowlist parsing Round-1 review findings on the opt-in gate: - Normalise coreTools entries with parseRule so specifier forms such as list_directory(/src) still re-enable the tool. isLsToolEnabled used resolveToolName, which does not strip specifiers, while PermissionManager admits the same entry via parseRule — so the allowlist accepted the tool and the registry never got it (R1-1). - Drop list_directory from the plan-mode block error. That message is returned to the model as the tool result of every blocked call, so it kept steering the model at an unregistered tool even after the system prompt stopped doing so (R1-2). - Remove the now-inert ToolNames.LS entries and the prompt text that advertised the tool to built-in agents. The gate also guards the forked-registry rebuild path, so these agents were silently stripped of a tool their own prompts told them to use (R1-3). - Say why the tool is missing and how to enable it in the tool-not-found message, instead of offering unrelated Levenshtein suggestions (R1-6). - Cover the alias and specifier forms in the registration tests (R1-4), and drop the stale examples from the sub-agents and Java SDK docs, where the listed entry can no longer register the tool (R1-5, R1-7). * fix(core): address list_directory opt-in round-2 review findings - Reword the skill-review agent task prompt so the inspection guidance only references read_file; the run's tool filter has no list_directory, glob, or shell, so the old `ls` instruction was unsatisfiable for the turn-budgeted background agent. - Resolve tool-name aliases (ListFiles, ListFilesTool, ReadFolder) in the list_directory not-found message so aliased calls get the enablement explanation instead of a Levenshtein suggestion. - Attribute a missing list_directory to the workspace tools toggle when the workspace disabledTools set blocks it, since the opt-in setting cannot lift that state. - Drop the coreTools allowlist advice from the enablement message: setting tools.core to ["list_directory"] alone would exclude every other tool. - Switch the two remaining sdk-java runTransportOptionsExample copies from list_directory to glob; setAllowedTools only adds auto-approve rules and never registers a tool. - Extract the shared fake-server scaffolding in the list_directory integration tests into a local helper, keeping the load-bearing CLI-flag comment. - Pin the skill-review agent tools array and assert the learn-skill prompt steers to read_file / glob, matching the sibling planners. * fix(core): only claim list_directory is opt-in-disabled when it is unregistered The not-found explanation resolved aliases (ListFiles, ReadFolder) before checking whether the tool was actually absent. The registry is keyed by canonical names while the lookup that reaches this path resolves legacy migrations only, so an alias call missed even when list_directory was enabled — and the message then told the user to switch on a setting that was already on, hiding the generic path's "Did you mean list_directory" self-correction. Gate the branch on the canonical name being absent from the registry, and pin the two alias combinations that were unpinned: an alias against a non-empty workspace disabledTools set, and an alias against a registered tool. |
||
|
|
60458f5e37
|
fix(serve): Coordinate caller-supplied session IDs (#8415)
* fix(serve): coordinate caller-supplied session IDs Complete daemon-wide admission across REST, ACP, workspace generations, SDKs, and MCP. Closes #8411 Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(serve): wire session bridges in hot-reload harness Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): address review round for caller-supplied session IDs (#8415) Restore the observability and fail-loud guarantees flagged in review: log every session-id admission routing failure, name the live foreign owner workspace in restore conflicts, make the ACP dispatcher's admission dependency required so load/resume cannot run on a mount without one, and require mountAcpHttp hosts to inject the daemon-wide admission instead of silently building a weak fallback. Harden the SDK WS transport against environments without global fetch and against non-capabilities 200 envelopes, and align the design doc with the implemented restore-sharing and persistence-failure semantics. * fix(sdk): harden session ID capability fallback Preserve REST capability errors, fail closed on malformed envelopes, retain restore routing diagnostics, and align retry documentation. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): normalize restored session IDs Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(session): preserve mixed-case legacy session access Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com> |
||
|
|
edfb43e954
|
fix(sdk-java): Harden daemon transport reliability (#7603)
* fix(sdk-java): propagate daemon event epochs Pair SSE cursors with the daemon event epoch, learn validated response epochs, and fail closed when the epoch changes during prompt observation. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(sdk-java): harden daemon reliability follow-ups Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(sdk-java): cover duplicate SSE event epoch headers * test(sdk-java): restore retryable admission coverage Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> |
||
|
|
e7097d0ef6
|
feat(sdk-java): Add daemon transport (#7463)
* feat(sdk-java): add daemon transport Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#7463) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(sdk-java): stabilize lifecycle lock test Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#7463) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#7463) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#7463) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): preserve prompt cancellation during context propagation Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> |
||
|
|
ed14a33064
|
feat(core): add NotebookEdit tool for Jupyter notebooks
Some checks are pending
Qwen Code CI / Classify PR (push) Waiting to run
Qwen Code CI / CodeQL (push) Blocked by required conditions
Qwen Code CI / Lint (push) Blocked by required conditions
Qwen Code CI / Test (macos-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (windows-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
Adds NotebookEdit as the structured write counterpart to existing notebook read support. Summary: - Add `notebook_edit` for safe cell-level `.ipynb` replace/insert/delete operations. - Integrate notebook editing with tool registration, permissions, Claude conversion, prior-read enforcement, IDE/inline modify flow, commit attribution, docs, and SDK permission docs. - Harden notebook read/edit behavior for truncated notebook renders, ambiguous fallback cell IDs, internal modify metadata, compact JSON, UTF-8 BOM notebooks, and cache behavior after structural edits. - Add unit and integration coverage for notebook read/edit behavior. Follow-up work remains for tab-indented notebook formatting preservation, a few low-risk unit-test additions, and non-blocking hardening suggestions from review. |
||
|
|
a1d1e5e276
|
Fix typo in class name (#2189) | ||
|
|
a4ffc6eb24 |
feat: promote Agent Skills from experimental to stable
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> |
||
|
|
0128f65fe8 | refactor structure |
Renamed from packages/sdk-java/README.md (Browse further)