diff options
Diffstat (limited to 'docs/superpowers/specs/2026-10-16-text-daemon-design.md')
| -rw-r--r-- | docs/superpowers/specs/2026-10-16-text-daemon-design.md | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/docs/superpowers/specs/2026-10-16-text-daemon-design.md b/docs/superpowers/specs/2026-10-16-text-daemon-design.md index 30f202b..40a73c8 100644 --- a/docs/superpowers/specs/2026-10-16-text-daemon-design.md +++ b/docs/superpowers/specs/2026-10-16-text-daemon-design.md @@ -54,7 +54,7 @@ merging, `--test`, `assistant.sh`. - **Thinking.** `chat_template_kwargs.enable_thinking` becomes true. `delta.reasoning_content` is streamed as its own `think` event, so the canvas can collapse it. Reasoning is not stored and not sent back to the - model. + model. It is the config key `thinking` (default true): measured live, reasoning added about 21 s before the first token of a two-line answer. - **System prompt.** The default is rewritten for text: markdown is allowed, there is no instruction to answer in short spoken sentences. - **Input.** The mic loop is replaced by a reader thread per client. Each @@ -71,6 +71,7 @@ merging, `--test`, `assistant.sh`. JSON lines both ways on the existing socket. Every connected client sees every outbound event, so a canvas reopened mid-reply catches up. +A client stalled for 2 s on a send is dropped. Inbound: @@ -84,6 +85,8 @@ Inbound: | `{"type":"search","q":"..."}` | answers `results` | | `{"type":"delete","id":N}` | deletes N, answers `conversations`; deleting the current one acts as `new` | +Ids in `open` and `delete` must be integers; a bad id, a non-string `text` or `q`, or a command that raises answers `error` (`bad id`, `bad text`, `bad query`, `<type> failed`) and leaves the conversation untouched. + An `ask` while a reply is streaming stops the old reply first. An unknown or malformed line is logged and answered with `error`; it never closes the connection. @@ -92,21 +95,20 @@ Outbound: | Event | Fields | | --- | --- | -| `hello` | `state`, `model`, `ctx_used`, `ctx_max`, `id`, `turns` (the current conversation) | +| `hello` | `state`, `model`, `ctx_used`, `ctx_max`, `id`, `turns` (the current conversation), `pending` (`{user, reply, think, tools}` of a reply in flight, or null) | | `state` | `state`: `idle`, `thinking`, `tool` (with `tool`) | | `user` | `text`: the question, echoed so every client draws it | | `think` | `delta` | | `token` | `delta` | | `tool` | `name`, `done` (false when it starts, true when it returns) | -| `done` | `id`: the conversation the turn was saved in | +| `done` | `id`: the conversation the turn was saved in; `stopped`: true for a reply that was stopped | | `error` | `message` | | `ctx` | `used`, `max` | | `conversations` | `items`: `[{id, title, updated}]`, newest first | | `conversation` | `id`, `turns`: `[{user, reply, tools}]` | | `results` | `items`: `[{id, title, snippet}]`, best first | -`hello` is sent on connect. A reply that was stopped emits `done` with -whatever text it had, and that partial turn is not saved. +`hello` is sent on connect. A stopped reply gets a `done` with `stopped: true` from whatever stopped it, and that partial turn is not saved. ## Storage @@ -142,12 +144,12 @@ delete trigger cleans the index. - `open` loads the last 10 turns' `messages` as the model history and all turns' `user`, `reply`, `tools` for the canvas. Tool results come back as the stored placeholder. -- `search` wraps the user's text as an FTS5 phrase (double quotes doubled - inside), so FTS syntax in the query cannot break or widen it. Results are +- `search` wraps the user's text as an FTS5 phrase (double quotes doubled inside) with a prefix star, so FTS syntax in the query cannot break or widen it and a half-typed word still matches. Snippets mark matches with `**`. Results are ranked by `bm25` and grouped to one row per conversation, with `snippet()` from its best turn. - One connection guarded by a lock: the reply threads and the client reader threads all go through it. Only the daemon touches the file. +- An index on `turns(conv, seq)`; `db_open` chmods the directory and file even when they already exist. ## assistant.sh |
