feat(daemon): add POST /session/:id/btw endpoint for side questions#4610
Conversation
Support /btw (side question) via daemon HTTP, allowing daemon clients (web-shell, IDE plugins) to run tool-free, single-turn LLM queries against the session's conversation context without blocking the main prompt stream. - Extract buildBtwPrompt + buildBtwCacheSafeParams to core/utils/btwUtils - Add sessionBtw ext-method to SERVE_CONTROL_EXT_METHODS - Add generateSessionBtw to HttpAcpBridge interface and implementation - Handle ext-method in acpAgent with 55s timeout self-guard - Add REST endpoint with AbortController wired to client disconnect - Register session_btw capability - Expand btwCommand supportedModes to include 'acp' with sync fallback 🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
There was a problem hiding this comment.
Pull request overview
This PR adds daemon/ACP support for /btw side questions, sharing prompt/cache utilities through core and exposing the feature via serve capabilities.
Changes:
- Adds shared
buildBtwPromptandbuildBtwCacheSafeParamsutilities in core. - Wires
/session/:id/btwthrough serve HTTP, ACP bridge ext-methods, and ACP agent handling. - Enables
btwCommandin ACP mode and adds ACP command tests.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
packages/core/src/utils/btwUtils.ts |
Adds shared prompt and cache-safe param helpers for /btw. |
packages/core/src/index.ts |
Exports the new /btw utilities. |
packages/cli/src/ui/commands/btwCommand.ts |
Reuses core helpers and adds ACP-mode synchronous execution. |
packages/cli/src/ui/commands/btwCommand.test.ts |
Updates mocks and adds ACP-mode command tests. |
packages/cli/src/serve/server.ts |
Adds POST /session/:id/btw route. |
packages/cli/src/serve/server.test.ts |
Adds capability expectation and fake bridge stub. |
packages/cli/src/serve/capabilities.ts |
Registers session_btw capability. |
packages/cli/src/acp-integration/acpAgent.ts |
Handles the new ACP control ext-method by running a forked, tool-free side query. |
packages/acp-bridge/src/status.ts |
Registers the qwen/control/session/btw ext-method name. |
packages/acp-bridge/src/bridgeTypes.ts / packages/acp-bridge/src/bridge.ts |
Adds bridge API and implementation for generating side-question answers. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
📋 Review SummaryThis PR adds HTTP endpoint support for 🔍 General Feedback
🎯 Specific Feedback🟡 High
🟢 Medium
🔵 Low
✅ Highlights
|
wenshao
left a comment
There was a problem hiding this comment.
[Critical] server.test.ts:662 [typecheck] — tsc --noEmit reports Property 'executeShellCommand' is missing in type ... but required in type 'FakeBridge'. This appears to be a pre-existing issue (not introduced by this PR) — npm run build and all 359 tests pass. Likely needs a rebase onto latest daemon_mode_b_main.
— qwen3.7-max via Qwen Code /review
- Use Array<Promise<unknown>> syntax (eslint array-type rule) - Use getHistoryTail() instead of full clone + slice (perf) - Add debug logging to catch block in buildBtwCacheSafeParams - Fall back to getCacheSafeParams() in acpAgent (consistency with CLI) - Add ACP mode test branches for null text and missing cache params 🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
Review round 1 — wenshaoAll 5 suggestions addressed in
All 361 tests pass. Regarding the typecheck note in the review summary — this is a pre-existing lint issue in |
…, length cap
- Clean up abort listener on happy path (prevent leak with long-lived signals)
- Move createDebugLogger('btw') to module level (match codebase convention)
- structuredClone generationConfig to match getCacheSafeParams contract
- Add 4096 char max length validation on question field
🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
Review round 2 — wenshao4/5 suggestions fixed in
All 361 tests pass. |
🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
…efore abort
- acpAgent sessionBtw: enforce 4096-char cap on `question`, matching the HTTP
route so direct ACP clients (Streamable HTTP/WebSocket) can't bypass it and
consume unbounded LLM tokens
- bridge generateSessionBtw: validate channel/isDying before the signal.aborted
short-circuit so a dead session throws SessionNotFoundError (404) instead of
returning {answer: null} (200), matching the generateSessionRecap ordering
🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
Review round — addressed wenshao's
|
| Thread | Severity | Action |
|---|---|---|
acpAgent.ts question length |
Critical | ✅ Fixed — added length > 4096 cap matching the HTTP route, closes the direct-ACP bypass |
bridge.ts abort ordering |
Critical | ✅ Fixed — validate channel/isDying before the signal.aborted short-circuit; dead sessions now 404 instead of {answer:null} |
acpAgent.ts:2571 maxOutputTokens |
Suggestion | Deferred — side-question answers are open-ended; cap value is a deliberate call, follow-up |
btwUtils.ts:39 history shallow-copy |
Suggestion | Acknowledged — valid, but the suggested geminiClient.getHistoryTailShallow is a private method; correct form is chat.getHistoryTailShallow(...). Can apply on request |
btwUtils.ts:42 drop structuredClone |
Suggestion | Not taking — mirrors the canonical saveCacheSafeParams clone (forkedAgent.ts:104) for snapshot stability |
btwCommand.ts:115 duplicated logic |
Suggestion | Partial — can add cross-ref comments; shared helper as follow-up |
Both Critical issues are fixed and pushed. The four Suggestion threads are left open for your input rather than unilaterally resolved.
Verification Report — PR #4610Commit: Test Results
Test Details
TypeScript Error Analysis
Pre-existing Issues (not caused by this PR)
Items Not Verified (require live infrastructure)
Verdict✅ All automatable checks pass. 352 tests total (22 btw + 330 acp-bridge), all 3 package typechecks clean (PR actually reduces CLI TS errors by 7). Safe to merge pending live endpoint verification. |
Summary
POST /session/:id/btwREST endpoint to support/btw(side question) in daemon HTTP modebuildBtwPrompt+buildBtwCacheSafeParamsutils topackages/corerunForkedAgent(cache path)btwCommandsupportedModesto include'acp'with synchronous fallbacksession_btwcapability for SDK feature discoveryDesign
Follows the recap pattern (ext-method control-plane operation):
AbortSignal.timeoutself-guard (slightly less than bridge){ answer: null }when no conversation context exists (no 500)Test plan
core,acp-bridge,clipackagesqwen serve→ create session →POST /session/:id/btw→ verify 200 responseGET /session/:id/supported-commandsincludesbtw🤖 Generated with Qwen Code