mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-08-04 13:51:13 +00:00
219 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0cb109f513
|
fix(core): Avoid replaying unsafe MCP tool calls (#8387)
* fix(core): Avoid replaying unsafe MCP tool calls Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(core): Revalidate MCP replay after reconnect Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> |
||
|
|
d1648b3af9
|
feat(telemetry): Track tool execution outcomes (#8180)
* feat(telemetry): track tool execution outcomes Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(telemetry): address execution-status review feedback (#8180) - Update stale nonInteractiveToolExecutor expectations for executionStatus (red CI) - Scope the cancelled span-status short-circuit to tool_call events so other cancelled events carrying an error keep ERROR status - Record loop-detection skips as UNKNOWN, not EXECUTION_DENIED, keeping the denial metric accurate - Assert execution_status on the resolved-with-error PostToolBatch path - Raise tool-call observer-failure logging from warn to error - Clarify subagent-projection exclusion and JSONL compatibility in design doc * fix(core): address review findings 3-6 on tool execution status (#8180) - recordToolExecutionMetrics now merges common attributes (session.id opt-in) like every other counter in metrics.ts - Lift TOOL_FAILURE_KIND_ATTRIBUTE / TOOL_FAILURE_KIND_CANCELLED into telemetry/constants.ts so coreToolScheduler and session-tracing share one definition - Add debugLogger to runToolTelemetrySink catch (was silent) - Replace delete-based absence in withPostToolBatchStop with conditional spread * fix(core): address remaining review findings on tool execution status (#8180) - Pass the frozen executionStatus variable instead of the literal 'success' in the post-hook-stop error response, keeping the frozen value the single source of truth (finding 4) - Force-finalize the deferred PostToolBatch parent span in the abort drain, since that terminal path cancels the batch hook that otherwise owns the span; documents the invariant at the call site (finding 6) - Comment the loop-detection guard so the permission-cancellation exclusion from invalid-param loop detection is explicit (finding 9) - Rename the design doc to the dated docs/design convention and note the schedule()/handleConfirmationResponse() resolution contract change for embedders (finding 2, doc convention) * docs(core): note schedule() resolution contract in tool execution status design (#8180) Record the embedder-facing behavior change that schedule() and handleConfirmationResponse() resolve with a terminal error call rather than rejecting, so a failing tool no longer aborts its siblings. * fix(telemetry): address review feedback for tool execution status (#8180) - Document the new tool_call attributes (call_id, execution_status), the qwen-code.tool.execution.count metric, the tool.execution span attributes, and the tool.failure_kind=cancelled span field in telemetry.md. - Pass ToolErrorType explicitly at loop-detection skip sites instead of inferring it from the skip message string, so copy edits cannot silently reclassify loop skips as approval denials. - Simplify withPostToolBatchStop response construction (drop the destructure-and-reattach used to preserve a missing execution status). - Add a debug breadcrumb when a PostToolBatch stop has no span to attach to, and a one-time warning when PostToolBatch hook detection fails open. - Drop the try/catch wrapping the pure isTelemetrySdkInitialized getter. - Clarify the design doc invalid-combination wording and note that the execution-failure SLI cannot be attributed to a specific tool. - Add a regression test pinning that schedule() resolves (not rejects) when a tool execution throws. * fix(telemetry): address round-7 review feedback for tool execution status (#8180) * fix(telemetry): restore type-safety fallback for executionErrorType (#8180) * fix(telemetry): align tool execution failure outcomes Keep Core and ACP cancellation arbitration consistent, preserve structured post-processing errors, and restore QwenLogger MCP metadata privacy. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(core): address review suggestions for tool execution status (#8180) * test(core,cli): strengthen test-efficacy for tool execution status (#8180) * fix(core): address review suggestions for tool execution status (#8180) - Improve post-processing cancellation message to indicate the tool had already completed, preventing silent model redo of completed work - Remove dead !isExecutionTimeout conjunct in Session.ts PostToolUse cancellation check (unreachable: timeout always sets toolResult.error) - Replace construct-then-delete with destructuring in withPostToolBatchStop - Move all failure-kind constants to telemetry/constants.ts so the full documented vocabulary lives in one place - Re-export StructuredToolError from tool-error.ts instead of importing from the unrelated priorReadEnforcement module - Add JSDoc to normalizeToolCallEvent documenting key-absent semantics - Add ordering-safety comment to createParentAbortRace microtask guarantee - Document endToolExecutionSpan not_started guard as defence-in-depth - Document PostToolBatch span leak window in finalizeToolSpan - Add design doc note about hand-placed cancellation check invariant - Add test for unknown execution_status normalization path - Revert unrelated generate-notices.js formatting change * fix(core): address review feedback for tool execution status (#8180) - Gate cancel message on executionThrew so the model sees 'User cancelled tool execution.' when execute() rejected under abort, reserving 'already completed' wording for post-processing cancels - Move StructuredToolError into tool-error.ts to break the tool-error ↔ priorReadEnforcement module cycle - Revert unrelated Prettier reformat in generate-notices.js * test(core): pin both tool cancellation notices; extract them as constants afd349ca gated the cancel message on executionThrew but left the two wordings as bare literals at four sites and added no test. That is the exact shape the bug had: it was introduced by editing one literal and missing the others. Extract TOOL_CANCELLED_{BEFORE,AFTER}_COMPLETION_MESSAGE so the four sites cannot drift, and add regression tests for both paths — a tool interrupted mid-flight (execute() rejected under abort) must report "User cancelled tool execution.", while a cancel after execute() returned must report that the output was discarded. The mid-flight test fails against the pre-afd349ca behaviour. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(core): keep MCP reconnect for a timeout on a dead transport Classifying every `-32001` as EXECUTION_TIMEOUT skips handleReconnectOnError, which previously recovered one real case: the transport dies mid-request, the SDK request times out because no response will ever arrive, and the server is already recorded DISCONNECTED. That reconnected and retried; now it hard-fails and the user has to retry by hand. Divert back to the reconnect path only on positive evidence the transport is dead. Note that getMCPServerStatus() reports DISCONNECTED for servers it has never seen, so the guard checks for a *recorded* DISCONNECTED — the naive comparison misroutes every timeout from a server whose status was never registered, which broke four existing timeout tests when tried. A timeout on a healthy server is still EXECUTION_TIMEOUT: retrying it after a reconnect would just double the wait. The client-side idle timeout keeps classifying unconditionally; it is our own timer, not a transport signal. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(core): address blocking review feedback for tool execution status (#8180) Two blocking items from the maintainer review: 1. Post-processing cancellations dropped persistedOutputFiles (and visionBridgeNotice) along with the model-visible output, orphaning files the tool had already spilled to disk. createCancelledResponse now carries both, and every cancelAfterPostProcessing site passes what it has; the settle-then-abort and hook-stop paths do the same. 2. A -32001 that lands while the parent signal is aborted is the SDK's abort rejection or a timeout that raced with a cancel; classifying it EXECUTION_TIMEOUT would count user cancels against the timeout SLI. isExecutionTimeoutFailure now defers to the abort in both catch blocks, regardless of which side settled the race first. The two tests that pinned the opposite timeout-wins ordering are updated to the abort-wins semantics the review asked for. Co-Authored-By: Qwen Code <noreply@alibaba-inc.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com> Co-authored-by: qwen-code-bot <qwen-code-bot@users.noreply.github.com> Co-authored-by: qwen-code-ci-bot <253268222+qwen-code-ci-bot@users.noreply.github.com> Co-authored-by: Qwen Code Autofix <qwen-code-autofix@users.noreply.github.com> Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Qwen Code <noreply@alibaba-inc.com> |
||
|
|
72bd3dccc2
|
ci: remove broken legacy scheduled PR triage workflow (#8434)
The Gemini-era scheduled PR triage workflow has been dead weight for a long time: - Its only business value — syncing labels from the linked issue to the PR — never fires: gh exports closingIssuesReferences as a flat array, so the script's '.closingIssuesReferences.nodes[0].number' jq path always errors, the error is swallowed by 2>/dev/null, and every PR falls into the "No linked issue found" branch. The latest production run logged 157 "No linked issue" hits and zero label syncs, despite many of those PRs having linked issues. - LABELS_TO_REMOVE is computed but never applied, PRS_NEEDING_COMMENT is never appended to, and the prs_needing_comment job output has no consumer — the rest of the script is dead code. - It burns 1+N API calls against every open PR every 15 minutes. - The id-token: write permission is a leftover from the Gemini/GCP OIDC era; nothing in the bash script uses it. Real PR triage lives in qwen-triage.yml. Remove the workflow and its script, drop the stale docs section describing behavior it never had, and pin the file into the legacy-workflow regression list. Co-authored-by: verify <verify@local> |
||
|
|
4338120100
|
feat(serve): resolve and report the daemon memory budget (#8245)
Some checks are pending
E2E Tests / E2E Test (Linux) - sandbox:docker - shard 1/3 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker - shard 2/3 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker - shard 3/3 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none - shard 1/3 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none - shard 2/3 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none - shard 3/3 (push) Waiting to run
E2E Tests / E2E Test - macOS - shard 1/2 (push) Waiting to run
E2E Tests / E2E Test - macOS - shard 2/2 (push) Waiting to run
E2E Tests / channel-plugin E2E (nightly) (push) Waiting to run
E2E Tests / cron-interactive E2E (nightly) (push) Waiting to run
E2E Tests / web-shell Browser Regression (push) Waiting to run
SDK Java / ubuntu-latest / Java 11 (push) Waiting to run
SDK Java / ubuntu-latest / Java 17 (push) Waiting to run
SDK Java / macos-latest / Java 21 (push) Waiting to run
SDK Java / ubuntu-latest / Java 21 (push) Waiting to run
SDK Java / windows-latest / Java 21 (push) Waiting to run
SDK Java / Real daemon E2E / Java 11 (push) Waiting to run
* feat(serve): resolve and report the daemon memory budget The daemon has no notion of how much memory it has. It samples its own RSS and heap every five seconds, and polls the primary ACP child's RSS, but there is no limit anywhere to divide those by: no cgroup read, no heap-size limit, no ratio, no `limits.*` memory field. Every number it reports is an absolute byte count with nothing to compare against, so "how close to exhaustion is this daemon" cannot be answered from `/daemon/status` at all. Resolve one set of figures at boot and report them. Configured and effective budgets are separate: the effective value is capped at resolved cgroup or host memory, so an operator passing a budget larger than the machine gets a denominator the machine can actually back, with the discrepancy visible rather than silently resolved. A derived budget below the documented minimum is reported as `insufficientMemory` rather than clamped upward, which would have invented capacity that does not exist — a 768 MB host would otherwise report a 1 GB budget and poison every ratio computed from it. `limits.memory` carries the static figures, including `legacyCeilingMb`: the ceiling an ACP child receives today with no budget involved, so the gap between current behavior and any future policy is measurable before that policy exists. `runtime.memory` carries live counts and the advisory per-child share at both the registered and the live child count. Nothing here sizes a child. Dividing the pool by a workspace count is not a sound policy on its own, and the advisory shares exist to show why: on a 32 GB host with 25 registered workspaces and only the preheated primary live, a registered-count divisor would cut that child from 16384 MB to 614 MB for memory no dormant workspace is holding, while the per-child floor still lets 25 children authorise more than the pool. Registration is not allocation; a real policy needs admission at spawn time keyed on concurrently live children, and it needs this data to be designed against. Applying such a share is also a compatibility change even with no refusals, since it alters child GC and OOM behavior — so it is not something this change should slip in under the heading of reporting. Refs #8182 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(serve): report honest memory counts and guard the registered share (#8245) * fix(serve): reuse workspace snapshots when counting active children Counting active ACP children from `listManaged()` is right — `list()` only returns entries in `active` state, so a workspace mid-drain, mid-replacement, or blocked still holds a live child that `list()` drops. But taking the count by calling `getDaemonStatusSnapshot()` again per managed runtime undoes the existing reuse of the primary bridge's snapshot, and `getDaemonStatusSnapshot` rebuilds the whole session array on every call. The second pass also reads the tree at a different instant than the rest of the response, so `activeAcpChildren` could disagree with the session and channel figures beside it. Reuse the snapshots already taken instead, keyed by bridge, and fall back to a fresh call only for a managed runtime the first pass missed — which is exactly the non-`active` entry the `listManaged()` change exists to catch. The reuse this restores was already guarded by a test asserting one snapshot call per bridge, but that test resolves no memory budget, and the second pass ran only on the budget path — so it stayed green while every production `/daemon/status` call did the work twice. Added a case that resolves a budget and asserts the same property; it fails against the previous commit with "expected 1 times, but got 2 times". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(serve): address review feedback on daemon memory budget (#8245) * fix(serve): import isValidMemoryBudgetMb in serve command (#8245) * fix(serve): address review feedback on daemon memory budget (#8245) * fix(serve): stub isChannelLive on serve test fake bridges (#8245) * fix(serve): address review feedback on daemon memory budget (#8245) - Make the stderr-gate test host-independent by pinning os.totalmem through a vi.mock toggle instead of reading the runner's cgroup - Add a spawn-path constant parity test enforcing that getAcpMemoryArgs and legacyChildCeilingMb agree on the fraction and cap, converting the comment-only invariant into a test - Narrow the mirror comment to name only the two constants that actually have spawn-path counterparts - Accept availableMemorySource through the resolveDaemonMemoryBudget seam so the constrained path is testable end-to-end - Report maxChildHeapMb alongside minChildHeapMb on the wire so clients can distinguish the 16 GB cap from a large host - Move the listManaged/list comment to the computation it describes - Add a cross-reference at the opts literal for the late-assigned daemonMemoryBudget field * fix(serve): address review feedback on daemon memory budget (#8245) * fix(serve): address review — split fraction constant, sharpen parity test, deduplicate error, populate bootstrap memory (#8245) * fix(serve): address review — document maxChildHeapMb, make parity test order-independent (#8245) * fix(serve): address review — split parity test into two files to avoid cold re-import timeout (#8245) * fix(serve): address review — correct session count, compatibility scope, bootstrap memory docs (#8245) * fix(serve): address review — align help text framing, document default cap, fix stale comment (#8245) * fix(serve): address review — add positive memory-budget validation test, correct activeAcpChildren docs (#8245) * fix(serve): address review — document childRssBytes stale tail after watcher detach (#8245) --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com> Co-authored-by: Qwen Autofix <qwen-autofix@users.noreply.github.com> Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com> Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com> |
||
|
|
4c6e2518a3
|
docs: refresh architecture overview (#8325)
* docs: refresh architecture overview * docs: complete architecture package table |
||
|
|
554c5e44ba
|
feat(web-shell): support mutable default mid-turn messages (#8229)
* feat(web-shell): support mutable default mid-turn messages * fix(serve): register mid-turn removal telemetry route * test(serve): update telemetry route totals * fix(test): add session_mid_turn_message_mutation to expected features list * fix(webui): forward clientId on cross-session mid-turn removal (#8229) - Forward the session clientId in the cross-session removeMidTurnMessage branch so the bridge's exact-originator match can succeed; without it the removal resolved to an undefined originator and could never remove the message stamped at enqueue. - Strip a misaligned/malformed messageIds from mid_turn_message_injected in asKnownDaemonEvent instead of rejecting the whole event, mirroring the sidechannel parser so a buggy daemon can't silently lose the injection signal. - Log a mid-turn removal miss in the bridge like the enqueue/pending-removal siblings, to make removal races diagnosable from daemon logs. * fix(web-shell): exclude annotations from mid-turn path and harden idle cleanup (#8229) * fix(web-shell): add container-type to .queuedPrompts so @container query applies (#8229) * fix(web-shell): harden mid-turn dedupe and capability gate per review (#8229) - removeInjectedFromQueue now matches by id first (position-independent) and falls back to text only when no id match exists, so two same-text sends can't remove the wrong row and double-deliver. - Thread canMutateMidTurn into useQueuedPrompts and gate the mid-turn delete/edit mutation on it, so the keyboard path can't hit a DELETE route the daemon doesn't advertise. - asMidTurnMessageInjectedData omits a malformed messageIds key instead of leaving a present undefined, matching the sidechannel parser. - Narrow MidTurnQueueItem.midTurnState, document the load-bearing effect order, and make clearQueuedPrompts return false on a no-op clear. * fix: harden mid-turn removal per review (log escape, cross-session client id) (#8229) - Escape the caller-controlled messageId (and sessionId) in the mid-turn removal-miss stderr line to prevent log injection (CWE-117). - Forward the target session's persisted client id on cross-session mid-turn removal so the bridge's exact-originator match no longer rejects valid removals after a session switch with per-session client ids. - Strengthen tests: distinct-id independence for two queued messages, deferred removal proving the composer waits for daemon removal, and the active-turn delete failed-action flag. --------- Co-authored-by: 钉萁 <dingqi.jww@alibaba-inc.com> Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com> Co-authored-by: Qwen Code Autofix <qwen-code-autofix@users.noreply.github.com> Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com> |
||
|
|
412eae24b4
|
feat(core): add project-level fork profiles (#8148)
* feat(core): add project-level fork profiles * fix(core): harden fork profile loading --------- Co-authored-by: destire-mio <248462155+destire-mio@users.noreply.github.com> |
||
|
|
77d8a27eda
|
feat(daemon): raise default max sessions from 20 to 32 (#8235)
* feat(daemon): raise default max sessions from 20 to 32 * fix(daemon): update test assertion and docs for new default max sessions (32) * fix(daemon): sync default max sessions Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> |
||
|
|
7189a68334
|
fix(serve): isolate managed memory by selected workspace (#8056)
* fix(serve): isolate managed memory by workspace * feat(serve): add memory project scope option * test(serve): fix clean build type assertion * test(serve): cover untrusted workspace memory tasks * test(memory): cover remaining workspace paths * test(serve): cover unavailable memory lanes * test(memory): isolate default scope * fix(serve): address review feedback on workspace memory isolation (#8056) - Create secondary ACP mounts on demand for dynamically-registered workspaces so the qualified memory routes work beyond boot-time runtimes (rename getWorkspaceRememberLane → ensureWorkspaceRememberLane) - Remove the symlink-alias machinery from getAutoMemoryRoot: it had no producer, relaxed a documented invariant, and could throw on the per-turn hot path; workspace mode now uses the same plain path.join as git-root mode - Move memoryProjectScope validation into the pre-listen block - Use the shared sendWorkspaceRuntimeUnavailable helper in server.ts - Revert an unrelated test mock change; fix misleading 'compatibility fallback' wording in ServeOptions - Add workspace_qualified_memory capability tag, docs for the new flag and env var * docs(serve): add workspace_qualified_memory to conditional features table (#8056) * fix(serve): address follow-up review feedback on workspace memory isolation (#8056) * fix(serve): address follow-up review feedback on workspace memory isolation (#8056) Extract MEMORY_PROJECT_SCOPES const and MemoryProjectScope type in core so yargs choices, ServeOptions, ServeArgs, and the runQwenServe guard share one source of truth (reduces drift risk from five to three edit points; the fast-path guard keeps inline comparisons because an import boundary test forbids core imports on the lightweight startup path). Document memory-project-scope caveats in the user-facing docs: daemon vs standalone CLI split-brain, sanitizeCwd punctuation collisions, and flag vs env normalization differences. Add the per-lane MAX_PENDING resource note to the developer configuration reference. * fix(cli): add missing sessionRuntimeBaseDir to late-add workspace test (#8056) * test(serve): cover untrusted forget/dream and no-lane memory poll (#8056) * fix(core): extract MEMORY_PROJECT_SCOPES into zero-import leaf module (#8056) Importing the constant as a value from the core barrel turned it into a real static edge that pulled the entire 5.6 MB barrel into the serve pre-listen bundle closure, breaking the fast-path gate. Move MEMORY_PROJECT_SCOPES and MemoryProjectScope into a new memory/scopes.ts with no imports of its own, re-export from paths.ts so the barrel surface is unchanged, add a ./memoryScopes subpath export, and switch run-qwen-serve.ts to the narrow import. Also derive the unknown-scope guard in resolveWorkspaceProjectScope() from the constant instead of hardcoding 'git-root'. * test(cli): pin non-allocating contract in workspace memory poll test (#8056) --------- Co-authored-by: qwen-code-dev-bot <269191875+qwen-code-dev-bot@users.noreply.github.com> Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com> Co-authored-by: Qwen Autofix <qwen-autofix@users.noreply.github.com> Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com> Co-authored-by: Qwen Code Autofix <qwen-code-autofix@users.noreply.github.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com> |
||
|
|
95657feb6e
|
feat(core): add GenAI time-to-first-chunk tracing (#8150)
* feat(core): add GenAI time-to-first-chunk tracing Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(core): address review feedback on GenAI streaming telemetry (#8150) * fix(core): correct ttft_ms migration claim in telemetry docs (#8150) * fix(core): address review feedback on GenAI streaming telemetry (#8150) * fix(core): address review feedback on GenAI streaming telemetry (#8150) --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com> Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com> |
||
|
|
c50137cf86
|
fix(core): prevent subagents from asking users (#8219) | ||
|
|
08798b4832
|
feat(core): Normalize tool-call terminal telemetry (#8176)
Some checks are pending
E2E Tests / E2E Test (Linux) - sandbox:docker - shard 1/3 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker - shard 2/3 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker - shard 3/3 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none - shard 1/3 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none - shard 2/3 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none - shard 3/3 (push) Waiting to run
E2E Tests / web-shell Browser Regression (push) Waiting to run
E2E Tests / E2E Test - macOS - shard 1/2 (push) Waiting to run
E2E Tests / E2E Test - macOS - shard 2/2 (push) Waiting to run
E2E Tests / channel-plugin E2E (nightly) (push) Waiting to run
E2E Tests / cron-interactive E2E (nightly) (push) Waiting to run
SDK Java / ubuntu-latest / Java 11 (push) Waiting to run
SDK Java / ubuntu-latest / Java 21 (push) Waiting to run
SDK Java / windows-latest / Java 21 (push) Waiting to run
SDK Java / Real daemon E2E / Java 11 (push) Waiting to run
SDK Java / ubuntu-latest / Java 17 (push) Waiting to run
SDK Java / macos-latest / Java 21 (push) Waiting to run
* feat(core): normalize tool-call terminal telemetry Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(desktop): handle cancelled tool telemetry replay Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> |
||
|
|
079ce5346a
|
feat(agent): add fork tool execution allowlist (#8066)
* feat(agent): add fork tool execution allowlist * fix(agent): address fork allowlist review feedback --------- Co-authored-by: destire-mio <248462155+destire-mio@users.noreply.github.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com> Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> |
||
|
|
c50120985b
|
fix(serve): Prevent repeated workspace skill rescans (#8080)
* fix(serve): prevent repeated workspace skill rescans Make workspace skill status reads use committed snapshots and move refresh work to explicit mutation paths. Add generation-safe daemon caching, conditional HTTP responses, SDK revalidation, and multi-session extension refresh safeguards. Refs #8079 Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): narrow the workspace-skills read model and close its regressions Follow-up to the previous commit on this branch, from reviewing it. Subtractions — these were separable from the fix and carried more surface than value, so they move out of this change: - Revert the ETag / If-None-Match layer (CORS allow+expose headers, the SDK conditional JSON cache, the browser bundle budget bump). Express already emits an ETag and answers 304 for these routes, so the only new behavior was the SDK cache. It saves transfer bytes but no daemon work — the ETag is a hash of the already-serialized body — and it shipped without a paired `Cache-Control`, which is what actually keeps an intermediary from serving a stale snapshot of an authenticated, mutable resource. The SDK cache was also unbounded, with no eviction or clear entry point. - Revert moving `extensions_final` ahead of skill initialization in `Config.initialize`. In non-safe, non-bare mode `extensions_initial` is already the same argument-less `refreshCache()`, and it runs `applyStoreActivation`, so `getActiveExtensions()` is fully populated before skills are enumerated either way. The move changed only startup event order (and pushed permissionManager past the extension refresh) for every surface including the interactive CLI. Regression fixes — the read went pure, but two of its inputs lost their only path back to disk: - Extension sources have no watcher, unlike skills. With the per-read `extensionManager.refreshCache()` gone, an extension installed, removed, enabled, or disabled outside the daemon would never reach the snapshot until the child restarted — and because extension-level skills are derived from the extension set, a skill-watcher tick could not recover it either. Adds `ExtensionManager.refreshCacheIfSourcesChanged()`: a stat-based fingerprint over the extension directory entries, each manifest, the enablement file, and the store state, which refreshes only when they moved. A status read pays one readdir plus one stat per entry instead of a directory scan and a full parse, and stays self-healing. The baseline is the pre-load fingerprint, so a change landing during a refresh stays visible to the next check instead of being masked by a post-load stat. The directory and store halves are captured at different points because a refresh writes the store itself but never the manifests. - Revalidation is skipped in safe and bare mode, and the whole of it — including that mode check — sits inside its error boundary. Those modes never populate the extension cache by design, while the snapshot derives extension skills from `getExtensions()`, so revalidating there would have loaded the extensions the mode exists to exclude. Keeping the mode check outside the boundary would also have let a config missing those accessors fail a read. - `initialized: true` with an empty list when the config has no `SkillManager` is now `initialized: false`. The daemon latches any initialized answer into `lastWorkspaceSkillsStatus` and then prefers it over its own local enumeration, so the old value could suppress the fallback permanently. Also: - The retained-snapshot path bumped the freshness timestamp without checking its generation, so a read that started before an invalidation could push out the TTL of a snapshot a later read had committed — letting a post-mutation snapshot go unrevalidated for longer than the window. - `setWorkspaceSkillEnabled` folded `configsFailed` into `sessionsFailed`, but it sends `reason: 'settings'`, which never refreshes a skill cache, so the term was structurally zero. Report `configsFailed` from the `content` path instead, where it can actually be non-zero. - Documents the settings-freshness gap this read model accepts: enablement now comes from the child's in-memory `LoadedSettings`, which `SettingsWatcher` keeps current for the User and Workspace scopes but not for System / SystemDefaults (locked-skill policy) or an untrusted workspace. Tests: adds a real-filesystem guard that drives 50 consecutive cached reads and asserts zero additional readdir/readFile calls — the mocked suites could only prove `refreshCache` was not *called*, which is not the invariant that broke. Adds coverage for the fingerprint gate (steady state, install, removal, in-place manifest edit, concurrent callers, and the mid-refresh race), for the null-manager, moved-sources, and safe/bare-mode read paths, and for the generation guard. The generation-guard and safe/bare-mode tests were each verified to fail with their fix reverted. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
f3ad4fcffb
|
feat(serve): page large text files by byte cursor (#8002)
* fix(serve): allow bounded reads of large text files
* fix(serve): bound large-text reads by scan cost, not by which knob was set
Follow-up to the bounded large-text read path. Three changes:
Gate on any explicit window argument, not on `limit`. Gating on `limit`
had the cost model backwards in both directions: `{ line: 900_000_000,
limit: 20 }` was admitted despite walking the whole file, while
`{ maxBytes: 4096 }` — satisfiable from the first 4 KiB — was refused. A
read with no window argument at all still fails, since a caller that
believes it holds the whole file may write it back truncated.
Add MAX_TEXT_SCAN_BYTES (8 MiB). MAX_READ_BYTES caps what a read
returns; nothing capped what it cost. Line offsets are resolved by
scanning from byte 0, so a query param could turn into an
uninterruptible multi-second scan of an arbitrarily large file — and on
Windows hold a read handle for that span, blocking renames and deletes.
Past the budget the read is refused with `file_too_large` pointing at
readBytes, which reaches any offset in O(1).
Tolerate appends on streamed windows. Requiring whole-file size/mtime
stability after reading a prefix rejected reads whose returned bytes
were still valid, and the case it rejected — tailing a live log — is the
one this path exists for. Streamed windows now assert inode identity
plus "did not shrink"; truncation and replacement are still rejected.
Also: non-UTF-8 large text now returns `binary_file` rather than
`file_too_large`, so a client retrying on 413 with a smaller window
can't loop forever; and `readFileWithLineAndLimit` throws instead of
silently ignoring a caller-supplied `fileHandle` on the by-path
fallback.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* refactor(core): thread the descriptor instead of forking text-read helpers
PR #7947 pinned large-text reads to one inode by threading a caller-owned
FileHandle into readTextRange as an optional field, plus a second field,
forceStreaming, to suppress the buffering fast path. Two optional fields
produced four combinations: one meaningful, one used by a single test, one
unreachable, and — in readFileWithLineAndLimit — one that silently fell
through to a by-path read, defeating the reason the caller opened a handle.
Unify the two encoding detectors. detectFileEncoding now takes a path or a
borrowed handle, so detectFileHandleEncoding is deleted along with the
message discrepancy between them: an encoding iconv-lite cannot load now
raises LargeNonUtf8TextError naming that encoding rather than deferring to
the decoder's generic invalid-utf8 variant. Both still refuse the file, and
the Serve boundary maps both to binary_file.
Split the reader into readTextRange (path) and readTextRangeFromHandle
(always streams, both byte bounds required). The unreachable combination and
its untested readFileHandleBuffer are gone, and with no fileHandle parameter
left for readFileWithLineAndLimit to ignore, the RangeError guarding that
fallthrough is deleted too — the trap can no longer be expressed.
CoreReadTextFileHandleRequest drops its required stats field. Nothing
downstream read it, and because the ACP request type it extends permits
extra properties, TypeScript accepted the dead argument silently.
readFileHandleChunks becomes chunksFromHandle(fh, from) — the one seam
byte-cursor text paging needs.
No observable change at the Serve boundary: its 222 tests pass unmodified.
Two fileSystemService tests were deleted rather than repaired; they asserted
the arguments readFileWithLineAndLimit received, which is nothing once the
handle path stops calling it. Their coverage lives in read-text-range.test.ts
against real files and in workspace-file-system.test.ts at the real boundary.
258 production lines in core, net -71 overall.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* refactor(core): make CoreReadTextFileHandleRequest standalone
Self-audit follow-up to f55c867a. Two fields survived the reshape that the
handle path never reads:
- `stats` was documented as required ("must pass the Stats captured from that
handle") and nothing downstream read it. The handle path always streams, so
it never needs a size to choose a strategy, and the encoding probe does its
own fstat.
- `path` became dead once readTextRangeFromHandle replaced the path-plus-handle
call. Errors are labelled with the path by the Serve boundary that owns it.
Neither was caught by the compiler: the ACP ReadTextFileRequest the type
derived from permits extra properties, so the CLI kept passing both silently.
That is the argument for declaring the type standalone rather than Omit-ing
four of six inherited fields and quietly re-admitting the rest.
Also record the second behaviour delta of the detector merge in the design
doc: detectFileEncoding catches I/O errors and falls back to 'utf-8', where
detectFileHandleEncoding let them propagate. The failure is not lost — a handle
that fails the 8 KiB probe fails the streaming read immediately after — but a
different call now reports it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(serve): page large text files by byte cursor
Line offsets address a byte stream, so `readText` resolves them by scanning
from byte 0. Paging a large log that way is O(n^2) across pages, and past
MAX_TEXT_SCAN_BYTES (8 MiB) a deep page is refused outright — agents had no
O(1) path short of dropping to GET /file/bytes and splitting lines themselves,
losing encoding handling, multibyte safety, and the binary_file refusal.
A response that leaves content behind now returns `hasMore`, and where a file
byte offset is derivable, an opaque `nextCursor`. Passing it back as `cursor`
resumes in O(1). Page 1 is an ordinary `limit` read, so clients never compute
byte offsets themselves, and a paging loop does not break when a file happens
to be small.
The cursor is unsigned base64url JSON carrying {off, size, dev, ino}, matching
encodeOrganizedCursor rather than the HMAC-signed transcript codec: the path is
re-resolved through the workspace boundary on every request, so a forged cursor
can only move the offset within a file the caller may already read — what
GET /file/bytes?offset= allows today. What the payload is for is staleness:
a replaced or truncated file yields hash_mismatch instead of bytes from the
wrong place, while an append leaves an outstanding cursor valid — the case the
feature exists for.
Every minted cursor points at the start of a line. When a single line exceeds
maxOutputBytes the reader emits a truncated prefix and skips to the next line
rather than resuming mid-line, because a mid-line cursor makes the following
page snap forward and silently drop the rest of that line at the seam. Windows
cut mid-line by a byte cap therefore report hasMore with no cursor, as do
non-UTF-8 snapshot reads whose decoded text is a UTF-8 re-encoding with no
mapping back to file offsets. That is why hasMore is a field rather than a
restatement of nextCursor.
Cursor reads branch before the size check, not by widening the window gate:
a cursor read of a file under MAX_READ_BYTES would otherwise land on the
snapshot path, which knows only line/limit, and silently return line 0.
Adds the workspace_file_read_cursor capability, per the convention that new
behavior gets a new tag, and retargets the scan-budget hint at cursor paging.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(core): advance UTF-8 cursors after truncation
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* docs(serve): clarify cursor bootstrap limits
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(sdk): raise daemon browser bundle budget
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* test(serve): cover ACP cursor dispatch and cursor binary_file mapping (#8002)
* fix(core): only set sawCrlf for emitted lines in cursor paging (#8002)
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com>
|
||
|
|
c97026040e
|
feat(channels): add pairing approval management API (#8045)
* feat(channels): add pairing approval management API * fix(sdk): expose pairing approval types Re-export the new approval and revocation types from the public SDK entry, and pin the qualified workspace DELETE request body in regression coverage. --------- Co-authored-by: qwen-code-dev-bot <269191875+qwen-code-dev-bot@users.noreply.github.com> |
||
|
|
ec9c36ef82
|
feat(channels): add GitLab polling channel adapter (#7862)
* feat(channels): add GitLab polling channel adapter
Poll GitLab todos via @gitbeaker/rest, dispatch notes through the
existing PollingChannelBase pipeline. Key design points:
- action_prompt_template config drives event filtering and metadata
rendering (unconfigured actions are skipped)
- Per-repo cursor (repo[chatId].last_read) as notes window lower bound,
global lastProcessedAt for todo-level dedup
- mark_done after successful processing; failure skips mark_done for
retry on next poll
- Mention gating delegated to base GroupGate (adapter only sets
isMentioned flag)
- First-contact body fallback for todos with no notes (e.g. mention in
issue description)
* fix(channels/gitlab): persist cursor after each successful todo
Call saveCursor() immediately after advancing lastProcessedAt so that
progress is durable even if the process crashes mid-poll. Also removes
the local watermark variable in favor of direct assignment.
* fix(channels/gitlab): persist cursor on every advancement including skips
* fix(channels/gitlab): address review critical issues
- Remove non-functional proxyAgent (gitbeaker doesn't support it)
- Construct repo_url from host + path (API doesn't return web_url)
- Handle directly_addressed action (falls back to mentioned template)
- First-contact fetches target description instead of using todo.body
- Move todo.project dereference inside try block
- Filter confidential notes
- Update channel-registry.test.ts for gitlab entry
* fix(channels/gitlab): address review suggestions
- Warn on connect if action_prompt_template is not configured
- Guard todo.target.iid before use
- Skip paths now mark_done (best-effort) to clean GitLab UI
- Remove postErrorComment (avoids duplicate comments on retry)
- Fetch only first page of notes (desc, maxPages:1, perPage:100)
instead of paginating entire note history
- Extract fetchRecentNotes for single-page windowed enumeration
* refactor(channels/gitlab): simplify to todo.body dispatch, add description mention support
- Remove notes API fetching; dispatch todo.body directly
- Detect description mentions via target_url anchor (#note_ absence)
- Always fetch target description for %description% metadata
- Remove per-repo cursor; dedup via cursor + mark_done only
- Cursor advances regardless of success/failure (no retry)
- Use zod for cursor validation
- Rename template vars to GitLab terminology:
%project% %project_url% %target_type% %iid% %title% %description% %todo_id%
- Support %% escape for literal percent
* docs(channels): add GitLab adapter documentation
- New user guide: docs/users/features/channels/gitlab.md
- Update _meta.ts navigation
- Update developer adapter matrix and SDK list
* fix(channels/gitlab): use correct Issues.show(issueIid, { projectId }) signature
* chore: regenerate NOTICES.txt for new gitlab channel dependencies
* fix(channels/gitlab): address review suggestions
- Add todo.project null guard (item 2)
- Single-pass regex for %% escape + %var% substitution (item 4)
- sendThreadMessage throws directly on undefined threadId (item 5)
- Dedup fetchDescription with per-poll cache (item 6)
- Remove per-todo saveCursor; base class saves after pollOnce (item 7)
- Add undefined threadId test (item 8)
- Expand confidential notes limitation in docs (item 3)
* test(channels/gitlab): add mention tests, directly_addressed coverage, skip assertions, temp cleanup
- New mention.test.ts: 14 cases for testBotMention/stripBotMention/escapeRegex
- Add directly_addressed fallback test
- Skip tests now assert TodoLists.done + cursor advancement
- afterEach cleans up mkdtempSync temp dirs
* fix(channels/gitlab): address review round 4
- Non-mention actions (assigned, etc.) set forceMentioned=true to bypass GroupGate
- Merge dead note-filter tests into single 'skips todo authored by bot'
- Log fetchDescription errors to stderr instead of silent swallow
- Post error comment on issue/MR when handleInbound fails (best-effort)
* fix(channels/gitlab): always force isMentioned=true, remove regex re-derivation
The action_prompt_template config is already the event filter, and
GitLab has already decided the mention when creating the todo.
Re-deriving isMentioned via regex on todo.body causes permanent
message loss when the regex misses (description mention + fetch
failure, group mentions). Always set forceMentioned=true so
GroupGate never drops a todo that passed the template filter.
* fix(channels/gitlab): propagate fetchDescription errors for description mentions
For note mentions, description is metadata-only — fetch failure is
logged and swallowed. For description mentions, description IS the
message — fetch failure now propagates to the outer catch, which
posts the ⚠️ error comment so the user knows to re-mention.
* perf(channels/gitlab): clean up stale todos, skip unnecessary fetchDescription
- Mark stale todos (updated_at <= cursor) as done on each poll to
prevent perpetual re-fetching of pre-existing pending todos
- Skip fetchDescription for note mentions when template does not
contain %description%, saving one API call per todo
- Update docs: stale todo cleanup, error comment on failure
* docs(channels/gitlab): clarify requireMention is bypassed, template is the real filter
* Apply suggestions from code review
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
* fix(channels/gitlab): use todo ID cursor instead of timestamp to eliminate equal-timestamp loss
Timestamp-based cursors (second granularity) could silently destroy
todos sharing the same updated_at as the cursor boundary. Switch to
monotonically increasing todo IDs which are unique and collision-free.
Add initialized flag to preserve first-start drain semantics: pre-existing
pending todos are marked done without dispatch on the first poll cycle.
* fix(channels/gitlab): harden first-poll drain, add ordering tests, fix lockfile
- Replace Math.max(...spread) with reduce to avoid RangeError on large
backlogs (~100k+ todos). Move initialized=true after the drain work so
any throw retries the drain instead of falling through to dispatch.
- Add unit tests: identical-timestamp delivery and id-order-when-updated_at-disagrees
(kills M2 sort mutant).
- Align lockfile: file:../base → ^0.21.0 for channel-base dep.
* fix(channels/gitlab): include dot in mention lookahead for GitLab usernames
GitLab usernames may contain dots (e.g. bot.name). The lookahead
character class inherited from GitHub omitted '.', causing @bot.name
to match as @bot. Add '.' to the negated class.
* docs(channels/gitlab): align docs with ID cursor and drain semantics
- Add first-poll drain as step 2 in How It Works
- Clarify GroupGate always passes (isMentioned forced true)
- Document initialized flag in Known Limitations
* Apply suggestions from code review
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
* fix(channels/gitlab): align package version and channel-base dependency to 0.21.1
Bump version from 0.21.0 to 0.21.1 to match other channel packages after
upstream merge. Pin @qwen-code/channel-base to exact 0.21.1 instead of
^0.21.0, matching the convention used by other published channels.
* fix(channels/gitlab): regenerate lockfile to match package.json versions
Manually add only gitlab-related lockfile entries (workspace, @gitbeaker
packages, transitive deps, channel-gitlab link) without unrelated npm
normalization churn.
* test(channels/gitlab): add regression tests for first-poll drain hardening
Two tests that kill the M1 (Math.max spread RangeError) and M2 (flag
ordering) mutants which survived the original 46-test suite:
- 150k todo drain verifies reduce() handles large backlogs without
RangeError and without dispatching
- Drain throw verifies initialized stays false so the next poll retries
the drain instead of falling through to dispatch
Test file duration: ~40ms → ~170ms.
* docs(channels/gitlab): clarify groupPolicy must be "open" and add runtime warning
The default groupPolicy "disabled" silently drops all mentions — todos are
marked done and cursor advances, but no dispatch occurs. Fix misleading docs
that said "GroupGate always passes" (only true at groupPolicy: "open") and
add a connect()-time warning when groupPolicy is not "open".
* fix(channels/gitlab): correct xcase integrity hash in lockfile
The manually added xcase entry had a typo in the sha512 hash (ys → ks),
causing npm ci EINTEGRITY failures in CI.
* fix(channels/gitlab): correct requester-utils integrity hash in lockfile
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(channels/gitlab): allow groupPolicy "allowlist" in warning and docs
The groupPolicy warning and docs incorrectly stated that groupPolicy
must be "open". In reality "allowlist" with the project listed also
works because isMentioned is forced true and GroupGate only requires
the group to be listed. Also fix the inaccurate "no error is logged"
claim — ChannelBase logs preflight rejected reason=group_disabled.
Fixes R5-🟡3 from PR #7862 review.
---------
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
||
|
|
4615f84d73
|
fix(serve): allow bounded reads of large text files (#7947)
* fix(serve): allow bounded reads of large text files
* fix(serve): bound large-text reads by scan cost, not by which knob was set
Follow-up to the bounded large-text read path. Three changes:
Gate on any explicit window argument, not on `limit`. Gating on `limit`
had the cost model backwards in both directions: `{ line: 900_000_000,
limit: 20 }` was admitted despite walking the whole file, while
`{ maxBytes: 4096 }` — satisfiable from the first 4 KiB — was refused. A
read with no window argument at all still fails, since a caller that
believes it holds the whole file may write it back truncated.
Add MAX_TEXT_SCAN_BYTES (8 MiB). MAX_READ_BYTES caps what a read
returns; nothing capped what it cost. Line offsets are resolved by
scanning from byte 0, so a query param could turn into an
uninterruptible multi-second scan of an arbitrarily large file — and on
Windows hold a read handle for that span, blocking renames and deletes.
Past the budget the read is refused with `file_too_large` pointing at
readBytes, which reaches any offset in O(1).
Tolerate appends on streamed windows. Requiring whole-file size/mtime
stability after reading a prefix rejected reads whose returned bytes
were still valid, and the case it rejected — tailing a live log — is the
one this path exists for. Streamed windows now assert inode identity
plus "did not shrink"; truncation and replacement are still rejected.
Also: non-UTF-8 large text now returns `binary_file` rather than
`file_too_large`, so a client retrying on 413 with a smaller window
can't loop forever; and `readFileWithLineAndLimit` throws instead of
silently ignoring a caller-supplied `fileHandle` on the by-path
fallback.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(serve): harden large text range snapshots
Treat caller-owned file handles as bounded streaming reads, cap them to the captured file size, and reuse the chunk buffer.
Restore strict Serve snapshot stability and align returned-slice metadata with the full-snapshot path.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(serve): make large text ranges snapshot-safe
* fix(serve): harden large-text ctime tests and document buffer reuse (#7947)
Address review feedback on the large-text range read PR:
- Pause before restoring mtime in the two ctime-dependent mutation tests so the change-time advances past the pre-read snapshot even on coarse-resolution filesystems, removing a latent flake in the same-size-overwrite precondition. The assertions are unchanged.
- Document at the readFileHandleChunks yield site that the 512 KiB buffer is reused across iterations, so yielded views must be decoded or copied before advancing the generator.
* docs(serve): soften same-size rewrite guarantee to coarse-clock best-effort (#7947)
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen Code Autofix <qwen-code-autofix@users.noreply.github.com>
|
||
|
|
788e5cd3a8
|
feat(core): add ARMS session user ID (#7921)
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> |
||
|
|
8785216be5
|
feat(web-shell): add monitor task details (#7817)
* feat(web-shell): add monitor task details * fix(web-shell): align monitor tab title with merged snapshot and reset expansion (#7817) --------- Co-authored-by: ytahdn <ytahdn@gmail.com> |
||
|
|
4958120c21
|
docs(channels): Document loops and proactive delivery (#7628)
* docs(channels): document loops and proactive delivery Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * docs(channels): clarify standalone vs daemon loop storage paths (#7628) --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com> |
||
|
|
3a6c8e0c03
|
feat(skills): add overridable default-disabled state (#7357)
* feat(skills): add overridable default-disabled state * fix(skills): address review feedback on default-disabled PR (#7357) - Fix disabledChanged comparison in SkillsManagerDialog to use previousDisabled (locked names filtered) instead of workspaceDisabled, preventing spurious settings writes when a skill is disabled at both workspace and higher scope - Import SettingScope as a value instead of string-casting literals in skill-settings.ts for compile-time safety - Add dual-key change test: enabling a workspace-hard-disabled default-disabled skill produces both skills.disabled and skills.enabled changes in one operation - Add legacy inactive-extension branch tests: reject when disabledReason is undefined and skill is not in settings disablements; allow when it is disabled by settings * fix(cli): address skills picker review feedback (#7357) Extract the skills picker's workspace persistence computation into a tested pure function so orphaned workspace disables (skills not currently loaded) are explicitly preserved and pinned by a regression test. Also add an integration test asserting a workspace-scope hard disable surfaces disabledReason 'hard' through the full loadSettings -> resolveSkillSettings -> mapSkillConfigToStatus pipeline. * fix(cli): resolve skill disablements in safe mode for status API (#7357) * fix(cli): dynamically import skill-settings in serve to keep fast-path closure clean (#7357) --------- Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com> Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com> Co-authored-by: Qwen Code Autofix <qwen-code-autofix@users.noreply.github.com> Co-authored-by: Qwen Code Autofix <qwen-code-autofix[bot]@users.noreply.github.com> Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com> |
||
|
|
a8a28a1137
|
fix(acp-bridge): raise live journal caps and expose as daemon config (#7715)
The live journal (DAEMON-009) caps were too conservative for real-world agent turns: 2000 events / 2 MiB caused 79% event loss on a typical long turn (9647 events). Raise defaults to 10 000 events / 8 MiB and expose them as --max-journal-events / --max-journal-bytes CLI flags, following the same config path as --compacted-replay-max-bytes. Also fix stale docs that described the liveJournal as uncapped. |
||
|
|
62e009a952
|
feat(channels): GitHub polling adapter with notification-as-wakeup architecture (#7632)
* feat(channels): add GitHub polling adapter with notification-as-wakeup architecture
Introduce a GitHub channel adapter that monitors notifications and
responds to @mentions on issues/PRs by posting comments. Uses
last_read_at as a per-thread watermark for comment enumeration,
replacing the unreliable latest_comment_url approach.
Foundation changes to ChannelBase:
- sendThreadMessage for thread-targeted delivery (IM adapters unchanged)
- Envelope.metadata appended to prompt after command parsing
- chat_thread session scope (channel:chatId:threadId) prevents
cross-repo session collision
- polling-helpers: testBotMention/stripBotMention (separate detection
from stripping, no whitespace collapsing), cursor persistence,
abortableSleep
GitHub adapter design:
- Notifications as wake-up signals only (unread filtering)
- listComments enumeration with last_read_at watermark
- Bot self-comment filtering, case-insensitive mention regex
- In-memory recentlyProcessed set for mark-read failure dedup
- First-contact: new issue body @bot triggers processing
- Error comment + cursor advance on handleInbound failure
- pollInterval minimum 60s, exponential backoff 2s-30s
* refactor(channels): extract PollingChannelBase from polling-helpers
Replace the loose polling-helpers module with a PollingChannelBase<Cursor>
abstract class that encapsulates the poll loop, cursor persistence (JSON,
atomic write), exponential backoff, and start/stop lifecycle. Subclasses
implement only pollOnce() and createInitialCursor().
- Delete polling-helpers.ts (cursor fns + abortableSleep moved into base)
- Move mention utilities (testBotMention/stripBotMention) to github pkg
- GithubAdapter now extends PollingChannelBase<{ lastProcessedAt }>
* fix(channels): remove Gitea/GitLab mention from sendThreadMessage JSDoc
* fix(channels): match /pulls/N in notification subject URL
GitHub PR notifications use /repos/{owner}/{repo}/pulls/{N} in
subject.url, not /issues/{N}. The regex only matched /issues/,
causing PR notifications to be skipped and marked read.
Also sets threadId to 'pr:N' for PRs (was always 'issue:N').
* test(channels): add PR body first-contact unit test
Verify that PR notifications with @mention in the body (not a comment)
correctly trigger the first-contact path: extractFromSubjectUrl matches
/pulls/N, listComments returns empty, tryFirstContactBody fetches the
PR body and dispatches to handleInbound with threadId 'pr:N'.
* feat(channels): read pollInterval from channel config in PollingChannelBase
Move pollInterval config reading from GithubAdapter to the base class.
The user's configured pollInterval in settings.json is now respected
directly without a minimum enforcement. Defaults to 60000ms when not
configured.
* fix(channels): prepend metadata before prompt text
Agent sees issue/PR context (type, title, URL) before the user's
request, improving comprehension. Metadata is still appended after
slash-command parsing so commands are not affected.
* refactor(channels): route all ChannelBase delivery through sendThreadMessage
Replace all internal sendMessage calls with sendThreadMessage, passing
envelope.threadId (or target.threadId / undefined) so polling adapters
can deliver to the correct thread. IM adapters are unaffected — the
default sendThreadMessage falls through to sendMessage.
* docs(channels): document sendThreadMessage delivery architecture
* fix(channels): address review findings
- Cap recentlyProcessed Set at 10k entries to prevent unbounded growth
- Validate cursor JSON shape (non-null object) in loadCursorFromDisk
- sendThreadMessage falls through to sendMessage when threadId is
undefined instead of silently dropping
- Remove duplicate pollInterval from GithubConfig (now in ChannelConfig)
- Fix chat_thread routing key trailing colon when threadId is undefined
* docs(channels): fix metadata JSDoc — prepended, not appended
* fix(channels): use recentlyProcessed dedup for first-contact body
Replace the fragile createdAt-vs-cursor check in tryFirstContactBody
with the recentlyProcessed set. The cursor advances globally based on
notification updated_at — when a different notification with a later
updated_at is processed first, the cursor can advance past the issue's
created_at, causing the first-contact check to incorrectly skip the
issue body (forget reply bug, found in E2E TC-2b).
* refactor(channels): two-layer dedup for GitHub adapter
Layer 1: global cursor filters notifications by updated_at (sorted
ascending, old first). Layer 2: server-side last_read_at filters
comments by created_at (sorted ascending).
- Delete recentlyProcessed Set (no longer needed)
- Sort notifications by updated_at ascending before processing
- Sort comments by created_at ascending before processing
- Pass latest comment created_at to markThreadAsRead as last_read_at
* fix(channels): address review findings on GitHub adapter
Blockers:
- sessionScope: add defaultSessionScope to ChannelPlugin, apply in
parseChannelConfig so router and adapter agree on 'chat_thread'
- channel-registry.test.ts: add 'github' to expected type list
Should-fix:
- Replace per-thread markThreadAsRead (PATCH) with bulk
markNotificationsAsRead (PUT /notifications + last_read_at).
API errors stop the batch without marking failed notifications
read; handleInbound errors still advance (error comment posted).
- connect() throws on bot identity failure instead of failing open
- metadata appended after promptText (inside sender attribution)
- isSharedSessionTarget includes 'chat_thread' scope
Nits:
- startPollLoop re-entrancy guard
- clean-package-build-artifacts.js includes github
- index.ts re-exports GithubChannel
* fix(channels): use max updated_at of all fetched notifications as last_read_at
Prevents re-fetching the same notifications in the next poll cycle.
The bulk PUT /notifications marks all fetched notifications as read
up to the max updated_at, regardless of per-notification success.
* fix(channels): address review round 2 findings
- #12: loadCursorFromDisk rejects arrays
- #13: pollInterval validates positive finite number
- #19: first-contact gate uses dispatchedMention flag (not newComments.length)
- #25: stripBotMention no longer trims (preserves indentation)
- #27: remove adapter-level requireMention, unify on GroupGate
- #31: add chat_thread SessionRouter routing key tests
- #33: clear metadata on collect-mode synthetic envelope
- #35: fix PollingChannelBase.test import path
- #36: add @octokit/rest to 15-channel-adapters.md dependencies
* docs(channels): document known limitations for GitHub adapter
- First start skips existing unread notifications (cursor = now)
- Requires classic PAT (fine-grained PATs lack notifications API)
- PR review comments not enumerated (issue comments only)
* fix(channels): address review round 3 findings
- #9: buildMetadata derives web URL from baseUrl (GHE support)
- #12: sendThreadMessage throws on invalid threadId format
- #19: mention lookbehind matches cc:@bot and "@bot" patterns
- #23: cursor file name uses sha256 hash to prevent collision
- #26: test verifies cursor persistence to disk
- #31: postErrorComment double-failure logs to stderr
- #45: tests use mkdtempSync isolation instead of real QWEN_HOME
* fix(channels): pass threadId through pairing flow + sendResponseMessage test
- #13+16: onPairingRequired receives envelope.threadId and passes it
to sendThreadMessage, so pairing codes are delivered on threaded
channels (GitHub) instead of throwing
- #6: add test verifying sendResponseMessage resolves threadId from
router.getTarget and passes it to sendThreadMessage
* fix(channels): pass proxy to Octokit for daemon-worker environments
- #44: read this.proxy from ChannelBaseOptions and pass
HttpsProxyAgent to Octokit request.agent, matching the
Telegram adapter pattern
* fix(channels): address review findings — immutable senderId, comment time window, validateCursor, retry wrapper
- senderId uses immutable user.id; allowedUsers resolved to IDs at connect
- Comment filter upper bound: updated_at <= maxUpdatedAt (batch window)
- Per-notification errors use continue (best-effort), not break
- validateCursor() virtual hook for subclass cursor shape validation
- sendThreadMessage/postErrorComment wrapped in githubApi() retry
- webOrigin handles default api.github.com → github.com
- Docs: classic PAT only, markNotificationsAsRead, dedup claims removed
- Tests: threadId priority, metadata consumption, defaultSessionScope,
QWEN_HOME isolation, persistent mock rejection
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(channels): mark notifications read before processing to prevent duplicate replies
Bot's own replies bump notification updated_at past the pre-captured
maxUpdatedAt, so markNotificationsAsRead(maxUpdatedAt) failed to mark
them read — the next poll re-fetched the same comments and replied
again.
Move markNotificationsAsRead + cursor advance before the processing
loop (best-effort delivery). This is safe because bot's own comments
do not flip notifications back to unread. Update docs to reflect the
new poll cycle order and best-effort semantics.
* fix(channels): update sender gate after allowedUser ID resolution and harden tests
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(channels): cursor-based comment window to prevent duplicate replies
PUT /notifications is async (202) with a last_read_at cutoff — the
bot's reply bumps updated_at past the cutoff before the server
processes the mark, so the notification is never marked read and gets
re-fetched on the next poll, causing duplicate replies.
Use the cursor value before advancement as an exclusive lower bound
for the comment enumeration window: (windowSince, maxUpdatedAt].
Comments already eligible in a previous poll are excluded regardless
of whether the mark succeeded. Zero new persistent state.
* fix(channels): cursor-based comment window to prevent duplicate replies
PUT /notifications is async (202) with a last_read_at cutoff — the
bot's reply bumps updated_at past the cutoff before the server
processes the mark, so the notification is never marked read and gets
re-fetched on the next poll, causing duplicate replies.
Use the cursor value before advancement as an exclusive lower bound
for the comment enumeration window, with per-notification last_read_at
as the preferred lower bound when available (server-side per-thread
watermark). Comments already eligible in a previous poll are excluded
regardless of whether the mark succeeded. Zero new persistent state.
* fix(channels): address review findings — null guard, cursor validation, metadata dedup, abortable sleep, docs
- Guard against null notification.subject.url in pollOnce
- Validate lastProcessedAt is a parseable date in validateCursor
- Add metadata: undefined to second collect-mode drain path
- Refactor abortableSleep as protected method on PollingChannelBase
- Fix docs: requireMention is nested under groups.*
- Add tests: chat_thread shared session, dispatchedBodies eviction,
cursor enumeration window, last_read_at in mention tests
* docs(channels): sync docs with implementation — cursor shape, error handling, GitHub adapter tables, first-contact
- Design doc: update Cursor to { lastProcessedAt, dispatchedBodies? }, add
validateCursor date check, abortableSleep protected method, break-on-error
semantics, subject.url null guard
- Developer docs: add GitHub to adapter table and adapter matrix
- User guide: add first-contact step to How It Works, clarify mark-before-process
* fix(channels): address review round 2 — error dedup, abortable retry, backoff reset, window test
- Record dispatchedBody on first-contact handleInbound failure to prevent
duplicate error comments when mark-read async hasn't taken effect
- Use abortableSleep instead of raw setTimeout in githubApi retry so
disconnect() can interrupt rate-limit cooldowns
- Reset consecutiveErrors in startPollLoop so stop/restart cycles don't
inherit stale elevated backoff
- Add test for cursor window client-side lower-bound exclusion filter
* fix(channels): address review round 3 — cursor validation, error dedup, sender gate, bot-self body
- validateCursor: normalize falsy non-array dispatchedBodies (false/0/""/null)
to [] instead of passing them through to .includes() which throws TypeError
- Set dispatchedMention after postErrorComment to prevent first-contact from
posting a duplicate error comment on the same thread
- Only set dispatchedMention when the sender passes the sender gate, so a
disallowed commenter's mention no longer suppresses a valid first-contact
body from an allowed issue author
- Skip bot-authored issue bodies in tryFirstContactBody to prevent
self-response loops under open sender policy
* fix(channels): address review suggestions — test coverage, cursor filename, assertion precision
- Pairing flow: add threadId pass-through regression test
- pollInterval: add table-driven edge cases (0, -1, NaN, Infinity, string)
- Add null-URL notification followed by valid notification batch test
- Fix comment window test to assert paginate call 3 (listComments) not call 2
- Truncate cursor filename encoded prefix to 200 chars (filesystem 255 limit)
- Assert mark-read uses batch maxUpdatedAt, not just { read: true }
- Assert real GitHub plugin declares defaultSessionScope chat_thread
- Add invocationCallOrder assertion for mark-before-process ordering
* fix(channels): address review round 4 — allowedUsers throw on resolve failure, crash table fix, mark-read failure test
* fix(channels): address review round 5 — created_at filter, retry-after NaN guard, retry/sendThreadMessage tests, docs fixes
* fix(channels): address ci-bot review 4778587403 — reconnect idempotency, github type enumerations, retry/webOrigin tests
* chore(channels): align channel-github version to 0.21.0 after upstream merge
* chore(channels): update package-lock.json for channel-github 0.21.0
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
---------
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: OrbitZore <orbitzore@users.noreply.github.com>
|
||
|
|
c4859627a7
|
feat(serve): Hot-reload workspace trust changes (#7268)
Some checks are pending
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
E2E Tests / cron-interactive E2E (nightly) (push) Waiting to run
E2E Tests / web-shell Browser Regression (push) Waiting to run
SDK Java / ubuntu-latest / Java 11 (push) Waiting to run
SDK Java / ubuntu-latest / Java 17 (push) Waiting to run
SDK Java / macos-latest / Java 21 (push) Waiting to run
SDK Java / ubuntu-latest / Java 21 (push) Waiting to run
SDK Java / windows-latest / Java 21 (push) Waiting to run
SDK Java / Real daemon E2E / Java 11 (push) Waiting to run
* feat(serve): hot-reload workspace trust changes Rebuild workspace runtime generations when trust policy changes, fail closed across daemon routes, and expose reconciliation status to SDK and Web Shell clients. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#7268) Document the trust hot-reload capability and reuse the daemon environment fallback so the serve process environment guard remains satisfied. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): cache workspace trust status snapshots Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix: address trust reload race regressions Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): avoid repeated runtime containment Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): harden workspace generation boundaries Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): restore stale session owner fallback Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): preserve workspace metadata across trust reloads Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): align hot-reload trust semantics Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): stop git-state watcher on dispose only, fix git chip test (#7268) beginDrain stopped the git-state watcher but cancelDrain had no way to restart it, leaving the watcher disposed until the next lazy poll. disposeRuntime already stops git-state when the drain is committed, so the beginDrain stop was redundant — remove it. Also fix the WorkspaceSection git chip test that broke when the trigger changed from <button> to <span role="button"> inside DropdownMenuTrigger: use closest('[role="button"]') and interact with the dropdown menu item. * fix(serve): address review feedback on trust polling and setValue assertion (#7268) * fix(cli): correct daemon trust policy settings precedence and drain continuation (#7268) * fix(serve): address review feedback on fork cleanup, persist simplification, sync guard, and a11y (#7268) * fix(serve): assert before mutate in setValue, add pre-mutation guard, trust-before-generation ordering (#7268) * fix(serve): honor system defaults in trust policy Apply the documented settings precedence to daemon folder trust evaluation and keep workspaces outside configured trust rules fail-closed. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): preserve managed scratch trust during reloads Keep daemon-created scratch workspaces trusted across policy reloads while retaining controlled-root validation, and reject trust mutations that cannot apply to these fixed-trust runtimes. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): guard auth provider persistence by generation Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(serve): remove Web Shell trust UI Keep this PR focused on daemon and SDK trust reconciliation; the Web Shell integration can follow separately. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(sdk): restore workspace trust bundle budget Preserve the merge-only browser bundle allowance required by the additive workspace trust v2 SDK surface after rebasing. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): handle trusted folder write failures Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): keep capabilities available during trust reload Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): address review feedback for workspace trust hot reload (#7268) Drop the closed generation guard before retrying dynamic workspace runtime creation so the retried runtime starts with a fresh, open guard instead of inheriting the one closed during the abandoned attempt. Make the /workspace/reload trust reconcile fire-and-forget with a swallowed rejection (failures are reported separately), reuse sendGenerationClosedError for the memory write error path, and assert the subagent deletion commit boundary once before unlinking so a closed generation fails atomically. Add coverage for the blocked-entry deep health probe and the /session/:id/cd generation-close-during-flight path. * fix(serve): close trust reload cleanup gaps Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): use fire-and-forget for trust reconcile in workspace-qualified reload (#7268) * fix(serve): address review feedback on generation guard and trust reconciler (#7268) * fix(serve): use shared helpers for untrusted/generation-closed responses (#7268) * fix(serve): continue cleanup after drain commit errors Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): retry transient trust policy disappearance Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): align status provider trust default with route-level check (#7268) * fix(serve): clean up worktree on generation guard abort (#7268) * fix(cli): guard tool and skill settings commits Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(cli): add discriminating persistent-ENOENT test for trust policy read (#7268) * fix(serve): close runtime generation gaps Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): preserve scheduled task cap errors Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(serve): address review feedback on trust reconciler, settings guard, and route simplification (#7268) * fix(serve): preserve containment retry semantics Restore the last verified trust-reconciliation and generation-guard behavior after the automated review fix marked an unconfirmed disposal as contained and removed per-scope commit checks. Defer the remaining late-round suggestions to avoid expanding the PR. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com> Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com> Co-authored-by: Qwen Autofix <qwen-autofix@alibaba-inc.com> Co-authored-by: Qwen Code Autofix <qwen-code-autofix@users.noreply.github.com> |
||
|
|
f4e333c580
|
fix(mcp): harden OAuth callback handling (#7510) | ||
|
|
541c80d678
|
feat(serve): expose workspace Channel management API (#7637)
* feat(serve): expose workspace Channel management API * fix(cli): add workspace boundary guards to stop and remove channel methods (#7637) * fix(cli): defer channel management runtime loading * test(serve): cover channel management capability * fix(serve): scope channel ownership to workspace and address review feedback (#7637) * fix(serve): scope assertOwnedRuntime to workspace and add no-store to mutation routes (#7637) * fix(serve): serve channel-types without resolving management service (#7637) * fix(serve): add validateClient to GET /channels and expand invalid-client test coverage (#7637) * fix(serve): prevent double 400 response when both name and body validation fail (#7637) * test(serve): assert workspace reload is blocked * test(serve): assert workspace reload is blocked (#7637) * test(serve): expand route test coverage for review suggestions (#7637) * refactor(cli): compose workspaceCommittedNames from workerFor to remove duplicated predicate (#7637) --------- Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com> Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com> Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com> |
||
|
|
055523afab
|
feat(core): Align GenAI content telemetry fields (#7667)
* feat(core): align GenAI content telemetry fields Capture provider-final GenAI messages and tool payloads with the shared ARMS/OpenTelemetry field contract, and retire equivalent private content aliases. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(telemetry): address content observability review Keep ACP tool telemetry best-effort, improve diagnostics and sensitive-off coverage, and document finish-reason and tool-description behavior. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * docs(telemetry): clarify optional tool parameters Document that invalid optional parameter schemas are omitted while required tool identities remain ordered and complete. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * docs(core): clarify telemetry compatibility behavior Document the changed semantics of deprecated helpers and the reason the fallback context shadows key operations. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> |
||
|
|
fcd358ae45
|
feat(core): align GenAI request telemetry fields (#7635)
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> |
||
|
|
45c8d8f8cc
|
docs: refresh subagent lifecycle guidance (#7624)
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> |
||
|
|
bfe8ab4fea
|
feat(daemon): add explicit channel delivery (#7388)
* docs(channels): define immediate delivery v1
* feat(channels): add proactive delivery boundary
* feat(daemon): route channel delivery to workers
* feat(scheduler): persist channel delivery targets
* feat(daemon): accept reverse channel deliveries
* feat(daemon): deliver prompt and scheduled finals
* feat(daemon): add synchronous channel notify
* fix(channels): classify Feishu delivery network errors
* fix(daemon): harden channel delivery failures
* fix(channels): wrap DingTalk proactive token fetch in typed delivery error
A proactive token fetch failure escaped sendProactiveChunk as a plain Error, bypassing ChannelProactiveDeliveryError classification. Wrap it as a transient typed error (preserving the cause) so downstream classification dispatches on it consistently. Also cover the scheduled-source branch of the bridge channel-delivery ext-method, which previously had no test coverage.
* refactor(cli): rename shutdown drain constant to reflect dual scope (#7388)
* fix(cli): support delivery updates in scheduled-task PATCH (#7388)
* fix(cli): address review feedback on channel delivery (#7388)
- Guard empty text before scheduling channel delivery in both prompt
and cron paths, avoiding unnecessary IPC round-trips when the model
emits only tool calls
- Import MAX_CHANNEL_DELIVERY_NAME_LENGTH and
MAX_CHANNEL_DELIVERY_TARGET_ID_LENGTH from core instead of
redeclaring them, preventing potential drift between the persistence
and API validation layers
- Remove dead thought parameter from #collectChannelDeliveryText —
all call sites pass a single argument
* fix(cli): add cross-reference and invariant comments for channel delivery (#7388)
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(cli): revert doc corruption and harden delivery event publish (#7388)
* fix(docs): revert prettier-mangled GitHub Action doc and add prettierignore guard (#7388)
* fix(cli): address review feedback on channel delivery (#7388)
- Make deliverChannelMessage error workspace-aware when routing fails
- Discriminate DaemonChannelDeliveryResultData union on status field
- Add old-target rejection assertion to PATCH delivery test
- Add IPC send failure path tests for channel delivery
- Add rehydration → authorization store integration test
* docs(cli): clarify delivery text scope, consume tradeoff, and 503 expectation (#7388)
* fix(cli): address review feedback on channel delivery (#7388)
- Document single-turn invariant on channelDeliveryCollector field
- Note adapter disposition drop in design doc for V1 scope
- Add text length bound to IPC request validator (defense-in-depth)
* docs(daemon): define final-only channel delivery
* fix(daemon): deliver only final response blocks
* test(daemon): cover cancelled scheduled delivery
* fix(daemon): skip delivery for unbound tasks, consolidate error codes (#7388)
* fix(feishu): validate message response codes
* Revert "fix(feishu): validate message response codes"
This reverts commit 85fc0943d69d2f5e7535477f2d46bfcd8c5c3c1e.
* refactor(channels): defer DingTalk error classification
* fix: apply CR suggestions from AI review
* test(channels): cover delivery failure paths
* fix(cli): add required ink FrameCell/ReadonlyFrame properties to selection tests
The branch was behind main where
|
||
|
|
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> |
||
|
|
1832a45ab8
|
fix(core): reject nested background requests (#7593) | ||
|
|
3617397e5f
|
feat(core): Align GenAI telemetry with ARMS (#7536)
* feat(core): align GenAI telemetry with ARMS Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(core): remove estimated token usage splits Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(core): address GenAI telemetry review feedback Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com> |
||
|
|
dc74279103
|
feat(serve): add workspace-level generation (#7552)
* feat(serve): add workspace-level generation * docs(serve): document workspace generation capability * fix(serve): align workspace generation contracts --------- Co-authored-by: ytahdn <ytahdn@gmail.com> |
||
|
|
b693fcfe6a
|
feat(serve): support forced MCP reconnects (#7488)
* feat(serve): support forced MCP reconnects * test(serve): cover forced MCP reconnect options --------- Co-authored-by: 克竟 <dingbingzhi.dbz@alibaba-inc.com> |
||
|
|
80863c0858
|
feat(web-shell): show subagent sessions in detail panel (#7380)
* feat(web-shell): show subagent sessions in detail panel * fix(web-shell): harden subagent session details * chore(sdk): account for subagent client APIs * fix(core): keep subagent resume history valid * fix(subagents): stabilize detail session streaming * test(cli): update telemetry route count * fix(subagents): address review feedback * fix(subagents): harden transcript refresh state * fix(subagents): address maintainer review * fix(subagents): preserve compact status details * fix(subagents): address review feedback round 3 (#7380) * fix(subagents): address remaining detail review feedback --------- Co-authored-by: ytahdn <ytahdn@gmail.com> Co-authored-by: 钉萁 <dingqi.jww@alibaba-inc.com> Co-authored-by: Qwen Code Autofix <qwen-code-autofix@users.noreply.github.com> |
||
|
|
6f5d6dfd65
|
feat(web-shell): add workspace selector button with add/switch dropdown in composer toolbar (#7390)
* feat(web-shell): add managed workspace selector Let Web Shell create and select daemon-managed workspaces without changing ownership of existing sessions. - Add capability-gated existing and scratch workspace registration - Validate scratch roots, trust provenance, capacity, and shutdown races - Serialize workspace mutations, session switching, and refresh results - Add SDK/WebUI wiring and focused cross-package regression coverage # Conflicts: # packages/web-shell/client/App.tsx # packages/web-shell/client/components/sidebar/WebShellSidebar.tsx # Conflicts: # packages/cli/src/serve/capabilities.ts # packages/cli/src/serve/routes/workspace-management.ts # packages/cli/src/serve/server.test.ts # packages/sdk-typescript/src/daemon/DaemonClient.ts # packages/web-shell/client/App.tsx # packages/web-shell/client/components/dialogs/AddWorkspaceDialog.tsx # packages/web-shell/client/components/sidebar/WebShellSidebar.tsx * fix(web-shell): revalidate workspace before session creation Prevent a stale workspace selection from bypassing the latest trusted capability snapshot during lazy session creation. - Validate the selected workspace before passing it to the daemon - Fall back to the primary workspace when trust has been revoked - Add a regression test for the pre-effect race window - Remove stale branch state and clarify add-workspace ownership * fix(web-shell): improve workspace removal feedback Keep workspace removal controls legible and make blocked force removals visibly inactive. - Size the action menu independently from its narrow icon trigger - Add a disabled affordance and suppress destructive hover styling - Cover the removal menu width override with a regression test * fix(web-shell): centralize existing workspace registration Route sidebar and composer entry points through the App-owned dialog so capability gating and workspace reconciliation remain consistent. - Forward display names only when the daemon advertises support - Hide and suppress persistence when registration is runtime-only - Mark directory registrations with existing-workspace provenance - Cover both entry points and capability combinations with tests * fix(web-shell): address review feedback on workspace dialogs and capability docs (#7390) - Document dynamic_workspace_registration and scratch_workspace_registration in the conditional serve-features table so the capabilities-docs-contract test passes. - Gate DialogShell backdrop-click and Escape dismissal on the dismissible prop so non-dismissible dialogs ignore both gestures. - Surface an inline error when an added folder registers but the capability refresh fails, mirroring the scratch recovery path. - Add coverage for the active-session workspace switch and the add-folder refresh-failure paths. * fix(web-shell): address review feedback on workspace dialogs and capability docs (#7390) --------- Co-authored-by: heyang.why <heyang.why@alibaba-inc.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com> Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com> |
||
|
|
cf6c51396c
|
chore(docs,test): batch three small docs and test fixes (#7373)
* docs(sdk): document auto permission mode * docs(sdk): clarify auto permission mode * docs(action): fix GitHub Action input names * test(weixin): cover exported AES key parser --------- Co-authored-by: 俊良 <zzj542558@alibaba-inc.com> |
||
|
|
ff14e65792
|
feat(web-shell): Add sidebar customization API for branding, navigation, session actions, and footer (#7379)
* feat(web-shell): Add sidebar customization API for branding, navigation, session actions, and footer Add new sidebar configuration options to WebShellSidebarOptions: - primaryNav.items: Control which built-in nav buttons are shown (newTask, plugins, scheduledTasks, goals) - primaryNav.render(): Append custom content after built-in nav buttons - hideProjectHeader: Hide the 'Projects' header row (search + add workspace) - sessionActions.items: Control which session action items appear (both inline and dropdown) - sessionActions.inlineItems: Control which items render as inline hover buttons (supports all action types with icon/text fallback) - footer.render(): Inject custom UI elements on the left side of the footer - Move scheduledTasks and goals from footer.items to primaryNav.items Visibility follows a strict 'hide-first' policy: inline buttons require all three conditions (items includes + inlineItems includes + built-in capability check) to render. * fix(web-shell): Prevent inline/dropdown duplication and add pin/archive dropdown fallback - Critical fix 1: Dropdown items now exclude items already shown as inline buttons (added !inlineActionItems.has guard to each dropdown entry and trigger visibility). - Critical fix 2: pin and archive now have dropdown menu entries as fallback when not configured as inline items, preventing them from becoming inaccessible. - Narrowed inlineItems type to WebShellSidebarSessionInlineActionItem (excludes details/group which have no working inline handlers), preventing dead buttons. - Added destructive color styling (var(--destructive)) to inline delete button when not disabled. * fix(web-shell): Re-export new sidebar types and add visibility matrix tests - Re-export WebShellSidebarPrimaryNavOptions, WebShellSidebarPrimaryNavItem, WebShellSidebarSessionActionsOptions, WebShellSidebarSessionActionItem, and WebShellSidebarSessionInlineActionItem from client/index.tsx so consumers can import them by name. - Add session-action-visibility.test.ts: table-driven tests covering the items × inlineItems × capability matrix (default config, empty items/inlineItems, dedup guarantee, pin fallback to dropdown). 7 test cases, all pass. * fix(web-shell): gate readOnly archive on sessionActionItems, fix footer null safety and docs accuracy (#7379) --------- Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com> |
||
|
|
443b81e180
|
feat(core): add opt-in built-in web_search backed by the DashScope Responses API (#7215)
* feat(core): add opt-in built-in web_search backed by the DashScope Responses API
Claude-Session: https://claude.ai/code/session_01KwsYFzWZ6VLCxVN8MbeFXb
* fix(core): require HTTPS for the web_search backend; fail closed on unresolved agent allow-lists
Review follow-ups on #7215: the endpoint gate now rejects plaintext
endpoints (the side request carries a bearer key), and an agent allow-list
whose names resolve to no registered tool keeps its dead entries instead of
widening to the inherited toolset — an agent restricted to the unavailable
WebSearch now runs tool-less rather than gaining shell/write.
Claude-Session: https://claude.ai/code/session_01KwsYFzWZ6VLCxVN8MbeFXb
* chore(cli): remove test-leaked debug artifacts; gitignore the leaked dirs
The CLI unit-test suites write debug logs relative to the package dir
(custom/, first/, from-env/, workspace/); a merge-commit git add swept
them in. Remove them and ignore the directories until the tests are
pointed at temp dirs.
Claude-Session: https://claude.ai/code/session_01KwsYFzWZ6VLCxVN8MbeFXb
* fix(core): honor web_search's own result budget and salvage in-stream-error partials
- Override maxOutputChars (result limit + envelope headroom) so the
scheduler's global 25k threshold no longer slices results before the
tool's section-aware truncation can protect URL evidence sections.
- Route in-stream backend errors through the shared terminal-failure
tail so results streamed (and billed) before the error surface as a
partial result, matching the transport-error path.
- Strengthen gate tests: assert gate.ok before webExtractor, exercise
the https-only endpoint guard, and make the config mock disambiguate
same-id entries by baseUrl like the real Config.
* fix(cli): treat whitespace-only WEB_SEARCH_API_KEY as unset
Apply the function's set-but-empty-is-unset rule to the API key env
var like every sibling env read, and add loadCliConfig coverage for
the web search settings resolution (env precedence, empty-env
fallthrough, base-URL key selection).
* fix(core): salvage failed-terminal web_search results and name the exact endpoint disqualifier
- Route the failed/cancelled terminal paths through the shared
terminal-failure tail so search evidence streamed (and billed) before
the backend gave up is salvaged, consistent with the in-stream-error
and transport-error paths; regression test included.
- Classify base-URL gate rejections so the startup notice blames the
actual disqualifier: a plaintext-HTTP endpoint now gets an "use
https://" notice at both the env-declared and modelProviders sites
instead of the misleading "non-DashScope endpoint" text.
- Cover WEB_SEARCH in the speculation boundary-tools test and the US
regional host in the DashScope provider test — both behavioral
changes this PR introduced without direct test coverage.
* test(cli): cover web search suppression in safe and bare modes
The bareMode/safeMode guard is the escape hatch that keeps web search
(external, billed API calls) off in troubleshooting modes; assert that
an enabled settings config resolves to no web search settings under
--safe-mode and --bare.
* fix(core): parse the search model selector once for both gate paths
A selector written for the modelProviders path ("openai:<model-id>", as
the gate's own OAuth notice suggests) was sent verbatim to DashScope
when WEB_SEARCH_BASE_URL overrode the backend, failing with
InvalidParameter. Hoist the resolveModelId parse above the env branch
so both paths share one interpretation of the selector.
Also cover two review gaps: the Claude extension WebSearch tool mapping
and the ACP startup-warning emission that surfaces WebSearch
misconfiguration notices in the client log.
* fix(core): handle response.cancelled in the web_search terminal-event switch and trim gate env keys
- Add response.cancelled to the terminal-event switch so the
status === 'cancelled' handler is reachable instead of dead code
- Trim API key env vars in the gate (all three check sites), matching
the CLI-side whitespace rule from
|
||
|
|
22963d5777
|
feat(core): add fork_turns to fork subagents (#7346)
* feat(core): add fork_turns to subagents * fix(core): preserve nested agent context inheritance * fix(core): isolate inherited subagent history * refactor(core): scope fork_turns to fork agents * test(core): cover zero-real-turns branch in selectForkHistory Add a regression guard asserting selectForkHistory returns [] when a numeric fork window finds no real user turns after the synthetic prefix (e.g. only startup context present). This pins the realUserTurnIndexes.length === 0 branch so a future refactor cannot silently return the full history instead of an empty selection. * docs(core): address fork_turns review feedback - Explain the curated vs uncurated history split between the fork_turns 'all' and numeric paths in createForkSubagent. - Document why includeCompressed is load-bearing in selectForkHistory. - Gate the 'forks inherit ...' prose in the Writing-the-prompt section behind isForkSubagentEnabled so non-interactive sessions no longer advertise fork behavior, and lock it with description assertions. * test(core): cover fork_turns 'all' and getHistoryForForkWindow fallback Add two integration tests for prepareForkConfig fork-history selection: - 'all' path: verify getHistoryShallow(true) sources the curated history and selectForkHistory(history, 'all') seeds the fork with the full history verbatim. - numeric path: verify the getHistoryForForkWindow?.() ?? getHistory(true) fallback still produces a correct bounded window (startup + latest real turn) when getHistoryForForkWindow is unavailable. * fix(core): use uncurated history for fork bounded-window fallback The numeric fork_turns path falls back to geminiClient.getHistory(true) when getHistoryForForkWindow is unavailable. Curated history coalesces the leading startup reminder into the first real user turn, so getStartupContextLength can no longer detect it as a pure prefix. selectForkHistory then leaves the startup text embedded in the first selected turn while the startupContext prefix is prepended separately, duplicating startup context in the fork's initial messages. Fall back to uncurated getHistory() instead, which keeps the startup reminder as its own pure entry that selectForkHistory strips cleanly. Update the fallback-path test to assert the uncurated call and document why curated history is unsafe here. --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
45d1eb6aa4
|
feat(serve): make ACP initialize handshake timeout configurable (#7246)
* fix(channels): exclude discrete messages from replies * feat(serve): make ACP initialize handshake timeout configurable Add --initialize-timeout-ms CLI flag to qwen serve, wiring it through to BridgeOptions.initializeTimeoutMs. The ACP initialize handshake defaults to 10 s (DEFAULT_INIT_TIMEOUT_MS); containerized deployments where the child process needs longer can now raise the ceiling without patching the source. Fixes #7244 * fix(serve): wire initializeTimeoutMs to fast-path parser and embed bridge Add the missing NUMBER_OPTIONS entry in fast-path.ts and forward initializeTimeoutMs in the server.ts inline createAcpSessionBridge call so the direct-embed / test path also respects the flag. * fix(serve): address review — fast-path test, timer upper bound, revert #7223, docs (#7246) * test(cli): add happy-path propagation test for initializeTimeoutMs (#7246) * refactor(cli): reuse isPositiveIntegerMs for initializeTimeoutMs validation (#7246) --------- Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com> Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com> Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com> |
||
|
|
9e822d6004
|
feat: support workspace display names (#7179)
* feat(sdk): support workspace display names * docs: add Web Shell screenshot * feat(web-shell): add workspace display names * fix(serve): harden workspace display name updates * refactor(serve): simplify workspace display names * fix(serve): validate trimmed workspace display names * feat(serve): add workspace update API * docs(serve): clarify workspace display name null handling * docs(sdk): list addWorkspace in daemon client methods |
||
|
|
6872b48c28
|
feat(daemon): Advertise ACP preheat readiness (#7200)
* feat(daemon): Advertise ACP preheat readiness Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#7200) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#7200) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> |
||
|
|
4e21f82c28
|
fix(ci): consolidate issue triage ownership (#7180)
* fix(ci): consolidate issue triage ownership Resolves #4786 * chore(vscode-ide-companion): regenerate NOTICES.txt to fix CI drift * fix(ci): close triage ownership review gaps * fix(ci): restore need-info label cleanup * docs(ci): document issue retriage triggers --------- Co-authored-by: Shaojin Wen <szujobs@gmail.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com> Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com> |
||
|
|
67e581aeba
|
feat(cli): Add bounded daemon log rotation (#6969)
Some checks are pending
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
E2E Tests / cron-interactive E2E (nightly) (push) Waiting to run
E2E Tests / web-shell Browser Regression (push) Waiting to run
* feat(cli): add bounded daemon log rotation Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#6969) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#6969) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#6969) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#6969) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#6969) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> |
||
|
|
d4db5fcfab
|
feat(core): improve subagent delegation defaults and guardrails (#7048)
* docs(design): define default background subagents * feat(core): improve subagent delegation defaults * docs(core): cross-reference the three background-classification sites Add pointer comments linking the core dispatch source of truth (AgentTool.execute) and its two UI mirrors (web-shell isBackgroundSubAgentToolCall, desktop detectBackgroundEvents) so the replicated top-level-agent background heuristic is not changed in isolation. Addresses PR review feedback. * fix(core): align background classification for fork and named-teammate launches Address review feedback on the background-classification rule so core dispatch and the two UI classifiers stay consistent: - core: exclude a name-without-active-team launch from the default-background path so it stays foreground, matching both UI classifiers (which exclude name). Previously such a launch was backgrounded by core but tracked as foreground by the UIs. - web-shell and desktop classifiers: exclude subagent_type "fork" from the default-background heuristic, mirroring core's !isForkRequested guard. A top-level fork request with an omitted flag runs foreground in core but was classified as background by the UIs. - add a core dispatch test asserting a working_dir launch with an omitted run_in_background flag stays in the foreground. * test: cover fork/background classification and precedence per review feedback Address unresolved review threads on PR #7048: - Add web-shell and desktop UI classifier tests asserting an omitted-flag `subagent_type: "fork"` launch stays in the foreground, verifying the documented `!isForkRequested` parity with core dispatch. - Add a core AgentTool test asserting an explicit `run_in_background: false` overrides a subagent config with `background: true`, locking in the `run_in_background ?? config` precedence against a `||` regression. - Harden the Explore read-only prompt: pipelines must not send data to a network endpoint (no curl/wget/nc), closing the `cat file | curl` exfiltration gap. * fix(core): restore general no-unnecessary-files guard in general-purpose prompt Address review feedback: the rewritten general-purpose prompt dropped the broad guard against creating unrequested files, keeping only the documentation-specific line. Restore a general 'do not create files unless necessary' guard so speculative utility/config files are not created. * test(desktop): cover named-teammate foreground guard in detectBackgroundEvents Add a desktop tool-matching test asserting a top-level Agent with a `name` set (named teammate) stays foreground and emits no task_backgrounded event, mirroring the web-shell classifier's named-teammate coverage and the existing fork-exclusion test. * test(core): cover named-teammate foreground dispatch when flag omitted Add a core-dispatch test asserting a top-level Agent launch with `name` set and `run_in_background` omitted stays foreground when no team is active, guarding the `this.params.name === undefined` exclusion in backgroundRequested directly (previously only covered by the UI classifiers). --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
e74c0cd33c
|
feat(serve): Complete legacy session workspace telemetry (#7003)
* feat(serve): Complete legacy session workspace telemetry Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#7003) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#7003) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * codex: address PR review feedback (#7003) 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-bot@users.noreply.github.com> |
||
|
|
b40978d6e6
|
feat(serve): add GET /workspace/:id/session-info for session totals (#7077)
Expose persisted active/archived/total (plus live) via a dedicated aggregate endpoint so clients do not need to page the full session list. Counts reuse the existing chats-dir disk scan pattern from session title search; responses mark expensive/disk_scan so callers know not to poll. Co-authored-by: Cursor Agent <cursoragent@cursor.com> |