qwen-code/packages/cli
wenshao ca996ecb54 feat(cli): wire POST /session/:id/prompt + /cancel for qwen serve (#3803)
Stage 1 follow-up after the bridge scaffold. Adds the two routes a client
needs to actually run a turn against the daemon.

Bridge:
  - `sendPrompt(sessionId, req)` looks up the session, FIFO-queues the
    call against the per-session prompt queue, and forwards through the
    SDK `ClientSideConnection.prompt`. Concurrent calls observe ACP's
    "one active prompt per session" invariant — second waits for first.
  - A failed prompt does NOT poison the queue; the tail catches and
    keeps draining so the next caller still runs (the original caller
    still sees its own rejection).
  - `cancelSession(sessionId, req?)` bypasses the queue and forwards
    the ACP notification immediately. ACP semantics: the agent winds
    down the *currently active* prompt; queued work is unaffected.
  - Both methods throw `SessionNotFoundError` (a typed Error subclass)
    when the id is unknown so route handlers can map cleanly to 404
    without brittle message matching.
  - Both methods overwrite the `sessionId` field in the request body
    with the routing id — a stale or spoofed body would otherwise be
    dispatched to the wrong agent process.

Routes:
  - `POST /session/:id/prompt` → 200 with PromptResponse, 400 on
    missing/non-array prompt, 404 on unknown session, 500 on agent
    error.
  - `POST /session/:id/cancel` → 204 always (cancel is a notification),
    404 on unknown session.

Tests (14 new — 7 bridge + 7 route, 0 regressions in the 4981 baseline):
  - sendPrompt: success forwards & returns response · routing-id
    overrides body sessionId · concurrent prompts FIFO-serialize
    (verified via per-prompt start/end ordering with a release latch) ·
    failed prompt doesn't block subsequent prompts · 404 for unknown id.
  - cancelSession: forwards with routing id · 404 for unknown id.
  - Routes: 200/400/404/500 paths for prompt; 204 with body or empty +
    404 for cancel.

Verified end-to-end against a real `qwen --acp` child:
  - POST /session/:id/prompt with `[{type:'text',text:'hi'}]` → 200
    `{"stopReason":"end_turn"}` in ~3.4s.
  - POST /session/:id/cancel → 204.
  - POST /session/does-not-exist/prompt → 404 with the unknown id
    surfaced in the body.
2026-05-07 11:10:58 +08:00
..
src feat(cli): wire POST /session/:id/prompt + /cancel for qwen serve (#3803) 2026-05-07 11:10:58 +08:00
index.ts fix(cli): stop double-wrapping and double-printing API errors in non-interactive mode (#3749) 2026-05-03 08:39:31 +08:00
package.json feat(cli): scaffold qwen serve HTTP daemon (Stage 1, #3803) 2026-05-07 10:44:16 +08:00
test-setup.ts fix: prevent bogus shell permission rules in tests 2026-03-20 17:55:33 +08:00
tsconfig.json Add background agent resume and continuation (#3739) 2026-05-01 12:14:33 +08:00
vitest.config.ts refactor(core): Unify package exports and improve dev experience 2026-02-01 11:59:05 +08:00