@markusylisiurunen/tau 0.3.78 → 0.3.79

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 (101) hide show
  1. package/dist/code_mode/images.d.ts +3 -0
  2. package/dist/code_mode/images.js +37 -0
  3. package/dist/code_mode/images.js.map +1 -0
  4. package/dist/code_mode/output.d.ts +22 -0
  5. package/dist/code_mode/output.js +109 -0
  6. package/dist/code_mode/output.js.map +1 -0
  7. package/dist/code_mode/runtime.d.ts +2 -1
  8. package/dist/code_mode/runtime.js +92 -12
  9. package/dist/code_mode/runtime.js.map +1 -1
  10. package/dist/core/client_tools/command_client_tools.js +2 -2
  11. package/dist/core/commands/registry.js +16 -1
  12. package/dist/core/commands/registry.js.map +1 -1
  13. package/dist/core/config/content_loader.js +3 -1
  14. package/dist/core/config/content_loader.js.map +1 -1
  15. package/dist/core/config/mcp.js +68 -0
  16. package/dist/core/config/mcp.js.map +1 -0
  17. package/dist/core/config/schema.js +26 -4
  18. package/dist/core/config/schema.js.map +1 -1
  19. package/dist/core/mcp/manager.js +245 -0
  20. package/dist/core/mcp/manager.js.map +1 -0
  21. package/dist/core/mcp/search.js +77 -0
  22. package/dist/core/mcp/search.js.map +1 -0
  23. package/dist/core/personas.js +2 -1
  24. package/dist/core/personas.js.map +1 -1
  25. package/dist/core/runtime/chat_runtime.js +3 -0
  26. package/dist/core/runtime/chat_runtime.js.map +1 -1
  27. package/dist/core/static/code_mode/mcp/documentation.md +113 -0
  28. package/dist/core/static/code_mode/sandbox_runner.mjs +58 -3
  29. package/dist/core/static/tau_docs/client-tools.md +32 -30
  30. package/dist/core/static/tau_docs/config-reference.md +48 -1
  31. package/dist/core/static/tau_docs/node-sdk.md +4 -2
  32. package/dist/core/static/tau_docs/ownership-and-scope.md +2 -0
  33. package/dist/core/static/tau_docs/personas.md +2 -2
  34. package/dist/core/static/tau_docs/security.md +13 -1
  35. package/dist/core/static/tau_docs/session-protocol-methods.md +8 -3
  36. package/dist/core/static/tau_docs/session-protocol.md +9 -9
  37. package/dist/core/static/tau_docs/subagents.md +2 -1
  38. package/dist/core/static/tau_docs/tools.md +21 -6
  39. package/dist/core/static/tau_docs/tui.md +6 -1
  40. package/dist/core/subagents/agent_supervisor.js +1 -1
  41. package/dist/core/subagents/agent_supervisor.js.map +1 -1
  42. package/dist/core/subagents/registry.js +2 -1
  43. package/dist/core/subagents/registry.js.map +1 -1
  44. package/dist/core/subagents/types.js +2 -1
  45. package/dist/core/subagents/types.js.map +1 -1
  46. package/dist/core/tools/catalog.js +14 -2
  47. package/dist/core/tools/catalog.js.map +1 -1
  48. package/dist/core/tools/code_mode.js +5 -2
  49. package/dist/core/tools/code_mode.js.map +1 -1
  50. package/dist/core/tools/code_mode_worker.js +33 -1
  51. package/dist/core/tools/code_mode_worker.js.map +1 -1
  52. package/dist/core/tools/history.js +1 -1
  53. package/dist/core/tools/history.js.map +1 -1
  54. package/dist/core/tools/mcp.js +167 -0
  55. package/dist/core/tools/mcp.js.map +1 -0
  56. package/dist/core/tools/nook.js +1 -1
  57. package/dist/core/tools/nook.js.map +1 -1
  58. package/dist/core/tools/spawn_agent.js +1 -0
  59. package/dist/core/tools/spawn_agent.js.map +1 -1
  60. package/dist/core/tools/tool_names.js +2 -0
  61. package/dist/core/tools/tool_names.js.map +1 -1
  62. package/dist/core/tools/view_image.js +1 -105
  63. package/dist/core/tools/view_image.js.map +1 -1
  64. package/dist/core/tools/web.js +1 -1
  65. package/dist/core/tools/web.js.map +1 -1
  66. package/dist/core/utils/bm25.js +74 -0
  67. package/dist/core/utils/bm25.js.map +1 -0
  68. package/dist/core/utils/model_image.js +106 -0
  69. package/dist/core/utils/model_image.js.map +1 -0
  70. package/dist/core/version.js +1 -1
  71. package/dist/host/client_tool_broker.js +1 -1
  72. package/dist/host/client_tool_broker.js.map +1 -1
  73. package/dist/host/local_session_host.js +11 -1
  74. package/dist/host/local_session_host.js.map +1 -1
  75. package/dist/host/session_host.js.map +1 -1
  76. package/dist/main.js +1 -0
  77. package/dist/main.js.map +1 -1
  78. package/dist/protocol/session_protocol.d.ts +12 -7
  79. package/dist/protocol/session_protocol.js +28 -2
  80. package/dist/protocol/session_protocol.js.map +1 -1
  81. package/dist/sdk/client_tool_command.d.ts +12 -11
  82. package/dist/sdk/client_tool_command.js +8 -8
  83. package/dist/sdk/client_tool_command.js.map +1 -1
  84. package/dist/sdk/code_mode.js +1 -1
  85. package/dist/sdk/code_mode.js.map +1 -1
  86. package/dist/sdk/local_client.js +1 -0
  87. package/dist/sdk/local_client.js.map +1 -1
  88. package/dist/sdk/session.js +1 -1
  89. package/dist/sdk/session.js.map +1 -1
  90. package/dist/sdk/types.d.ts +2 -1
  91. package/dist/tui/chat_view.js +3 -1
  92. package/dist/tui/chat_view.js.map +1 -1
  93. package/dist/tui/session_chat_controller.js +111 -5
  94. package/dist/tui/session_chat_controller.js.map +1 -1
  95. package/dist/tui/ui/custom_editor.js +49 -10
  96. package/dist/tui/ui/custom_editor.js.map +1 -1
  97. package/dist/tui/ui/footer.js +4 -2
  98. package/dist/tui/ui/footer.js.map +1 -1
  99. package/dist/tui/ui/slash_autocomplete.js +5 -1
  100. package/dist/tui/ui/slash_autocomplete.js.map +1 -1
  101. package/package.json +7 -6
@@ -88,6 +88,9 @@ export class SessionChatController {
88
88
  submissionHiddenSystemMessages = [];
89
89
  pendingEditorMutations = 0;
90
90
  speechActivityLabel;
91
+ autoSpeak = false;
92
+ pendingAutoSpeak;
93
+ lastAutoSpeakMessageId;
91
94
  speakTask;
92
95
  constructor(options) {
93
96
  this.view = options.view;
@@ -118,6 +121,7 @@ export class SessionChatController {
118
121
  reload: () => this.reloadContent(),
119
122
  listen: (action) => this.handleListenCommand(action),
120
123
  speak: () => this.speakLastAssistantMessage(),
124
+ autoSpeak: (enabled) => this.setAutoSpeak(enabled),
121
125
  persona: (id) => this.setPersona(id),
122
126
  prompt: (id) => this.insertPrompt(id),
123
127
  theme: (id) => this.switchTheme(id),
@@ -185,7 +189,8 @@ export class SessionChatController {
185
189
  onShiftTab: () => void this.cycleReasoningLevel(),
186
190
  onCtrlP: () => void this.cyclePersonality(),
187
191
  onCtrlS: () => void this.stashEditorToClipboard(),
188
- onCtrlY: () => void this.toggleListenCapture(),
192
+ onToggleRecording: () => void this.toggleListenCapture(),
193
+ recordingShortcut: this.config.speech?.recordingShortcut,
189
194
  onDisabledSubmit: (mode) => {
190
195
  if (this.listenRecording && !this.listenTransition) {
191
196
  void this.runListenTransition(() => this.stopListenCapture(mode));
@@ -321,6 +326,9 @@ export class SessionChatController {
321
326
  contextFiles: this.getContextFilePaths(),
322
327
  skills: this.snapshot.catalog.skills,
323
328
  themes: this.themeIds,
329
+ recordingShortcut: this.config.speech?.recordingShortcut
330
+ ? `${this.config.speech.recordingShortcut.gesture === "double-tap" ? "double-tap " : ""}${this.config.speech.recordingShortcut.key}`
331
+ : "ctrl+y",
324
332
  formatPath: (path) => formatPathForSessionDisplay(path, this.snapshot.executionEnvironment.home),
325
333
  }),
326
334
  });
@@ -544,8 +552,10 @@ export class SessionChatController {
544
552
  this.view.startWorkingIcon();
545
553
  this.refreshStatus();
546
554
  try {
547
- await task();
555
+ const result = await task();
548
556
  await this.syncFromSessionSnapshot();
557
+ if (result.turn.status === "completed")
558
+ this.queueAutoSpeak();
549
559
  }
550
560
  catch (error) {
551
561
  this.view.addTranscriptNotice("failed to run assistant turn", "error", [
@@ -561,6 +571,7 @@ export class SessionChatController {
561
571
  }
562
572
  }
563
573
  async interrupt() {
574
+ this.pendingAutoSpeak = undefined;
564
575
  if (this.interruptLifecycle.interruptActiveTask()) {
565
576
  this.view.showFooterNotice("interrupted", "default");
566
577
  return;
@@ -646,7 +657,15 @@ export class SessionChatController {
646
657
  this.view.showFooterNotice("speech transcription already in progress", "default");
647
658
  return;
648
659
  }
649
- await this.runListenTransition(() => this.startListenCapture());
660
+ this.pendingAutoSpeak = undefined;
661
+ await this.runListenTransition(async () => {
662
+ if (this.speakTask) {
663
+ this.speakTask.abortController.abort();
664
+ await this.speakTask.completion.catch(() => { });
665
+ }
666
+ if (!this.disposed)
667
+ await this.startListenCapture();
668
+ });
650
669
  }
651
670
  async runListenTransition(task) {
652
671
  if (this.listenTransition) {
@@ -1114,6 +1133,9 @@ export class SessionChatController {
1114
1133
  this.ephemeralUnsubscribe?.();
1115
1134
  this.pendingUserMessagesUnsubscribe?.();
1116
1135
  this.subagentActivitiesUnsubscribe?.();
1136
+ this.autoSpeak = false;
1137
+ this.pendingAutoSpeak = undefined;
1138
+ this.lastAutoSpeakMessageId = undefined;
1117
1139
  this.session = nextSession;
1118
1140
  this.snapshot = nextSnapshot;
1119
1141
  this.subagentActivities = nextSession.subagentActivities();
@@ -1215,9 +1237,48 @@ export class SessionChatController {
1215
1237
  this.snapshotRecoveryDeltas.push(delta);
1216
1238
  return;
1217
1239
  }
1240
+ if (delta.toRevision <= this.snapshot.revision)
1241
+ return;
1242
+ const invalidatesSpeech = delta.cause.type === "rewind" ||
1243
+ delta.cause.type === "compaction" ||
1244
+ delta.cause.type === "resync";
1245
+ if (invalidatesSpeech)
1246
+ this.pendingAutoSpeak = undefined;
1247
+ const previousLifecycle = this.snapshot.lifecycle;
1248
+ const previousTurns = this.snapshot.turns;
1218
1249
  if (this.tryApplySdkDelta(delta)) {
1250
+ if (this.autoSpeak && !invalidatesSpeech) {
1251
+ if (previousLifecycle !== "running" && this.snapshot.lifecycle === "running") {
1252
+ this.pendingAutoSpeak = undefined;
1253
+ this.speakTask?.abortController.abort();
1254
+ this.lastAutoSpeakMessageId = this.snapshot.messages.findLast((entry) => isAssistantMessage(entry.message) && entry.state === "committed")?.id;
1255
+ }
1256
+ if (delta.delta.type === "snapshot.patch") {
1257
+ for (const change of delta.delta.changes) {
1258
+ if (change.type !== "turn.set")
1259
+ continue;
1260
+ const turn = change.turn;
1261
+ if (turn.state === "running") {
1262
+ this.pendingAutoSpeak = undefined;
1263
+ this.speakTask?.abortController.abort();
1264
+ continue;
1265
+ }
1266
+ if (previousTurns[turn.userHistoryEntryId]?.state === "running" &&
1267
+ turn.outcome.status === "completed") {
1268
+ this.queueAutoSpeak();
1269
+ }
1270
+ }
1271
+ }
1272
+ if (previousLifecycle === "running" &&
1273
+ this.snapshot.lifecycle === "idle" &&
1274
+ !Object.values(previousTurns).some((turn) => turn.state === "running")) {
1275
+ this.queueAutoSpeak();
1276
+ }
1277
+ this.drainAutoSpeak();
1278
+ }
1219
1279
  return;
1220
1280
  }
1281
+ this.pendingAutoSpeak = undefined;
1221
1282
  this.snapshotRecoveryDeltas.push(delta);
1222
1283
  void this.recoverFromRevisionGap();
1223
1284
  }
@@ -1985,7 +2046,50 @@ export class SessionChatController {
1985
2046
  this.view.addTranscriptNotice("failed to clear goal", "error", [error.message]);
1986
2047
  }
1987
2048
  }
1988
- async speakLastAssistantMessage() {
2049
+ setAutoSpeak(enabled) {
2050
+ if ((enabled ?? !this.autoSpeak) && this.deps.env.platform() !== "darwin") {
2051
+ this.view.showFooterNotice("auto-speak is currently supported only on macOS", "default");
2052
+ return;
2053
+ }
2054
+ const next = enabled ?? !this.autoSpeak;
2055
+ if (next && !this.autoSpeak) {
2056
+ this.lastAutoSpeakMessageId = this.snapshot.messages.findLast((entry) => isAssistantMessage(entry.message))?.id;
2057
+ }
2058
+ this.autoSpeak = next;
2059
+ if (!this.autoSpeak) {
2060
+ this.pendingAutoSpeak = undefined;
2061
+ this.speakTask?.abortController.abort();
2062
+ }
2063
+ this.view.showFooterNotice(`auto-speak ${this.autoSpeak ? "on" : "off"}`, "default");
2064
+ this.refreshStatus();
2065
+ }
2066
+ queueAutoSpeak() {
2067
+ if (!this.autoSpeak)
2068
+ return;
2069
+ const entry = this.snapshot.messages.findLast((entry) => isAssistantMessage(entry.message));
2070
+ if (!entry || entry.id === this.lastAutoSpeakMessageId || !isAssistantMessage(entry.message))
2071
+ return;
2072
+ this.lastAutoSpeakMessageId = entry.id;
2073
+ if (entry.message.stopReason === "stop" || entry.message.stopReason === "length") {
2074
+ this.pendingAutoSpeak = entry.message;
2075
+ }
2076
+ }
2077
+ drainAutoSpeak() {
2078
+ if (!this.pendingAutoSpeak || this.isSessionOperationActive())
2079
+ return;
2080
+ const message = this.pendingAutoSpeak;
2081
+ this.pendingAutoSpeak = undefined;
2082
+ if (!this.autoSpeak ||
2083
+ this.disposed ||
2084
+ this.listenRecording ||
2085
+ this.listenTransition ||
2086
+ this.listenActivityLabel ||
2087
+ this.speakTask ||
2088
+ this.hasPendingUserMessages)
2089
+ return;
2090
+ void this.speakLastAssistantMessage(message);
2091
+ }
2092
+ async speakLastAssistantMessage(message) {
1989
2093
  if (this.speakTask) {
1990
2094
  this.view.showFooterNotice("speech playback already in progress", "default");
1991
2095
  return;
@@ -1998,7 +2102,7 @@ export class SessionChatController {
1998
2102
  this.view.showFooterNotice("/speak is currently supported only on macOS.", "default");
1999
2103
  return;
2000
2104
  }
2001
- const lastAssistant = this.getLastAssistantMessage();
2105
+ const lastAssistant = message ?? this.getLastAssistantMessage();
2002
2106
  if (!lastAssistant) {
2003
2107
  this.view.showFooterNotice("no assistant message to speak yet.", "default");
2004
2108
  return;
@@ -2064,6 +2168,7 @@ export class SessionChatController {
2064
2168
  });
2065
2169
  }
2066
2170
  refreshStatus() {
2171
+ this.drainAutoSpeak();
2067
2172
  const activityLabel = this.getActivityLabel();
2068
2173
  this.view.updateStatus({
2069
2174
  footer: activityLabel
@@ -2075,6 +2180,7 @@ export class SessionChatController {
2075
2180
  sessionCost: this.getSessionCostString(),
2076
2181
  duration: this.getTurnDurationString(),
2077
2182
  pursuingGoal: this.snapshot.goal?.status === "active",
2183
+ autoSpeak: this.autoSpeak,
2078
2184
  },
2079
2185
  editor: {
2080
2186
  mode: this.getInputMode(),