@markusylisiurunen/tau 0.3.82 → 0.3.83

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.
Files changed (147) hide show
  1. package/README.md +1 -3
  2. package/dist/core/agent/agent_runtime.js +6 -4
  3. package/dist/core/agent/agent_runtime.js.map +1 -1
  4. package/dist/core/cli.js +2 -2
  5. package/dist/core/cli.js.map +1 -1
  6. package/dist/core/code_mode/models.js +61 -22
  7. package/dist/core/code_mode/models.js.map +1 -1
  8. package/dist/core/history/cli.js +48 -0
  9. package/dist/core/history/cli.js.map +1 -1
  10. package/dist/core/history/history_manager.js +9 -3
  11. package/dist/core/history/history_manager.js.map +1 -1
  12. package/dist/core/history/local_history_store.js +9 -2
  13. package/dist/core/history/local_history_store.js.map +1 -1
  14. package/dist/core/history/remote_history_client.js +18 -3
  15. package/dist/core/history/remote_history_client.js.map +1 -1
  16. package/dist/core/models/openrouter.js +17 -5
  17. package/dist/core/models/openrouter.js.map +1 -1
  18. package/dist/core/models/openrouter_decisions.js +16 -1
  19. package/dist/core/models/openrouter_decisions.js.map +1 -1
  20. package/dist/core/static/tau_docs/client-tools.md +53 -53
  21. package/dist/core/static/tau_docs/config-reference.md +46 -43
  22. package/dist/core/static/tau_docs/configuration.md +40 -36
  23. package/dist/core/static/tau_docs/credentials.md +32 -31
  24. package/dist/core/static/tau_docs/getting-started.md +28 -28
  25. package/dist/core/static/tau_docs/history.md +114 -79
  26. package/dist/core/static/tau_docs/image-generation.md +20 -18
  27. package/dist/core/static/tau_docs/index.md +30 -31
  28. package/dist/core/static/tau_docs/manifest.json +1 -0
  29. package/dist/core/static/tau_docs/models.md +17 -17
  30. package/dist/core/static/tau_docs/node-sdk.md +69 -69
  31. package/dist/core/static/tau_docs/nook.md +75 -69
  32. package/dist/core/static/tau_docs/openrouter.md +28 -13
  33. package/dist/core/static/tau_docs/ownership-and-scope.md +21 -23
  34. package/dist/core/static/tau_docs/pdf-unpacking.md +6 -6
  35. package/dist/core/static/tau_docs/personas.md +29 -27
  36. package/dist/core/static/tau_docs/prompts-and-project-context.md +41 -39
  37. package/dist/core/static/tau_docs/remote-sessions.md +38 -38
  38. package/dist/core/static/tau_docs/sdk-diff-review.md +16 -12
  39. package/dist/core/static/tau_docs/security.md +72 -72
  40. package/dist/core/static/tau_docs/session-protocol-methods.md +45 -45
  41. package/dist/core/static/tau_docs/session-protocol.md +43 -43
  42. package/dist/core/static/tau_docs/sessions.md +99 -88
  43. package/dist/core/static/tau_docs/skills.md +25 -20
  44. package/dist/core/static/tau_docs/speech-generation.md +5 -5
  45. package/dist/core/static/tau_docs/subagents.md +42 -44
  46. package/dist/core/static/tau_docs/telegram-projects.md +142 -0
  47. package/dist/core/static/tau_docs/telegram.md +64 -181
  48. package/dist/core/static/tau_docs/tools.md +72 -80
  49. package/dist/core/static/tau_docs/troubleshooting.md +94 -149
  50. package/dist/core/static/tau_docs/tui.md +124 -80
  51. package/dist/core/tool/image_generate.js +5 -17
  52. package/dist/core/tool/image_generate.js.map +1 -1
  53. package/dist/core/tool/openrouter.js +21 -2
  54. package/dist/core/tool/openrouter.js.map +1 -1
  55. package/dist/core/utils/gemini_transcription.js +43 -13
  56. package/dist/core/utils/gemini_transcription.js.map +1 -1
  57. package/dist/core/utils/model_stream.js +17 -1
  58. package/dist/core/utils/model_stream.js.map +1 -1
  59. package/dist/core/version.js +2 -2
  60. package/dist/diff_tool/app/dist/assets/{angular-html-D20byCHL.js → angular-html-x29PkEoY.js} +1 -1
  61. package/dist/diff_tool/app/dist/assets/{angular-ts-CvVQslm2.js → angular-ts-CsWCqoCf.js} +1 -1
  62. package/dist/diff_tool/app/dist/assets/{apl-DNIxlYWe.js → apl-CEvdc7jl.js} +1 -1
  63. package/dist/diff_tool/app/dist/assets/{astro-DDOw4EUG.js → astro-Cgi6YxH2.js} +1 -1
  64. package/dist/diff_tool/app/dist/assets/{blade-DlhB-SLW.js → blade-B0pr7Zx6.js} +1 -1
  65. package/dist/diff_tool/app/dist/assets/{c-C1f4vhDm.js → c-DDVLgtVy.js} +1 -1
  66. package/dist/diff_tool/app/dist/assets/{chapel-Ctt8xOX1.js → chapel-Bk9M7Jej.js} +1 -1
  67. package/dist/diff_tool/app/dist/assets/{cobol-BXw71PAA.js → cobol-DyEvnPuC.js} +1 -1
  68. package/dist/diff_tool/app/dist/assets/{coffee-CRh_5Nmr.js → coffee-Di2-m3Jq.js} +1 -1
  69. package/dist/diff_tool/app/dist/assets/{cpp-IlI-zWOZ.js → cpp-CWpAaUgO.js} +1 -1
  70. package/dist/diff_tool/app/dist/assets/{crystal-CXeL28i7.js → crystal-CUker9Zt.js} +1 -1
  71. package/dist/diff_tool/app/dist/assets/{css-BfST9hFI.js → css-D4XpBIiJ.js} +1 -1
  72. package/dist/diff_tool/app/dist/assets/{edge--Q22k_ty.js → edge-CVxhhF7L.js} +1 -1
  73. package/dist/diff_tool/app/dist/assets/{elixir-CIfC_rQx.js → elixir-B_FS9APl.js} +1 -1
  74. package/dist/diff_tool/app/dist/assets/{elm-OkZ29XRO.js → elm-1KyefTkH.js} +1 -1
  75. package/dist/diff_tool/app/dist/assets/{erb-B8ZXgEqv.js → erb-CCgO9dRW.js} +1 -1
  76. package/dist/diff_tool/app/dist/assets/{git-rebase-CxkO_WGd.js → git-rebase-D0VYo_oY.js} +1 -1
  77. package/dist/diff_tool/app/dist/assets/{glimmer-js-BVadyIrr.js → glimmer-js-Ce07ngjZ.js} +1 -1
  78. package/dist/diff_tool/app/dist/assets/{glimmer-ts-D5J3Qb7n.js → glimmer-ts-BmOM4djO.js} +1 -1
  79. package/dist/diff_tool/app/dist/assets/{glsl-B6iy73-Y.js → glsl-D-jkLYJ8.js} +1 -1
  80. package/dist/diff_tool/app/dist/assets/{graphql-Dc3rUXf5.js → graphql-DZOwJE5e.js} +1 -1
  81. package/dist/diff_tool/app/dist/assets/{hack-q8Utf8Jp.js → hack-Cgvn19h8.js} +1 -1
  82. package/dist/diff_tool/app/dist/assets/{haml-mjMIlj_2.js → haml-JTmDSYQl.js} +1 -1
  83. package/dist/diff_tool/app/dist/assets/{handlebars-CA-BL8Ks.js → handlebars-CChh7Dy5.js} +1 -1
  84. package/dist/diff_tool/app/dist/assets/{html-BmPxhYCX.js → html-BKgzx_cb.js} +1 -1
  85. package/dist/diff_tool/app/dist/assets/{html-derivative-CvknIjuB.js → html-derivative-CdFl0BmX.js} +1 -1
  86. package/dist/diff_tool/app/dist/assets/{http-DNxLDRIi.js → http-DZeL7KvH.js} +1 -1
  87. package/dist/diff_tool/app/dist/assets/{hurl-kbd3Eq2V.js → hurl-CqKevOlQ.js} +1 -1
  88. package/dist/diff_tool/app/dist/assets/index-BXyr8GCM.js +341 -0
  89. package/dist/diff_tool/app/dist/assets/{java-BuZshgf1.js → java-Sq3MCkId.js} +1 -1
  90. package/dist/diff_tool/app/dist/assets/{javascript-DfL2oeFU.js → javascript-CHZB4Nse.js} +1 -1
  91. package/dist/diff_tool/app/dist/assets/{jinja-Bu0KQihU.js → jinja-C4ucJVla.js} +1 -1
  92. package/dist/diff_tool/app/dist/assets/{jison-Bqn7Mf3Q.js → jison-D3mprebA.js} +1 -1
  93. package/dist/diff_tool/app/dist/assets/{json-BuX5LKaB.js → json-DgPfCYJ1.js} +1 -1
  94. package/dist/diff_tool/app/dist/assets/{jsx-DdVJ-ZBp.js → jsx-BG-Tx0cw.js} +1 -1
  95. package/dist/diff_tool/app/dist/assets/{julia-CQeijOoQ.js → julia-B1GnFeUC.js} +1 -1
  96. package/dist/diff_tool/app/dist/assets/{just-vzAktFGR.js → just-_MZzo0MF.js} +1 -1
  97. package/dist/diff_tool/app/dist/assets/{latex-Dm60cg0k.js → latex-DI0kqjQy.js} +1 -1
  98. package/dist/diff_tool/app/dist/assets/{liquid-vxKzm2P8.js → liquid-BtMAPeHl.js} +1 -1
  99. package/dist/diff_tool/app/dist/assets/{lua-DIoqi4dd.js → lua-CFxaP0To.js} +1 -1
  100. package/dist/diff_tool/app/dist/assets/{marko-BTHgFKby.js → marko-BIJocuFI.js} +1 -1
  101. package/dist/diff_tool/app/dist/assets/{mdc-CEfz8gZ9.js → mdc-BAgrdjTH.js} +1 -1
  102. package/dist/diff_tool/app/dist/assets/{nginx-DNlFDEfJ.js → nginx-DE-3CsYn.js} +1 -1
  103. package/dist/diff_tool/app/dist/assets/{nim-DnvT_0lZ.js → nim-DOxeXLhb.js} +1 -1
  104. package/dist/diff_tool/app/dist/assets/{org-BbD-ElVf.js → org-KTfP0tHA.js} +1 -1
  105. package/dist/diff_tool/app/dist/assets/{perl-DTsbnAmK.js → perl-BH-NxpgK.js} +1 -1
  106. package/dist/diff_tool/app/dist/assets/{php-CwEsJe-W.js → php-vuiVEXZK.js} +1 -1
  107. package/dist/diff_tool/app/dist/assets/{pug-BOttMVH-.js → pug-VlIlTMUy.js} +1 -1
  108. package/dist/diff_tool/app/dist/assets/{qml-C8KkSItN.js → qml-k6wTtGG-.js} +1 -1
  109. package/dist/diff_tool/app/dist/assets/{r-K4ksJj_R.js → r-Ccjcb2zh.js} +1 -1
  110. package/dist/diff_tool/app/dist/assets/{razor-yuWRrrG6.js → razor-BNhYgSCv.js} +1 -1
  111. package/dist/diff_tool/app/dist/assets/{regexp-CV-jhnUz.js → regexp-C4LFejPu.js} +1 -1
  112. package/dist/diff_tool/app/dist/assets/{rst-CLA3Attc.js → rst-DXLxI-UJ.js} +1 -1
  113. package/dist/diff_tool/app/dist/assets/{ruby-DiHR2-DX.js → ruby-BPuL4jDV.js} +1 -1
  114. package/dist/diff_tool/app/dist/assets/{sas-DxIjbYJ5.js → sas-B3Yz8snb.js} +1 -1
  115. package/dist/diff_tool/app/dist/assets/{scss-CShwEaV4.js → scss-B2AJ5vpk.js} +1 -1
  116. package/dist/diff_tool/app/dist/assets/{shellscript-CeezOnrF.js → shellscript-zyDexxnC.js} +1 -1
  117. package/dist/diff_tool/app/dist/assets/{shellsession-CjSS2r7j.js → shellsession-C8b8xluk.js} +1 -1
  118. package/dist/diff_tool/app/dist/assets/{soy-CI_v23nJ.js → soy-DKWe_XML.js} +1 -1
  119. package/dist/diff_tool/app/dist/assets/{sql-D9GaB00A.js → sql-uEbz-Epf.js} +1 -1
  120. package/dist/diff_tool/app/dist/assets/{stata-hK92TPE_.js → stata-DieRPmHY.js} +1 -1
  121. package/dist/diff_tool/app/dist/assets/{surrealql-UO8LtPJG.js → surrealql-Dbk3Sp1P.js} +1 -1
  122. package/dist/diff_tool/app/dist/assets/{svelte-kIlaw_oh.js → svelte-CjPbRmkM.js} +1 -1
  123. package/dist/diff_tool/app/dist/assets/{templ-DFRz1JP6.js → templ-Do_f5vc4.js} +1 -1
  124. package/dist/diff_tool/app/dist/assets/{tex-CfxIXk_z.js → tex-UjLP4qUm.js} +1 -1
  125. package/dist/diff_tool/app/dist/assets/{ts-tags-BtUHl0ff.js → ts-tags-5L2FutA6.js} +1 -1
  126. package/dist/diff_tool/app/dist/assets/{tsx-Cd4SAe2C.js → tsx-B1pNtpUr.js} +1 -1
  127. package/dist/diff_tool/app/dist/assets/{twig-CWk4q5Y3.js → twig-O41Vg_IM.js} +1 -1
  128. package/dist/diff_tool/app/dist/assets/{typescript-BqxGJiP0.js → typescript-Bj9uwnnJ.js} +1 -1
  129. package/dist/diff_tool/app/dist/assets/{typst-D9nAun2p.js → typst-DsibO7oD.js} +1 -1
  130. package/dist/diff_tool/app/dist/assets/{vue-D6HYhg6_.js → vue-DPhaEurv.js} +1 -1
  131. package/dist/diff_tool/app/dist/assets/{vue-html-1VRlaENS.js → vue-html-DDV9NSy1.js} +1 -1
  132. package/dist/diff_tool/app/dist/assets/{vue-vine-BaH0We9y.js → vue-vine-Dh4jOifx.js} +1 -1
  133. package/dist/diff_tool/app/dist/assets/{xml-C4RWnUuj.js → xml-DtIulkQk.js} +1 -1
  134. package/dist/diff_tool/app/dist/assets/{xsl-D1iD38ga.js → xsl-DoWtb58Z.js} +1 -1
  135. package/dist/diff_tool/app/dist/assets/{yaml-yAb4W0G-.js → yaml-CZC-l1Dg.js} +1 -1
  136. package/dist/diff_tool/app/dist/index.html +1 -1
  137. package/dist/history/worker/index.js +87 -83
  138. package/dist/history/worker/index.js.map +1 -1
  139. package/dist/main.js +6 -7
  140. package/dist/main.js.map +1 -1
  141. package/dist/tui/session_chat_controller.js +14 -3
  142. package/dist/tui/session_chat_controller.js.map +1 -1
  143. package/dist/tui/ui/footer.js +2 -4
  144. package/dist/tui/ui/footer.js.map +1 -1
  145. package/package.json +9 -9
  146. package/dist/diff_tool/app/dist/assets/index-D8ZI_2RC.js +0 -340
  147. package/dist/nook/README.md +0 -123
@@ -1,32 +1,32 @@
1
1
  # Models
2
2
 
3
- A model definition tells Tau how to call a provider model and how to reason about its capabilities, limits, and cost. A persona selects one provider and model, while credentials authorize the resulting request. Keeping those layers separate makes it possible to update model metadata without rewriting persona behavior.
3
+ A model definition tells Tau how to call a provider's model and what the model can do, including its limits and cost. A persona picks one provider and model, and credentials authorize the request. Because these are separate, model metadata can be updated without changing personas.
4
4
 
5
- Tau ships a versioned catalog and refreshes compatible model metadata from `pi.dev`. The effective catalog for a session therefore depends on the installed Tau version and the host's cached remote catalog.
5
+ Tau ships a model catalog and refreshes compatible metadata from `pi.dev`. The catalog a session sees therefore depends on the installed Tau version and on the host's cached copy of the remote catalog.
6
6
 
7
7
  ## Providers, models, and personas
8
8
 
9
- A **provider** owns authentication and one or more request APIs. A **model** is addressed by a provider ID and an exact model ID, such as `openai/gpt-6.1-sol`. A [persona](personas.md) binds that pair to a system prompt, settings, tools, and subagents.
9
+ A **provider** has its own authentication and one or more request APIs. A **model** is named by a provider ID and an exact model ID, such as `openai/gpt-6.1-sol`. A [persona](personas.md) combines a model with a system prompt, settings, tools, and subagents.
10
10
 
11
- The bundled catalog comes from Tau's model runtime. It supplies known provider IDs, bundled model IDs, request API names, endpoints, capability flags, token limits, and pricing. Bundled does not mean currently usable: a provider may still lack credentials, an account may not expose a model, or a configured endpoint may reject it. See [credentials](credentials.md).
11
+ The bundled catalog comes from Tau's model library, `pi-ai`. It lists known provider IDs and model IDs, with request API names, endpoints, capabilities, token limits, and pricing. A model in the catalog is not necessarily usable: the provider may lack credentials, the account may not have access to the model, or the endpoint may reject it. See [credentials](credentials.md).
12
12
 
13
13
  ## Remote catalog
14
14
 
15
- A model-owning Tau host restores provider catalogs from `~/.config/tau/models-store.json` during startup, then checks `pi.dev` asynchronously when the cache is older than four hours. This is a startup freshness check, not a recurring timer. Set `TAU_OFFLINE` to skip the automatic network check.
15
+ A Tau host that runs models loads cached catalogs from `~/.config/tau/models-store.json` at startup. If the cache is older than four hours, it checks `pi.dev` in the background. This check happens only at startup; there is no recurring refresh. Set `TAU_OFFLINE` to skip it.
16
16
 
17
- Tau requests one catalog shard for every provider included in its installed `pi-ai` version. Each request has a 15-second timeout and is independent: successful shards are cached even when another provider fails, while failed providers retain their previous valid shard or fall back to bundled metadata. Run `tau models refresh` on the host to bypass the freshness window and force a best-effort refresh. The command exits nonzero if any provider fails after preserving successful updates.
17
+ Tau requests the catalog separately for each provider that its `pi-ai` version supports. Each request has a 15-second timeout. A successful provider is cached even when another fails. A failed provider keeps its previous cached data, or the bundled data if there is none. Run `tau models refresh` on the host to refresh immediately, regardless of cache age. It keeps every successful update and exits nonzero if any provider failed.
18
18
 
19
- Remote data replaces complete matching `pi-ai` model records and may add model IDs. Tau identifies the installed `pi-ai` version to `pi.dev` so the service can select compatible records. Cached data older than the catalog bundled into `pi-ai` is ignored.
19
+ Remote data replaces matching model records completely and can add new model IDs. Tau sends its `pi-ai` version to `pi.dev` so the service returns compatible records. Cached data older than the bundled catalog is ignored.
20
20
 
21
- A session captures the available remote catalog when it is created. A background refresh does not change that session. Run `/reload` to adopt the latest host cache; ordinary persona switching keeps the session's captured catalog.
21
+ A session keeps the catalog that was available when it was created. A background refresh does not change it. Run `/reload` to use the host's latest cache. Switching personas keeps the session's current catalog.
22
22
 
23
23
  ## Unbundled model IDs
24
24
 
25
- Custom personas and subagent launch allowlists may name an unbundled model ID when the provider is known. General model resolution synthesizes the requested ID from that provider's bundled template. This supports newly released IDs but does not discover their capabilities or prices. Prefer IDs present in the bundled or refreshed catalog when accurate metadata matters.
25
+ Custom personas and subagent launch allowlists may name a model ID that is not in the catalog, as long as the provider is known. Tau then builds the model from that provider's default template. This lets you use newly released models, but Tau does not know their real capabilities or prices. Prefer IDs from the catalog when accurate metadata matters.
26
26
 
27
27
  ## Model system notices
28
28
 
29
- `modelSystemNotices` belongs in `config.json`, but its keys are validated against the bundled and refreshed model catalog, so it is closely tied to model configuration:
29
+ `modelSystemNotices` is set in `config.json`, and its keys are checked against the model catalog:
30
30
 
31
31
  ```json
32
32
  {
@@ -36,22 +36,22 @@ Custom personas and subagent launch allowlists may name an unbundled model ID wh
36
36
  }
37
37
  ```
38
38
 
39
- Keys use exact `<provider>/<model>` form. Provider IDs must be known. Model IDs are case-sensitive and must be bundled or present in the refreshed catalog. Values must be non-empty strings. The map merges by key across configuration levels, with the nearest notice winning.
39
+ Keys use the exact form `<provider>/<model>`. Provider IDs must be known. Model IDs are case-sensitive and must be in the catalog. Values must be non-empty strings. The map merges by key across configuration levels, and the nearest notice wins.
40
40
 
41
- When Tau commits input for a main agent or subagent using that model, it prepends the notice as a hidden model-facing system block. The block is persisted with the user message and later compaction sees it as source history. Tau does not add a fresh current notice to maintenance prompts or synthetic compaction messages. Ephemeral agents do not receive model system notices.
41
+ When a main agent or subagent using that model receives user input, Tau adds the notice to the start of the input as a system block that the model sees and the transcript hides. The block is saved with the user message, and later compaction treats it as part of the history. Maintenance prompts and compaction messages do not get a new notice. Ephemeral agents never receive model system notices.
42
42
 
43
- Use notices for model-specific operational guidance, not credentials or transient secrets. The notice becomes durable session content.
43
+ Use notices for guidance specific to one model. Never put credentials or other secrets in them, because the notice is saved in the session.
44
44
 
45
45
  ## Applying and verifying changes
46
46
 
47
- Run `/reload` in an idle TUI session after refreshing the model catalog or changing `modelSystemNotices`. Reload resolves runtime content again, reapplies the active persona when its ID still exists, and reports model or configuration warnings. The TUI refuses to reload during an active turn.
47
+ Run `/reload` in an idle TUI session after refreshing the model catalog or changing `modelSystemNotices`. Reload loads the session's configuration and content again, reapplies the active persona if its ID still exists, and reports model or configuration warnings. The TUI refuses to reload while a turn is running.
48
48
 
49
- For a new local session, this command verifies that the intended persona resolves to the expected provider and model ID without starting the TUI:
49
+ To check, without starting the TUI, that a persona resolves to the expected provider and model for a new local session:
50
50
 
51
51
  ```sh
52
52
  tau --debug --persona release-coder
53
53
  ```
54
54
 
55
- Debug output shows effective persona IDs and selected model IDs, not every model metadata field. It also prints the full effective system prompt and project context, so treat its output accordingly. A small real request is the final check for endpoint, API compatibility, model availability, and credentials.
55
+ Debug output shows persona IDs and the selected model IDs, but not every metadata field. It also prints the full system prompt and project context, so be careful where you share it. A small real request is the final check for the endpoint, API compatibility, model access, and credentials.
56
56
 
57
- Unknown providers, unresolved persona models, and notices targeting IDs absent from the catalog produce configuration warnings. In a remote session, warnings identify files on the session target. See [troubleshooting](troubleshooting.md).
57
+ Unknown providers, persona models that cannot be resolved, and notices for IDs missing from the catalog produce configuration warnings. In a remote session, the warnings name files on the session's execution environment. See [troubleshooting](troubleshooting.md).
@@ -1,8 +1,8 @@
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 with a custom connection implementation.
3
+ Tau's Node SDK is a typed client for creating, observing, and controlling sessions without handling the wire protocol yourself. Use the in-process client when your application should run the host itself, the WebSocket client to connect to a long-running `tau serve` host, or the transport adapter to bring your own connection.
4
4
 
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.
5
+ The SDK speaks the same [session protocol](session-protocol.md) as the TUI, so sessions behave the same in local applications, remote integrations, and the terminal.
6
6
 
7
7
  ## Install and import
8
8
 
@@ -32,7 +32,7 @@ const client = await createTauSdkClient({
32
32
  });
33
33
  ```
34
34
 
35
- The host uses the current host user's Tau session store and history database. `cwd` in the client options controls startup configuration for host-wide services and defaults to `process.cwd()`. Each session separately resolves runtime configuration and content from the execution environment and `cwd` passed to `client.sessions.create()`.
35
+ The host uses the current user's Tau session store and history database. The `cwd` option decides which configuration the host reads at startup, for host-wide services, and defaults to `process.cwd()`. Each session reads its own configuration and content from the execution environment and `cwd` passed to `client.sessions.create()`.
36
36
 
37
37
  The in-process options are:
38
38
 
@@ -50,13 +50,13 @@ type TauSdkClientOptions = {
50
50
  };
51
51
  ```
52
52
 
53
- `persona`, `reasoning`, and `noAgentContextFiles` configure sessions created by this owned host. `connectTimeoutMs` defaults to 5,000 ms. Default initialization metadata is `{ client: { name: "tau-sdk", version: "1" } }`.
53
+ `persona`, `reasoning`, and `noAgentContextFiles` apply to sessions created by this host. `connectTimeoutMs` defaults to 5,000 ms. Default initialization metadata is `{ client: { name: "tau-sdk", version: "1" } }`.
54
54
 
55
- The in-process host does not write asynchronous diagnostics to stdout or stderr. Set `onDiagnostic` to receive structured host diagnostics such as retryable history replication failures and route them through the embedding application's logging or presentation owner.
55
+ The in-process host never writes background diagnostics to stdout or stderr. Set `onDiagnostic` to receive them as structured objects, such as history replication failures that will be retried, and route them to your application's logging.
56
56
 
57
- By default, creating an in-process client starts one asynchronous model-catalog freshness check against `pi.dev`. The host restores `~/.config/tau/models-store.json` first, does not refresh on a recurring timer, and keeps each session on its captured catalog until `session.reload()`. Set `refreshModelCatalog: false` to disable this client's automatic check, or set `TAU_OFFLINE` to disable automatic checks process-wide. Both controls preserve an existing cache and do not prevent an explicit `tau models refresh`. See [models](models.md) for precedence and [security](security.md) for the trust boundary.
57
+ By default, creating an in-process client starts one background check of the model catalog against `pi.dev`. The host loads `~/.config/tau/models-store.json` first, never refreshes on a timer, and keeps each session on the catalog it started with until `session.reload()`. Set `refreshModelCatalog: false` to skip this client's check, or set `TAU_OFFLINE` to skip automatic checks for the whole process. Neither removes an existing cache or blocks an explicit `tau models refresh`. See [models](models.md) for details and [security](security.md) for why the catalog is trusted.
58
58
 
59
- Closing this client shuts down its host after persisting live sessions. It also cancels and awaits a client-owned catalog refresh; a refresh shared with another in-process client continues until its final owner closes.
59
+ Closing this client saves live sessions and shuts down its host. It also cancels its catalog refresh and waits for it. A refresh shared with another in-process client continues until the last of them closes.
60
60
 
61
61
  ### Connect to `tau serve`
62
62
 
@@ -74,13 +74,13 @@ const client = await createTauSdkWebSocketClient({
74
74
  });
75
75
  ```
76
76
 
77
- Options include `url`, optional `authToken`, `connectTimeoutMs`, `initialize`, `clientTools`, and an optional `webSocketFactory` for runtimes that need a custom WebSocket implementation. Closing the SDK client closes only its connection. Sessions remain with the server.
77
+ Options are `url`, optional `authToken`, `connectTimeoutMs`, `initialize`, `clientTools`, and an optional `webSocketFactory` for runtimes that need their own WebSocket implementation. Closing the client closes only its connection; the sessions stay on the server.
78
78
 
79
- WebSocket authentication grants full session access. Deployment and TLS guidance belongs to [remote sessions](remote-sessions.md), and the trust model belongs to [security](security.md).
79
+ The WebSocket token gives full access to all sessions. See [remote sessions](remote-sessions.md) for deployment and TLS, and [security](security.md) for the trust model.
80
80
 
81
81
  ### Supply a protocol transport
82
82
 
83
- `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.
83
+ `createTauSdkClientFromTransport(transport, options?)` builds the same client on top of any `SessionProtocolTransport`, so you can use another transport with the same session behavior.
84
84
 
85
85
  A custom transport implements:
86
86
 
@@ -99,11 +99,11 @@ type SessionProtocolTransport = {
99
99
  };
100
100
  ```
101
101
 
102
- A terminal transport failure must call `onFailure` listeners so the SDK can abort delegated client tools and reject outstanding work.
102
+ When the transport fails for good, it must call the `onFailure` listeners, so the SDK can abort client tools and reject open requests.
103
103
 
104
104
  ## Create and run a session
105
105
 
106
- A typical integration creates and automatically observes a session, listens for state, submits work, and closes cleanly:
106
+ A typical integration creates a session (which also observes it), listens for updates, submits work, and closes cleanly:
107
107
 
108
108
  ```ts
109
109
  import {
@@ -147,64 +147,64 @@ try {
147
147
  }
148
148
  ```
149
149
 
150
- `client.sessions.create(input)` sends `session.create`, then observes the new session before resolving. `client.sessions.observe(sessionId)` does the same observation handshake for an existing session. `client.sessions.list()` returns `{ sessionId, lifecycle }` summaries.
150
+ `client.sessions.create(input)` sends `session.create`, then observes the new session before returning. `client.sessions.observe(sessionId)` observes an existing session. `client.sessions.list()` returns `{ sessionId, lifecycle }` for each session.
151
151
 
152
- Creation requires complete execution-environment input and immutable attributes. The execution `cwd` must be absolute and belongs to the selected environment, not necessarily the SDK process. Fly Sprite sessions refer to already-provisioned targets configured on the host. See [sessions](sessions.md) for creation attributes and [ownership and scope](ownership-and-scope.md) for path ownership.
152
+ Creating a session requires the full execution environment and the creation attributes, which never change afterward. The `cwd` must be absolute and is a path in the chosen environment, which may not be where the SDK runs. A Fly Sprite session refers to an existing Sprite that the host is configured to reach. See [sessions](sessions.md) for creation attributes and [ownership and scope](ownership-and-scope.md) for which machine owns which paths.
153
153
 
154
- `session.unobserve()` stops observation and makes that `TauSdkSession` facade terminal. It does not delete the hosted session. `client.close()` is idempotent and closes the whole client.
154
+ `session.unobserve()` stops observing, and that `TauSdkSession` object can no longer be used. The session itself is not deleted. `client.close()` closes the whole client and is safe to call more than once.
155
155
 
156
156
  The connected `TauSdkClient` exposes:
157
157
 
158
158
  | Member | Purpose |
159
159
  | --- | --- |
160
160
  | `ready` | The validated server `ready` message and advertised methods. |
161
- | `sessions.create(input)` | Create, observe, and return a session facade. |
161
+ | `sessions.create(input)` | Create and observe a session, and return its object. |
162
162
  | `sessions.list()` | List hosted session summaries. |
163
- | `sessions.observe(sessionId)` | Observe an existing session and return a facade. |
163
+ | `sessions.observe(sessionId)` | Observe an existing session and return its object. |
164
164
  | `subscribe(listener)` | Receive deltas for every observed session on this connection. |
165
165
  | `subscribePendingUserMessages(listener)` | Receive pending-state replacements across observed sessions. |
166
166
  | `subscribeSubagentActivities(listener)` | Receive subagent-activity changes across observed sessions. |
167
- | `subscribeEphemeral(listener)` | Receive best-effort ephemeral events across observed sessions. |
168
- | `close()` | Close the client and its owned resources. |
167
+ | `subscribeEphemeral(listener)` | Receive ephemeral events, which are not guaranteed, across observed sessions. |
168
+ | `close()` | Close the client and everything it owns. |
169
169
 
170
170
  Each subscription returns an unsubscribe function.
171
171
 
172
- ## Use the session facade
172
+ ## Use the session object
173
173
 
174
- `TauSdkSession.id` is the bound session id. Its methods map directly to protocol operations; the [method reference](session-protocol-methods.md) defines exact results, turn outcomes, busy rules, and mutation behavior.
174
+ `TauSdkSession.id` is the session's ID. Each method corresponds to a protocol method; the [method reference](session-protocol-methods.md) gives exact results, turn outcomes, and when a call returns `busy` or interrupts work.
175
175
 
176
176
  | SDK method | Purpose |
177
177
  | --- | --- |
178
178
  | `record(text, options?)` | Append user text without running a turn. |
179
179
  | `submit(text, options?)` | Append user text and run an idle session turn. |
180
- | `queue(text, options?)` | Run now or wait behind active session work. |
181
- | `steer(text)` | Redirect active model work at a safe boundary. |
182
- | `cancelPendingMessages()` | Cancel all queued and unapplied steering input. |
180
+ | `queue(text, options?)` | Run now, or after the running turn. |
181
+ | `steer(text)` | Change the running turn's direction at its next safe point. |
182
+ | `cancelPendingMessages()` | Cancel all queued messages and steering not yet applied. |
183
183
  | `retry()` | Run from current history without appending user text. |
184
- | `exec(command, options?)` | Run an independent login-Bash command in the execution environment. |
185
- | `sample({ context, options })` | Run isolated inference without mutating the session. |
186
- | `interrupt()` | Request cancellation of active session work. |
187
- | `snapshot()` | Read the complete authoritative snapshot. |
188
- | `setReasoning(reasoning)` | Set reasoning for the next independently started turn. |
184
+ | `exec(command, options?)` | Run a command in a login Bash in the execution environment. |
185
+ | `sample({ context, options })` | Run a standalone model call without changing the session. |
186
+ | `interrupt()` | Ask the session's running work to stop. |
187
+ | `snapshot()` | Read the complete current snapshot. |
188
+ | `setReasoning(reasoning)` | Set reasoning, starting with the next turn. |
189
189
  | `setPersona(personaId)` | Change persona and return the updated snapshot. |
190
190
  | `resolvePrompt(promptId)` | Load a current prompt body from the execution environment. |
191
- | `autocompletePaths({ query, limit })` | Request bounded execution-environment path suggestions. |
192
- | `reload()` | Reload session-owned configuration and content. |
191
+ | `autocompletePaths({ query, limit })` | Get a limited list of path suggestions from the execution environment. |
192
+ | `reload()` | Reload the session's configuration and content. |
193
193
  | `compact(mode, options?)` | Manually compact model context. |
194
194
  | `rewindToHistoryEntryId(id)` | Rewind from one user history entry while idle. |
195
195
  | `interruptSubagent(subagentId)` | Interrupt one live subagent run. |
196
- | `createEphemeralContext(options)` | Create a non-persisted host-owned agent context. |
196
+ | `createEphemeralContext(options)` | Create an agent context on the host that is not saved. |
197
197
  | `submitEphemeralThread(options)` | Run or continue one ephemeral thread. |
198
198
  | `closeEphemeralContext(contextId)` | Close an ephemeral context and its threads. |
199
- | `unobserve()` | Stop observation and retire this facade. |
199
+ | `unobserve()` | Stop observing; this object can no longer be used. |
200
200
 
201
- `submit`, `queue`, and `record` accept `{ historyEntryId?: string }`. When omitted, Tau generates the user history id. Use `getTauSdkSessionTurnRecord(snapshot, id)` to distinguish unknown, running, and settled accepted turns, or `getTauSdkSessionTurnOutcome(snapshot, id)` when only a settled outcome matters.
201
+ `submit`, `queue`, and `record` accept `{ historyEntryId?: string }`; without it, Tau generates the ID. Use `getTauSdkSessionTurnRecord(snapshot, id)` to tell whether an accepted turn is unknown, running, or finished, or `getTauSdkSessionTurnOutcome(snapshot, id)` when you only need the final outcome.
202
202
 
203
- `createEphemeralContext` and `submitEphemeralThread` accept an optional `reasoning` effort. A context inherits the parent session agent's current effort when creation omits it. A submission override becomes that thread's current effort before its turn; forks inherit the source thread's effort before applying an override.
203
+ `createEphemeralContext` and `submitEphemeralThread` accept an optional `reasoning` effort. Without it, a new context uses the session's current effort. On submission, the given effort becomes the thread's effort before the turn runs. A fork copies the source thread's effort, then applies any given effort.
204
204
 
205
205
  ### Execute a command
206
206
 
207
- `exec` generates a unique wire-level execution id and supports exact positional arguments, environment overrides other than `HOME`, binary stdin, a command `cwd`, timeout, capture limit, and cancellation signal:
207
+ `exec` generates a unique execution ID for you. It supports exact positional arguments, environment variables other than `HOME`, binary stdin, a starting `cwd`, a timeout, a capture limit, and a cancellation signal:
208
208
 
209
209
  ```ts
210
210
  const controller = new AbortController();
@@ -219,11 +219,11 @@ const result = await session.exec('exec "$0" "$@"', {
219
219
  console.log(result.exitCode, result.output);
220
220
  ```
221
221
 
222
- Aborting the signal sends targeted `session.cancelExec` and rejects the SDK call. It does not interrupt turns or other executions. The operation does not enter conversation history.
222
+ Aborting the signal cancels only this command, with `session.cancelExec`, and rejects the call. Turns and other commands keep running. The command is never added to the conversation.
223
223
 
224
224
  ### Sample a model
225
225
 
226
- `sample` uses the session's active resolved model target and credentials but only the supplied provider-neutral context:
226
+ `sample` uses the session's current model and credentials, but only the context you supply, in Tau's provider-independent format:
227
227
 
228
228
  ```ts
229
229
  const sampled = await session.sample({
@@ -243,21 +243,21 @@ const sampled = await session.sample({
243
243
  console.log(sampled.message.content);
244
244
  ```
245
245
 
246
- The returned complete assistant message can be reused in a later sampling context. Optional tool schemas can produce tool-call content, but Tau does not execute those calls. Sampling does not emit deltas, change snapshot revision or cost, or write conversation history.
246
+ You can reuse the returned assistant message in a later sample's context. If you pass tool schemas, the model may return tool calls, but Tau never runs them. Sampling sends no deltas, changes neither the snapshot revision nor the cost, and adds nothing to the conversation.
247
247
 
248
248
  ## Consume streamed state
249
249
 
250
- The SDK exposes connection-wide subscriptions on `TauSdkClient` and session-filtered subscriptions on `TauSdkSession`. Prefer the session facade unless one component deliberately multiplexes several sessions.
250
+ `TauSdkClient` has subscriptions for all sessions on the connection, and `TauSdkSession` has subscriptions for one session. Prefer the session's own unless one component handles several sessions.
251
251
 
252
252
  ### Snapshot deltas
253
253
 
254
- `session.onDelta(listener)` receives only that session's `TauSdkDelta` messages. The facade buffers deltas received before its first local delta listener and replays them when that listener is attached. Use `applySessionProtocolDelta` against an installed snapshot. On any revision gap or invalid transition, refresh with `session.snapshot()`.
254
+ `session.onDelta(listener)` receives only that session's `TauSdkDelta` messages. Deltas that arrive before the first listener is added are kept and delivered to it. Apply them to your snapshot with `applySessionProtocolDelta`. If a revision is missing or a change is invalid, fetch a fresh copy with `session.snapshot()`.
255
255
 
256
- A method that returns an authoritative snapshot, such as reload, compact, rewind, or persona change, lets the facade discard buffered deltas through that revision. Do not also replay stale presentation transitions from those discarded deltas.
256
+ Methods that return a full snapshot, such as reload, compact, rewind, and persona change, let the session object drop the kept deltas up to that revision. Do not replay UI effects from those dropped deltas.
257
257
 
258
258
  ### Pending input
259
259
 
260
- `session.pendingUserMessages()` returns a clone of the current full pending-message state. `session.onPendingUserMessages(listener)` immediately emits the current baseline, then newer full replacements. Its revision is independent of the snapshot.
260
+ `session.pendingUserMessages()` returns a copy of the full pending-message state. `session.onPendingUserMessages(listener)` sends the current state right away, then each newer full replacement. Its revision is separate from the snapshot's.
261
261
 
262
262
  ```ts
263
263
  const stopPending = session.onPendingUserMessages(({ state }) => {
@@ -265,29 +265,29 @@ const stopPending = session.onPendingUserMessages(({ state }) => {
265
265
  });
266
266
  ```
267
267
 
268
- Pending input is shared among clients observing the live hosted session and starts empty after recovery.
268
+ All clients observing the live session share pending input. It is empty after recovery.
269
269
 
270
270
  ### Subagent activity
271
271
 
272
- `session.subagentActivities()` returns the current transient activity state. `session.onSubagentActivities(listener)` immediately emits the current agents as `agent.set` changes, then later per-agent replacements and removals.
272
+ `session.subagentActivities()` returns the current live activity. `session.onSubagentActivities(listener)` sends the current subagents right away as `agent.set` changes, then later replacements and removals for each subagent.
273
273
 
274
- For a custom accumulator, use `applySessionProtocolSubagentActivitiesMessage`. This channel has its own revision and does not replace durable `snapshot.agents`.
274
+ To keep your own copy, use `applySessionProtocolSubagentActivitiesMessage`. This channel has its own revision and does not replace the saved `snapshot.agents`.
275
275
 
276
276
  ### Ephemeral events
277
277
 
278
- `session.onEphemeral(listener)` receives best-effort footer notices, ephemeral thread progress, and non-recoverable timeline notices. These events are not replayed or included in `session.snapshot()`.
278
+ `session.onEphemeral(listener)` receives footer notices, ephemeral thread progress, and timeline notices that are not saved. Delivery is not guaranteed, and these events are never replayed or included in `session.snapshot()`.
279
279
 
280
- If rendering `timeline.item`, accept only the active epoch and merge by its allocated sequence. Compaction and rewind causes determine which client-local ephemeral items remain valid. The [session protocol](session-protocol.md) gives the application rules.
280
+ If you show `timeline.item` events, accept only the current epoch and place each by its sequence number. Compaction and rewind causes decide which of these items you keep. The [session protocol](session-protocol.md) gives the application rules.
281
281
 
282
282
  ## Host a browser diff review
283
283
 
284
- `startTauSdkDiffReview()` starts the built-in browser review UI for an observed session without requiring the TUI or opening a browser. It supports client-owned reverse proxying, durable review-state storage, restored conversation context, and an awaited one-shot submission callback.
284
+ `startTauSdkDiffReview()` starts the built-in browser review UI for an observed session, without the TUI and without opening a browser. Your application can put it behind its own reverse proxy, store review state, restore earlier conversations, and receive the submitted review once through a callback.
285
285
 
286
- See [SDK browser diff review](sdk-diff-review.md) for its startup, persistence, submission, and lifecycle contracts.
286
+ See [SDK browser diff review](sdk-diff-review.md) for startup, storage, submission, and lifecycle.
287
287
 
288
288
  ## Provide client tools
289
289
 
290
- Pass `TauSdkClientTool` entries in `clientTools` when model-facing work must run in the integration process:
290
+ Pass `TauSdkClientTool` entries in `clientTools` to give the model tools that run in your process:
291
291
 
292
292
  ```ts
293
293
  import {
@@ -338,19 +338,19 @@ const client = await createTauSdkClient({
338
338
  });
339
339
  ```
340
340
 
341
- 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.
341
+ The handler receives `sessionId`, the calling `agentId`, `callId`, an `AbortSignal`, and the execution-environment API. The handler runs on the client machine, while `context.executionEnvironment.exec()` runs commands in the session's execution environment.
342
342
 
343
- `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`.
343
+ `describe` is optional. If present, the SDK calls it before accepting the call, with the arguments and a smaller context of `sessionId`, `agentId`, `callId`, and `signal`, without execution-environment access. It may return a partial presentation for the running card, with `subject`, `subjectWrap`, `details`, or `metadata`. Tau sets the action and operation, fills in omitted fields, and acknowledges with the result before calling `execute`.
344
344
 
345
- 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. Successful `content` may be a string or an ordered array of text/image blocks. Strings are delivered as one text block. 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.
345
+ The execution result may include the same partial shape for the finished card. Return a string or `{ content, presentation? }` for success, or `{ ok: false, error, presentation? }` for a handled failure. `content` may be a string, sent as one text block, or an ordered array of text and image blocks. Omitted presentation fields get Tau's defaults, and an empty `details` or `metadata` array hides that default. If `describe` throws, the SDK reports a preparation error and does not call `execute`. If no result is returned, because of cancellation, timeout, detach, or another failure, the host shows a complete default card.
346
346
 
347
- 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.
347
+ Tau keeps every presentation field you set, up to the protocol limits, without truncating or normalizing it. `truncateTauClientToolText` truncates text for you by lines and characters, keeping the start or the middle. Use its result directly as a subject. For a block of detail text, split the result on `\n` and make each line one `details` entry; use `maxLines: 1` when the result goes into a single entry. The helper does not replace protocol validation. The SDK aborts handlers when the host cancels, the client closes, or the transport fails, and `client.close()` waits for running handlers to finish.
348
348
 
349
- 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.
349
+ Each assistant turn keeps the tool definitions it started with. Client tools are not affected by the persona's tool list. Names must not match host tools or tools of another observing client. See [client tools](client-tools.md) for authority, limits, command-backed tools, and disconnect behavior.
350
350
 
351
351
  ### Build a code-mode tool
352
352
 
353
- `createTauCodeModeClientTool()` wraps a bounded one-shot JavaScript API as an SDK client tool:
353
+ `createTauCodeModeClientTool()` turns an API you define into a client tool that runs one-off JavaScript programs against it:
354
354
 
355
355
  ```ts
356
356
  import {
@@ -372,40 +372,40 @@ const tickets = createTauCodeModeClientTool({
372
372
  });
373
373
  ```
374
374
 
375
- Pass `tickets` in `clientTools`. Generated code receives the declared API namespace, progressively disclosed `docs`, `printText`, the asynchronous `printImage` output helper, `truncate` and `truncateLines`, and live `Date` and `Math`. 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.
375
+ Pass `tickets` in `clientTools`. The model's code receives your API namespace, `docs` (read on demand), `printText`, the async `printImage`, `truncate` and `truncateLines`, and the real `Date` and `Math`. API calls pass through a size-limited JSON bridge. The submitted code, truncated and wrapped, is the subject of the running and finished tool cards. You write the description; the description builder is optional.
376
376
 
377
- Use `await printImage({ data, mimeType })` to forward a base64 image. Successful code-mode results contain an ordered `content` array of text/image blocks. SDK client tools preserve that order: adjacent text writes form one text block, and each awaited image separates the preceding and following text. The helper validates and prepares JPEG, PNG, or WebP images outside the sandbox, creates no files, and shares the limits described in [tools](tools.md).
377
+ Use `await printImage({ data, mimeType })` to return a base64 image. Results contain an ordered `content` array of text and image blocks, and SDK client tools keep that order: consecutive text output forms one block, and each image splits the text before and after it. The helper validates and prepares JPEG, PNG, or WebP images outside the sandbox, creates no files, and uses the limits described in [tools](tools.md).
378
378
 
379
- Code-mode tool calls and standalone execution accept optional `maxOutputTokens` (1 through 65,536), with an 8,192-token default text budget. Output persistence is opt-in through the definition's `persistOutput` callback.
379
+ Code-mode calls and standalone runs accept an optional `maxOutputTokens` (1 through 65,536), with a default text budget of 8,192 tokens. Saving output to files is off unless the definition provides a `persistOutput` callback.
380
380
 
381
- The SDK also exports `executeTauCodeMode` for standalone execution. The separate `@markusylisiurunen/tau/code-mode` entry point additionally exports `runTauClientToolCommand`, and `runTauCodeModeCommand` for command-backed tools. Use the helpers instead of implementing their framing manually.
381
+ The SDK also exports `executeTauCodeMode` for standalone runs. The separate `@markusylisiurunen/tau/code-mode` entry point also exports `runTauClientToolCommand` and `runTauCodeModeCommand` for command tools. Use these helpers instead of implementing the protocol yourself.
382
382
 
383
383
  ## Cancel and close deliberately
384
384
 
385
- 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.
385
+ Most turn and session-changing methods do not accept an `AbortSignal`. Call `session.interrupt()` to stop running work on the host. `session.exec()` is the exception: its optional signal cancels only that command.
386
386
 
387
- `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.
387
+ `session.unobserve()` ends one session object. `client.close()` ends the connection: it rejects open requests, aborts client tool handlers, waits for them to finish, and closes the transport. For the default in-process client, it also saves sessions and shuts down the host. Over WebSocket, the remote host and its sessions keep running.
388
388
 
389
- Always close clients in `finally`. Do not continue using a session facade after unobserve or any client after close.
389
+ Always close clients in `finally`. Never use a session object after `unobserve()`, or a client after `close()`.
390
390
 
391
391
  ## Handle errors
392
392
 
393
393
  All exported SDK and transport errors extend `TauSessionClientError`:
394
394
 
395
395
  - `TauSessionProtocolResponseError` means the host returned a protocol error. It exposes `code`, `message`, `requestId`, and optional `data`.
396
- - `TauTransportError` means connection setup, framing, version validation, timeout, closure, or another terminal transport operation failed.
396
+ - `TauTransportError` means the connection failed: during setup, framing, version checks, a timeout, closing, or another fatal transport error.
397
397
 
398
398
  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.
399
399
 
400
- Listener exceptions are isolated from SDK event delivery. Handle failures inside listeners and keep state application deterministic.
400
+ An exception in one listener does not stop delivery to others. Handle errors inside your listeners, and keep state updates deterministic.
401
401
 
402
402
  ## Use the public types and helpers
403
403
 
404
- The SDK entry point exports the types needed at integration boundaries rather than requiring imports from internal modules:
404
+ The SDK entry point exports every type an integration needs, so you never import from internal modules:
405
405
 
406
406
  - `TauSdkClient`, `TauSdkSession`, client option types, session summaries, and request and result aliases;
407
407
  - `TauSdkDelta`, `SessionProtocolSnapshot`, pending-message types, subagent-activity types, and ephemeral event types;
408
- - `TauSdkClientTool`, its execution context and environment facade, and code-mode definition and result types;
408
+ - `TauSdkClientTool`, its execution context and execution-environment API, and code-mode definition and result types;
409
409
  - `SessionProtocolTransport`, listener types, WebSocket options, and transport errors.
410
410
 
411
411
  It also exports `applySessionProtocolDelta`, `applySessionProtocolSubagentActivitiesMessage`, the turn-ledger helpers, and user-text projection helpers:
@@ -418,4 +418,4 @@ import {
418
418
  } from "@markusylisiurunen/tau/sdk";
419
419
  ```
420
420
 
421
- Use `getTauUserDisplayText` before rendering raw snapshot user text. It removes Tau metadata and leading exact hidden system blocks. `getTauUserModelText` removes Tau metadata while preserving model-facing hidden instructions. `projectTauUserText` returns both views together. These helpers apply only to user messages.
421
+ Use `getTauUserDisplayText` before showing user text from a snapshot. It removes Tau metadata and leading hidden `<system>` blocks. `getTauUserModelText` removes Tau metadata but keeps the hidden blocks the model sees. `projectTauUserText` returns both. These helpers are for user messages only.