mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-08-04 05:40:58 +00:00
4 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
71165fce0f
|
feat(cli): improve subagent observability — untruncated live commands, transcript path, approval context (#6580)
* feat(cli): improve subagent observability in detail view and approval prompts The agent detail view now renders the newest in-progress tool call in full (wrapped) instead of truncating it to one line, shows up to 10 recent activities (registry buffer raised from 5), and surfaces the JSONL transcript path so the full execution trace can be followed live or reviewed post-mortem. Inline subagent approval prompts now show the agent's last three prior tool calls as context for the permission decision. Refs #6569 * refactor(cli): address review — shared tool display map, C0 sanitization, named caps, boundary tests Extract the four duplicated tool-name→display-name maps into a single shared module; export the activity buffer cap from core so the detail view's slice bound can't drift; sanitize bare C0 control bytes in the live activity row and approval context lines; name the live-label and approval-context magic numbers; add boundary tests for the progress buffer and approval-context edge cases (empty context, executing glyph, unknown tool fallback, empty description). Refs #6569 * fix(cli): keep live-row prefix spacing under MaxSizedBox wrap layout The wrapped live activity row rendered as `>Shell(...` — MaxSizedBox's wrap layout drops the prefix's trailing space when prefix and label arrive as separate Text segments. Concatenate them into a single string child so the glyph renders as `> Shell(...`. * test(integration): add deterministic capture scenario for subagent observability evidence Drives the fake OpenAI server through an 11-read + long-shell-command subagent run and screenshots the detail view (yolo) and the inline approval banner (default mode) — the reproducible source of PR #6580's Before/After captures. * refactor(cli): address follow-up review — consistent C0 sanitization, named web-shell activity cap Switch the two remaining activity-label surfaces (live panel row, inline parallel-agents row) to the same bare-C0-stripping sanitizer the dialog and approval context use; name web-shell's 5-row activity display budget with a comment marking the intentional divergence from core's 10-entry retention cap. Refs #6569 * fix(cli): budget subagent observability surfaces against short terminals Addresses the review verification report on #6580 (issue #6569): - Approval context (Finding 1, blocking): the prior-call context lines added above a subagent approval prompt were unbudgeted, so on a short terminal they pushed the question and its options off-screen and Enter approved blind. Reserve one line per rendered context call out of the confirmation's height budget so the confirmation prompt always wins. - Detail view live row (Finding 2): MaxSizedBox clips from the bottom, so a full 10-row history could push the live command and Transcript pointer off a short terminal. Render the live row separately and budget the always-valuable sections first, dropping the OLDEST history rows when space is tight so the live row survives. Move Transcript above Prompt. - Transcript path (Finding 3): render the path with wrap="wrap" instead of truncate-end so the full ~130-char path can actually be copied / tail -f'd. - Minor: correct the MAX_LIVE_LABEL_CHARS comment (a very large terminal could display past the cap; on such a description the row is truncated). Also addresses inline suggestions: cache hot-path string-width measurements in the detail view, sanitize the transcript path for defense-in-depth, update the height-budget comment to mention the Transcript section, and add a tool-display-map parity test that fails on core ToolNames/ToolDisplayNames drift. New regression tests cover the confirmation-height reservation, the short-terminal live-row survival, and the full transcript path. * fix(cli): harden LiveAgentPanel task-description label against bare C0 controls The glance-panel `label` (the subagent task description) still used escapeAnsiCtrlCodes while the sibling `activity` line and every other subagent surface were hardened to sanitizeMultilineForDisplay. The task description is model-generated, so bare C0 controls (\r, BS, BEL) could pass through the ANSI-sequence escape and corrupt the panel chrome. Route it through sanitizeMultilineForDisplay to match. * fix(cli): resolve duplicate i18n 'Transcript' key after main merge Merging main brought in its own `Transcript` locale key (the conversation TranscriptView), colliding with the one this PR added for the subagent detail view — `no-dupe-keys` failed CI's ESLint step across en/zh/zh-TW. Drop the PR's duplicate entries; `t('Transcript')` now resolves to the shared canonical key (main's), so both surfaces render one consistent label. * feat(web-shell): align tasks panel with CLI subagent surfaces Address the three web-shell review suggestions on #6580. The web-shell is a browser bundle with no dependency on @qwen-code/qwen-code-core, so it can't import the CLI's shared helpers — mirror them locally instead: - Sanitize LLM-generated activity descriptions: add `sanitizeControlChars` (mirrors the CLI's `sanitizeMultilineForDisplay`) and apply it in `formatActivityLabel`, so a stray \r/BEL/ESC can't garble the panel. - Reduce display-name drift: document `TOOL_DISPLAY_NAMES` as a deliberate standalone copy of core's `ToolDisplayNames`, and sync the entries it was missing (loop_wakeup, create_sub_session, read_mcp_resource, team_plan_approval, artifact, record_artifact) with their zh translations. - Add test coverage: sanitizeControlChars unit tests, and a render test asserting the detail progress list caps at the newest MAX_DISPLAYED_ACTIVITIES rows. * test(web-shell): polyfill Range.getClientRects for CodeMirror in jsdom CodeMirror's text measurement calls `range.getClientRects()` from a requestAnimationFrame measure pass. jsdom (26.1.0) doesn't implement `Range.prototype.getClientRects` / `getBoundingClientRect`, so that async callback throws `TypeError: getClientRects is not a function`. Vitest surfaces it as an *unhandled error* that fails the whole run (exit 1) even though every test passes — and because it depends on rAF timing it's flaky (it fired on CI, passed locally). `useComposerCore.dom.test.tsx` (added via the main merge) is the trigger. Polyfill both Range methods in the shared test setup with empty rects; CodeMirror already handles the no-layout case. * fix(cli): also reserve the approval header line in the confirmation budget Follow-up to the approval-context budgeting: the "Approval requested by" header renders one line above the context block, but only `contextLines` was subtracted from the confirmation's `availableTerminalHeight`. Total rendered height was `1 (header) + contextLines + (availableHeight - contextLines)` = `availableHeight + 1`, so on a short terminal the confirmation options overflowed by one line — the exact blind-approval failure this budgeting prevents. Subtract the header line too. * test(cli): prove the live row survives the short-terminal budget (no transcript) The re-review flagged a suspected off-by-one in `reservedLines` (missing the Progress spacer+header). It isn't: the `2` in the `liveActivity` reservation IS the Progress `<Box/>` spacer + bold header, and the live row has no spacer of its own — so the accounting already balances (reservedLines + historyBudget == maxHeight). Add the exact reviewer scenario as a regression test — 10 activities, no outputFile, maxHeight=14 — asserting the live command still renders. It passes, confirming no clip. * test(web-shell): guard TOOL_DISPLAY_NAMES against drift from core ToolNames The web-shell map is a standalone copy of core's tool list (the browser bundle can't depend on core). Add a build-time drift guard that reads core's tool-names.ts source and asserts this map covers every enumerated wire name, so a tool added to core can't silently leak a raw internal name into the web panel via the fallback. Mirrors the CLI's tool-display-map.test.ts parity check without pulling core into the bundle. --------- Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.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> |
||
|
|
075c3f03e5
|
feat(cli): forward ask_user_question answers from SDK can_use_tool (#6655)
* feat(cli): forward ask_user_question answers from SDK can_use_tool SDK-hosted agents could receive ask_user_question calls through the can_use_tool callback and approve them, but the user's answers never reached the tool: the CLI called onConfirm(ProceedOnce) with no payload, so the tool read an empty answers map and the model never got the decisions. Route updatedInput.answers from the SDK's allow response into the tool confirmation payload so the collected answers reach the tool. Reuses the existing updatedInput channel — no new SDK API or types. Document the pattern in the TypeScript and Python SDK READMEs. * fix(cli): forward ask_user_question answers on teammate approval path Address review feedback on #6655: - handleTeammateApproval now mirrors the leader path and promotes the user's answers from updatedInput into the confirmation payload, so ask_user_question calls approved through a teammate no longer drop the user's choices (wenshao). - Extract a shared buildAllowConfirmationPayload helper used by both the leader and teammate paths, and only promote `answers` for ask_user_question so a same-named field on any other tool's input can't leak into the payload. - Add tests for the teammate path and the defensive guards (array updatedInput, array/null/empty answers, foreign answers field). * test(web-shell): stub Range client-rect methods to fix flaky CI CodeMirror's async measure pass (scheduled via requestAnimationFrame) calls getClientRects()/getBoundingClientRect() on a text Range. jsdom implements these on Element but not on Range, so the call throws "textRange(...).getClientRects is not a function" from a rAF callback after the test completed. Vitest surfaces it as an unhandled error and fails the whole run with exit code 1 even though every assertion passed (seen intermittently in useComposerCore.dom.test.tsx). Polyfill both methods on Range.prototype in the shared test setup, mirroring the existing ResizeObserver/scrollIntoView stubs. * refactor(cli): use ToolNames constant and broaden permission tests Address review suggestions on #6655: - buildAllowConfirmationPayload now gates answers-promotion on the ToolNames.ASK_USER_QUESTION constant instead of a bare string literal, so a future rename of the tool name is a compile-time break rather than a silent regression. - Add an it.each case for a non-object primitive updatedInput (string) to cover the `typeof updatedInput !== 'object'` guard branch. - Assert the leader path overrides toolCall.request.args with the host's sanitized updatedInput before confirming. - Add a teammate-path test for an allow response with no updatedInput, asserting respond is called with (ProceedOnce, undefined). --------- Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com> |
||
|
|
f06e932260
|
fix(web-shell): polyfill Range layout APIs in tests (#6677)
* fix(web-shell): polyfill range layout in tests * test(webui): stabilize heartbeat prompt cleanup |
||
|
|
5c82857fea
|
Add harness infrastructure for web-shell package (#6517)
Some checks are pending
* test(web-shell): add browser and lint harness * test(web-shell): harden browser smoke harness * fix(web-shell): guard mock daemon model state * test(web-shell): remove unused scenario harness * fix(web-shell): remove stale lint disables * test(web-shell): make matchMedia stub writable * fix(web-shell): exclude tests from package typecheck * test(web-shell): tighten mock daemon route contract * Update packages/web-shell/client/e2e/utils/mockDaemon.ts Co-authored-by: qwen-code-ci-bot <qwen-code-ci@service.alibaba.com> * test(web-shell): clear stale SSE connections * ci(web-shell): gate smoke on full CI profile --------- Co-authored-by: ermin.zem <ermin.zem@alibaba-inc.com> Co-authored-by: qwen-code-ci-bot <qwen-code-ci@service.alibaba.com> Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com> Co-authored-by: 易良 <1204183885@qq.com> |