@getpaseo/server 0.1.37 → 0.1.38

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 (295) hide show
  1. package/dist/scripts/dev-runner.js +1 -1
  2. package/dist/scripts/dev-runner.js.map +1 -1
  3. package/dist/scripts/{daemon-runner.js → supervisor-entrypoint.js} +7 -9
  4. package/dist/scripts/supervisor-entrypoint.js.map +1 -0
  5. package/dist/scripts/supervisor.js +17 -1
  6. package/dist/scripts/supervisor.js.map +1 -1
  7. package/dist/server/server/bootstrap.d.ts +0 -4
  8. package/dist/server/server/bootstrap.d.ts.map +1 -1
  9. package/dist/server/server/bootstrap.js +8 -22
  10. package/dist/server/server/bootstrap.js.map +1 -1
  11. package/dist/server/server/index.js +0 -4
  12. package/dist/server/server/index.js.map +1 -1
  13. package/dist/server/server/pid-lock.d.ts +7 -2
  14. package/dist/server/server/pid-lock.d.ts.map +1 -1
  15. package/dist/server/server/pid-lock.js +21 -0
  16. package/dist/server/server/pid-lock.js.map +1 -1
  17. package/dist/server/server/session.d.ts.map +1 -1
  18. package/dist/server/server/session.js +2 -2
  19. package/dist/server/server/session.js.map +1 -1
  20. package/dist/src/server/pid-lock.js +21 -0
  21. package/dist/src/server/pid-lock.js.map +1 -1
  22. package/package.json +3 -3
  23. package/dist/scripts/daemon-runner.js.map +0 -1
  24. package/dist/src/server/agent/activity-curator.js +0 -243
  25. package/dist/src/server/agent/activity-curator.js.map +0 -1
  26. package/dist/src/server/agent/agent-manager.js +0 -1855
  27. package/dist/src/server/agent/agent-manager.js.map +0 -1
  28. package/dist/src/server/agent/agent-metadata-generator.js +0 -161
  29. package/dist/src/server/agent/agent-metadata-generator.js.map +0 -1
  30. package/dist/src/server/agent/agent-projections.js +0 -254
  31. package/dist/src/server/agent/agent-projections.js.map +0 -1
  32. package/dist/src/server/agent/agent-response-loop.js +0 -304
  33. package/dist/src/server/agent/agent-response-loop.js.map +0 -1
  34. package/dist/src/server/agent/agent-sdk-types.js +0 -12
  35. package/dist/src/server/agent/agent-sdk-types.js.map +0 -1
  36. package/dist/src/server/agent/agent-storage.js +0 -302
  37. package/dist/src/server/agent/agent-storage.js.map +0 -1
  38. package/dist/src/server/agent/agent-title-limits.js +0 -3
  39. package/dist/src/server/agent/agent-title-limits.js.map +0 -1
  40. package/dist/src/server/agent/audio-utils.js +0 -19
  41. package/dist/src/server/agent/audio-utils.js.map +0 -1
  42. package/dist/src/server/agent/dictation-debug.js +0 -50
  43. package/dist/src/server/agent/dictation-debug.js.map +0 -1
  44. package/dist/src/server/agent/mcp-server.js +0 -754
  45. package/dist/src/server/agent/mcp-server.js.map +0 -1
  46. package/dist/src/server/agent/orchestrator-instructions.js +0 -51
  47. package/dist/src/server/agent/orchestrator-instructions.js.map +0 -1
  48. package/dist/src/server/agent/pcm16-resampler.js +0 -63
  49. package/dist/src/server/agent/pcm16-resampler.js.map +0 -1
  50. package/dist/src/server/agent/provider-launch-config.js +0 -213
  51. package/dist/src/server/agent/provider-launch-config.js.map +0 -1
  52. package/dist/src/server/agent/provider-manifest.js +0 -127
  53. package/dist/src/server/agent/provider-manifest.js.map +0 -1
  54. package/dist/src/server/agent/provider-registry.js +0 -45
  55. package/dist/src/server/agent/provider-registry.js.map +0 -1
  56. package/dist/src/server/agent/providers/claude/partial-json.js +0 -306
  57. package/dist/src/server/agent/providers/claude/partial-json.js.map +0 -1
  58. package/dist/src/server/agent/providers/claude/sdk-model-resolver.js +0 -104
  59. package/dist/src/server/agent/providers/claude/sdk-model-resolver.js.map +0 -1
  60. package/dist/src/server/agent/providers/claude/sidechain-tracker.js +0 -230
  61. package/dist/src/server/agent/providers/claude/sidechain-tracker.js.map +0 -1
  62. package/dist/src/server/agent/providers/claude/task-notification-tool-call.js +0 -267
  63. package/dist/src/server/agent/providers/claude/task-notification-tool-call.js.map +0 -1
  64. package/dist/src/server/agent/providers/claude/tool-call-detail-parser.js +0 -121
  65. package/dist/src/server/agent/providers/claude/tool-call-detail-parser.js.map +0 -1
  66. package/dist/src/server/agent/providers/claude/tool-call-mapper.js +0 -252
  67. package/dist/src/server/agent/providers/claude/tool-call-mapper.js.map +0 -1
  68. package/dist/src/server/agent/providers/claude-agent.js +0 -3166
  69. package/dist/src/server/agent/providers/claude-agent.js.map +0 -1
  70. package/dist/src/server/agent/providers/codex/tool-call-detail-parser.js +0 -104
  71. package/dist/src/server/agent/providers/codex/tool-call-detail-parser.js.map +0 -1
  72. package/dist/src/server/agent/providers/codex/tool-call-mapper.js +0 -758
  73. package/dist/src/server/agent/providers/codex/tool-call-mapper.js.map +0 -1
  74. package/dist/src/server/agent/providers/codex-app-server-agent.js +0 -2949
  75. package/dist/src/server/agent/providers/codex-app-server-agent.js.map +0 -1
  76. package/dist/src/server/agent/providers/codex-rollout-timeline.js +0 -544
  77. package/dist/src/server/agent/providers/codex-rollout-timeline.js.map +0 -1
  78. package/dist/src/server/agent/providers/opencode/tool-call-detail-parser.js +0 -39
  79. package/dist/src/server/agent/providers/opencode/tool-call-detail-parser.js.map +0 -1
  80. package/dist/src/server/agent/providers/opencode/tool-call-mapper.js +0 -144
  81. package/dist/src/server/agent/providers/opencode/tool-call-mapper.js.map +0 -1
  82. package/dist/src/server/agent/providers/opencode-agent.js +0 -1193
  83. package/dist/src/server/agent/providers/opencode-agent.js.map +0 -1
  84. package/dist/src/server/agent/providers/tool-call-detail-primitives.js +0 -686
  85. package/dist/src/server/agent/providers/tool-call-detail-primitives.js.map +0 -1
  86. package/dist/src/server/agent/providers/tool-call-mapper-utils.js +0 -115
  87. package/dist/src/server/agent/providers/tool-call-mapper-utils.js.map +0 -1
  88. package/dist/src/server/agent/recordings-debug.js +0 -19
  89. package/dist/src/server/agent/recordings-debug.js.map +0 -1
  90. package/dist/src/server/agent/stt-debug.js +0 -33
  91. package/dist/src/server/agent/stt-debug.js.map +0 -1
  92. package/dist/src/server/agent/stt-manager.js +0 -232
  93. package/dist/src/server/agent/stt-manager.js.map +0 -1
  94. package/dist/src/server/agent/timeline-append.js +0 -27
  95. package/dist/src/server/agent/timeline-append.js.map +0 -1
  96. package/dist/src/server/agent/timeline-projection.js +0 -215
  97. package/dist/src/server/agent/timeline-projection.js.map +0 -1
  98. package/dist/src/server/agent/tool-name-normalization.js +0 -45
  99. package/dist/src/server/agent/tool-name-normalization.js.map +0 -1
  100. package/dist/src/server/agent/tts-debug.js +0 -24
  101. package/dist/src/server/agent/tts-debug.js.map +0 -1
  102. package/dist/src/server/agent/tts-manager.js +0 -374
  103. package/dist/src/server/agent/tts-manager.js.map +0 -1
  104. package/dist/src/server/agent/wait-for-agent-tracker.js +0 -53
  105. package/dist/src/server/agent/wait-for-agent-tracker.js.map +0 -1
  106. package/dist/src/server/agent-attention-policy.js +0 -40
  107. package/dist/src/server/agent-attention-policy.js.map +0 -1
  108. package/dist/src/server/allowed-hosts.js +0 -94
  109. package/dist/src/server/allowed-hosts.js.map +0 -1
  110. package/dist/src/server/bootstrap.js +0 -620
  111. package/dist/src/server/bootstrap.js.map +0 -1
  112. package/dist/src/server/chat/chat-mentions.js +0 -71
  113. package/dist/src/server/chat/chat-mentions.js.map +0 -1
  114. package/dist/src/server/chat/chat-rpc-schemas.js +0 -103
  115. package/dist/src/server/chat/chat-rpc-schemas.js.map +0 -1
  116. package/dist/src/server/chat/chat-service.js +0 -330
  117. package/dist/src/server/chat/chat-service.js.map +0 -1
  118. package/dist/src/server/chat/chat-types.js +0 -22
  119. package/dist/src/server/chat/chat-types.js.map +0 -1
  120. package/dist/src/server/checkout-diff-manager.js +0 -272
  121. package/dist/src/server/checkout-diff-manager.js.map +0 -1
  122. package/dist/src/server/checkout-git-utils.js +0 -37
  123. package/dist/src/server/checkout-git-utils.js.map +0 -1
  124. package/dist/src/server/client-message-id.js +0 -12
  125. package/dist/src/server/client-message-id.js.map +0 -1
  126. package/dist/src/server/config.js +0 -73
  127. package/dist/src/server/config.js.map +0 -1
  128. package/dist/src/server/connection-offer.js +0 -59
  129. package/dist/src/server/connection-offer.js.map +0 -1
  130. package/dist/src/server/daemon-keypair.js +0 -40
  131. package/dist/src/server/daemon-keypair.js.map +0 -1
  132. package/dist/src/server/daemon-version.js +0 -22
  133. package/dist/src/server/daemon-version.js.map +0 -1
  134. package/dist/src/server/dictation/dictation-stream-manager.js +0 -571
  135. package/dist/src/server/dictation/dictation-stream-manager.js.map +0 -1
  136. package/dist/src/server/file-download/token-store.js +0 -40
  137. package/dist/src/server/file-download/token-store.js.map +0 -1
  138. package/dist/src/server/file-explorer/service.js +0 -180
  139. package/dist/src/server/file-explorer/service.js.map +0 -1
  140. package/dist/src/server/json-utils.js +0 -45
  141. package/dist/src/server/json-utils.js.map +0 -1
  142. package/dist/src/server/loop/rpc-schemas.js +0 -159
  143. package/dist/src/server/loop/rpc-schemas.js.map +0 -1
  144. package/dist/src/server/loop-service.js +0 -741
  145. package/dist/src/server/loop-service.js.map +0 -1
  146. package/dist/src/server/messages.js +0 -29
  147. package/dist/src/server/messages.js.map +0 -1
  148. package/dist/src/server/package-version.js +0 -46
  149. package/dist/src/server/package-version.js.map +0 -1
  150. package/dist/src/server/pairing-offer.js +0 -45
  151. package/dist/src/server/pairing-offer.js.map +0 -1
  152. package/dist/src/server/pairing-qr.js +0 -45
  153. package/dist/src/server/pairing-qr.js.map +0 -1
  154. package/dist/src/server/path-utils.js +0 -20
  155. package/dist/src/server/path-utils.js.map +0 -1
  156. package/dist/src/server/persisted-config.js +0 -265
  157. package/dist/src/server/persisted-config.js.map +0 -1
  158. package/dist/src/server/persistence-hooks.js +0 -60
  159. package/dist/src/server/persistence-hooks.js.map +0 -1
  160. package/dist/src/server/push/push-service.js +0 -68
  161. package/dist/src/server/push/push-service.js.map +0 -1
  162. package/dist/src/server/push/token-store.js +0 -70
  163. package/dist/src/server/push/token-store.js.map +0 -1
  164. package/dist/src/server/relay-transport.js +0 -461
  165. package/dist/src/server/relay-transport.js.map +0 -1
  166. package/dist/src/server/schedule/cron.js +0 -103
  167. package/dist/src/server/schedule/cron.js.map +0 -1
  168. package/dist/src/server/schedule/rpc-schemas.js +0 -112
  169. package/dist/src/server/schedule/rpc-schemas.js.map +0 -1
  170. package/dist/src/server/schedule/service.js +0 -397
  171. package/dist/src/server/schedule/service.js.map +0 -1
  172. package/dist/src/server/schedule/store.js +0 -56
  173. package/dist/src/server/schedule/store.js.map +0 -1
  174. package/dist/src/server/schedule/types.js +0 -73
  175. package/dist/src/server/schedule/types.js.map +0 -1
  176. package/dist/src/server/server-id.js +0 -63
  177. package/dist/src/server/server-id.js.map +0 -1
  178. package/dist/src/server/session.js +0 -6381
  179. package/dist/src/server/session.js.map +0 -1
  180. package/dist/src/server/speech/audio.js +0 -101
  181. package/dist/src/server/speech/audio.js.map +0 -1
  182. package/dist/src/server/speech/provider-resolver.js +0 -7
  183. package/dist/src/server/speech/provider-resolver.js.map +0 -1
  184. package/dist/src/server/speech/providers/local/config.js +0 -74
  185. package/dist/src/server/speech/providers/local/config.js.map +0 -1
  186. package/dist/src/server/speech/providers/local/models.js +0 -17
  187. package/dist/src/server/speech/providers/local/models.js.map +0 -1
  188. package/dist/src/server/speech/providers/local/pocket/pocket-tts-onnx.js +0 -436
  189. package/dist/src/server/speech/providers/local/pocket/pocket-tts-onnx.js.map +0 -1
  190. package/dist/src/server/speech/providers/local/runtime.js +0 -238
  191. package/dist/src/server/speech/providers/local/runtime.js.map +0 -1
  192. package/dist/src/server/speech/providers/local/sherpa/model-catalog.js +0 -166
  193. package/dist/src/server/speech/providers/local/sherpa/model-catalog.js.map +0 -1
  194. package/dist/src/server/speech/providers/local/sherpa/model-downloader.js +0 -165
  195. package/dist/src/server/speech/providers/local/sherpa/model-downloader.js.map +0 -1
  196. package/dist/src/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js +0 -73
  197. package/dist/src/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js.map +0 -1
  198. package/dist/src/server/speech/providers/local/sherpa/sherpa-online-recognizer.js +0 -84
  199. package/dist/src/server/speech/providers/local/sherpa/sherpa-online-recognizer.js.map +0 -1
  200. package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-loader.js +0 -11
  201. package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-loader.js.map +0 -1
  202. package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js +0 -102
  203. package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js.map +0 -1
  204. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js +0 -135
  205. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js.map +0 -1
  206. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js +0 -130
  207. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js.map +0 -1
  208. package/dist/src/server/speech/providers/local/sherpa/sherpa-realtime-session.js +0 -110
  209. package/dist/src/server/speech/providers/local/sherpa/sherpa-realtime-session.js.map +0 -1
  210. package/dist/src/server/speech/providers/local/sherpa/sherpa-stt.js +0 -138
  211. package/dist/src/server/speech/providers/local/sherpa/sherpa-stt.js.map +0 -1
  212. package/dist/src/server/speech/providers/local/sherpa/sherpa-tts.js +0 -98
  213. package/dist/src/server/speech/providers/local/sherpa/sherpa-tts.js.map +0 -1
  214. package/dist/src/server/speech/providers/local/sherpa/silero-vad-provider.js +0 -23
  215. package/dist/src/server/speech/providers/local/sherpa/silero-vad-provider.js.map +0 -1
  216. package/dist/src/server/speech/providers/local/sherpa/silero-vad-session.js +0 -107
  217. package/dist/src/server/speech/providers/local/sherpa/silero-vad-session.js.map +0 -1
  218. package/dist/src/server/speech/providers/openai/config.js +0 -80
  219. package/dist/src/server/speech/providers/openai/config.js.map +0 -1
  220. package/dist/src/server/speech/providers/openai/realtime-transcription-session.js +0 -168
  221. package/dist/src/server/speech/providers/openai/realtime-transcription-session.js.map +0 -1
  222. package/dist/src/server/speech/providers/openai/runtime.js +0 -112
  223. package/dist/src/server/speech/providers/openai/runtime.js.map +0 -1
  224. package/dist/src/server/speech/providers/openai/stt.js +0 -206
  225. package/dist/src/server/speech/providers/openai/stt.js.map +0 -1
  226. package/dist/src/server/speech/providers/openai/tts.js +0 -46
  227. package/dist/src/server/speech/providers/openai/tts.js.map +0 -1
  228. package/dist/src/server/speech/speech-config-resolver.js +0 -102
  229. package/dist/src/server/speech/speech-config-resolver.js.map +0 -1
  230. package/dist/src/server/speech/speech-provider.js +0 -2
  231. package/dist/src/server/speech/speech-provider.js.map +0 -1
  232. package/dist/src/server/speech/speech-runtime.js +0 -530
  233. package/dist/src/server/speech/speech-runtime.js.map +0 -1
  234. package/dist/src/server/speech/speech-types.js +0 -8
  235. package/dist/src/server/speech/speech-types.js.map +0 -1
  236. package/dist/src/server/speech/turn-detection-provider.js +0 -2
  237. package/dist/src/server/speech/turn-detection-provider.js.map +0 -1
  238. package/dist/src/server/utils/diff-highlighter.js +0 -257
  239. package/dist/src/server/utils/diff-highlighter.js.map +0 -1
  240. package/dist/src/server/voice/fixed-duration-pcm-ring-buffer.js +0 -35
  241. package/dist/src/server/voice/fixed-duration-pcm-ring-buffer.js.map +0 -1
  242. package/dist/src/server/voice/voice-turn-controller.js +0 -159
  243. package/dist/src/server/voice/voice-turn-controller.js.map +0 -1
  244. package/dist/src/server/voice-config.js +0 -51
  245. package/dist/src/server/voice-config.js.map +0 -1
  246. package/dist/src/server/voice-mcp-bridge-command.js +0 -31
  247. package/dist/src/server/voice-mcp-bridge-command.js.map +0 -1
  248. package/dist/src/server/voice-mcp-bridge.js +0 -109
  249. package/dist/src/server/voice-mcp-bridge.js.map +0 -1
  250. package/dist/src/server/voice-permission-policy.js +0 -13
  251. package/dist/src/server/voice-permission-policy.js.map +0 -1
  252. package/dist/src/server/voice-types.js +0 -2
  253. package/dist/src/server/voice-types.js.map +0 -1
  254. package/dist/src/server/websocket-server.js +0 -1048
  255. package/dist/src/server/websocket-server.js.map +0 -1
  256. package/dist/src/server/workspace-registry-bootstrap.js +0 -98
  257. package/dist/src/server/workspace-registry-bootstrap.js.map +0 -1
  258. package/dist/src/server/workspace-registry-model.js +0 -175
  259. package/dist/src/server/workspace-registry-model.js.map +0 -1
  260. package/dist/src/server/workspace-registry.js +0 -151
  261. package/dist/src/server/workspace-registry.js.map +0 -1
  262. package/dist/src/server/worktree-bootstrap.js +0 -508
  263. package/dist/src/server/worktree-bootstrap.js.map +0 -1
  264. package/dist/src/shared/agent-attention-notification.js +0 -130
  265. package/dist/src/shared/agent-attention-notification.js.map +0 -1
  266. package/dist/src/shared/agent-lifecycle.js +0 -8
  267. package/dist/src/shared/agent-lifecycle.js.map +0 -1
  268. package/dist/src/shared/connection-offer.js +0 -17
  269. package/dist/src/shared/connection-offer.js.map +0 -1
  270. package/dist/src/shared/daemon-endpoints.js +0 -122
  271. package/dist/src/shared/daemon-endpoints.js.map +0 -1
  272. package/dist/src/shared/messages.js +0 -2107
  273. package/dist/src/shared/messages.js.map +0 -1
  274. package/dist/src/shared/path-utils.js +0 -16
  275. package/dist/src/shared/path-utils.js.map +0 -1
  276. package/dist/src/shared/terminal-stream-protocol.js +0 -99
  277. package/dist/src/shared/terminal-stream-protocol.js.map +0 -1
  278. package/dist/src/shared/tool-call-display.js +0 -122
  279. package/dist/src/shared/tool-call-display.js.map +0 -1
  280. package/dist/src/terminal/terminal-manager.js +0 -136
  281. package/dist/src/terminal/terminal-manager.js.map +0 -1
  282. package/dist/src/terminal/terminal.js +0 -333
  283. package/dist/src/terminal/terminal.js.map +0 -1
  284. package/dist/src/utils/checkout-git.js +0 -1518
  285. package/dist/src/utils/checkout-git.js.map +0 -1
  286. package/dist/src/utils/directory-suggestions.js +0 -671
  287. package/dist/src/utils/directory-suggestions.js.map +0 -1
  288. package/dist/src/utils/path.js +0 -15
  289. package/dist/src/utils/path.js.map +0 -1
  290. package/dist/src/utils/project-icon.js +0 -389
  291. package/dist/src/utils/project-icon.js.map +0 -1
  292. package/dist/src/utils/worktree-metadata.js +0 -116
  293. package/dist/src/utils/worktree-metadata.js.map +0 -1
  294. package/dist/src/utils/worktree.js +0 -744
  295. package/dist/src/utils/worktree.js.map +0 -1
@@ -1,215 +0,0 @@
1
- function appendSeqToRanges(ranges, seq) {
2
- if (ranges.length === 0) {
3
- return [{ startSeq: seq, endSeq: seq }];
4
- }
5
- const next = [...ranges];
6
- const last = next[next.length - 1];
7
- if (!last) {
8
- return [{ startSeq: seq, endSeq: seq }];
9
- }
10
- if (seq <= last.endSeq + 1) {
11
- last.endSeq = Math.max(last.endSeq, seq);
12
- return next;
13
- }
14
- next.push({ startSeq: seq, endSeq: seq });
15
- return next;
16
- }
17
- function mergeSeqRanges(existing, incoming) {
18
- let merged = [...existing];
19
- for (const range of incoming) {
20
- for (let seq = range.startSeq; seq <= range.endSeq; seq += 1) {
21
- merged = appendSeqToRanges(merged, seq);
22
- }
23
- }
24
- return merged;
25
- }
26
- function mergeToolCallDetail(existing, incoming) {
27
- if (existing.type === "unknown" && incoming.type !== "unknown") {
28
- return incoming;
29
- }
30
- if (incoming.type === "unknown" && existing.type !== "unknown") {
31
- return existing;
32
- }
33
- return incoming;
34
- }
35
- function mergeToolCallItems(existing, incoming) {
36
- const mergedDetail = mergeToolCallDetail(existing.detail, incoming.detail);
37
- const mergedMetadata = existing.metadata || incoming.metadata
38
- ? { ...(existing.metadata ?? {}), ...(incoming.metadata ?? {}) }
39
- : undefined;
40
- const merged = {
41
- ...existing,
42
- ...incoming,
43
- detail: mergedDetail,
44
- metadata: mergedMetadata,
45
- };
46
- if (incoming.status === "failed") {
47
- merged.error = incoming.error;
48
- }
49
- else if (incoming.status === "completed" || incoming.status === "canceled") {
50
- merged.error = null;
51
- }
52
- else if (incoming.error !== undefined) {
53
- merged.error = incoming.error;
54
- }
55
- return merged;
56
- }
57
- function makeCanonicalEntries(rows, provider) {
58
- return rows.map((row) => ({
59
- provider,
60
- item: row.item,
61
- timestamp: row.timestamp,
62
- seqStart: row.seq,
63
- seqEnd: row.seq,
64
- sourceSeqRanges: [{ startSeq: row.seq, endSeq: row.seq }],
65
- collapsed: [],
66
- }));
67
- }
68
- function collapseToolLifecycle(entries) {
69
- const output = [];
70
- const toolIndexByCallId = new Map();
71
- for (const entry of entries) {
72
- if (entry.item.type !== "tool_call") {
73
- output.push(entry);
74
- continue;
75
- }
76
- const existingIndex = toolIndexByCallId.get(entry.item.callId);
77
- if (existingIndex === undefined) {
78
- toolIndexByCallId.set(entry.item.callId, output.length);
79
- output.push(entry);
80
- continue;
81
- }
82
- const existing = output[existingIndex];
83
- if (!existing || existing.item.type !== "tool_call") {
84
- output.push(entry);
85
- continue;
86
- }
87
- const mergedItem = mergeToolCallItems(existing.item, entry.item);
88
- const mergedRanges = mergeSeqRanges(existing.sourceSeqRanges, entry.sourceSeqRanges);
89
- const collapsed = existing.collapsed.includes("tool_lifecycle")
90
- ? existing.collapsed
91
- : [...existing.collapsed, "tool_lifecycle"];
92
- output[existingIndex] = {
93
- ...existing,
94
- item: mergedItem,
95
- seqEnd: Math.max(existing.seqEnd, entry.seqEnd),
96
- sourceSeqRanges: mergedRanges,
97
- collapsed,
98
- };
99
- }
100
- return output;
101
- }
102
- function mergeAssistantChunks(entries) {
103
- const output = [];
104
- for (const entry of entries) {
105
- const previous = output[output.length - 1];
106
- const shouldMerge = previous &&
107
- previous.item.type === "assistant_message" &&
108
- entry.item.type === "assistant_message" &&
109
- previous.seqEnd + 1 === entry.seqStart;
110
- if (!shouldMerge || !previous) {
111
- output.push(entry);
112
- continue;
113
- }
114
- const previousAssistant = previous.item;
115
- const entryAssistant = entry.item;
116
- const collapsedKinds = new Set([
117
- ...previous.collapsed,
118
- ...entry.collapsed,
119
- "assistant_merge",
120
- ]);
121
- output[output.length - 1] = {
122
- ...previous,
123
- item: {
124
- type: "assistant_message",
125
- text: `${previousAssistant.text}${entryAssistant.text}`,
126
- },
127
- seqEnd: entry.seqEnd,
128
- sourceSeqRanges: mergeSeqRanges(previous.sourceSeqRanges, entry.sourceSeqRanges),
129
- collapsed: Array.from(collapsedKinds),
130
- };
131
- }
132
- return output;
133
- }
134
- export function projectTimelineRows(rows, provider, mode) {
135
- const canonical = makeCanonicalEntries(rows, provider);
136
- if (mode === "canonical") {
137
- return canonical;
138
- }
139
- const toolCollapsed = collapseToolLifecycle(canonical);
140
- return mergeAssistantChunks(toolCollapsed);
141
- }
142
- /**
143
- * Select a timeline window based on projected-entry count, then map it back to
144
- * contiguous canonical rows. This avoids cutting through merged assistant
145
- * chunks when callers request canonical rows with a bounded limit.
146
- */
147
- export function selectTimelineWindowByProjectedLimit(input) {
148
- const { rows, provider, direction } = input;
149
- const limit = Math.max(0, Math.floor(input.limit));
150
- const collapseTools = input.collapseToolLifecycle ?? true;
151
- const canonical = makeCanonicalEntries(rows, provider);
152
- const projectedAll = mergeAssistantChunks(collapseTools ? collapseToolLifecycle(canonical) : canonical);
153
- if (projectedAll.length === 0) {
154
- return {
155
- projectedEntries: [],
156
- selectedRows: [],
157
- minSeq: null,
158
- maxSeq: null,
159
- };
160
- }
161
- const projectedEntries = limit === 0 || limit >= projectedAll.length
162
- ? projectedAll
163
- : direction === "after"
164
- ? projectedAll.slice(0, limit)
165
- : projectedAll.slice(projectedAll.length - limit);
166
- if (projectedEntries.length === 0) {
167
- return {
168
- projectedEntries: [],
169
- selectedRows: [],
170
- minSeq: null,
171
- maxSeq: null,
172
- };
173
- }
174
- const computeWindowBounds = (entries) => {
175
- let minSeq = Number.POSITIVE_INFINITY;
176
- let maxSeq = Number.NEGATIVE_INFINITY;
177
- for (const entry of entries) {
178
- if (entry.seqStart < minSeq) {
179
- minSeq = entry.seqStart;
180
- }
181
- if (entry.seqEnd > maxSeq) {
182
- maxSeq = entry.seqEnd;
183
- }
184
- }
185
- return { minSeq, maxSeq };
186
- };
187
- let { minSeq, maxSeq } = computeWindowBounds(projectedEntries);
188
- let expandedEntries = projectedEntries;
189
- if (collapseTools) {
190
- // Expand to include any projected entries that overlap the selected
191
- // canonical range. Tool lifecycle collapse can produce non-monotonic
192
- // seqEnd values, which would otherwise create cursor gaps.
193
- for (let iteration = 0; iteration < projectedAll.length + 1; iteration += 1) {
194
- const overlapping = projectedAll.filter((entry) => entry.seqStart <= maxSeq && entry.seqEnd >= minSeq);
195
- const nextBounds = computeWindowBounds(overlapping);
196
- if (overlapping.length === expandedEntries.length &&
197
- nextBounds.minSeq === minSeq &&
198
- nextBounds.maxSeq === maxSeq) {
199
- expandedEntries = overlapping;
200
- break;
201
- }
202
- expandedEntries = overlapping;
203
- minSeq = nextBounds.minSeq;
204
- maxSeq = nextBounds.maxSeq;
205
- }
206
- }
207
- const selectedRows = rows.filter((row) => row.seq >= minSeq && row.seq <= maxSeq);
208
- return {
209
- projectedEntries: expandedEntries,
210
- selectedRows,
211
- minSeq: Number.isFinite(minSeq) ? minSeq : null,
212
- maxSeq: Number.isFinite(maxSeq) ? maxSeq : null,
213
- };
214
- }
215
- //# sourceMappingURL=timeline-projection.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"timeline-projection.js","sourceRoot":"","sources":["../../../../src/server/agent/timeline-projection.ts"],"names":[],"mappings":"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"}
@@ -1,45 +0,0 @@
1
- const TOOL_TOKEN_REGEX = /[a-z0-9]+/g;
2
- const STANDARD_NAMESPACE_SEPARATOR_REGEX = /[.:/]/;
3
- export function normalizeToolName(name) {
4
- return name.trim().toLowerCase();
5
- }
6
- export function tokenizeToolName(name) {
7
- const normalized = normalizeToolName(name);
8
- return normalized.match(TOOL_TOKEN_REGEX) ?? [];
9
- }
10
- export function getToolLeafName(name) {
11
- const tokens = tokenizeToolName(name);
12
- return tokens.length > 0 ? tokens[tokens.length - 1] : null;
13
- }
14
- export function isSpeakToolName(name) {
15
- return getToolLeafName(name) === "speak";
16
- }
17
- export function isLikelyNamespacedToolName(name) {
18
- const normalized = normalizeToolName(name);
19
- if (STANDARD_NAMESPACE_SEPARATOR_REGEX.test(normalized)) {
20
- return true;
21
- }
22
- if (!normalized.includes("__")) {
23
- return false;
24
- }
25
- // Keep `__` handling strict to avoid false positives on arbitrary custom names.
26
- const segments = normalized.split("__").filter((segment) => segment.length > 0);
27
- if (segments.length >= 3) {
28
- return true;
29
- }
30
- if (segments.length === 2 && segments[1].includes("_")) {
31
- return true;
32
- }
33
- return false;
34
- }
35
- export function isLikelyExternalToolName(name) {
36
- const normalized = normalizeToolName(name);
37
- if (!normalized) {
38
- return false;
39
- }
40
- if (isSpeakToolName(normalized)) {
41
- return true;
42
- }
43
- return isLikelyNamespacedToolName(normalized);
44
- }
45
- //# sourceMappingURL=tool-name-normalization.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tool-name-normalization.js","sourceRoot":"","sources":["../../../../src/server/agent/tool-name-normalization.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB,GAAG,YAAY,CAAC;AACtC,MAAM,kCAAkC,GAAG,OAAO,CAAC;AAEnD,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC3C,OAAO,UAAU,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,eAAe,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,IAAY;IACrD,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,kCAAkC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,gFAAgF;IAChF,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChF,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,0BAA0B,CAAC,UAAU,CAAC,CAAC;AAChD,CAAC"}
@@ -1,24 +0,0 @@
1
- import { mkdir, writeFile } from "fs/promises";
2
- import { join } from "path";
3
- import { inferAudioExtension, sanitizeForFilename } from "./audio-utils.js";
4
- import { resolveRecordingsDebugDir } from "./recordings-debug.js";
5
- const debugDir = resolveRecordingsDebugDir("TTS_DEBUG_AUDIO_DIR");
6
- let announced = false;
7
- export async function maybePersistTtsDebugAudio(audio, metadata, logger) {
8
- if (!debugDir) {
9
- return null;
10
- }
11
- if (!announced) {
12
- logger.info({ debugDir }, "TTS audio capture enabled");
13
- announced = true;
14
- }
15
- const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
16
- const folder = join(debugDir, sanitizeForFilename(metadata.sessionId, "session"));
17
- await mkdir(folder, { recursive: true });
18
- const parts = [timestamp, sanitizeForFilename(metadata.groupId, "tts")];
19
- const ext = inferAudioExtension(metadata.format);
20
- const filePath = join(folder, `${parts.join("_")}.${ext}`);
21
- await writeFile(filePath, audio);
22
- return filePath;
23
- }
24
- //# sourceMappingURL=tts-debug.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tts-debug.js","sourceRoot":"","sources":["../../../../src/server/agent/tts-debug.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAElE,MAAM,QAAQ,GAAG,yBAAyB,CAAC,qBAAqB,CAAC,CAAC;AAClE,IAAI,SAAS,GAAG,KAAK,CAAC;AAQtB,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,KAAa,EACb,QAA+B,EAC/B,MAAmB;IAEnB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,2BAA2B,CAAC,CAAC;QACvD,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,mBAAmB,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;IAClF,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzC,MAAM,KAAK,GAAG,CAAC,SAAS,EAAE,mBAAmB,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IACxE,MAAM,GAAG,GAAG,mBAAmB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IAC3D,MAAM,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACjC,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -1,374 +0,0 @@
1
- import { v4 as uuidv4 } from "uuid";
2
- import { toResolver } from "../speech/provider-resolver.js";
3
- const MAX_TTS_SEGMENT_CHARS = 260;
4
- const TTS_PREFETCH_SEGMENTS = 2;
5
- const CLOSED_AUDIO_ID_TTL_MS = 10000;
6
- function splitOversizedFragment(fragment, maxChars) {
7
- const trimmed = fragment.trim();
8
- if (!trimmed) {
9
- return [];
10
- }
11
- if (trimmed.length <= maxChars) {
12
- return [trimmed];
13
- }
14
- const clauseChunks = trimmed.split(/(?<=[,;:])\s+/);
15
- if (clauseChunks.length > 1) {
16
- const parts = [];
17
- let current = "";
18
- const pushCurrent = () => {
19
- const value = current.trim();
20
- if (value) {
21
- parts.push(value);
22
- }
23
- current = "";
24
- };
25
- for (const clause of clauseChunks) {
26
- const clauseText = clause.trim();
27
- if (!clauseText) {
28
- continue;
29
- }
30
- if (clauseText.length > maxChars) {
31
- pushCurrent();
32
- parts.push(...splitOversizedFragment(clauseText, maxChars));
33
- continue;
34
- }
35
- if (!current) {
36
- current = clauseText;
37
- continue;
38
- }
39
- const candidate = `${current} ${clauseText}`;
40
- if (candidate.length <= maxChars) {
41
- current = candidate;
42
- continue;
43
- }
44
- pushCurrent();
45
- current = clauseText;
46
- }
47
- pushCurrent();
48
- if (parts.length > 1 || parts[0] !== trimmed) {
49
- return parts;
50
- }
51
- }
52
- const parts = [];
53
- let remaining = trimmed;
54
- while (remaining.length > maxChars) {
55
- let idx = remaining.lastIndexOf(" ", maxChars);
56
- if (idx < Math.floor(maxChars * 0.5)) {
57
- idx = maxChars;
58
- }
59
- parts.push(remaining.slice(0, idx).trim());
60
- remaining = remaining.slice(idx).trim();
61
- }
62
- if (remaining.length > 0) {
63
- parts.push(remaining);
64
- }
65
- return parts;
66
- }
67
- function splitTextForTts(text) {
68
- const normalized = text.trim().replace(/\s+/g, " ");
69
- if (!normalized) {
70
- throw new Error("Cannot synthesize empty text");
71
- }
72
- const sentences = normalized.split(/(?<=[.!?])\s+/);
73
- const parts = [];
74
- let segmentIndex = 0;
75
- for (const sentence of sentences) {
76
- const fragments = splitOversizedFragment(sentence, MAX_TTS_SEGMENT_CHARS);
77
- for (const fragment of fragments) {
78
- parts.push({ index: segmentIndex, text: fragment });
79
- segmentIndex += 1;
80
- }
81
- }
82
- return parts;
83
- }
84
- /**
85
- * Per-session TTS manager
86
- * Handles TTS audio generation and playback confirmation tracking
87
- */
88
- export class TTSManager {
89
- constructor(sessionId, logger, tts) {
90
- this.pendingPlaybacks = new Map();
91
- this.recentlyClosedAudioIds = new Map();
92
- this.logger = logger.child({ module: "agent", component: "tts-manager", sessionId });
93
- this.resolveTts = toResolver(tts);
94
- }
95
- /**
96
- * Generate TTS audio, emit to client, and wait for playback confirmation
97
- * Returns a Promise that resolves when the client confirms playback completed
98
- */
99
- async generateAndWaitForPlayback(text, emitMessage, abortSignal, isVoiceMode) {
100
- const ttsStartMs = Date.now();
101
- this.logger.info({
102
- isVoiceMode,
103
- textLength: text.length,
104
- text,
105
- }, "TTS input text");
106
- const segments = splitTextForTts(text);
107
- this.logger.info({
108
- segmentCount: segments.length,
109
- segments: segments.map((s) => ({
110
- index: s.index,
111
- chars: s.text.length,
112
- text: s.text.slice(0, 80),
113
- })),
114
- }, `TTS split into ${segments.length} segment(s)`);
115
- const inflight = new Map();
116
- let nextSegmentToSchedule = 0;
117
- const scheduleNextSegments = () => {
118
- while (nextSegmentToSchedule < segments.length && inflight.size < TTS_PREFETCH_SEGMENTS) {
119
- const segment = segments[nextSegmentToSchedule];
120
- inflight.set(segment.index, this.scheduleSegmentSynthesis(segment, abortSignal));
121
- nextSegmentToSchedule += 1;
122
- }
123
- };
124
- scheduleNextSegments();
125
- try {
126
- for (const segment of segments) {
127
- if (abortSignal.aborted) {
128
- this.logger.debug("Aborted before emitting segmented audio");
129
- return;
130
- }
131
- const synthWaitStart = Date.now();
132
- const result = await inflight.get(segment.index);
133
- const synthWaitMs = Date.now() - synthWaitStart;
134
- inflight.delete(segment.index);
135
- scheduleNextSegments();
136
- if (result.kind === "aborted") {
137
- return;
138
- }
139
- if (result.kind === "error") {
140
- throw result.error;
141
- }
142
- this.logger.info({
143
- segmentIndex: segment.index,
144
- synthWaitMs,
145
- totalElapsedMs: Date.now() - ttsStartMs,
146
- chars: segment.text.length,
147
- }, `TTS segment ${segment.index} synthesis ready (waited ${synthWaitMs}ms, total ${Date.now() - ttsStartMs}ms)`);
148
- const emitStart = Date.now();
149
- await this.emitPreparedSegment({
150
- prepared: result.prepared,
151
- emitMessage,
152
- abortSignal,
153
- isVoiceMode,
154
- });
155
- this.logger.info({
156
- segmentIndex: segment.index,
157
- emitAndPlayMs: Date.now() - emitStart,
158
- totalElapsedMs: Date.now() - ttsStartMs,
159
- }, `TTS segment ${segment.index} playback confirmed (emit+play ${Date.now() - emitStart}ms, total ${Date.now() - ttsStartMs}ms)`);
160
- scheduleNextSegments();
161
- }
162
- }
163
- finally {
164
- this.cleanupPrefetchedSegments(inflight);
165
- this.logger.info({ totalMs: Date.now() - ttsStartMs }, `TTS generateAndWaitForPlayback done (${Date.now() - ttsStartMs}ms)`);
166
- }
167
- }
168
- async synthesizeSegment(segment, abortSignal) {
169
- const resolveStart = Date.now();
170
- const tts = this.resolveTts();
171
- if (!tts) {
172
- throw new Error("TTS not configured");
173
- }
174
- const resolveMs = Date.now() - resolveStart;
175
- if (abortSignal.aborted) {
176
- throw new Error("TTS synthesis aborted");
177
- }
178
- const synthStart = Date.now();
179
- const { stream, format } = await tts.synthesizeSpeech(segment.text);
180
- this.logger.info({
181
- segmentIndex: segment.index,
182
- resolveMs,
183
- synthMs: Date.now() - synthStart,
184
- chars: segment.text.length,
185
- }, `TTS segment ${segment.index} synthesized (resolve=${resolveMs}ms, synth=${Date.now() - synthStart}ms, ${segment.text.length} chars)`);
186
- if (abortSignal.aborted) {
187
- this.destroySpeechStream(stream);
188
- throw new Error("TTS synthesis aborted");
189
- }
190
- return {
191
- ...segment,
192
- stream,
193
- format,
194
- };
195
- }
196
- scheduleSegmentSynthesis(segment, abortSignal) {
197
- return this.synthesizeSegment(segment, abortSignal).then((prepared) => {
198
- if (abortSignal.aborted) {
199
- this.destroySpeechStream(prepared.stream);
200
- return { kind: "aborted" };
201
- }
202
- return { kind: "prepared", prepared };
203
- }, (error) => {
204
- if (abortSignal.aborted) {
205
- return { kind: "aborted" };
206
- }
207
- return { kind: "error", error };
208
- });
209
- }
210
- cleanupPrefetchedSegments(inflight) {
211
- if (inflight.size === 0) {
212
- return;
213
- }
214
- for (const pending of inflight.values()) {
215
- void pending.then((result) => {
216
- if (result.kind === "prepared") {
217
- this.destroySpeechStream(result.prepared.stream);
218
- }
219
- });
220
- }
221
- }
222
- destroySpeechStream(stream) {
223
- if (typeof stream.destroy === "function" && !stream.destroyed) {
224
- stream.destroy();
225
- }
226
- }
227
- pruneRecentlyClosedAudioIds(now) {
228
- for (const [audioId, expiresAt] of this.recentlyClosedAudioIds.entries()) {
229
- if (expiresAt <= now) {
230
- this.recentlyClosedAudioIds.delete(audioId);
231
- }
232
- }
233
- }
234
- rememberClosedAudioId(audioId) {
235
- const now = Date.now();
236
- this.pruneRecentlyClosedAudioIds(now);
237
- this.recentlyClosedAudioIds.set(audioId, now + CLOSED_AUDIO_ID_TTL_MS);
238
- }
239
- async emitPreparedSegment(params) {
240
- const { prepared, emitMessage, abortSignal, isVoiceMode } = params;
241
- const { stream, format, text } = prepared;
242
- const audioId = uuidv4();
243
- let playbackResolve;
244
- let playbackReject;
245
- const playbackPromise = new Promise((resolve, reject) => {
246
- playbackResolve = resolve;
247
- playbackReject = reject;
248
- });
249
- const pendingPlayback = {
250
- resolve: playbackResolve,
251
- reject: playbackReject,
252
- pendingChunks: 0,
253
- streamEnded: false,
254
- };
255
- this.pendingPlaybacks.set(audioId, pendingPlayback);
256
- let onAbort;
257
- onAbort = () => {
258
- this.logger.debug("Aborted while waiting for playback");
259
- pendingPlayback.streamEnded = true;
260
- pendingPlayback.pendingChunks = 0;
261
- this.pendingPlaybacks.delete(audioId);
262
- this.rememberClosedAudioId(audioId);
263
- playbackResolve();
264
- this.destroySpeechStream(stream);
265
- };
266
- abortSignal.addEventListener("abort", onAbort, { once: true });
267
- try {
268
- const buffers = [];
269
- for await (const chunk of stream) {
270
- if (abortSignal.aborted) {
271
- this.logger.debug("Aborted during stream collection");
272
- break;
273
- }
274
- buffers.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
275
- }
276
- if (!abortSignal.aborted && buffers.length > 0) {
277
- const fullBuffer = Buffer.concat(buffers);
278
- const chunkId = `${audioId}:0`;
279
- pendingPlayback.pendingChunks = 1;
280
- emitMessage({
281
- type: "audio_output",
282
- payload: {
283
- id: chunkId,
284
- groupId: audioId,
285
- chunkIndex: 0,
286
- isLastChunk: true,
287
- audio: fullBuffer.toString("base64"),
288
- format,
289
- isVoiceMode,
290
- },
291
- });
292
- }
293
- pendingPlayback.streamEnded = true;
294
- if (pendingPlayback.pendingChunks === 0) {
295
- this.pendingPlaybacks.delete(audioId);
296
- this.rememberClosedAudioId(audioId);
297
- playbackResolve();
298
- }
299
- await playbackPromise;
300
- }
301
- catch (error) {
302
- if (abortSignal.aborted) {
303
- this.logger.debug("Audio stream closed after abort");
304
- }
305
- else {
306
- this.logger.error({ err: error }, "Error streaming audio");
307
- this.pendingPlaybacks.delete(audioId);
308
- throw error;
309
- }
310
- }
311
- finally {
312
- if (onAbort) {
313
- abortSignal.removeEventListener("abort", onAbort);
314
- }
315
- this.destroySpeechStream(stream);
316
- }
317
- if (abortSignal.aborted) {
318
- return;
319
- }
320
- this.logger.debug({ audioId, textLength: text.length }, "Audio playback confirmed");
321
- }
322
- /**
323
- * Called when client confirms audio playback completed
324
- * Resolves the corresponding promise
325
- */
326
- confirmAudioPlayed(chunkId) {
327
- const [audioId] = chunkId.includes(":") ? chunkId.split(":") : [chunkId];
328
- const pending = this.pendingPlaybacks.get(audioId);
329
- if (!pending) {
330
- const now = Date.now();
331
- this.pruneRecentlyClosedAudioIds(now);
332
- const expiresAt = this.recentlyClosedAudioIds.get(audioId);
333
- if (expiresAt && expiresAt > now) {
334
- this.logger.debug({ chunkId }, "Ignoring late confirmation for recently closed audio ID");
335
- return;
336
- }
337
- this.logger.warn({ chunkId }, "Received confirmation for unknown audio ID");
338
- return;
339
- }
340
- pending.pendingChunks = Math.max(0, pending.pendingChunks - 1);
341
- if (pending.pendingChunks === 0 && pending.streamEnded) {
342
- pending.resolve();
343
- this.pendingPlaybacks.delete(audioId);
344
- this.rememberClosedAudioId(audioId);
345
- }
346
- }
347
- /**
348
- * Cancel all pending playbacks (e.g., user interrupted audio)
349
- */
350
- cancelPendingPlaybacks(reason) {
351
- if (this.pendingPlaybacks.size === 0) {
352
- return;
353
- }
354
- this.logger.debug({ count: this.pendingPlaybacks.size, reason }, "Cancelling pending playbacks");
355
- for (const [audioId, pending] of this.pendingPlaybacks.entries()) {
356
- pending.resolve();
357
- this.pendingPlaybacks.delete(audioId);
358
- this.rememberClosedAudioId(audioId);
359
- this.logger.debug({ audioId }, "Cleared pending playback");
360
- }
361
- }
362
- /**
363
- * Cleanup all pending playbacks
364
- */
365
- cleanup() {
366
- // Reject all pending playbacks
367
- for (const [audioId, pending] of this.pendingPlaybacks.entries()) {
368
- pending.reject(new Error("Session closed"));
369
- this.pendingPlaybacks.delete(audioId);
370
- this.rememberClosedAudioId(audioId);
371
- }
372
- }
373
- }
374
- //# sourceMappingURL=tts-manager.js.map