[pull] main from QwenLM:main - #540
Merged
Merged
Conversation
…es (#10803) * fix(ci): stop stable releases from disabling per-workspace test retries The workspace shards passed --retry=0 on stable releases, and a command line option outranks the Vitest config, so the release lane switched off the retry packages/sdk-typescript sets for itself while every other lane kept it. Omit the flag instead of zeroing it, and refresh the stale.yml comment that still described the nightly release as running at 00:00 UTC. Claude-Session: https://claude.ai/code/session_01AWWgJEqafyAT1Mc75T8N7h * test(ci): preserve empty retry arguments in assertion Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…ed package early (#10784) * fix(release): raise the package size budget and stop hiding sandbox build failures The docker sandbox build in `integration_docker` has been failing every release since 0.22.3-release-7df5ac68. The build itself is fine; what fails is `npm run prepare:package` inside the Dockerfile's builder stage: Error: Prepared package unpacked size 101897869 bytes exceeds 100663296 bytes `assertPreparedPackageSize`'s 96 MiB budget was set in #6691 when the prepared package was ~80.6 MiB. It has grown with ordinary feature work since — 96,802,417 bytes at 0.22.1, 98,582,313 at the 08-31 nightly, 101,897,869 now, with the OpenTUI migration batches carrying two UI stacks at once — and it crossed the ceiling. Raise the budget to 112 MiB, the same "headroom, not target" call #6688 and #6691 made before it. vendor/ripgrep (24 MiB, five platform binaries) and web-shell/assets (18 MiB, mostly shiki grammars, mermaid and cytoscape) are the two places worth trimming if we would rather bring the package down than keep raising the ceiling; that is a separate change. The reason a one-line size error cost a 20-minute release run to diagnose is the other half of this commit: - `build_sandbox.js` sent the image build's output to /dev/null unless VERBOSE was set, so the failure surfaced as an execSync stack trace with `stdout: null` and no way to tell what broke without rebuilding by hand. `e2e.yml` had already worked around this by setting VERBOSE; the release workflow had not. Now CI streams the output, and a quiet local build keeps it and prints the tail when the build fails. - Nothing ran `prepare:package` before the publish job, so its guards were first exercised by the Dockerfile — the slowest consumer in the pipeline. `quality_build` now runs bundle + prepare:package after uploading its build artifact, which reports the same failure in minutes without touching what downstream jobs consume. * fix(release): close sandbox output review gaps Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…eases (#10814) * feat(release): add gated bun/OpenTUI preview flavor to standalone releases Phase 2 validation needs a real archive that boots the OpenTUI renderer, so the standalone pipeline gains an opt-in second flavor instead of replacing the classic Node.js one: - create-standalone-package.js derives archive names from a shared standaloneArchiveName() helper; bun archives carry the -opentui-preview suffix, and bun shims default QWEN_TUI_RENDERER to opentui (explicit user overrides still win). - build-standalone-release.js accepts --include-opentui-preview to package both flavors in one run, with per-flavor publisher checksums and a flavor-aware output assertion. - verify-installation-release.js accepts the same flag so a gated release directory/URL and the OSS upload list both expect the preview archives. - release.yml and sync-release-to-oss.yml thread the flag behind a vars.OPENTUI_PREVIEW_RELEASE_ENABLED gate (off by default, byte-identical behavior when unset); .size-baseline re-pinned in the same PR. - Also fix a latent crash in copyOpenTuiAddon's warn-only degradation path, which asserted against a lib/node_modules directory it never created. * feat(release): add a thin installer for the gated opentui-preview archives The preview flavor is not reachable through the hosted installer chain, which only packages assets for stable releases, so testers had to download and unpack the archive by hand. This adds a scratch-directory installer pair that resolves the platform target, verifies the release SHA256SUMS, and unpacks into ~/.qwen-preview without touching PATH or an existing classic installation. A local archive can be installed directly so the path is testable before a gated release exists.
) Release run 33576013293 (nightly 77d41f4) failed with 211 test files and 9480 tests passing and the job still exiting 1: Vitest caught 1 unhandled error during the test run. Error: write after end ❯ wt.write node_modules/tar/node_modules/minipass/src/index.ts:547 ❯ wt.[process] node_modules/tar/src/pack.ts:352 ❯ wt.[jobDone] node_modules/tar/src/pack.ts:378 This error originated in "src/extension/archive-safety.test.ts" The latest test that might've caused the error is "rejects a hard link even when it points inside the archive root" packages/core/vitest.config.ts sets dangerouslyIgnoreUnhandledErrors to false on Linux, so an unhandled error fails a CI run whose tests all passed — and it is ignored on macOS, which is why this never appears locally. The log carries no FAIL line, so the release notification is indistinguishable from a real test failure. tar's [PROCESS] finalizes the archive when the queue drains, and [JOBDONE] has a branch only hard links reach: stat.nlink > 1 re-processes the pending link job and re-enters [PROCESS]. Under contention that second pass can reach the finalization branch after the pack already ended, and minipass throws from a stream nothing awaits — an uncaught exception, so `await tar.c(...)` cannot catch it. This fixture is the only place in the repo that packs a hard link; the other fs.link callers never hand the link to tar, and symlink fixtures do not take the PENDINGLINKS path. Crafting the two headers keeps the archive shape tar itself produces (typeflag '1', linkname pointing at the original, verified by dumping a real packed archive) and drops the test's dependency on fs.link, so it now runs on Windows too. With the cores saturated the parent commit hit this 3 times in 28 runs; this commit survived 32. On an idle machine the parent commit survived 30 runs, so the contention is what makes it visible.
…#10760) * fix(release): cap Vitest workers in the quality_scripts lane (#10755) The 2026-09-02 nightly failed on the quality aggregate because the quality_scripts lane (added by the release-sharding split, #10619) ran the scripts suite with vitest's default worker count — one worker per host core — on the shared ECS pool. On a 64-core runner executing several pool jobs at once, the suite's ESLint instances and bash replays spawned dozens of heavy subprocesses in parallel and 5-8 tests per run blew through the 30s test timeout non-deterministically (reproduced twice on the failing SHA: 30s timeouts across the ESLint boundary guards and workflow replays, plus a spawn-latency race in the upload-stall test). The sibling workspace_tests lane and the main CI gate already bound their vitest workers on ECS (#10667); the new lane never inherited the bound. Apply the same tunable per-process bound to the lane and pin it in the release contract test next to the workspace lane's copy. Also deflake the upload-stall test: its 400ms kill bound raced child-spawn latency under pool load, losing attempt log lines and reading 1 or 2 attempts instead of 3; the bound is now 2s — still far under the shim's 60s hang, so the kill semantics are unchanged, and the worst-case run stays inside the test's own 30s budget. * refactor(release): alias the Vitest worker bound across release test lanes (#10755) Review of the worker-cap fix noted that the Run Script Tests step carried a byte-identical copy of the Run Workspace Tests env block, so any future tuning (bumping the '4' default, adding another pool/thread variable) would need two synchronized edits, and editing one step while missing the other would silently restore the unbounded-worker timeout on the untouched lane — caught only reactively by a red contract test. Anchor the block at its first occurrence (&vitest_worker_bound) and alias it into the scripts lane, the same mechanism this file already uses for &release_test_env across six jobs. Reshape the contract assertions to pin the structure: the bound's four variables at the anchor definition and the bare alias at the consumer, so dropping either side turns the test red. Net five lines removed. --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* feat(channels): expose BTW through agent bridges * test(web-shell): remove duplicate language bindings * fix(cli): gate channel BTW by daemon capability * docs(channels): document the btw capability gate The daemon-worker facade exposes `bridge.btw` only when the daemon advertises `session_btw`, but the base README documented that gating pattern for `shellCommand` alone. An adapter author hitting a silently absent `bridge.btw` had nowhere to look it up. Extend the Runtime modes sentence and the optional-methods note to cover both methods and name their capabilities, and add `btw?` to the `ChannelAgentBridge` interface sketch in source order. * docs(channels): clarify BTW plugin capability --------- Co-authored-by: qqqys <266654365+qqqys@users.noreply.github.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com>
* fix(web-shell): keep manual title across clear * fix(acp-bridge): reject an empty session displayName on metadata update An empty displayName only cleared the live bridge entry: the sessionTitle persist runs for truthy names, so no tombstone reached the transcript. The persisted manual custom_title record then resurfaced through mergeLiveSessionSummary (live.displayName ?? existing.displayName) with manual provenance, and the /clear carry renamed the successor session back to the deleted name before persisting it there as manual. Reject empty or whitespace-only names in updateSessionMetadata, the choke point shared by the REST metadata routes, the SDK client, and the daemon-MCP session_update_metadata tool, mirroring the rejection the workspace-scoped metadata route already applies. All internal callers pass generated non-empty names, and every UI rename path trims and rejects empty input client-side. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Patrol-Run: qwen-pr-closeout/jmtj23z78au * fix(web-shell): keep title provenance when metadata events echo the same name A `session_metadata_updated` event that echoes the unchanged displayName without an explicit titleSource — the bridge's pr-only publish when a PR is bound — reset the connection's provenance to undefined, wiping the 'manual' provenance the `/clear` carry reads. Preserve the prior provenance for an unchanged-name echo; only a changed name of unknown provenance resets it. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Patrol-Run: qwen-pr-closeout/jmtjeyxvebk * fix(web-shell): discard an armed /clear carry when other paths bind a session Two session-binding paths bypassed the carry's consume/discard network while pendingManualTitleRef was armed: the shrink-fold landing of the first split pane on the sessionless chat connection, and resolveSessionForWorkspace's direct createSession (Commit-dialog flow). A cleared manual title could then resurface on the bound session's successor and persist as user-authored provenance. Discard the armed carry at both sites, mirroring loadSidebarSession. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Patrol-Run: qwen-pr-closeout/jmtjeyxvebk * fix(serve): preserve automatic title provenance Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(serve): type automatic title metadata Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(web-shell): keep clear recovery after rename failure Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Batch 7 added a dedicated OpenTUI leg to e2e.yml. It never ran on its own PR — the workflow triggers only on push to main, nightly and dispatch — so its first executions were on main, where it fails deterministically: the same four interactive files have failed across three consecutive main commits. The failures are not test fragility. Each one is a parity gap the renderer still has, and the leg did its job by surfacing them: - the approval-mode indicator is never drawn, so a user running --yolo cannot see which mode they are in; - the submit seam drops submittedPrompt, so the UserPromptSubmit hook input loses submitted_prompt and external-context auto-recall silently no-ops; - the live turn bypasses the query-preparation pipeline, so @file expansion does not work under this renderer at all. Removing the leg keeps main green without deleting any test: the ink leg still runs every one of these files, so nothing regresses silently. The renderer matrix stays wired in — the e2e legs keep pinning their renderer, and the OpenTUI side remains runnable locally through npm run test:integration:interactive:opentui:sandbox:none. Restoring the CI leg is gated on closing the three gaps, tracked in #8662. The design doc claimed the build/CI batch "runs the OpenTUI e2e leg green on CI"; that named a mechanism this commit removes, so both mentions now match the tree.
…ublish (#10827) Co-authored-by: Claude <noreply@anthropic.com>
Refresh standalone session options whenever a cleared draft re-enters the deferred state, while preserving lazy session creation. Refs #10821 Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
#10787) * fix(goal): stop exporting the unreachable propose_goal decline message PROPOSE_GOAL_NOT_APPROVED_MESSAGE is written as if the model reads it. It does not. A declined dialog resolves as ToolConfirmationOutcome.Cancel, and coreToolScheduler settles the call as cancelled without ever entering execute(); what the model receives is the scheduler's own "[Operation Cancelled] Reason: User did not allow tool call". The guard itself is worth keeping as a defence against a host that one day runs execute() after a cancelled confirmation, so a decline can never fall through to parking an approval. It is now module-private with a comment saying why, since nothing outside the module should assert on a string the model cannot receive. What actually stops the model from re-proposing is the tool description, which already says so. The test that pinned the message now pins the real path -- a cancelled dialog parks nothing -- and a second test keeps the defensive branch honest without depending on the exact wording. The documentation sentence that made the same wrong claim is corrected in the Goal docs sync PR, which already rewrites that paragraph. * test(goal): pin the propose_goal decline contract Three gaps this PR left in what holds the decline behavior. The refusal assertion matched only the shared 'The Goal was not set' prefix, which PROPOSE_GOAL_NO_TURN_MESSAGE also begins with, so the two refusal branches were indistinguishable: returning the no-turn message from the not-approved guard kept the suite green while handing the model a string that invites the re-proposal the decline forbids. Match the 'the user did not approve it' fragment instead, which occurs only in the decline message. The tool description's decline clause was asserted nowhere, and dropping the exported constant made that description the only thing left telling the model not to re-propose. Pin the clause next to the existing name and permission checks, reusing the fragment the bundled goal-draft skill test already pins so the two copies cannot drift apart silently. Drop 'parks nothing when the dialog is cancelled': it never called execute(), and its assertions were a strict subset of the test below it, which runs the same cancelled confirmation and then executes. Its comment described the scheduler path it did not exercise; that rationale now sits on the surviving test, pointing at the scheduler test that does cover it.
* fix(ci): stop heartbeat mint-skip test racing loop startup (#10523) The test slept a fixed 2.5s and then required the mint-failure log line, but the loop sleeps a full interval before its first tick, so bash startup plus the tick's forks land after that budget on a loaded runner — reddening the helper-tests lane with no product defect. Poll the skip line itself (the file's existing waitFor shape) and keep all three assertions. * fix(ci): gate heartbeat mint-skip test on the second skip line (#10523) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(ci): carry observed log state into the mint-skip gate failure (#10523) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.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>
* fix(dws): isolate direct message ingestion * fix(dws): harden concurrent direct dispatch * fix(dws): address concurrent dispatch review * fix(dws): preserve direct message progress * fix(dws): scope the direct replay cap to replay dispatches The replay cap measured queuedDirectMessages.size, which in followup mode also counts the live per-conversation backlog: entries are added at schedule time and removed only when their own turn finishes, so N chained messages hold N entries while one turn runs. A single conversation's backlog of 16 could therefore keep every poll from replaying any parked failed direct message of any other conversation, and parked entries have no other redelivery surface. Count only replay-started dispatches against the cap, tracked in a map cleared on disconnect alongside queuedDirectMessages so replay-alone concurrency still stays at or below the cap across polls. Also add the missing test witnesses for the disconnect and tail cleanup introduced earlier in this branch: the conversation-tail reset on disconnect, the identity-guarded tail release in scheduleDirectMessage, and failed ambient parking when a capacity wait is released by disconnect. --------- Co-authored-by: qqqys <266654365+qqqys@users.noreply.github.com>
* fix(web-shell): preserve slash command attachments * fix(web-shell): align attachment command resolution * fix(web-shell): preserve attachments for slash-like text --------- Co-authored-by: 钉萁 <dingqi.jww@alibaba-inc.com>
* feat(serve): establish workspace runtime ownership * feat(serve): add workspace-scoped MCP management * fix(serve): address workspace MCP review findings * fix(serve): address follow-up MCP review findings * test(serve): stabilize MCP drain race coverage --------- Co-authored-by: 钉萁 <dingqi.jww@alibaba-inc.com>
Co-authored-by: qqqys <266654365+qqqys@users.noreply.github.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com>
* feat(channels): add BTW side questions * fix(channels): address review round 1 on BTW side questions Critical: - Deliver the /btw answer to the chat/thread captured from the asking envelope instead of the session's creation-time router target, which froze the destination for sessions shared across chats or threads - Keep an acknowledged /btw current when SessionRouter promotes the live target to a group mid-flight; the promotion changes neither the conversation nor the delivery destination, while the named-task branch keeps the stricter target comparison Suggestions: - Move the shared-session authorization gate ahead of the usage, length, and attachment validation so non-members no longer receive validation answers - Move the bridge capability check ahead of session resolution so an unsupported /btw no longer creates and persists a session - Declare btw on ChannelAgentBridge as an optional capability instead of a module-private intersection type - Describe /btw in the /help command list and the channel docs Tests: cross-chat delivery under sessionScope single, mid-flight group promotion, foreign-session response rejection, unauthorized bare and oversized /btw, no-session-creation on unsupported bridges, and the described /help entry. * fix(channels): address review round 2 on BTW side questions * fix(channels): close BTW review gaps * fix(channels): close BTW delivery review gaps * fix(channels): let /btw reach the agent when no bridge answers it No ChannelAgentBridge in this tree implements the optional btw capability yet, so the unsupported-bridge gate was taken on every shipped connection and /btw refused. At the merge base /btw was not a locally handled command: it fell through to the agent, which serves it as its own slash command and answered. Landing the interception before any producer therefore replaced a working answer with a permanent refusal. Intercept only when the bridge can answer out of band. Without the capability /btw falls through unchanged, so this PR no longer depends on the bridge half landing first. The /help de-duplication needed the same treatment: `btw` is registered locally whether or not the bridge supports it, so the filter hid the agent's entry even when that entry was the only working one. Tests: the fail-closed case is replaced by one asserting the /btw text reaches bridge.prompt, plus a case keeping the agent entry visible in /help. Also adds the session-scoped de-duplication case — the existing one runs with no active session, so it never reached getAgentCommandsForSession and a filter narrowed to the non-session branch stayed green while a live conversation listed /btw twice. --------- Co-authored-by: qqqys <266654365+qqqys@users.noreply.github.com> Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )