@markusylisiurunen/tau 0.3.50 → 0.3.51
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/dist/code_mode/command.js +26 -14
- package/dist/code_mode/command.js.map +1 -1
- package/dist/code_mode/index.d.ts +2 -1
- package/dist/code_mode/index.js +1 -0
- package/dist/code_mode/index.js.map +1 -1
- package/dist/core/cli.js +0 -11
- package/dist/core/cli.js.map +1 -1
- package/dist/core/client_tools/command_client_tools.js +236 -151
- package/dist/core/client_tools/command_client_tools.js.map +1 -1
- package/dist/core/modes/index.js +0 -1
- package/dist/core/modes/index.js.map +1 -1
- package/dist/core/static/tau_docs/client-tools.md +212 -12
- package/dist/core/static/tau_docs/configuration.md +1 -1
- package/dist/core/static/tau_docs/credentials.md +4 -4
- package/dist/core/static/tau_docs/history.md +1 -1
- package/dist/core/static/tau_docs/index.md +1 -1
- package/dist/core/static/tau_docs/node-sdk.md +33 -26
- package/dist/core/static/tau_docs/ownership-and-scope.md +3 -4
- package/dist/core/static/tau_docs/prompts-and-project-context.md +2 -2
- package/dist/core/static/tau_docs/remote-sessions.md +4 -47
- package/dist/core/static/tau_docs/security.md +2 -6
- package/dist/core/static/tau_docs/session-protocol-methods.md +48 -7
- package/dist/core/static/tau_docs/session-protocol.md +18 -18
- package/dist/core/static/tau_docs/sessions.md +6 -5
- package/dist/core/static/tau_docs/telegram.md +8 -4
- package/dist/core/static/tau_docs/troubleshooting.md +3 -5
- package/dist/core/static/tau_docs/tui.md +4 -6
- package/dist/core/telegram/adapter.js +226 -18
- package/dist/core/telegram/adapter.js.map +1 -1
- package/dist/core/telegram/config.js +1 -1
- package/dist/core/telegram/config.js.map +1 -1
- package/dist/core/telegram/project_preferences.js +42 -12
- package/dist/core/telegram/project_preferences.js.map +1 -1
- package/dist/core/telegram/runtime.js +6 -1
- package/dist/core/telegram/runtime.js.map +1 -1
- package/dist/core/telegram/session_manager.js +50 -4
- package/dist/core/telegram/session_manager.js.map +1 -1
- package/dist/core/telegram/tts.js +137 -0
- package/dist/core/telegram/tts.js.map +1 -0
- package/dist/core/tools/presentation.js +55 -17
- package/dist/core/tools/presentation.js.map +1 -1
- package/dist/core/utils/gemini_speech.js +122 -41
- package/dist/core/utils/gemini_speech.js.map +1 -1
- package/dist/core/version.js +1 -1
- package/dist/host/client_tool_broker.js +71 -17
- package/dist/host/client_tool_broker.js.map +1 -1
- package/dist/host/local_session_host.js +2 -2
- package/dist/host/local_session_host.js.map +1 -1
- package/dist/host/session_host.js.map +1 -1
- package/dist/host/session_protocol_handler.js +17 -6
- package/dist/host/session_protocol_handler.js.map +1 -1
- package/dist/main.js +18 -92
- package/dist/main.js.map +1 -1
- package/dist/protocol/session_protocol.d.ts +22 -2
- package/dist/protocol/session_protocol.js +47 -3
- package/dist/protocol/session_protocol.js.map +1 -1
- package/dist/sdk/client_tool_command.d.ts +41 -13
- package/dist/sdk/client_tool_command.js +157 -39
- package/dist/sdk/client_tool_command.js.map +1 -1
- package/dist/sdk/client_tool_presentation.d.ts +17 -0
- package/dist/sdk/client_tool_presentation.js +9 -0
- package/dist/sdk/client_tool_presentation.js.map +1 -0
- package/dist/sdk/code_mode.js +10 -1
- package/dist/sdk/code_mode.js.map +1 -1
- package/dist/sdk/index.d.ts +5 -4
- package/dist/sdk/index.js +2 -1
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/session.js +28 -9
- package/dist/sdk/session.js.map +1 -1
- package/dist/sdk/types.d.ts +11 -1
- package/dist/transport/errors.d.ts +0 -11
- package/dist/transport/errors.js +0 -12
- package/dist/transport/errors.js.map +1 -1
- package/dist/transport/index.d.ts +1 -3
- package/dist/transport/index.js +1 -2
- package/dist/transport/index.js.map +1 -1
- package/dist/tui/session_chat_app.js +28 -15
- package/dist/tui/session_chat_app.js.map +1 -1
- package/dist/tui/session_chat_controller.js +0 -51
- package/dist/tui/session_chat_controller.js.map +1 -1
- package/dist/tui/speech_playback.js +3 -3
- package/dist/tui/speech_playback.js.map +1 -1
- package/package.json +2 -2
- package/dist/core/modes/rpc_server.js +0 -105
- package/dist/core/modes/rpc_server.js.map +0 -1
- package/dist/transport/stdio_session_transport.d.ts +0 -48
- package/dist/transport/stdio_session_transport.js +0 -338
- package/dist/transport/stdio_session_transport.js.map +0 -1
|
@@ -117,23 +117,222 @@ Diff-tool launcher settings are separate from command client-tool definitions. T
|
|
|
117
117
|
|
|
118
118
|
## Implement a command tool with Tau's helper
|
|
119
119
|
|
|
120
|
-
Command client tools use Tau's version
|
|
120
|
+
Command client tools use Tau's version 4 bidirectional NDJSON protocol over stdin and stdout. Use the exported helper instead of implementing framing manually:
|
|
121
121
|
|
|
122
122
|
```ts
|
|
123
|
-
import {
|
|
123
|
+
import {
|
|
124
|
+
runTauClientToolCommand,
|
|
125
|
+
truncateTauClientToolText,
|
|
126
|
+
} from "@markusylisiurunen/tau/code-mode";
|
|
127
|
+
|
|
128
|
+
await runTauClientToolCommand({
|
|
129
|
+
name: "notify_desktop",
|
|
130
|
+
describe(args) {
|
|
131
|
+
const input = args as { title: string; message: string };
|
|
132
|
+
return {
|
|
133
|
+
subject: truncateTauClientToolText(input.title),
|
|
134
|
+
};
|
|
135
|
+
},
|
|
136
|
+
async execute(args, context) {
|
|
137
|
+
const input = args as { title: string; message: string };
|
|
138
|
+
context.signal.throwIfAborted();
|
|
139
|
+
|
|
140
|
+
await showNotification(input.title, input.message, context.signal);
|
|
141
|
+
return {
|
|
142
|
+
content: "Notification displayed.",
|
|
143
|
+
presentation: {
|
|
144
|
+
subject: truncateTauClientToolText(input.title),
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
`describe` is optional. When present, it runs before acknowledgement and may return a partial running presentation containing `subject`, `subjectWrap`, `details`, or `metadata`. The execution result may independently include the same partial shape for the terminal card. Tau supplies every omitted field, owns lifecycle actions and the operation derived from the registered tool name, and renders a complete fallback when execution ends without a result.
|
|
152
|
+
|
|
153
|
+
Tau preserves every explicit presentation field up to the protocol safety limits; it does not apply display truncation or normalize client text. `truncateTauClientToolText` provides optional caller-controlled `maxLines`, `maxLineChars`, and `head` or `middle` truncation. Its defaults match Tau's concise subject policy, but callers may select larger or smaller positive limits.
|
|
154
|
+
|
|
155
|
+
For a subject, use the returned string directly. For a block of detail text, split the returned string on `\n` and map each line to one `details` entry:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
const details = truncateTauClientToolText(output, {
|
|
159
|
+
maxLines: 7,
|
|
160
|
+
maxLineChars: 512,
|
|
161
|
+
strategy: "middle",
|
|
162
|
+
})
|
|
163
|
+
.split("\n")
|
|
164
|
+
.map((text) => ({ text }));
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Each detail or metadata entry is a single protocol line, so use `maxLines: 1` when assigning the helper's result directly to one entry. The helper shapes text for presentation; the protocol byte and collection limits still apply. Empty detail or metadata arrays explicitly suppress that phase's defaults.
|
|
168
|
+
|
|
169
|
+
`runTauClientToolCommand` reads the preparation, writes readiness and any running presentation, waits until the host accepts the call, then provides the standard execution context and writes the final result. It handles execution-environment request and cancellation framing and reacts to `SIGINT`, `SIGTERM`, and protocol input closure by aborting the handler.
|
|
170
|
+
|
|
171
|
+
Reserve stdout for the helper's protocol. Write diagnostics to stderr. Return a string or `{ content, presentation? }` for success. Return `{ ok: false, error, presentation? }` for a structured tool failure. Successful content and failure text become model-visible tool results.
|
|
172
|
+
|
|
173
|
+
### Version 4 frame reference
|
|
174
|
+
|
|
175
|
+
The shapes below use TypeScript notation. Serialize each frame as one exact JSON object followed by a newline; unknown fields are invalid.
|
|
124
176
|
|
|
125
|
-
|
|
126
|
-
const input = args as { title: string; message: string };
|
|
127
|
-
context.signal.throwIfAborted();
|
|
177
|
+
Tau starts the exchange by writing:
|
|
128
178
|
|
|
129
|
-
|
|
130
|
-
|
|
179
|
+
- `{ version: 4, type: "prepare", sessionId, agentId, callId, toolName, arguments }` exactly once. The identity fields are non-empty strings and `arguments` is the validated model input.
|
|
180
|
+
- `{ version: 4, type: "execute" }` after accepting the command's ready frame. This authorizes execution.
|
|
181
|
+
|
|
182
|
+
The command writes:
|
|
183
|
+
|
|
184
|
+
- `{ version: 4, type: "ready", presentation?: PresentationOverride }` exactly once after preparation.
|
|
185
|
+
- `{ version: 4, type: "result", ok: true, content, presentation?: PresentationOverride }` or `{ version: 4, type: "result", ok: false, error, presentation?: PresentationOverride }` exactly once after authorization. `content` and `error` are strings.
|
|
186
|
+
|
|
187
|
+
During authorized execution, the command may write `{ version: 4, type: "exec", requestId, command, options }`. The non-empty `command` string runs in the session execution environment. `options` is required and may contain `args: string[]`, `env: Record<string, string>`, base64-encoded string `stdinBase64`, string `cwd`, positive integer `timeoutMs`, and positive integer `maxCaptureBytes`.
|
|
188
|
+
|
|
189
|
+
Tau answers with the same `requestId` and either:
|
|
190
|
+
|
|
191
|
+
- `{ version: 4, type: "exec.result", requestId, ok: true, result: ExecResult }`
|
|
192
|
+
- `{ version: 4, type: "exec.result", requestId, ok: false, error: string }`
|
|
193
|
+
|
|
194
|
+
`ExecResult` contains string `output`, `stdout`, and `stderr`; nullable `exitCode` and `closeSignal`; and boolean `truncated`, `timedOut`, and `aborted`. A command may cancel one unresolved request with `{ version: 4, type: "exec.cancel", requestId }`. Request IDs must be non-empty strings and cannot be reused within a call.
|
|
195
|
+
|
|
196
|
+
### Implement the protocol directly in JavaScript
|
|
197
|
+
|
|
198
|
+
A JavaScript command can implement the version 4 handshake using only Node.js built-ins, without importing Tau or the code-mode package:
|
|
199
|
+
|
|
200
|
+
```js
|
|
201
|
+
#!/usr/bin/env node
|
|
202
|
+
|
|
203
|
+
import { arch, platform, release } from "node:os";
|
|
204
|
+
import { createInterface } from "node:readline";
|
|
205
|
+
|
|
206
|
+
const lines = createInterface({
|
|
207
|
+
input: process.stdin,
|
|
208
|
+
crlfDelay: Number.POSITIVE_INFINITY,
|
|
131
209
|
});
|
|
210
|
+
const input = lines[Symbol.asyncIterator]();
|
|
211
|
+
|
|
212
|
+
async function readFrame() {
|
|
213
|
+
const next = await input.next();
|
|
214
|
+
if (next.done) throw new Error("Tau closed the command protocol");
|
|
215
|
+
return JSON.parse(next.value);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function writeFrame(frame) {
|
|
219
|
+
process.stdout.write(`${JSON.stringify(frame)}\n`);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const prepare = await readFrame();
|
|
223
|
+
if (
|
|
224
|
+
prepare.version !== 4 ||
|
|
225
|
+
prepare.type !== "prepare" ||
|
|
226
|
+
prepare.toolName !== "system_info"
|
|
227
|
+
) {
|
|
228
|
+
throw new Error("Invalid system_info preparation");
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
writeFrame({
|
|
232
|
+
version: 4,
|
|
233
|
+
type: "ready",
|
|
234
|
+
presentation: {
|
|
235
|
+
subject: "local system",
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
const execute = await readFrame();
|
|
240
|
+
if (execute.version !== 4 || execute.type !== "execute") {
|
|
241
|
+
throw new Error("Invalid system_info authorization");
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
writeFrame({
|
|
245
|
+
version: 4,
|
|
246
|
+
type: "exec",
|
|
247
|
+
requestId: "git-status",
|
|
248
|
+
command: "git status --short",
|
|
249
|
+
options: {
|
|
250
|
+
maxCaptureBytes: 256 * 1024,
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
const response = await readFrame();
|
|
255
|
+
if (
|
|
256
|
+
response.version !== 4 ||
|
|
257
|
+
response.type !== "exec.result" ||
|
|
258
|
+
response.requestId !== "git-status"
|
|
259
|
+
) {
|
|
260
|
+
throw new Error("Invalid execution-environment response");
|
|
261
|
+
}
|
|
262
|
+
if (!response.ok) throw new Error(response.error);
|
|
263
|
+
|
|
264
|
+
const localSystem = `${platform()} ${release()} ${arch()}`;
|
|
265
|
+
const workspaceStatus =
|
|
266
|
+
response.result.output.trim() || "Working tree is clean.";
|
|
267
|
+
writeFrame({
|
|
268
|
+
version: 4,
|
|
269
|
+
type: "result",
|
|
270
|
+
ok: true,
|
|
271
|
+
content: `${localSystem}\n\n${workspaceStatus}`,
|
|
272
|
+
presentation: {
|
|
273
|
+
subject: "local system",
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
lines.close();
|
|
132
278
|
```
|
|
133
279
|
|
|
134
|
-
`
|
|
280
|
+
The `exec` frame asks Tau to run `git status --short` in the session execution environment, which may be a different machine from the JavaScript process. Tau returns the matching `exec.result` on stdin. Request IDs are single-use, and the command must check both the ID and `ok` before consuming the result.
|
|
281
|
+
|
|
282
|
+
Make the file executable with `chmod +x`. Diagnostics and uncaught errors go to stderr; stdout remains reserved for protocol frames.
|
|
283
|
+
|
|
284
|
+
### Implement a simple command tool in Bash
|
|
285
|
+
|
|
286
|
+
A small command that needs only client-machine authority can also implement the handshake in Bash. This example depends on `jq` for safe JSON parsing and encoding:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
#!/usr/bin/env bash
|
|
290
|
+
set -euo pipefail
|
|
291
|
+
|
|
292
|
+
IFS= read -r prepare
|
|
293
|
+
jq -e '
|
|
294
|
+
.version == 4 and
|
|
295
|
+
.type == "prepare" and
|
|
296
|
+
.toolName == "system_info"
|
|
297
|
+
' >/dev/null <<<"$prepare"
|
|
298
|
+
|
|
299
|
+
jq -cn '{
|
|
300
|
+
version: 4,
|
|
301
|
+
type: "ready",
|
|
302
|
+
presentation: {
|
|
303
|
+
subject: "local system"
|
|
304
|
+
}
|
|
305
|
+
}'
|
|
306
|
+
|
|
307
|
+
IFS= read -r execute
|
|
308
|
+
jq -e '.version == 4 and .type == "execute"' >/dev/null <<<"$execute"
|
|
309
|
+
|
|
310
|
+
content=$(uname -a)
|
|
311
|
+
jq -cn --arg content "$content" '{
|
|
312
|
+
version: 4,
|
|
313
|
+
type: "result",
|
|
314
|
+
ok: true,
|
|
315
|
+
content: $content
|
|
316
|
+
}'
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Configure either executable as an argument-free command tool:
|
|
320
|
+
|
|
321
|
+
```json
|
|
322
|
+
{
|
|
323
|
+
"name": "system_info",
|
|
324
|
+
"defaultEnabled": true,
|
|
325
|
+
"description": "Report operating-system information from the client machine.",
|
|
326
|
+
"parameters": {
|
|
327
|
+
"type": "object",
|
|
328
|
+
"properties": {},
|
|
329
|
+
"additionalProperties": false
|
|
330
|
+
},
|
|
331
|
+
"command": "./bin/tau-system-info"
|
|
332
|
+
}
|
|
333
|
+
```
|
|
135
334
|
|
|
136
|
-
|
|
335
|
+
Both `ready.presentation` and `result.presentation` are optional partial objects with `subject`, `subjectWrap`, `details`, and `metadata`. The ready value applies while the call runs; the result value applies only to its terminal state. Omit either object, or any field within it, to use Tau's default for that phase. Empty `details` or `metadata` arrays suppress the corresponding default field. The script must emit `ready` before reading the authorization-bearing `execute` frame. Direct implementations can emit the same `exec` frames shown in the JavaScript example, but the TypeScript helper is preferable when the tool needs multiple target-environment requests, cancellation forwarding, or more involved protocol handling.
|
|
137
336
|
|
|
138
337
|
The handler receives:
|
|
139
338
|
|
|
@@ -181,7 +380,7 @@ Tau exports two higher-level helpers for client tools that expose a bounded Java
|
|
|
181
380
|
|
|
182
381
|
For an executable configured through `clientTools`, keep the exact parameters schema to one required `code` string with no additional properties, then call `runTauCodeModeCommand` in the executable. For SDK clients, pass the returned tool from `createTauCodeModeClientTool` in the client's `clientTools` array.
|
|
183
382
|
|
|
184
|
-
Both helpers supply the invocation identities, cancellation signal, execution-environment facade, progressive `docs` value, bounded API bridge, and agent-scoped scratch files. The model-facing description remains explicit caller input. Use Tau's optional shared description builder only when its progressive-disclosure wording fits the tool; Tau does not silently rewrite a configured description.
|
|
383
|
+
Both helpers supply the invocation identities, cancellation signal, execution-environment facade, progressive `docs` value, bounded API bridge, and agent-scoped scratch files. They use the submitted code, concisely truncated and character-wrapped, as the running and terminal tool-card subject. The model-facing description remains explicit caller input. Use Tau's optional shared description builder only when its progressive-disclosure wording fits the tool; Tau does not silently rewrite a configured description.
|
|
185
384
|
|
|
186
385
|
The generic code-mode runtime is documented through its exported types and generated tool documentation. Do not layer another unbounded process or network channel behind it without making that authority clear in the tool description.
|
|
187
386
|
|
|
@@ -195,12 +394,13 @@ The command protocol is intentionally bounded:
|
|
|
195
394
|
- Captured stderr is limited to 1 MiB. Exceeding it terminates the command and fails the tool.
|
|
196
395
|
- Execution-environment stdin is limited to 16 MiB decoded, and capture can be requested up to 24 MiB per execution.
|
|
197
396
|
- At most eight execution requests may be unresolved concurrently.
|
|
397
|
+
- Each client-tool presentation override is limited to 1 MiB in total. Its subject is limited to 256 KiB; metadata values to 16 KiB each; detail values to 256 KiB each; and detail and metadata collections to 1,024 entries each. These are safety limits, not recommended UI sizes. Tau preserves explicit values within those limits. Clients may use the exported helper when they want a concise preview.
|
|
198
398
|
|
|
199
|
-
The configured `executionTimeoutMs` covers
|
|
399
|
+
The configured `executionTimeoutMs` covers preparation and execution and defaults to 60 seconds. The host also requires the owning client to prepare and acknowledge a dispatched call promptly. Command executables emit readiness and any bounded running presentation before acknowledgement, then wait for Tau to authorize execution.
|
|
200
400
|
|
|
201
401
|
Tau starts each configured command in a detached process group. Cancellation sends termination to the group and escalates to `SIGKILL` after a short grace period, even if the original group leader exits first. The helper aborts pending execution-environment requests and stops accepting work when stdin closes.
|
|
202
402
|
|
|
203
|
-
A successful
|
|
403
|
+
A successful protocol exchange must emit one version 4 ready frame, wait for the execute frame, emit one final version 4 result with `ok: true` or `ok: false`, and exit with status zero. An `ok: false` frame is a communicated tool failure; process and framing failures still use stderr and a nonzero exit. Missing or duplicate readiness, execution data before authorization, missing results, malformed framing, data after the result, reused execution request IDs, timeout, cancellation, excessive output, and protocol-limit violations fail the call.
|
|
204
404
|
|
|
205
405
|
## Disconnects, reconnects, and durability
|
|
206
406
|
|
|
@@ -185,7 +185,7 @@ Restart the host process to apply settings used to construct host-wide services,
|
|
|
185
185
|
- `history`
|
|
186
186
|
- host environment variables and Codex account forcing
|
|
187
187
|
|
|
188
|
-
For `tau serve
|
|
188
|
+
For `tau serve`, make the changes on the host machine and restart the server. Restarting only an attached TUI does not rebuild the host.
|
|
189
189
|
|
|
190
190
|
### New session or runner
|
|
191
191
|
|
|
@@ -19,10 +19,10 @@ Common cases are:
|
|
|
19
19
|
| Nook host tool | Session host |
|
|
20
20
|
| Cloudflare Sandbox bridge and Fly Sprite API | Session host startup |
|
|
21
21
|
| `/listen` and `/speak` | TUI client |
|
|
22
|
-
| Telegram transcription | Telegram runner |
|
|
22
|
+
| Telegram transcription and voice responses | Telegram runner |
|
|
23
23
|
| `tau tool pdf-unpack` | The process running that command |
|
|
24
24
|
|
|
25
|
-
With local `tau`, these roles normally share one machine. With `tau attach`, setting a key only in the attached client's shell does not authenticate the remote host. Run `tau auth` on the host machine and set host-owned environment variables where `tau serve
|
|
25
|
+
With local `tau`, these roles normally share one machine. With `tau attach`, setting a key only in the attached client's shell does not authenticate the remote host. Run `tau auth` on the host machine and set host-owned environment variables where `tau serve` or the SDK host actually runs. See [ownership and scope](ownership-and-scope.md) for the full boundary.
|
|
26
26
|
|
|
27
27
|
## Provider API keys
|
|
28
28
|
|
|
@@ -61,12 +61,12 @@ Several Tau features share provider credentials but intentionally prefer a fixed
|
|
|
61
61
|
| Feature | Resolution order |
|
|
62
62
|
| --- | --- |
|
|
63
63
|
| Exa web search and fetch | `EXA_API_KEY`, then `apiKeys.exa` |
|
|
64
|
-
| Google speech, Gemini speech-to-text,
|
|
64
|
+
| Google speech, Gemini speech-to-text, Telegram Gemini transcription, and Telegram voice responses | `GEMINI_API_KEY`, then `apiKeys.google` |
|
|
65
65
|
| Mistral speech-to-text, Telegram Mistral transcription, and PDF OCR | `MISTRAL_API_KEY`, then `apiKeys.mistral` |
|
|
66
66
|
|
|
67
67
|
The Google and Mistral rows describe feature-specific helpers. Model calls follow the general model-authentication order instead, where the configured provider key wins over ambient environment authentication.
|
|
68
68
|
|
|
69
|
-
`web.discover` does not require Exa. `web.search` and `web.fetch` do. `/speak`
|
|
69
|
+
`web.discover` does not require Exa. `web.search` and `web.fetch` do. `/speak` and Telegram `/tts_on` voice responses use Google. `/listen` and incoming Telegram audio use the configured `speechToText.provider`, which is `mistral` unless configuration selects `gemini`. PDF OCR through `tau tool pdf-unpack` uses Mistral.
|
|
70
70
|
|
|
71
71
|
Set these variables on the process that owns the feature. For example, a remote TUI's `/speak` reads the attached client's `GEMINI_API_KEY`, while a Google model selected by the session reads credentials at the host.
|
|
72
72
|
|
|
@@ -12,7 +12,7 @@ Every Tau host opens a machine-local SQLite database at:
|
|
|
12
12
|
~/.config/tau/history.sqlite
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
The path belongs to the **host home**. An attached TUI and a remote execution environment do not get separate history stores merely because they participate in the session. Local `tau`, `tau serve`,
|
|
15
|
+
The path belongs to the **host home**. An attached TUI and a remote execution environment do not get separate history stores merely because they participate in the session. Local `tau`, `tau serve`, and the default SDK host all use the host machine's database.
|
|
16
16
|
|
|
17
17
|
For each session, history stores its immutable creation attributes and an ordered active transcript containing:
|
|
18
18
|
|
|
@@ -34,7 +34,7 @@ The intrinsic `tau_docs` tool reads one exact Markdown path at a time. It does n
|
|
|
34
34
|
|
|
35
35
|
- [Tools](tools.md) explains built-in tool availability, execution, cancellation, and code-mode tools.
|
|
36
36
|
- [Sessions](sessions.md) covers creation, turns, queueing, compaction, rewind, goals, recovery, and persistence.
|
|
37
|
-
- [Remote sessions](remote-sessions.md) explains `serve`, `
|
|
37
|
+
- [Remote sessions](remote-sessions.md) explains `serve`, `attach`, remote paths, and transport authentication.
|
|
38
38
|
- [History](history.md) covers local transcript history, optional remote replication, and the history tool.
|
|
39
39
|
- [Nook](nook.md) explains configuration and operation of the optional static mini-app platform.
|
|
40
40
|
- [Telegram](telegram.md) covers runner configuration, projects, workspaces, routing, and recovery.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Node SDK
|
|
2
2
|
|
|
3
|
-
Tau's Node SDK provides a typed client for creating, observing, and controlling sessions without implementing the wire protocol directly. Use the in-process client when your application should own the host, the WebSocket client for a long-running `tau serve` host, or the transport adapter
|
|
3
|
+
Tau's Node SDK provides a typed client for creating, observing, and controlling sessions without implementing the wire protocol directly. Use the in-process client when your application should own the host, the WebSocket client for a long-running `tau serve` host, or the transport adapter with a custom connection implementation.
|
|
4
4
|
|
|
5
5
|
The SDK uses the same public [session protocol](session-protocol.md) as the TUI. Session behavior is therefore consistent across local applications, remote integrations, and terminal clients.
|
|
6
6
|
|
|
@@ -74,23 +74,7 @@ WebSocket authentication grants full session access. Deployment and TLS guidance
|
|
|
74
74
|
|
|
75
75
|
### Supply a protocol transport
|
|
76
76
|
|
|
77
|
-
`createTauSdkClientFromTransport(transport, options?)` builds the same client facade over any `SessionProtocolTransport`.
|
|
78
|
-
|
|
79
|
-
```ts
|
|
80
|
-
import { spawn } from "node:child_process";
|
|
81
|
-
import {
|
|
82
|
-
StdioSessionProtocolTransport,
|
|
83
|
-
createTauSdkClientFromTransport,
|
|
84
|
-
} from "@markusylisiurunen/tau/sdk";
|
|
85
|
-
|
|
86
|
-
const child = spawn("tau", ["rpc"], {
|
|
87
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
88
|
-
});
|
|
89
|
-
const transport = new StdioSessionProtocolTransport(child);
|
|
90
|
-
const client = await createTauSdkClientFromTransport(transport);
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
The stdio transport owns the supplied process connection and terminates it on close. Stdout must contain only protocol NDJSON; stderr is retained for bounded process diagnostics.
|
|
77
|
+
`createTauSdkClientFromTransport(transport, options?)` builds the same client facade over any `SessionProtocolTransport`. This keeps the SDK facade independent of WebSocket and allows applications to supply another transport without changing session semantics.
|
|
94
78
|
|
|
95
79
|
A custom transport implements:
|
|
96
80
|
|
|
@@ -295,6 +279,11 @@ If rendering `timeline.item`, accept only the active epoch and merge by its allo
|
|
|
295
279
|
Pass `TauSdkClientTool` entries in `clientTools` when model-facing work must run in the integration process:
|
|
296
280
|
|
|
297
281
|
```ts
|
|
282
|
+
import {
|
|
283
|
+
createTauSdkClient,
|
|
284
|
+
truncateTauClientToolText,
|
|
285
|
+
} from "@markusylisiurunen/tau/sdk";
|
|
286
|
+
|
|
298
287
|
const client = await createTauSdkClient({
|
|
299
288
|
clientTools: [
|
|
300
289
|
{
|
|
@@ -303,12 +292,22 @@ const client = await createTauSdkClient({
|
|
|
303
292
|
description: "Choose one item from the user's local workspace.",
|
|
304
293
|
parameters: {
|
|
305
294
|
type: "object",
|
|
306
|
-
properties: {
|
|
295
|
+
properties: {
|
|
296
|
+
choice: { type: "string" },
|
|
297
|
+
},
|
|
298
|
+
required: ["choice"],
|
|
307
299
|
additionalProperties: false,
|
|
308
300
|
},
|
|
309
301
|
executionTimeoutMs: 60_000,
|
|
310
302
|
},
|
|
311
|
-
|
|
303
|
+
describe: (args) => {
|
|
304
|
+
const input = args as { choice: string };
|
|
305
|
+
return {
|
|
306
|
+
subject: truncateTauClientToolText(input.choice),
|
|
307
|
+
};
|
|
308
|
+
},
|
|
309
|
+
execute: async (args, context) => {
|
|
310
|
+
const input = args as { choice: string };
|
|
312
311
|
context.signal.throwIfAborted();
|
|
313
312
|
const status = await context.executionEnvironment.exec(
|
|
314
313
|
"git status --short",
|
|
@@ -316,7 +315,12 @@ const client = await createTauSdkClient({
|
|
|
316
315
|
signal: context.signal,
|
|
317
316
|
},
|
|
318
317
|
);
|
|
319
|
-
return
|
|
318
|
+
return {
|
|
319
|
+
content: status.output || "Working tree is clean.",
|
|
320
|
+
presentation: {
|
|
321
|
+
subject: truncateTauClientToolText(input.choice),
|
|
322
|
+
},
|
|
323
|
+
};
|
|
320
324
|
},
|
|
321
325
|
},
|
|
322
326
|
],
|
|
@@ -325,7 +329,11 @@ const client = await createTauSdkClient({
|
|
|
325
329
|
|
|
326
330
|
The handler receives `sessionId`, owning `agentId`, `callId`, an `AbortSignal`, and an execution-environment facade. The handler itself runs on the client machine. `context.executionEnvironment.exec()` crosses the session boundary and runs in the session execution environment.
|
|
327
331
|
|
|
328
|
-
|
|
332
|
+
`describe` is optional. When present, the SDK calls it with the arguments and a reduced context containing `sessionId`, `agentId`, `callId`, and `signal` before acknowledgement. This context deliberately has no execution-environment facade. It may return a partial running presentation containing `subject`, `subjectWrap`, `details`, or `metadata`. Tau owns action and operation, fills every omitted field, and acknowledges the resolved presentation before calling `execute`.
|
|
333
|
+
|
|
334
|
+
The execution result may independently include the same partial shape for the terminal card. Return a string or `{ content, presentation? }` for success, or `{ ok: false, error, presentation? }` for a structured failure. Omitted presentation fields use Tau's terminal defaults; empty detail or metadata arrays suppress those defaults. If `describe` throws, the SDK reports a preparation error without calling `execute`. If the client never returns a result because of cancellation, timeout, detach, or another failure, the host produces a complete fallback presentation.
|
|
335
|
+
|
|
336
|
+
Tau preserves every explicit presentation field up to the protocol safety limits; it does not apply display truncation or normalize client text. `truncateTauClientToolText` provides optional caller-controlled line, character, and head or middle truncation. Use its result directly for a subject. For a block of detail text, split the result on `\n` and map each line to one `details` entry; use `maxLines: 1` when assigning it directly to one detail or metadata entry. The helper shapes text but does not replace protocol validation. The SDK aborts handlers on host cancellation, client close, or terminal transport failure. `client.close()` waits for active handlers to settle.
|
|
329
337
|
|
|
330
338
|
Tool definitions are frozen for each assistant turn and remain independent of persona tool allowlists. Names cannot collide with host tools or another observing client's tools. See [client tools](client-tools.md) for authority, limits, command-backed tools, and disconnect behavior.
|
|
331
339
|
|
|
@@ -353,7 +361,7 @@ const tickets = createTauCodeModeClientTool({
|
|
|
353
361
|
});
|
|
354
362
|
```
|
|
355
363
|
|
|
356
|
-
Pass `tickets` in `clientTools`. Generated code receives the declared API namespace, progressively disclosed `docs`, console output, live `Date` and `Math`, and agent-scoped scratch files when invoked as a client tool. API calls cross a bounded JSON bridge. The tool description remains explicit caller input; the builder is optional.
|
|
364
|
+
Pass `tickets` in `clientTools`. Generated code receives the declared API namespace, progressively disclosed `docs`, console output, live `Date` and `Math`, and agent-scoped scratch files when invoked as a client tool. API calls cross a bounded JSON bridge. The submitted code appears, concisely truncated and character-wrapped, as the running and terminal tool-card subject. The tool description remains explicit caller input; the builder is optional.
|
|
357
365
|
|
|
358
366
|
The SDK also exports `executeTauCodeMode` for standalone execution. The separate `@markusylisiurunen/tau/code-mode` entry point additionally exports file-capability types, `runTauClientToolCommand`, and `runTauCodeModeCommand` for command-backed tools. Use the helpers instead of implementing their framing manually.
|
|
359
367
|
|
|
@@ -361,7 +369,7 @@ The SDK also exports `executeTauCodeMode` for standalone execution. The separate
|
|
|
361
369
|
|
|
362
370
|
Most turn and mutation methods do not accept an `AbortSignal`. Call `session.interrupt()` to cancel active host work. `session.exec()` is the exception: its optional signal targets only that execution.
|
|
363
371
|
|
|
364
|
-
`session.unobserve()` retires one facade. `client.close()` retires the connection, rejects pending transport requests, aborts client-tool handlers, waits for them to settle, and then closes the transport. For the default in-process client it also persists sessions and shuts down the owned host. For WebSocket it leaves the remote host and sessions running.
|
|
372
|
+
`session.unobserve()` retires one facade. `client.close()` retires the connection, rejects pending transport requests, aborts client-tool handlers, waits for them to settle, and then closes the transport. For the default in-process client it also persists sessions and shuts down the owned host. For WebSocket it leaves the remote host and sessions running.
|
|
365
373
|
|
|
366
374
|
Always close clients in `finally`. Do not continue using a session facade after unobserve or any client after close.
|
|
367
375
|
|
|
@@ -371,7 +379,6 @@ All exported SDK and transport errors extend `TauSessionClientError`:
|
|
|
371
379
|
|
|
372
380
|
- `TauSessionProtocolResponseError` means the host returned a protocol error. It exposes `code`, `message`, `requestId`, and optional `data`.
|
|
373
381
|
- `TauTransportError` means connection setup, framing, version validation, timeout, closure, or another terminal transport operation failed.
|
|
374
|
-
- `TauProcessError` extends `TauTransportError` for a stdio subprocess failure and includes `exitCode`, `signal`, and bounded `stderr`.
|
|
375
382
|
|
|
376
383
|
Branch on a protocol error's `code`, not its message. A successful request can still return a failed, aborted, or blocked turn outcome, so inspect `result.turn.status` separately.
|
|
377
384
|
|
|
@@ -384,7 +391,7 @@ The SDK entry point exports the types needed at integration boundaries rather th
|
|
|
384
391
|
- `TauSdkClient`, `TauSdkSession`, client option types, session summaries, and request and result aliases;
|
|
385
392
|
- `TauSdkDelta`, `SessionProtocolSnapshot`, pending-message types, subagent-activity types, and ephemeral event types;
|
|
386
393
|
- `TauSdkClientTool`, its execution context and environment facade, and code-mode definition and result types;
|
|
387
|
-
- `SessionProtocolTransport`, listener types, WebSocket options,
|
|
394
|
+
- `SessionProtocolTransport`, listener types, WebSocket options, and transport errors.
|
|
388
395
|
|
|
389
396
|
It also exports `applySessionProtocolDelta`, `applySessionProtocolSubagentActivitiesMessage`, the turn-ledger helpers, and user-text projection helpers:
|
|
390
397
|
|
|
@@ -12,7 +12,7 @@ Client tools execute on the client machine, not wherever the agent's Bash tool r
|
|
|
12
12
|
|
|
13
13
|
### Host
|
|
14
14
|
|
|
15
|
-
The **host** creates, observes, persists, and recovers sessions. It owns model calls, credentials, session orchestration, tool binding, history storage, and execution-environment lifecycle. Local `tau` creates an in-process host. `tau serve`
|
|
15
|
+
The **host** creates, observes, persists, and recovers sessions. It owns model calls, credentials, session orchestration, tool binding, history storage, and execution-environment lifecycle. Local `tau` creates an in-process host. `tau serve` is the standalone host entry point.
|
|
16
16
|
|
|
17
17
|
The host's home owns data such as session snapshots, authentication storage, usage logs, and the local history database. Use Tau commands and session operations to manage these stores rather than editing their files directly.
|
|
18
18
|
|
|
@@ -38,10 +38,9 @@ For repository and composite projects it prepares managed workspaces. A configur
|
|
|
38
38
|
| --- | --- | --- | --- |
|
|
39
39
|
| `tau` | Local TUI process | In-process on the same machine | Local `cwd` where Tau started |
|
|
40
40
|
| `tau attach … ws://…` | Machine running `tau attach` | Machine running `tau serve` | Environment selected or restored by that host |
|
|
41
|
-
| `tau
|
|
42
|
-
| `tau rpc` or `tau serve` | A separate protocol client | The server process | Local or configured hosted environment chosen by the client |
|
|
41
|
+
| `tau serve` | A separate protocol client | The server process | Local or configured hosted environment chosen by the client |
|
|
43
42
|
| Default Node SDK client | SDK caller | In-process with the SDK caller | Usually a local environment supplied at session creation |
|
|
44
|
-
| SDK over WebSocket
|
|
43
|
+
| SDK over WebSocket | SDK caller | Remote server | Environment selected or restored by that host |
|
|
45
44
|
| `tau telegram` | Telegram runner | In-process on the runner machine | Prepared project workspace or persistent directory |
|
|
46
45
|
|
|
47
46
|
A Cloudflare Sandbox or Fly Sprite can place the execution environment on another target while the host stays on its own machine. The host keeps provider credentials and orchestration authority; the target owns its paths and commands.
|
|
@@ -139,7 +139,7 @@ tau --no-agent-context-files
|
|
|
139
139
|
|
|
140
140
|
This disables ancestor `AGENTS.md` injection, configured `agentContextFiles`, and the descendant paths-only scan. It does not disable personas, prompt templates, or [skills](skills.md).
|
|
141
141
|
|
|
142
|
-
The option applies to local TUI sessions and to hosts started with `tau
|
|
142
|
+
The option applies to local TUI sessions and to hosts started with `tau serve`. For the Node SDK, `noAgentContextFiles: true` provides the same host-level behavior. An attached client cannot retroactively change how an existing remote host session was created.
|
|
143
143
|
|
|
144
144
|
## Alternate subagent working directories
|
|
145
145
|
|
|
@@ -176,6 +176,6 @@ For a new local TUI session, debug mode prints discovered content, loaded contex
|
|
|
176
176
|
tau --debug --persona release-coder
|
|
177
177
|
```
|
|
178
178
|
|
|
179
|
-
Add `--no-agent-context-files` to verify the context-free variant. Debug mode is TUI startup functionality and is not available with `tau
|
|
179
|
+
Add `--no-agent-context-files` to verify the context-free variant. Debug mode is TUI startup functionality and is not available with `tau serve`.
|
|
180
180
|
|
|
181
181
|
If expected context is missing, verify the execution-environment `cwd` and `home`, not just the attached client's current directory. Then check exact filenames, canonical path eligibility, configuration-level path bases, scan exclusions, and reload warnings. See [troubleshooting](troubleshooting.md) for broader diagnostics.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Remote sessions
|
|
2
2
|
|
|
3
|
-
Remote sessions let the terminal stay close to the user while the session host and execution environment run elsewhere. Tau does not turn remote work into a second product mode: `tau attach` uses the same TUI over
|
|
3
|
+
Remote sessions let the terminal stay close to the user while the session host and execution environment run elsewhere. Tau does not turn remote work into a second product mode: `tau attach` uses the same TUI over WebSocket. The important boundaries are who owns credentials and persistence and where agent-visible commands run.
|
|
4
4
|
|
|
5
5
|
## Choose the connection shape
|
|
6
6
|
|
|
@@ -9,12 +9,10 @@ Use the smallest shape that matches the lifecycle you need.
|
|
|
9
9
|
| Shape | Best for | Lifetime and ownership |
|
|
10
10
|
| --- | --- | --- |
|
|
11
11
|
| `tau serve` plus WebSocket attach | Long-running hosts, reconnects, and multiple observers | The server owns the host independently of any one TUI. |
|
|
12
|
-
| `tau attach -- ssh … tau rpc` | Ad hoc access through SSH without exposing a listener | The attachment owns one remote RPC process. Closing it shuts that host down. |
|
|
13
|
-
| `tau rpc` directly | Editors, automation, and custom protocol clients over NDJSON | The parent process owns the RPC host and its stdin/stdout. |
|
|
14
12
|
| Node SDK with its default client | Applications that want an in-process host | The SDK client owns the host and closes it with the client. |
|
|
15
13
|
| Node SDK over WebSocket | Applications sharing a long-running `tau serve` host | The server owns sessions; the SDK observes them remotely. |
|
|
16
14
|
|
|
17
|
-
Use `tau serve`
|
|
15
|
+
Use `tau serve` for remote TUI and SDK connections. Keep it bound to loopback behind an SSH tunnel when SSH is the desired security boundary. The [session protocol](session-protocol.md) and [Node SDK](node-sdk.md) cover developer APIs and wire details; this page stays at the operational level.
|
|
18
16
|
|
|
19
17
|
## Host sessions over WebSocket
|
|
20
18
|
|
|
@@ -58,24 +56,6 @@ Then attach locally:
|
|
|
58
56
|
tau attach ws://127.0.0.1:8787
|
|
59
57
|
```
|
|
60
58
|
|
|
61
|
-
## Attach through stdio and SSH
|
|
62
|
-
|
|
63
|
-
Anything after `--` is launched as a local child process and must speak Tau’s session protocol over stdin and stdout. SSH makes that child a remote `tau rpc` process:
|
|
64
|
-
|
|
65
|
-
```sh
|
|
66
|
-
tau attach -- ssh dev@buildbox.example tau rpc
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
A login shell or project-specific host configuration can be selected in the remote command:
|
|
70
|
-
|
|
71
|
-
```sh
|
|
72
|
-
tau attach -- ssh dev@buildbox.example 'cd /srv/tau-host && tau rpc'
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
The remote process’s stdin and stdout are protocol traffic. Shell startup files and wrapper scripts must not print banners to stdout. Put diagnostics on stderr.
|
|
76
|
-
|
|
77
|
-
This is a one-shot host. When the TUI exits or the transport fails, the local child is terminated, `tau rpc` shuts down its host, active work is interrupted, and durable state is recovered on the next process. Do not use this shape when work must continue through client disconnects; run `tau serve` instead.
|
|
78
|
-
|
|
79
59
|
## List, select, create, or attach
|
|
80
60
|
|
|
81
61
|
Without `--session` or `--new`, `tau attach` asks the host for its session list and opens an interactive selector:
|
|
@@ -94,14 +74,6 @@ tau attach \
|
|
|
94
74
|
ws://127.0.0.1:8787
|
|
95
75
|
```
|
|
96
76
|
|
|
97
|
-
The equivalent SSH form is:
|
|
98
|
-
|
|
99
|
-
```sh
|
|
100
|
-
tau attach \
|
|
101
|
-
--session 0195d6e4-4cf9-7f44-a2d8-f8f7f49ee9d3 \
|
|
102
|
-
-- ssh dev@buildbox.example tau rpc
|
|
103
|
-
```
|
|
104
|
-
|
|
105
77
|
Create a new session with an absolute cwd in the selected execution environment:
|
|
106
78
|
|
|
107
79
|
```sh
|
|
@@ -111,15 +83,6 @@ tau attach \
|
|
|
111
83
|
ws://127.0.0.1:8787
|
|
112
84
|
```
|
|
113
85
|
|
|
114
|
-
For stdio/SSH:
|
|
115
|
-
|
|
116
|
-
```sh
|
|
117
|
-
tau attach \
|
|
118
|
-
--new \
|
|
119
|
-
--cwd /srv/workspaces/tau \
|
|
120
|
-
-- ssh dev@buildbox.example tau rpc
|
|
121
|
-
```
|
|
122
|
-
|
|
123
86
|
For the default `local` execution kind, this path is on the host machine, not the attaching machine. It must already be a usable directory with the desired repository or workspace. Tau creates the session, not the directory or repository.
|
|
124
87
|
|
|
125
88
|
Remote `--new` supplies the conventional creation attribute `source: "tui"`. It does not infer repository metadata by inspecting the remote cwd. Clients that need repository provenance should create through the SDK or protocol and provide complete immutable attributes. See [sessions](sessions.md).
|
|
@@ -215,7 +178,7 @@ Different changes have different owners:
|
|
|
215
178
|
| Effective model `apiKeys` in execution-environment or session configuration | Wait for idle, then run `/reload`; new sessions also resolve the current values. |
|
|
216
179
|
| Managed Codex auth changed with `tau auth` | No host restart; auth storage is read again on later credential resolutions. |
|
|
217
180
|
| Attaching themes, diff launcher, speech config, or configured client tools | Restart `tau attach`. |
|
|
218
|
-
| Host process environment variables, history target, WebSocket listener, Cloudflare bridge, Fly API target, or host startup flags | Restart `tau serve
|
|
181
|
+
| Host process environment variables, history target, WebSocket listener, Cloudflare bridge, Fly API target, or host startup flags | Restart `tau serve`. |
|
|
219
182
|
| Host Tau package, built-in tools, protocol, session recovery code, or built-in documentation | Upgrade and restart the host. |
|
|
220
183
|
| TUI package, keybindings, rendering, local speech, or client-tool implementation | Upgrade and restart the attaching client. |
|
|
221
184
|
|
|
@@ -227,8 +190,6 @@ A WebSocket connection observes a hosted session; it does not own or delete it.
|
|
|
227
190
|
|
|
228
191
|
A clean `tau serve` shutdown interrupts active work, persists live sessions, and closes clients. On restart, the host lists sessions whose execution environments it can restore. Recovery returns sessions idle, drops pending queued and steering messages, discards live subagents, and changes an active persistent goal to blocked. Use `/goal resume` only after checking why the host stopped.
|
|
229
192
|
|
|
230
|
-
A stdio/SSH connection is different because its RPC process is the host. Closing the connection ends that process. The session remains stored under the remote host user’s `~/.config/tau/sessions` and can be observed by a later `tau rpc` process using the same home and compatible resolver configuration.
|
|
231
|
-
|
|
232
193
|
## Use multiple observers carefully
|
|
233
194
|
|
|
234
195
|
Multiple WebSocket clients can observe the same live session and receive the same committed updates and pending-message state. They can also submit, queue, steer, interrupt, or mutate that session, so coordinate human or automation ownership rather than treating observers as read-only.
|
|
@@ -265,10 +226,6 @@ Do not edit the session JSON to change environment identity. Restore the owning
|
|
|
265
226
|
|
|
266
227
|
Verify that server and client use the same token and that a reverse proxy preserves the WebSocket request path and query string. `TAU_WS_AUTH_TOKEN` can silently supply either side, so inspect the environment as well as command-line flags. Do not print the token in shared logs.
|
|
267
228
|
|
|
268
|
-
### SSH attachment fails before the TUI opens
|
|
269
|
-
|
|
270
|
-
Run the remote command directly and confirm that `tau rpc` is installed and can start. Protocol stdout must contain only NDJSON. Login banners, shell startup output, or wrapper diagnostics on stdout corrupt the transport; redirect them to stderr or remove them.
|
|
271
|
-
|
|
272
229
|
### A reconnect shows an interrupted turn
|
|
273
230
|
|
|
274
|
-
A client disconnect alone does not stop a WebSocket-hosted turn, but server shutdown does.
|
|
231
|
+
A client disconnect alone does not stop a WebSocket-hosted turn, but server shutdown does. Review the last assistant and tool states, verify the execution environment with `!!pwd` and `!!git status --short`, then retry or resume a blocked goal intentionally. [Sessions](sessions.md) explains recovery and safe verification.
|