@markusylisiurunen/tau 0.3.49 → 0.3.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -908
- package/dist/core/commands/registry.js +4 -4
- package/dist/core/commands/registry.js.map +1 -1
- package/dist/core/personas.js +19 -10
- package/dist/core/personas.js.map +1 -1
- package/dist/core/runtime/runtime_bootstrap.js +14 -9
- package/dist/core/runtime/runtime_bootstrap.js.map +1 -1
- package/dist/core/static/tau_docs/client-tools.md +228 -0
- package/dist/core/static/tau_docs/config-reference.md +422 -0
- package/dist/core/static/tau_docs/configuration.md +210 -0
- package/dist/core/static/tau_docs/credentials.md +200 -0
- package/dist/core/static/tau_docs/getting-started.md +140 -0
- package/dist/core/static/tau_docs/history.md +163 -0
- package/dist/core/static/tau_docs/index.md +40 -0
- package/dist/core/static/tau_docs/manifest.json +28 -0
- package/dist/core/static/tau_docs/models.md +198 -0
- package/dist/core/static/tau_docs/node-sdk.md +399 -0
- package/dist/core/static/tau_docs/nook.md +264 -0
- package/dist/core/static/tau_docs/ownership-and-scope.md +104 -0
- package/dist/core/static/tau_docs/personas.md +199 -0
- package/dist/core/static/tau_docs/prompts-and-project-context.md +181 -0
- package/dist/core/static/tau_docs/remote-sessions.md +274 -0
- package/dist/core/static/tau_docs/security.md +188 -0
- package/dist/core/static/tau_docs/session-protocol-methods.md +577 -0
- package/dist/core/static/tau_docs/session-protocol.md +265 -0
- package/dist/core/static/tau_docs/sessions.md +223 -0
- package/dist/core/static/tau_docs/skills.md +176 -0
- package/dist/core/static/tau_docs/subagents.md +203 -0
- package/dist/core/static/tau_docs/telegram.md +342 -0
- package/dist/core/static/tau_docs/tools.md +203 -0
- package/dist/core/static/tau_docs/troubleshooting.md +292 -0
- package/dist/core/static/tau_docs/tui.md +224 -0
- package/dist/core/telegram/session_manager.js +4 -3
- package/dist/core/telegram/session_manager.js.map +1 -1
- package/dist/core/tools/catalog.js +3 -1
- package/dist/core/tools/catalog.js.map +1 -1
- package/dist/core/tools/presentation.js +12 -1
- package/dist/core/tools/presentation.js.map +1 -1
- package/dist/core/tools/tau_docs.js +115 -0
- package/dist/core/tools/tau_docs.js.map +1 -0
- package/dist/core/tools/tool_names.js +8 -0
- package/dist/core/tools/tool_names.js.map +1 -1
- package/dist/core/utils/repository.js +19 -0
- package/dist/core/utils/repository.js.map +1 -1
- package/dist/core/version.js +1 -1
- package/dist/host/client_tool_broker.js +3 -18
- package/dist/host/client_tool_broker.js.map +1 -1
- package/dist/protocol/session_protocol.d.ts +1 -0
- package/dist/protocol/session_protocol.js +2 -1
- package/dist/protocol/session_protocol.js.map +1 -1
- package/dist/tui/session_chat_app.js +1 -0
- package/dist/tui/session_chat_app.js.map +1 -1
- package/dist/tui/session_chat_controller.js +13 -13
- package/dist/tui/session_chat_controller.js.map +1 -1
- package/dist/tui/session_creation_attributes.js +3 -3
- package/dist/tui/session_creation_attributes.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# Session protocol
|
|
2
|
+
|
|
3
|
+
Tau's session protocol is the public wire contract for clients that create, observe, and control hosted sessions. Use it when an integration needs to speak directly to `tau rpc` or `tau serve`. Node applications can usually use the typed [Node SDK](node-sdk.md) instead.
|
|
4
|
+
|
|
5
|
+
The protocol carries the same semantics over stdio and WebSocket. It is request and response based, with separate server messages for observed state, pending input, subagent activity, ephemeral feedback, and delegated client tools. The complete method surface is in the [session protocol method reference](session-protocol-methods.md).
|
|
6
|
+
|
|
7
|
+
## Choose a transport
|
|
8
|
+
|
|
9
|
+
`tau rpc` uses UTF-8 NDJSON. The client writes one JSON request per stdin line and reads one JSON server message per stdout line. Stdout is protocol-only. Process diagnostics and login-shell output must go to stderr.
|
|
10
|
+
|
|
11
|
+
`tau serve` uses one UTF-8 JSON object per text WebSocket message. Binary messages are not supported. Authentication, TLS, listener setup, SSH attachment, and host lifetime belong to [remote sessions](remote-sessions.md).
|
|
12
|
+
|
|
13
|
+
Both transports expose one host. Starting either server does not create or select a session. A client lists, creates, or observes sessions explicitly.
|
|
14
|
+
|
|
15
|
+
The client, host, and execution environment remain separate logical machines even when they share a process or filesystem. Session paths and commands belong to the execution environment. Persistence, credentials, model work, and protocol coordination belong to the host. Client tools and local UI belong to the connected client. See [ownership and scope](ownership-and-scope.md) before passing paths or credentials across this boundary.
|
|
16
|
+
|
|
17
|
+
## Connect and initialize
|
|
18
|
+
|
|
19
|
+
The server sends `ready` as its first message:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"version": 12,
|
|
24
|
+
"type": "ready",
|
|
25
|
+
"methods": ["initialize", "session.create", "session.list"]
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The actual `methods` array contains the complete supported method set, not only the shortened example above. Protocol versioning is exact rather than negotiated. A client and host that disagree on `version` must use compatible Tau releases.
|
|
30
|
+
|
|
31
|
+
After `ready`, send `initialize` with non-empty client metadata:
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"version": 12,
|
|
36
|
+
"type": "request",
|
|
37
|
+
"id": "init-1",
|
|
38
|
+
"method": "initialize",
|
|
39
|
+
"params": {
|
|
40
|
+
"client": { "name": "acme-editor", "version": "1.4.0" }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
A successful result returns `protocolVersion`, the complete `methods` array, and `alreadyInitialized`. Repeating `initialize` is allowed and reports `alreadyInitialized: true`. Initialization is a handshake signal, not a session operation, but clients should complete it before other requests.
|
|
46
|
+
|
|
47
|
+
An initializing client may advertise in-process client tools through `client.tools`. Tool calls are then delegated over this connection. The [client tools](client-tools.md) page owns tool behavior, authority, and command-backed helpers; this page describes the wire messages required by a raw protocol client.
|
|
48
|
+
|
|
49
|
+
## Send requests and match responses
|
|
50
|
+
|
|
51
|
+
Every request has the same envelope:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"version": 12,
|
|
56
|
+
"type": "request",
|
|
57
|
+
"id": "req-42",
|
|
58
|
+
"method": "session.snapshot",
|
|
59
|
+
"params": { "sessionId": "0195d6e4-4cf9-7f44-a2d8-f8f7f49ee9d3" }
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`id` is a non-empty client-chosen string and must identify the outstanding request on that connection. `params` is always required, including `{}` for `session.list`. The host validates required fields, field types, discriminators, method names, and the exact protocol version. Unknown object fields are accepted and stripped.
|
|
64
|
+
|
|
65
|
+
Successful responses echo the request id:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"version": 12,
|
|
70
|
+
"type": "response",
|
|
71
|
+
"id": "req-42",
|
|
72
|
+
"ok": true,
|
|
73
|
+
"result": { "sessionId": "..." }
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
A request can remain open while the host emits state messages or handles later requests. Route responses by `id`, never by arrival order. Route streamed messages by `sessionId`.
|
|
78
|
+
|
|
79
|
+
## Observe before consuming session state
|
|
80
|
+
|
|
81
|
+
`session.create` creates a hosted session but does not observe it. `session.observe` establishes observation on this connection and returns three authoritative baselines together:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"snapshot": { "sessionId": "...", "revision": 8 },
|
|
86
|
+
"pendingUserMessages": { "revision": 3, "messages": [] },
|
|
87
|
+
"subagentActivities": { "revision": 5, "agents": {} }
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Install all three baselines before processing later messages for that session. The host buffers updates while preparing the observe response and sends only updates newer than the returned revisions afterward.
|
|
92
|
+
|
|
93
|
+
Observation controls delivery, not session ownership. `session.unobserve` stops this connection's updates without deleting the session or interrupting work. Several connections may observe the same session, and every observer can mutate it. Client-tool names must remain unique across observing clients.
|
|
94
|
+
|
|
95
|
+
## Treat the snapshot as authoritative
|
|
96
|
+
|
|
97
|
+
`SessionProtocolSnapshot` is the recoverable public state for one session. Its major fields are:
|
|
98
|
+
|
|
99
|
+
| Field | Meaning |
|
|
100
|
+
| --- | --- |
|
|
101
|
+
| `sessionId`, `attributes`, `createdAt` | Identity and immutable creation metadata. |
|
|
102
|
+
| `revision` | Monotonic protocol snapshot revision. |
|
|
103
|
+
| `lifecycle` | `idle` or `running`. |
|
|
104
|
+
| `agentState` | Independent agent revision, model context key, and optional usage checkpoint. |
|
|
105
|
+
| `goal`, `settings`, `costTotal` | Current goal, persona and reasoning settings, and accumulated session cost. |
|
|
106
|
+
| `bootstrap`, `catalog` | Selected model and prompt metadata plus available personas, prompt metadata, and skills. |
|
|
107
|
+
| `executionEnvironment` | The environment kind, identity, `cwd`, and home used for agent-visible work. |
|
|
108
|
+
| `messages`, `turns` | Synchronized model-facing records and durable logical-turn receipts. |
|
|
109
|
+
| `timeline` | Ordered active transcript placement. |
|
|
110
|
+
| `tools`, `operations`, `agents` | Mutable semantic state referenced by timeline items or client views. |
|
|
111
|
+
| `facets` | Versioned client-facing metadata. Unknown facet kinds and versions should be ignored. |
|
|
112
|
+
|
|
113
|
+
Render active transcript order from `timeline.items`, not by sorting or filtering `messages`. A timeline item either contains a notice or references a message, tool, or operation in the corresponding snapshot collection. Some model-visible messages intentionally have no timeline item.
|
|
114
|
+
|
|
115
|
+
The timeline has an `epoch`, a per-epoch sequence high-water mark, and ordered items. Successful compaction replaces the active recoverable timeline and advances the epoch. Rewind stays in the same epoch, removes later items, and preserves the sequence high-water mark so sequence numbers are not reused.
|
|
116
|
+
|
|
117
|
+
User message text is raw recoverable session text. User-facing renderers should remove Tau metadata and leading exact `<system>...</system>\n` blocks. The Node SDK exports projection helpers for this purpose. Do not apply user-text projection to assistant, tool-result, or protocol system messages.
|
|
118
|
+
|
|
119
|
+
Turn requests return a terminal outcome, and accepted user turns are also keyed by `userHistoryEntryId` in `snapshot.turns`. Use that ledger to distinguish an unknown request from accepted running work and settled work. Do not infer request outcomes from notice titles, message counts, or timing.
|
|
120
|
+
|
|
121
|
+
User-facing behavior such as goals, retry, compaction, rewind, and recovery is described in [sessions](sessions.md).
|
|
122
|
+
|
|
123
|
+
## Apply snapshot deltas in order
|
|
124
|
+
|
|
125
|
+
Observed snapshot changes arrive as `session.delta`:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"version": 12,
|
|
130
|
+
"type": "session.delta",
|
|
131
|
+
"sessionId": "0195d6e4-4cf9-7f44-a2d8-f8f7f49ee9d3",
|
|
132
|
+
"fromRevision": 8,
|
|
133
|
+
"toRevision": 9,
|
|
134
|
+
"cause": { "type": "assistant-stream" },
|
|
135
|
+
"delta": {
|
|
136
|
+
"type": "snapshot.patch",
|
|
137
|
+
"changes": [
|
|
138
|
+
{
|
|
139
|
+
"type": "message.content.append",
|
|
140
|
+
"messageId": "assistant-1",
|
|
141
|
+
"text": "Done.",
|
|
142
|
+
"timestamp": 1784463600000
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
For a patch, `fromRevision` must equal the installed snapshot revision and `toRevision` becomes the new revision. Apply every `changes` entry atomically and in order. Changes can set scalar state, append or replace messages, append streamed content, update the timeline, or set and remove keyed tools, operations, agents, turns, and facets.
|
|
150
|
+
|
|
151
|
+
`snapshot.reset` carries a complete replacement snapshot. Reset causes identify `compaction`, `rewind`, or `resync`; compaction and rewind include the timeline data needed to validate the transition. Use the structured cause rather than inferring destructive transitions from content.
|
|
152
|
+
|
|
153
|
+
If a patch has an unexpected `fromRevision`, or applying any change would produce invalid references or ordering, stop applying deltas and call `session.snapshot`. Deltas whose `toRevision` is already installed are stale and must not replay client presentation transitions.
|
|
154
|
+
|
|
155
|
+
Node clients can use `applySessionProtocolDelta`, which validates session identity, revision continuity, timeline rules, references, and the resulting snapshot.
|
|
156
|
+
|
|
157
|
+
## Maintain the independent live-state channels
|
|
158
|
+
|
|
159
|
+
Not all observed state belongs in the recoverable snapshot. Each live channel has its own revision or delivery semantics.
|
|
160
|
+
|
|
161
|
+
### Pending user messages
|
|
162
|
+
|
|
163
|
+
`session.pendingUserMessages` is a full replacement:
|
|
164
|
+
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"version": 12,
|
|
168
|
+
"type": "session.pendingUserMessages",
|
|
169
|
+
"sessionId": "...",
|
|
170
|
+
"state": {
|
|
171
|
+
"revision": 4,
|
|
172
|
+
"messages": [
|
|
173
|
+
{ "id": "pending-1", "mode": "steer", "text": "Use the smaller API." },
|
|
174
|
+
{ "id": "pending-2", "mode": "queue", "text": "Run tests afterward." }
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Replace the complete pending list only when its revision is newer. Pending revisions are independent of snapshot revisions. This state is shared by observers while the hosted session remains in memory, but it starts empty after recovery.
|
|
181
|
+
|
|
182
|
+
### Subagent activities
|
|
183
|
+
|
|
184
|
+
`session.subagentActivities` carries an independent `revision` and a list of changes. `agent.set` replaces that agent's complete current-run activity list; `agent.remove` deletes it. Apply changes only when the message revision is newer than the installed activity revision. The observe result provides the complete baseline.
|
|
185
|
+
|
|
186
|
+
Activity lists contain bounded assistant text, settled tool presentations, and notices. They are transient supervision state, not a substitute for `snapshot.agents`, and they start empty after recovery.
|
|
187
|
+
|
|
188
|
+
### Ephemeral events
|
|
189
|
+
|
|
190
|
+
`session.ephemeral` carries best-effort live events with no channel revision:
|
|
191
|
+
|
|
192
|
+
- `feedback.notice` is temporary footer feedback.
|
|
193
|
+
- `ephemeral-agent.thread-update` reports live progress for an ephemeral context and thread.
|
|
194
|
+
- `timeline.item` is a non-recoverable notice with an active timeline epoch and allocated sequence.
|
|
195
|
+
|
|
196
|
+
A `timeline.item` can be merged into current presentation only when its epoch matches the installed snapshot. Discard old-epoch items after compaction and post-cutoff items after rewind. Missing ephemeral events do not require resynchronization.
|
|
197
|
+
|
|
198
|
+
## Delegate client tools
|
|
199
|
+
|
|
200
|
+
An initialized client that advertised a tool can receive:
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"version": 12,
|
|
205
|
+
"type": "session.clientTool.call",
|
|
206
|
+
"sessionId": "...",
|
|
207
|
+
"agentId": "main",
|
|
208
|
+
"callId": "call-1",
|
|
209
|
+
"toolName": "local_picker",
|
|
210
|
+
"arguments": {},
|
|
211
|
+
"ackDeadlineMs": 2000,
|
|
212
|
+
"executionDeadlineMs": 60000
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Acknowledge promptly with `session.clientTool.ack`, then send exactly one `session.clientTool.result` with either `{ ok: true, content }` or `{ ok: false, error }`. The result methods return `{ accepted: boolean }`; `false` means the call is no longer waiting for that message.
|
|
217
|
+
|
|
218
|
+
`session.clientTool.cancel` names the session and call with reason `aborted`, `timeout`, or `client-detached`. Abort local work and do not send a late result. The SDK implements this lifecycle automatically. Tool execution authority and the execution-environment facade are covered in [client tools](client-tools.md).
|
|
219
|
+
|
|
220
|
+
## Handle errors and terminal transport failure
|
|
221
|
+
|
|
222
|
+
Error responses use `ok: false`:
|
|
223
|
+
|
|
224
|
+
```json
|
|
225
|
+
{
|
|
226
|
+
"version": 12,
|
|
227
|
+
"type": "response",
|
|
228
|
+
"id": "req-42",
|
|
229
|
+
"ok": false,
|
|
230
|
+
"error": {
|
|
231
|
+
"code": "busy",
|
|
232
|
+
"message": "a session turn is already running"
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
The supported codes are:
|
|
238
|
+
|
|
239
|
+
| Code | Meaning |
|
|
240
|
+
| --- | --- |
|
|
241
|
+
| `parse_error` | The JSON payload could not be parsed. |
|
|
242
|
+
| `invalid_request` | The envelope, version, type, id, or requested operation is invalid. |
|
|
243
|
+
| `method_not_found` | The method is unsupported. |
|
|
244
|
+
| `invalid_params` | Method parameters failed validation. |
|
|
245
|
+
| `not_found` | The addressed session does not exist on this host. |
|
|
246
|
+
| `busy` | Conflicting session work or a same-thread ephemeral submission is active. |
|
|
247
|
+
| `cancelled` | Pending input, execution, or sampling was cancelled. |
|
|
248
|
+
| `internal_error` | The host could not complete the operation. |
|
|
249
|
+
|
|
250
|
+
When no valid request id can be recovered, an error response uses `id: null`. Error `message` and optional `data` are diagnostic. Branch on `code`, not message text.
|
|
251
|
+
|
|
252
|
+
A closed stdio stream, process exit, WebSocket close, malformed server payload, unsupported version, or other terminal transport failure rejects all outstanding requests. Stop sending, cancel client-local delegated tools, and reconnect or create a new transport deliberately. A WebSocket disconnect detaches from a long-running host; closing a stdio RPC process shuts down the host it owns.
|
|
253
|
+
|
|
254
|
+
## Coordinate concurrent work
|
|
255
|
+
|
|
256
|
+
The server can accept several requests before earlier requests settle, so responses and streamed messages may interleave.
|
|
257
|
+
|
|
258
|
+
- Only one ordinary main-session turn or goal turn runs at a time. `session.submit`, `session.retry`, `session.startGoal`, and `session.resumeGoal` return `busy` on conflict.
|
|
259
|
+
- `session.queue` waits for idle work. `session.steer` requests the next safe turn boundary. Each request receives its own eventual response.
|
|
260
|
+
- Session mutations are serialized in arrival order across clients. Mutations that replace context can interrupt active work and reject pending input. `session.rewind` instead requires the session to be idle with no pending input.
|
|
261
|
+
- `session.setReasoning` is serialized but does not interrupt the active turn. The new setting applies to the next independently started turn.
|
|
262
|
+
- `session.exec` and `session.sample` are side channels. They can overlap turns, mutations, each other, and ephemeral agents. Clients own workspace coordination.
|
|
263
|
+
- Ephemeral contexts run outside the main mutation queue. Two submissions to the same ephemeral thread conflict, while different threads can run independently.
|
|
264
|
+
|
|
265
|
+
Do not assume a success response arrives before the deltas caused by that request. Maintain state from the observed streams, correlate completion by request id, and use `session.snapshot` when continuity is uncertain.
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# Sessions
|
|
2
|
+
|
|
3
|
+
A Tau session is the durable home of one conversation and its execution environment. It keeps enough state to continue after detaching or restarting the host, while deliberately leaving short-lived client and process state out. Understanding that boundary makes interruption, recovery, compaction, and remote work predictable.
|
|
4
|
+
|
|
5
|
+
## Create a session
|
|
6
|
+
|
|
7
|
+
Running `tau` creates a fresh local session with the current directory as its execution cwd. The host resolves [configuration](configuration.md), models, [personas](personas.md), [skills](skills.md), prompts, and project context from that execution environment before the first turn.
|
|
8
|
+
|
|
9
|
+
The session also receives immutable creation attributes. They are bounded string pairs used for provenance and [history](history.md), not mutable runtime settings. Conventional attributes are:
|
|
10
|
+
|
|
11
|
+
- `source`, identifying the creating client, such as `tui` or `sdk`.
|
|
12
|
+
- `repository`, using a normalized `host/owner/repository` value. Composite workspaces use comma-delimited repository values.
|
|
13
|
+
|
|
14
|
+
For a local TUI, Tau can derive `repository` before creation because that client directly manages the local execution environment. A remote host does not inspect an execution path to infer attributes. Remote TUI creation supplies `source: "tui"`; SDK and protocol clients should provide complete authoritative attributes themselves.
|
|
15
|
+
|
|
16
|
+
A session’s execution-environment identity and cwd are fixed at creation. `/new` creates another session in the same environment with the current persona and reasoning settings. It does not clear or reuse the existing session.
|
|
17
|
+
|
|
18
|
+
## Know what owns the session
|
|
19
|
+
|
|
20
|
+
Three components can be physically colocated but remain logically separate:
|
|
21
|
+
|
|
22
|
+
- The TUI or SDK client submits input, observes updates, and may provide client-local tools.
|
|
23
|
+
- The session host orchestrates turns, resolves credentials, persists sessions, and supervises execution environments.
|
|
24
|
+
- The execution environment owns the agent-visible cwd, files, repository, project configuration, commands, platform, and runtime tools.
|
|
25
|
+
|
|
26
|
+
The host persists ordinary sessions under `~/.config/tau/sessions` for the host user. These versioned documents are managed storage, not an editing interface. Never modify them directly. Use Tau’s session operations, normal project configuration, and recovery path instead.
|
|
27
|
+
|
|
28
|
+
## Submit, queue, and steer
|
|
29
|
+
|
|
30
|
+
A normal submission is accepted and persisted before model work begins. Tau then runs model and tool subturns until the turn completes, fails, is blocked, or is interrupted.
|
|
31
|
+
|
|
32
|
+
Only one logical turn runs at a time. Input sent during active work has two useful delivery modes:
|
|
33
|
+
|
|
34
|
+
- A queued message waits for the session to become idle, then starts an independent turn.
|
|
35
|
+
- Steering joins the active logical turn at a safe continuation boundary.
|
|
36
|
+
|
|
37
|
+
In the TUI, Enter queues and Ctrl+Enter steers while work is active. When idle, either starts a normal turn. Pending messages are visible to every observer of the same live hosted session. Alt+Up cancels queued messages and steering that has not been applied and restores the text to the editor.
|
|
38
|
+
|
|
39
|
+
A turn captures its model, persona, reasoning, system prompt, tools, retry policy, and compaction policy when it starts. Tool subturns and steering continuations keep that captured specification even if reasoning or host configuration changes meanwhile. A queued turn captures the then-current specification when it later starts.
|
|
40
|
+
|
|
41
|
+
Pending queue and steering state survives client detach only while the hosted session remains alive in memory. It is not part of durable recovery and starts empty after a host restart.
|
|
42
|
+
|
|
43
|
+
## Interrupt and retry
|
|
44
|
+
|
|
45
|
+
Ordinary session interruption is cooperative. It requests cancellation of the main session’s active turn, all direct executions, isolated model samples, and maintenance work. An interrupted turn records an interrupted assistant result where one exists. It does not stop independently running supervised subagents; select one with Alt+Down and use Ctrl+G, or call `session.interruptSubagent` from a protocol client. Host shutdown or session disposal cleans up those child runtimes. In the TUI, Escape interrupts client-local foreground work such as diff review, recording, or speech playback before requesting main-session interruption from the host.
|
|
46
|
+
|
|
47
|
+
Retry runs another assistant turn from the current session history. It does not remove the interrupted or failed result, rewind context, or submit the previous user text again. This lets Tau continue from completed tool results without automatically rerunning them. In the TUI, press Enter twice on an empty editor while idle.
|
|
48
|
+
|
|
49
|
+
Retry is unavailable when there is no prior user turn. It is also unavailable for goal-controlled turns because a blocked goal has an explicit resume operation.
|
|
50
|
+
|
|
51
|
+
Detaching is not the same as interrupting. Closing one observer of a long-running host leaves the hosted turn running. By contrast, a local TUI owns its in-process host, and a stdio attachment owns its `tau rpc` process; closing either causes that host to shut down and interrupt active work. See [remote sessions](remote-sessions.md).
|
|
52
|
+
|
|
53
|
+
## Change persona and reasoning safely
|
|
54
|
+
|
|
55
|
+
The selected persona and reasoning level are durable session settings.
|
|
56
|
+
|
|
57
|
+
Persona changes require idle state because they rebuild the effective model, system instructions, skills, and tools from the execution environment’s current configuration. In the TUI, use `/persona:<id>` or Ctrl+P.
|
|
58
|
+
|
|
59
|
+
Reasoning can be changed while work is active. The current turn keeps its captured reasoning, while the next independently started or queued turn uses the new setting. Use Shift+Tab in the TUI.
|
|
60
|
+
|
|
61
|
+
After a host restart, recovery resolves current runtime configuration so providers and model definitions remain usable, then reapplies the session’s persisted persona and reasoning settings where possible. The effective recovered bootstrap can change when the current installation or model catalog has changed, but the session’s committed semantic content remains the recovery source of truth.
|
|
62
|
+
|
|
63
|
+
## Detach, reattach, and recover
|
|
64
|
+
|
|
65
|
+
A session is persisted throughout its lifetime, not only when the TUI exits. Reattaching to a live host returns the current state and continues receiving updates. Reattaching after host restart loads the stored session and restores its execution environment through a configured resolver.
|
|
66
|
+
|
|
67
|
+
Recovery preserves user-visible durable state including:
|
|
68
|
+
|
|
69
|
+
- committed conversation messages and terminal tool results
|
|
70
|
+
- current persona and reasoning settings
|
|
71
|
+
- cumulative usage cost and context accounting needed for continuation
|
|
72
|
+
- persistent goal state
|
|
73
|
+
- execution-environment identity, cwd, and creation attributes
|
|
74
|
+
- compaction and rewind results
|
|
75
|
+
|
|
76
|
+
Recovery intentionally does not recreate every live process. It returns the session idle, settles any accepted but unfinished turn as aborted, cancels running maintenance operations, and normalizes tools whose completion cannot be proven. Supervised subagents and their live activity do not survive restart. An active persistent goal becomes blocked rather than continuing autonomously without an explicit resume.
|
|
77
|
+
|
|
78
|
+
A stored session is listed or recovered only when the current host has a resolver capable of restoring its execution-environment kind and named target. Recovery can therefore fail even when the session document is valid, for example when a Cloudflare bridge was removed, a Fly API target is no longer configured, or the underlying sandbox, Sprite, directory, or credentials are unavailable.
|
|
79
|
+
|
|
80
|
+
Newer Tau versions preserve the openability of supported stored sessions through storage migrations and recovery normalization. This promises access to recoverable semantic data, not byte-for-byte files or identical historical presentation. A genuinely newer unsupported storage version or corrupted document can still be rejected.
|
|
81
|
+
|
|
82
|
+
## Use persistent goals
|
|
83
|
+
|
|
84
|
+
A persistent goal lets Tau continue across repeated model turns until the agent marks the objective complete or blocked. Start one from the TUI:
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
/goal prepare the release and verify the package
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Tau stores the objective before running it. While the goal remains active, the host creates continuation turns automatically. The agent’s goal tools can refine the objective, block it when human input is needed, or complete and clear it.
|
|
91
|
+
|
|
92
|
+
Use the controls deliberately:
|
|
93
|
+
|
|
94
|
+
- `/goal` shows the current objective and status.
|
|
95
|
+
- `/goal resume` resumes a blocked goal.
|
|
96
|
+
- `/goal clear` clears the goal. If work is active, clearing interrupts it and cancels pending input associated with the old flow.
|
|
97
|
+
|
|
98
|
+
Only one goal can exist at a time. Clear it before starting another. Interruption, provider failure, blocked execution, or host recovery changes an active goal to `blocked`. Tau never silently resumes autonomous goal work after recovery. Goal-controlled turns cannot use ordinary retry; use `/goal resume` after resolving the blocker.
|
|
99
|
+
|
|
100
|
+
A goal survives client detach and host restart because its objective and status are session state. The process doing the work does not survive restart.
|
|
101
|
+
|
|
102
|
+
## Compact model context
|
|
103
|
+
|
|
104
|
+
Compaction replaces older model-visible conversation context with a synthetic summary so the session can continue within the model’s context window. It changes active model context, not the independent searchable transcript.
|
|
105
|
+
|
|
106
|
+
### Automatic compaction
|
|
107
|
+
|
|
108
|
+
Automatic compaction runs before a model subturn when fresh provider usage plus newly added estimated context exceeds the configured threshold. The threshold is the model context window minus `autoCompact.reserveTokens`. Tau keeps a recent tail bounded by `autoCompact.keepRecentTokens`, summarizes older context, and can compact more than once during a long logical turn.
|
|
109
|
+
|
|
110
|
+
The summary model may copy important original user messages verbatim into the summary. Recent retained messages stay available to the model, although unusually large textual tool and recovery results may be truncated in retained context. Tau records the compaction as a new active context segment.
|
|
111
|
+
|
|
112
|
+
Before replacing context, Tau makes a best-effort archive in the execution environment’s temporary directory. Each automatic compaction adds a numbered `.txt` and `.json` pair under a directory isolated by agent id. The text file is convenient for bounded search and truncates large tool results; the JSON pair retains the archived content without those tool-result truncations, excluding assistant thinking. The continuation message gives the agent the exact paths when archiving succeeds.
|
|
113
|
+
|
|
114
|
+
These archives are temporary recovery aids, not backups. Archive failure does not block compaction, and execution-environment cleanup may remove them.
|
|
115
|
+
|
|
116
|
+
Configure the policy in [configuration](configuration.md):
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"autoCompact": {
|
|
121
|
+
"enabled": true,
|
|
122
|
+
"reserveTokens": 16384,
|
|
123
|
+
"keepRecentTokens": 20000
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Manual compaction
|
|
129
|
+
|
|
130
|
+
Manual compaction requires idle state and summarizes the whole active model history rather than retaining an automatic recent tail.
|
|
131
|
+
|
|
132
|
+
```text
|
|
133
|
+
/compact-all preserve the deployment constraints
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`/compact-all` replaces context with the generated summary. `/compact-keep-last` also asks the summary to include the prior last assistant response verbatim when one is available. Text after either command is optional guidance to the compaction model, not a new conversation turn.
|
|
137
|
+
|
|
138
|
+
A failed, skipped, or interrupted compaction leaves the previous context active. Manual compaction does not create the automatic pre-compaction archive.
|
|
139
|
+
|
|
140
|
+
## Rewind deliberately
|
|
141
|
+
|
|
142
|
+
`/rewind` opens a picker of eligible user messages. Selecting one removes that selected message and everything after it from the active session, then returns the selected text to the editor so it can be revised and resubmitted.
|
|
143
|
+
|
|
144
|
+
Rewind requires the session to be idle with no pending submissions. It truncates messages, tool state, turn outcomes, and searchable transcript entries from the selected boundary onward. It is not a display-only operation and has no built-in undo. If the intent is merely to correct course without deleting history, submit a new message or steer the active turn instead.
|
|
145
|
+
|
|
146
|
+
Compaction and rewind differ in an important way: compaction preserves the flat transcript history, while rewind truncates it to match the chosen session boundary.
|
|
147
|
+
|
|
148
|
+
## Reload session content
|
|
149
|
+
|
|
150
|
+
Run `/reload` from the TUI while the session is idle. The host rereads runtime configuration and model overlays, personas, prompts, skills, and AGENTS.md context from the execution environment cwd. It keeps the current persona if that id still exists and otherwise selects the first available persona. Reload warnings appear in the transcript.
|
|
151
|
+
|
|
152
|
+
Reload updates future turns. It does not rewrite committed conversation content or change the execution environment. It also does not reload client-owned themes, diff launchers, speech settings, or client tools. Restart the attaching TUI for those. Effective configured model `apiKeys` update through `/reload`, while managed Codex auth storage is read again on later credential resolutions. Restart the host for changed process environment variables, listener settings, resolver targets, or the Tau binary. [Credentials](credentials.md) has the canonical distinctions, and [remote sessions](remote-sessions.md) identifies each owner.
|
|
153
|
+
|
|
154
|
+
Protocol clients can request mutations directly, but should still wait for idle state. Mutating operations can interrupt current work and reject pending messages so the session reaches one canonical configuration.
|
|
155
|
+
|
|
156
|
+
## Session state and transcript history are different
|
|
157
|
+
|
|
158
|
+
Tau keeps two durable views for different jobs:
|
|
159
|
+
|
|
160
|
+
- The session snapshot is the recoverable source of truth for continuing one conversation. It contains the current active model context and user-visible session state.
|
|
161
|
+
- Transcript history is a flat sequence of committed user entries, assistant text, and completed tools used for cross-session search and reading. It is stored separately in the host’s history database and may also replicate to a configured history service.
|
|
162
|
+
|
|
163
|
+
Compaction changes the session snapshot’s active context but leaves transcript history intact. Rewind truncates both from the removed boundary. Transcript history cannot reconstruct all session runtime state and is not used to recover a session. See [history](history.md) for storage, replication, and the history tool.
|
|
164
|
+
|
|
165
|
+
## Inspect model usage
|
|
166
|
+
|
|
167
|
+
Tau writes host-owned usage records to daily `~/.config/tau/logs/usage-YYYY-MM-DD.jsonl` files under the host user’s home. Records cover finalized assistant model responses from main sessions, supervised subagents, and ephemeral threads. They include timestamps and session, persona, provider, model, reasoning, and agent attribution, plus input, output, cache-read, cache-write, total-token, and Tau-recorded cost values. They do not contain prompt or response text and are separate from session snapshots and transcript history.
|
|
168
|
+
|
|
169
|
+
Run the summary command as the user who runs the host:
|
|
170
|
+
|
|
171
|
+
```sh
|
|
172
|
+
tau usage
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
It groups by day by default and prints request count, each token category, total tokens, cost, and an overall total. The supported options are:
|
|
176
|
+
|
|
177
|
+
| Option | Behavior |
|
|
178
|
+
| --- | --- |
|
|
179
|
+
| `--since <date>` | Include entries on or after an inclusive `YYYY-MM-DD` or ISO date. |
|
|
180
|
+
| `--persona <id>` | Match an exact persona id, case-insensitively. |
|
|
181
|
+
| `--provider <name>` | Match an exact provider, case-insensitively. |
|
|
182
|
+
| `--model <id>` | Match an exact model id, case-insensitively. |
|
|
183
|
+
| `--group-by day\|model` | Group by calendar day or by `provider/model`; the default is `day`. |
|
|
184
|
+
| `--help`, `-h` | Show the command help. |
|
|
185
|
+
|
|
186
|
+
Filters can be combined:
|
|
187
|
+
|
|
188
|
+
```sh
|
|
189
|
+
tau usage --since 2026-08-01 --provider openai-codex --group-by model
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
There is no `--until`, `--session`, or `--agent` filter. For a remote session, run `tau usage` on the host under the same user as `tau serve` or `tau rpc`; running it on an attaching client reads that client user’s logs instead. The command is read-only, but the raw files still reveal timestamps, session identifiers, model choices, token volume, and cost activity. Prefer the filtered aggregate output over copying raw JSONL into a shared transcript, and treat Tau-recorded costs as operational estimates rather than a provider invoice.
|
|
193
|
+
|
|
194
|
+
## What survives each boundary
|
|
195
|
+
|
|
196
|
+
| Event | Durable session state | Pending input | Active turns and subagents | Client-local state |
|
|
197
|
+
| --- | --- | --- | --- | --- |
|
|
198
|
+
| Another client detaches from a live WebSocket host | Preserved | Preserved in host memory | Continue | Detached client tools, themes, drafts, and local tasks are lost |
|
|
199
|
+
| Local TUI or stdio/RPC attachment exits | Persisted by owned-host shutdown | Cancelled | Interrupted and settled where possible | Lost |
|
|
200
|
+
| WebSocket host restarts | Recovered from storage | Lost | Returns idle; subagents are not restored | Each client reconnects separately |
|
|
201
|
+
| TUI restarts while host stays live | Preserved | Preserved in host memory | Continue | Reloaded from the new client process |
|
|
202
|
+
| `/new` | Old session remains stored | Not copied | New idle session | Same TUI process continues |
|
|
203
|
+
|
|
204
|
+
An unsent editor draft belongs only to the TUI. Use Ctrl+S to move it to the local clipboard before restarting a client.
|
|
205
|
+
|
|
206
|
+
## Verify a recovered session safely
|
|
207
|
+
|
|
208
|
+
Use normal Tau operations rather than opening or editing session files.
|
|
209
|
+
|
|
210
|
+
1. Wait for active work to finish or interrupt it intentionally.
|
|
211
|
+
2. Note the session id shown in the TUI startup block.
|
|
212
|
+
3. Exit cleanly and reattach through the same host.
|
|
213
|
+
4. Confirm the expected messages, persona, reasoning level, and `/goal` status.
|
|
214
|
+
5. Run non-contextual environment checks with `!!`, for example `!!pwd` and `!!git status --short`.
|
|
215
|
+
6. Submit a small read-only request before resuming destructive work.
|
|
216
|
+
|
|
217
|
+
For a local stored session, a one-shot local RPC attachment exercises the same recovery path:
|
|
218
|
+
|
|
219
|
+
```sh
|
|
220
|
+
tau attach --session 0195d6e4-4cf9-7f44-a2d8-f8f7f49ee9d3 -- tau rpc
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
If recovery fails, verify the host version, execution-environment resolver configuration, target availability, and credentials before assuming the stored session is damaged. [Remote sessions](remote-sessions.md) covers those checks.
|