mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-10-22 06:49:52 +00:00
docs(serve): fix stale permission-route note and document pending-prompt events (#13281)
docs/users/qwen-serve.md still described session-scoped permission routing as Stage 1.5 future work and pointed integrators at the legacy process-global vote route. Rewrite the note: the session-scoped route ships (Wave 4 / F3) and is the recommended form for new multi-workspace integrations; the legacy route remains for pre-F3 single-workspace clients with its 404 semantics spelled out (the same body as a lost vote for a session owned by another runtime). Add event-reference entries for pending_prompt_added / pending_prompt_started / pending_prompt_completed to docs/developers/daemon/09-event-schema.md: payload fields, the state union, the idle-session no-event caveat, and the "queue-view bookkeeping, not a turn terminal" guidance (correlate turn_complete / turn_error by promptId for completion). Derived from the field notes and triage in #13279.
This commit is contained in:
parent
9d4e1e1c5d
commit
8505479d87
2 changed files with 10 additions and 2 deletions
|
|
@ -162,6 +162,14 @@ These events are workspace-keyed, not session-keyed. The session reducer treats
|
|||
| --------------------------- | --------- | ----------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `mid_turn_message_injected` | S->C | Web-shell or remote client injected messages into a running turn via `POST /session/:id/inject` | `sessionId, messages: string[], originatorClientId?`; consumers MUST compare `originatorClientId` to their own id before deduping. |
|
||||
|
||||
### Pending prompt queue
|
||||
|
||||
| Type | Direction | Trigger | Key payload fields |
|
||||
| -------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
|
||||
| `pending_prompt_added` | S->C | A prompt was appended to the session's prompt FIFO and is waiting behind the active turn. Published only when the prompt is *genuinely queued* — the first prompt on an idle session starts immediately and emits no queue events. | `sessionId, promptId, text, queuedAt` |
|
||||
| `pending_prompt_started` | S->C | The queued prompt reached the head of the FIFO and was promoted to running (also emitted for a promoted mid-turn message that starts immediately). Skipped when the prompt is aborted before promotion. | `sessionId, promptId, text` |
|
||||
| `pending_prompt_completed` | S->C | A queued prompt settled — `state: 'completed'` (it ran; execution errors still report `completed` and ride the terminal `turn_error` frame) or `state: 'removed'` (removed from the queue and never ran). Only emitted for prompts that were genuinely queued (an `added` was published). This is queue-view bookkeeping, **not a turn terminal**; correlate `turn_complete` / `turn_error` by `promptId` for completion. | `sessionId, promptId, state: 'completed' \| 'removed'` |
|
||||
|
||||
### Turn lifecycle / assistant pushes
|
||||
|
||||
| Type | Direction | Trigger | Key payload fields |
|
||||
|
|
|
|||
|
|
@ -771,7 +771,7 @@ provider decision with their normal tool policy and isolation boundary.
|
|||
- **Per-session prompt admission cap** — defaults to 5 accepted-but-unsettled prompts per session. A buggy client cannot enqueue unbounded prompt promises or temporary SSE waits for one session.
|
||||
- **Graceful shutdown** — SIGINT/SIGTERM drain the agent children before closing the listener (10s deadline per child).
|
||||
|
||||
> ⚠️ **Stage 1 known gap — permissions are daemon-global, not per-session (BUy4H).** `pendingPermissions` lives at daemon scope; any client holding the bearer token can vote on any `requestId` for any session it can see (and SSE `permission_request` events carry the requestId in their payload). This is acceptable under the single-user / small-team trust model where every authenticated client is the same human or collaborators they trust. Stage 1.5 will move to `POST /session/:id/permission/:requestId` + session-scoped pending map + per-client identity (must-have #3 from the downstream review); until then, don't run `qwen serve` behind a bearer shared with untrusted parties.
|
||||
> ⚠️ **Permission votes are session-scoped now — plus a standing shared-bearer caveat.** Prefer `POST /session/:id/permission/:requestId` (Wave 4 / F3): it routes to the runtime that owns the named live session and never falls back to the primary bridge — new multi-workspace integrations should always use this route (pre-flight `caps.features.session_permission_vote`). The legacy process-global `POST /permission/:requestId` remains for pre-F3 single-workspace clients: it is primary-bound and `404`s for a session owned by another registered runtime — the same body as a lost vote under the default `first-responder` policy — so a `404` there does not by itself mean the request was already answered. Route table: [daemon REST API reference](../developers/daemon-rest-api-reference.md#permissions). Standing caveat: every client holding the bearer token is the same security principal — don't run `qwen serve` behind a bearer shared with untrusted parties.
|
||||
>
|
||||
> ⚠️ **Stage 1 known gap — `POST /session/:id/prompt` body capped at 10 MB (BUy4L).** Multimodal prompts containing images / PDFs / audio that exceed 10 MB will fail at body-parse time before route logic runs (no streaming, no mid-upload abort). Workaround: shrink the content client-side, or pass a path reference and let the agent read the file via `readTextFile`. Stage 1.5 will accept `multipart/form-data` or chunked encoding on `/prompt` so large prompts don't hit a cliff.
|
||||
>
|
||||
|
|
@ -958,7 +958,7 @@ The Stage 1.5 plan describes TUI as an in-process EventBus subscriber. In practi
|
|||
No TUI shell runs inside the daemon. The slash commands listed above **don't exist** in this mode — there's no terminal UI to issue them from. Session state is therefore:
|
||||
|
||||
- **Boot-time-frozen** for `approval-mode` / `memory` / `agents` / `tools` allowlist / `auth` — all loaded from settings + disk when the daemon's `qwen --acp` child starts; immutable for the session's lifetime. Settings-defined MCP servers are likewise frozen at boot, but **runtime-added servers** (via `POST /workspace/mcp/servers`) can be added or removed without restart.
|
||||
- **Mutable over HTTP** via `POST /session/:id/model` (publishes `model_switched`), `POST /workspace/mcp/servers` / `DELETE /workspace/mcp/servers/:name` (publishes `mcp_server_added` / `mcp_server_removed`), and permission votes (`POST /permission/:requestId`).
|
||||
- **Mutable over HTTP** via `POST /session/:id/model` (publishes `model_switched`), `POST /workspace/mcp/servers` / `DELETE /workspace/mcp/servers/:name` (publishes `mcp_server_added` / `mcp_server_removed`), and permission votes (`POST /session/:id/permission/:requestId`; the legacy process-global `POST /permission/:requestId` remains for pre-F3 single-workspace clients).
|
||||
|
||||
**Consequence:** remote clients in headless mode see the **full session state**. No TUI hides additional state; no drift is possible. If you want to change `approval-mode`, restart the daemon with new settings. MCP servers can now be added/removed at runtime via the mutation routes (`POST /workspace/mcp/servers`, `DELETE /workspace/mcp/servers/:name`) — see [Runtime MCP server management](#runtime-mcp-server-management-issue-4514).
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue