@sumicom/quicksave 0.8.14 → 0.8.15

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 (87) hide show
  1. package/dist/ai/cardBuilder.d.ts +21 -2
  2. package/dist/ai/cardBuilder.d.ts.map +1 -1
  3. package/dist/ai/cardBuilder.js +100 -6
  4. package/dist/ai/cardBuilder.js.map +1 -1
  5. package/dist/ai/claudeCliProvider.d.ts +25 -2
  6. package/dist/ai/claudeCliProvider.d.ts.map +1 -1
  7. package/dist/ai/claudeCliProvider.js +76 -19
  8. package/dist/ai/claudeCliProvider.js.map +1 -1
  9. package/dist/ai/codexAppServer/cardAdapter.d.ts.map +1 -1
  10. package/dist/ai/codexAppServer/cardAdapter.js +87 -7
  11. package/dist/ai/codexAppServer/cardAdapter.js.map +1 -1
  12. package/dist/ai/codexAppServer/provider.d.ts +3 -0
  13. package/dist/ai/codexAppServer/provider.d.ts.map +1 -1
  14. package/dist/ai/codexAppServer/provider.js +15 -4
  15. package/dist/ai/codexAppServer/provider.js.map +1 -1
  16. package/dist/ai/codexMcpProvider.d.ts.map +1 -1
  17. package/dist/ai/codexMcpProvider.js +6 -0
  18. package/dist/ai/codexMcpProvider.js.map +1 -1
  19. package/dist/ai/provider.d.ts +3 -0
  20. package/dist/ai/provider.d.ts.map +1 -1
  21. package/dist/ai/provider.js.map +1 -1
  22. package/dist/ai/queuedUserPrompts.d.ts +6 -0
  23. package/dist/ai/queuedUserPrompts.d.ts.map +1 -1
  24. package/dist/ai/queuedUserPrompts.js +9 -0
  25. package/dist/ai/queuedUserPrompts.js.map +1 -1
  26. package/dist/ai/realtimeTranscription.d.ts +2 -0
  27. package/dist/ai/realtimeTranscription.d.ts.map +1 -1
  28. package/dist/ai/realtimeTranscription.js +14 -0
  29. package/dist/ai/realtimeTranscription.js.map +1 -1
  30. package/dist/ai/sessionManager.d.ts +12 -0
  31. package/dist/ai/sessionManager.d.ts.map +1 -1
  32. package/dist/ai/sessionManager.js +73 -12
  33. package/dist/ai/sessionManager.js.map +1 -1
  34. package/dist/ai/voiceIntermediary/historyStore.d.ts +54 -0
  35. package/dist/ai/voiceIntermediary/historyStore.d.ts.map +1 -0
  36. package/dist/ai/voiceIntermediary/historyStore.js +159 -0
  37. package/dist/ai/voiceIntermediary/historyStore.js.map +1 -0
  38. package/dist/ai/voiceIntermediary/index.d.ts +13 -0
  39. package/dist/ai/voiceIntermediary/index.d.ts.map +1 -0
  40. package/dist/ai/voiceIntermediary/index.js +13 -0
  41. package/dist/ai/voiceIntermediary/index.js.map +1 -0
  42. package/dist/ai/voiceIntermediary/llm.d.ts +52 -0
  43. package/dist/ai/voiceIntermediary/llm.d.ts.map +1 -0
  44. package/dist/ai/voiceIntermediary/llm.js +63 -0
  45. package/dist/ai/voiceIntermediary/llm.js.map +1 -0
  46. package/dist/ai/voiceIntermediary/manager.d.ts +58 -0
  47. package/dist/ai/voiceIntermediary/manager.d.ts.map +1 -0
  48. package/dist/ai/voiceIntermediary/manager.js +134 -0
  49. package/dist/ai/voiceIntermediary/manager.js.map +1 -0
  50. package/dist/ai/voiceIntermediary/memory.d.ts +22 -0
  51. package/dist/ai/voiceIntermediary/memory.d.ts.map +1 -0
  52. package/dist/ai/voiceIntermediary/memory.js +109 -0
  53. package/dist/ai/voiceIntermediary/memory.js.map +1 -0
  54. package/dist/ai/voiceIntermediary/session.d.ts +81 -0
  55. package/dist/ai/voiceIntermediary/session.d.ts.map +1 -0
  56. package/dist/ai/voiceIntermediary/session.js +567 -0
  57. package/dist/ai/voiceIntermediary/session.js.map +1 -0
  58. package/dist/ai/voiceIntermediary/tools.d.ts +58 -0
  59. package/dist/ai/voiceIntermediary/tools.d.ts.map +1 -0
  60. package/dist/ai/voiceIntermediary/tools.js +277 -0
  61. package/dist/ai/voiceIntermediary/tools.js.map +1 -0
  62. package/dist/ai/voiceIntermediary/tts.d.ts +28 -0
  63. package/dist/ai/voiceIntermediary/tts.d.ts.map +1 -0
  64. package/dist/ai/voiceIntermediary/tts.js +66 -0
  65. package/dist/ai/voiceIntermediary/tts.js.map +1 -0
  66. package/dist/ai/voiceLog.d.ts +18 -0
  67. package/dist/ai/voiceLog.d.ts.map +1 -0
  68. package/dist/ai/voiceLog.js +74 -0
  69. package/dist/ai/voiceLog.js.map +1 -0
  70. package/dist/ai/voiceStream.d.ts +5 -0
  71. package/dist/ai/voiceStream.d.ts.map +1 -1
  72. package/dist/ai/voiceStream.js +29 -5
  73. package/dist/ai/voiceStream.js.map +1 -1
  74. package/dist/handlers/legacyBusAdapter.d.ts.map +1 -1
  75. package/dist/handlers/legacyBusAdapter.js +8 -0
  76. package/dist/handlers/legacyBusAdapter.js.map +1 -1
  77. package/dist/handlers/messageHandler.d.ts +14 -0
  78. package/dist/handlers/messageHandler.d.ts.map +1 -1
  79. package/dist/handlers/messageHandler.js +150 -1
  80. package/dist/handlers/messageHandler.js.map +1 -1
  81. package/dist/index.js +2 -2
  82. package/dist/service/ipcClient.js +1 -1
  83. package/dist/service/run.d.ts.map +1 -1
  84. package/dist/service/run.js +14 -1
  85. package/dist/service/run.js.map +1 -1
  86. package/dist/service/types.js +1 -1
  87. package/package.json +3 -3
@@ -0,0 +1,567 @@
1
+ // SPDX-FileCopyrightText: 2026 King Young Technology
2
+ // SPDX-License-Identifier: MIT
3
+ import { chatCompletion } from './llm.js';
4
+ import { synthesizeSpeech } from './tts.js';
5
+ import { VOICE_AGENT_TOOLS, executeTool, formatCardForBrain } from './tools.js';
6
+ import { loadMemory } from './memory.js';
7
+ import { voiceEventLogger } from '../voiceLog.js';
8
+ import { VoiceHistoryStore } from './historyStore.js';
9
+ /** Upper bound on tool round-trips per utterance — a runaway-loop backstop. */
10
+ const MAX_TOOL_TURNS = 6;
11
+ const LIVE_CARD_CAP = 30;
12
+ const VOICE_HISTORY_MAX_MESSAGES = 80;
13
+ const VOICE_HISTORY_KEEP_MESSAGES = 40;
14
+ const VOICE_COMPACTION_SUMMARY_CHARS = 4000;
15
+ export class VoiceIntermediarySession {
16
+ sessionId;
17
+ cwd;
18
+ config;
19
+ bridge;
20
+ cb;
21
+ fetchImpl;
22
+ history;
23
+ messages = [];
24
+ systemPrompt = '';
25
+ ready;
26
+ /** Serializes turns so overlapping utterances don't interleave tool calls. */
27
+ chain = Promise.resolve();
28
+ closed = false;
29
+ /** Set after a provider clearly rejects the TTS endpoint; keep later turns text-only. */
30
+ ttsUnavailableReason = '';
31
+ /** Passive mirror of the coding agent's newest live card stream. */
32
+ liveCards = new Map();
33
+ liveNotes = [];
34
+ pendingPlaybackNote = '';
35
+ constructor(opts) {
36
+ this.sessionId = opts.sessionId;
37
+ this.cwd = opts.cwd;
38
+ this.config = opts.config;
39
+ this.bridge = opts.bridge;
40
+ this.cb = opts.callbacks;
41
+ this.fetchImpl = opts.fetchImpl;
42
+ this.history = opts.historyStore ?? new VoiceHistoryStore(this.sessionId);
43
+ this.ready = this.init();
44
+ }
45
+ /** Refresh config (e.g. user changed model/voice) without losing history. */
46
+ updateConfig(config, cwd) {
47
+ this.config = config;
48
+ if (cwd)
49
+ this.cwd = cwd;
50
+ this.ttsUnavailableReason = '';
51
+ }
52
+ /** True when a brain model is configured, i.e. the agent can actually respond. */
53
+ hasBrain() {
54
+ return !!this.config.agentModel?.trim();
55
+ }
56
+ async init() {
57
+ const [memory, restored] = await Promise.all([
58
+ loadMemory(this.cwd).catch(() => ''),
59
+ this.history.restore(),
60
+ ]);
61
+ this.systemPrompt = buildSystemPrompt(memory);
62
+ this.messages = [{ role: 'system', content: this.systemPrompt }];
63
+ if (restored.compactionSummary) {
64
+ this.messages.push({ role: 'system', content: buildCompactionMessage(restored.compactionSummary) });
65
+ }
66
+ this.messages.push(...restored.activeMessages);
67
+ }
68
+ /** Handle a final user utterance (STT transcript). Serialized per session. */
69
+ handleUtterance(text, meta = {}) {
70
+ const run = this.chain.then(() => this.runTurn({ role: 'user', content: text }, meta));
71
+ // Swallow errors on the chain so one failed turn doesn't poison the next.
72
+ this.chain = run.catch(() => undefined);
73
+ return run;
74
+ }
75
+ /** Proactively wake the agent on a coding-side event (e.g. permission pending). */
76
+ notify(systemNote) {
77
+ const run = this.chain.then(() => this.runTurn({ role: 'user', content: `(系統事件)${systemNote}` }));
78
+ this.chain = run.catch(() => undefined);
79
+ return run;
80
+ }
81
+ /** Wake the voice brain when the coding agent finishes a turn. The brain may no-op. */
82
+ notifyCodingTurnEnded(result) {
83
+ const state = result.interrupted
84
+ ? '已中斷'
85
+ : result.success === false
86
+ ? '失敗'
87
+ : '已完成';
88
+ const details = [
89
+ result.error ? `錯誤:${result.error}` : '',
90
+ result.totalCostUsd != null ? `成本:${result.totalCostUsd}` : '',
91
+ ].filter(Boolean).join(';');
92
+ const run = this.chain.then(() => this.runTurn({
93
+ role: 'user',
94
+ content: `(系統事件)coding agent 這一回合${state}${details ? `。${details}` : ''}。` +
95
+ '請檢查最新 live cards / read_cards。若有使用者正在等待的答案、完成結果、錯誤、阻塞或需要確認,請用一句話主動告知。' +
96
+ '若沒有值得打擾使用者的新資訊,請 no-op:回覆空內容且不要呼叫任何工具。',
97
+ }));
98
+ this.chain = run.catch(() => undefined);
99
+ return run;
100
+ }
101
+ close() {
102
+ this.closed = true;
103
+ void this.history.flush();
104
+ }
105
+ /** Passively record coding-agent card updates. Does not wake or interrupt the voice LLM. */
106
+ recordCardEvent(event) {
107
+ if (event.sessionId !== this.sessionId)
108
+ return;
109
+ switch (event.type) {
110
+ case 'add':
111
+ this.liveCards.set(event.card.id, { ...event.card });
112
+ break;
113
+ case 'append_text': {
114
+ const card = this.liveCards.get(event.cardId);
115
+ if (card && 'text' in card) {
116
+ this.liveCards.set(event.cardId, { ...card, text: `${card.text}${event.text}` });
117
+ }
118
+ break;
119
+ }
120
+ case 'update': {
121
+ const card = this.liveCards.get(event.cardId);
122
+ if (!card)
123
+ break;
124
+ const next = { ...card };
125
+ for (const [key, value] of Object.entries(event.patch)) {
126
+ if (value === null)
127
+ delete next[key];
128
+ else
129
+ next[key] = value;
130
+ }
131
+ this.liveCards.set(event.cardId, next);
132
+ break;
133
+ }
134
+ case 'remove':
135
+ this.liveCards.delete(event.cardId);
136
+ break;
137
+ }
138
+ this.trimLiveCards();
139
+ }
140
+ /** Record turn completion metadata without triggering a voice response. */
141
+ recordStreamEnd(result) {
142
+ if (result.sessionId !== this.sessionId)
143
+ return;
144
+ this.liveNotes.push(`[狀態] coding agent turn ${result.interrupted ? '已中斷' : '已完成'}`);
145
+ while (this.liveNotes.length > 5)
146
+ this.liveNotes.shift();
147
+ }
148
+ recordPlaybackEvent(event) {
149
+ if (event.sessionId !== this.sessionId)
150
+ return;
151
+ void this.history.appendRuntimeEvent(`playback.${event.event}`, {
152
+ turnId: event.turnId,
153
+ interactionId: event.interactionId,
154
+ utteranceId: event.utteranceId,
155
+ audioId: event.audioId,
156
+ reason: event.reason,
157
+ });
158
+ if (event.event === 'interrupted') {
159
+ this.pendingPlaybackNote =
160
+ '上一段語音回覆在播放中被使用者打斷;不要假設使用者已完整聽完那段回答。' +
161
+ '下一次回覆時,先接住使用者新的話,不要重複剛剛被打斷的內容,除非使用者要求。';
162
+ }
163
+ }
164
+ async runTurn(userMessage, meta = {}) {
165
+ await this.ready;
166
+ if (this.closed)
167
+ return;
168
+ const turnId = meta.turnId;
169
+ if (this.pendingPlaybackNote) {
170
+ const note = { role: 'system', content: `(播放狀態)${this.pendingPlaybackNote}` };
171
+ this.messages.push(note);
172
+ await this.history.appendChatMessage(note);
173
+ this.pendingPlaybackNote = '';
174
+ }
175
+ this.messages.push(userMessage);
176
+ await this.history.appendChatMessage(userMessage);
177
+ await this.history.appendRuntimeEvent('turn.start', {
178
+ turnId,
179
+ interactionId: meta.interactionId,
180
+ utteranceId: meta.utteranceId,
181
+ textChars: userMessage.content?.length ?? 0,
182
+ });
183
+ voiceEventLogger.log({
184
+ sessionId: this.sessionId,
185
+ event: 'voice_agent.turn.start',
186
+ phase: 'voice_agent',
187
+ turnId,
188
+ data: {
189
+ text: userMessage.content ?? '',
190
+ textChars: userMessage.content?.length ?? 0,
191
+ interactionId: meta.interactionId,
192
+ utteranceId: meta.utteranceId,
193
+ },
194
+ });
195
+ this.cb.emit({ kind: 'state', state: 'thinking' });
196
+ try {
197
+ for (let turn = 0; turn < MAX_TOOL_TURNS; turn++) {
198
+ const messages = this.messagesWithLiveContext();
199
+ const llmStarted = Date.now();
200
+ voiceEventLogger.log({
201
+ sessionId: this.sessionId,
202
+ event: 'llm.request',
203
+ phase: 'llm',
204
+ turnId,
205
+ data: {
206
+ model: this.config.agentModel,
207
+ messageCount: messages.length,
208
+ toolCount: VOICE_AGENT_TOOLS.length,
209
+ },
210
+ });
211
+ const result = await chatCompletion(this.config, {
212
+ messages,
213
+ tools: VOICE_AGENT_TOOLS,
214
+ fetchImpl: this.fetchImpl,
215
+ });
216
+ voiceEventLogger.log({
217
+ sessionId: this.sessionId,
218
+ event: 'llm.response',
219
+ phase: 'llm',
220
+ turnId,
221
+ data: {
222
+ durationMs: Date.now() - llmStarted,
223
+ text: result.content,
224
+ textChars: result.content.length,
225
+ toolCalls: result.toolCalls.map((call) => call.function.name),
226
+ },
227
+ });
228
+ if (this.closed)
229
+ return;
230
+ // Speak any narration the model produced this round (interim or final).
231
+ if (result.content)
232
+ await this.speak(result.content, meta);
233
+ const assistantMessage = {
234
+ role: 'assistant',
235
+ content: result.content || null,
236
+ ...(result.toolCalls.length ? { tool_calls: result.toolCalls } : {}),
237
+ };
238
+ this.messages.push(assistantMessage);
239
+ await this.history.appendChatMessage(assistantMessage);
240
+ if (result.toolCalls.length === 0)
241
+ break;
242
+ for (const call of result.toolCalls) {
243
+ const args = safeParseArgs(call.function.arguments);
244
+ const toolStarted = Date.now();
245
+ voiceEventLogger.log({
246
+ sessionId: this.sessionId,
247
+ event: 'tool.call',
248
+ phase: 'tool',
249
+ turnId,
250
+ data: { toolName: call.function.name, args },
251
+ });
252
+ const toolResult = await executeTool(call.function.name, args, {
253
+ sessionId: this.sessionId,
254
+ cwd: this.cwd,
255
+ bridge: this.bridge,
256
+ liveContext: this.liveContextForBrain(),
257
+ readVoiceHistory: (opts) => this.history.read(opts),
258
+ emitAction: (summary) => this.cb.emit({ kind: 'action', summary }),
259
+ });
260
+ voiceEventLogger.log({
261
+ sessionId: this.sessionId,
262
+ event: 'tool.result',
263
+ phase: 'tool',
264
+ turnId,
265
+ data: {
266
+ toolName: call.function.name,
267
+ durationMs: Date.now() - toolStarted,
268
+ result: toolResult,
269
+ resultChars: toolResult.length,
270
+ },
271
+ });
272
+ const toolMessage = { role: 'tool', tool_call_id: call.id, content: toolResult };
273
+ this.messages.push(toolMessage);
274
+ await this.history.appendChatMessage(toolMessage);
275
+ }
276
+ }
277
+ }
278
+ catch (err) {
279
+ voiceEventLogger.log({
280
+ sessionId: this.sessionId,
281
+ event: 'voice_agent.error',
282
+ phase: 'voice_agent',
283
+ level: 'error',
284
+ turnId,
285
+ data: { message: err.message },
286
+ });
287
+ this.cb.emit({ kind: 'error', message: err.message });
288
+ }
289
+ finally {
290
+ await this.maybeCompactHistory().catch((err) => {
291
+ console.error(`[voice-history] compaction failed session=${this.sessionId}:`, err);
292
+ });
293
+ await this.history.appendRuntimeEvent('turn.end', {
294
+ turnId,
295
+ interactionId: meta.interactionId,
296
+ utteranceId: meta.utteranceId,
297
+ });
298
+ voiceEventLogger.log({
299
+ sessionId: this.sessionId,
300
+ event: 'voice_agent.turn.end',
301
+ phase: 'voice_agent',
302
+ turnId,
303
+ });
304
+ if (!this.closed)
305
+ this.cb.emit({ kind: 'state', state: 'idle' });
306
+ }
307
+ }
308
+ async speak(text, meta = {}) {
309
+ const turnId = meta.turnId;
310
+ this.cb.emit({ kind: 'state', state: 'speaking' });
311
+ this.cb.emit({ kind: 'speech-text', text });
312
+ voiceEventLogger.log({
313
+ sessionId: this.sessionId,
314
+ event: 'speech.text',
315
+ phase: 'tts',
316
+ turnId,
317
+ data: { text, textChars: text.length, interactionId: meta.interactionId, utteranceId: meta.utteranceId },
318
+ });
319
+ if (this.ttsUnavailableReason) {
320
+ voiceEventLogger.log({
321
+ sessionId: this.sessionId,
322
+ event: 'tts.skipped',
323
+ phase: 'tts',
324
+ turnId,
325
+ data: { reason: this.ttsUnavailableReason, fallback: 'text_only' },
326
+ });
327
+ this.cb.emit({ kind: 'speak', audioId: '', text, mimeType: '' });
328
+ return;
329
+ }
330
+ try {
331
+ const ttsStarted = Date.now();
332
+ voiceEventLogger.log({
333
+ sessionId: this.sessionId,
334
+ event: 'tts.request',
335
+ phase: 'tts',
336
+ turnId,
337
+ data: {
338
+ model: this.config.ttsModel,
339
+ voice: this.config.ttsVoice,
340
+ textChars: text.length,
341
+ },
342
+ });
343
+ const speech = await synthesizeSpeech(this.config, text, { fetchImpl: this.fetchImpl });
344
+ if (this.closed)
345
+ return;
346
+ if (speech) {
347
+ const audioId = this.cb.storeAudio(speech.audio, speech.mimeType);
348
+ voiceEventLogger.log({
349
+ sessionId: this.sessionId,
350
+ event: 'tts.result',
351
+ phase: 'tts',
352
+ turnId,
353
+ data: {
354
+ durationMs: Date.now() - ttsStarted,
355
+ audioId,
356
+ audioBytes: speech.audio.length,
357
+ mimeType: speech.mimeType,
358
+ requestId: speech.requestId,
359
+ },
360
+ });
361
+ this.cb.emit({ kind: 'speak', audioId, text, mimeType: speech.mimeType });
362
+ }
363
+ else {
364
+ // No TTS configured — still surface the text so the PWA can render/voice it.
365
+ voiceEventLogger.log({
366
+ sessionId: this.sessionId,
367
+ event: 'tts.skipped',
368
+ phase: 'tts',
369
+ turnId,
370
+ data: { reason: 'no_tts_model', fallback: 'text_only' },
371
+ });
372
+ this.cb.emit({ kind: 'speak', audioId: '', text, mimeType: '' });
373
+ }
374
+ }
375
+ catch (err) {
376
+ // A TTS failure shouldn't kill the turn — show the text and only surface
377
+ // actionable errors. Unsupported endpoint 404s are common on chat-only
378
+ // OpenAI-compatible providers, so they silently downgrade to text-only.
379
+ this.cb.emit({ kind: 'speak', audioId: '', text, mimeType: '' });
380
+ const message = err.message;
381
+ const ttsErr = err;
382
+ voiceEventLogger.log({
383
+ sessionId: this.sessionId,
384
+ event: 'tts.error',
385
+ phase: 'tts',
386
+ level: 'error',
387
+ turnId,
388
+ data: {
389
+ model: this.config.ttsModel,
390
+ voice: this.config.ttsVoice,
391
+ status: ttsErr.status,
392
+ requestId: ttsErr.requestId,
393
+ message,
394
+ textChars: text.length,
395
+ fallback: 'text_only',
396
+ },
397
+ });
398
+ if (isUnsupportedTtsEndpoint(message)) {
399
+ this.ttsUnavailableReason = message;
400
+ this.cb.emit({ kind: 'action', summary: 'TTS endpoint unavailable; continuing text-only.' });
401
+ }
402
+ else {
403
+ this.cb.emit({ kind: 'error', message });
404
+ }
405
+ }
406
+ }
407
+ messagesWithLiveContext() {
408
+ const live = this.liveContextForBrain();
409
+ const messages = sanitizeMessagesForChatCompletion(this.messages);
410
+ if (!live)
411
+ return messages;
412
+ return [
413
+ ...messages,
414
+ {
415
+ role: 'system',
416
+ content: '以下是 coding agent 最新 live card/stream 更新,可能包含尚未完成的 streaming 輸出。' +
417
+ '這是被動上下文,不代表使用者要求你插話;只有在回答目前使用者問題時才引用。\n' +
418
+ live,
419
+ },
420
+ ];
421
+ }
422
+ liveContextForBrain() {
423
+ const lines = [
424
+ ...Array.from(this.liveCards.values()).map(formatCardForBrain).filter(Boolean),
425
+ ...this.liveNotes,
426
+ ];
427
+ return lines.slice(-12).join('\n');
428
+ }
429
+ trimLiveCards() {
430
+ while (this.liveCards.size > LIVE_CARD_CAP) {
431
+ const oldest = this.liveCards.keys().next().value;
432
+ if (!oldest)
433
+ break;
434
+ this.liveCards.delete(oldest);
435
+ }
436
+ }
437
+ async maybeCompactHistory() {
438
+ const historyMessages = this.messages.slice(1);
439
+ if (historyMessages.length <= VOICE_HISTORY_MAX_MESSAGES)
440
+ return;
441
+ const existingSummary = isCompactionMessage(historyMessages[0]) ? historyMessages[0].content ?? '' : '';
442
+ const modelMessages = isCompactionMessage(historyMessages[0]) ? historyMessages.slice(1) : historyMessages;
443
+ const keep = modelMessages.slice(-VOICE_HISTORY_KEEP_MESSAGES);
444
+ const dropped = modelMessages.slice(0, Math.max(0, modelMessages.length - keep.length));
445
+ if (dropped.length === 0)
446
+ return;
447
+ const summary = summarizeCompactedMessages(existingSummary, dropped);
448
+ const beforeSeq = this.history.latestSeq();
449
+ await this.history.appendCompactionBoundary(summary, beforeSeq, dropped.length);
450
+ for (const message of keep) {
451
+ await this.history.appendChatMessage(message);
452
+ }
453
+ this.messages = [
454
+ { role: 'system', content: this.systemPrompt },
455
+ { role: 'system', content: buildCompactionMessage(summary) },
456
+ ...keep,
457
+ ];
458
+ }
459
+ }
460
+ export function sanitizeMessagesForChatCompletion(messages) {
461
+ const out = [];
462
+ for (let i = 0; i < messages.length; i++) {
463
+ const message = messages[i];
464
+ if (message.role === 'tool')
465
+ continue;
466
+ if (message.role === 'assistant' && message.tool_calls?.length) {
467
+ const expectedIds = new Set(message.tool_calls.map((call) => call.id));
468
+ const toolMessages = [];
469
+ let j = i + 1;
470
+ for (; j < messages.length && messages[j]?.role === 'tool'; j++) {
471
+ const toolMessage = messages[j];
472
+ if (toolMessage.tool_call_id && expectedIds.has(toolMessage.tool_call_id)) {
473
+ toolMessages.push(toolMessage);
474
+ }
475
+ }
476
+ const seenIds = new Set(toolMessages.map((toolMessage) => toolMessage.tool_call_id));
477
+ const hasAllResults = message.tool_calls.every((call) => seenIds.has(call.id));
478
+ if (hasAllResults) {
479
+ out.push(message, ...toolMessages);
480
+ }
481
+ else {
482
+ out.push({
483
+ role: 'assistant',
484
+ content: message.content || '(先前有工具呼叫紀錄,但工具結果不完整,已略過細節。)',
485
+ });
486
+ }
487
+ i = j - 1;
488
+ continue;
489
+ }
490
+ out.push(message);
491
+ }
492
+ return out;
493
+ }
494
+ function isUnsupportedTtsEndpoint(message) {
495
+ return /Speech synthesis failed \(404\)/.test(message) || /Invalid URL .*audio\/speech/i.test(message);
496
+ }
497
+ function safeParseArgs(raw) {
498
+ try {
499
+ const parsed = JSON.parse(raw || '{}');
500
+ return parsed && typeof parsed === 'object' ? parsed : {};
501
+ }
502
+ catch {
503
+ return {};
504
+ }
505
+ }
506
+ export function buildSystemPrompt(memory) {
507
+ return [
508
+ '你是使用者的「AI 同事」,也是使用者正在直接對話與委派工作的 agent。',
509
+ '',
510
+ '身份呈現:',
511
+ '- 對使用者而言,你就是正在協助他的 agent,不是轉接員、PM、或第三方代理的旁白。',
512
+ '- 內部工具與 coding agent 是你的執行能力;不要說「我去叫 coding agent」、「我去問 Claude」、「後面的 agent」。',
513
+ '- 對使用者說「我來處理」、「我正在檢查」、「我會先修」、「我已經開始跑測試」。',
514
+ '- 只有在權限、安全、或不可逆操作需要確認時,才簡短說明具體動作,例如「這需要允許執行 npm test,要允許嗎?」。',
515
+ '',
516
+ '語言與風格:',
517
+ '- 一律用繁體中文(台灣用語)、口語、簡短地回覆;你的回覆文字會被唸出來給使用者聽。',
518
+ '- 漸進式揭露:預設只講 1 到 3 句,約 30 秒內可以唸完;需要細節時使用者會自己問。',
519
+ '- 篩選少量最重要資訊:完成了什麼、目前卡在哪裡、下一步是什麼。不要一次講完整背景。',
520
+ '- 絕不把長輸出、card、log、diff、測試輸出逐字唸出來;只摘要成口語結論。',
521
+ '- 不要唸檔名、hash、路徑、commit id、UUID、URL 參數、錯誤碼、程式碼片段;若重要,改成概念性描述。',
522
+ '- 如果有多個結果,最多講 3 點;每點一句。沒有值得告知的新資訊時就 no-op。',
523
+ '- 查詢類動作(讀卡片、查狀態)保持安靜,只有真正要告訴使用者的結論才開口。',
524
+ '- 你可以 no-op:當系統事件或 live card 沒有值得打擾使用者的新資訊時,回覆空內容且不要呼叫工具;這代表保持安靜。',
525
+ '',
526
+ '你能做的事(工具):',
527
+ '- send_to_coding_agent:把使用者的意思轉成內部執行指令;對使用者呈現為你正在處理。stop_coding_agent:停止目前工作。',
528
+ '- get_status / read_cards:掌握現況、詮釋目前工作進度。',
529
+ '- read_voice_history:查詢你自己的語音對話 JSONL 歷史,包含被壓縮移出目前 context window 的內容。',
530
+ '- respond_to_permission:回覆權限提示;set_permission_mode:調整自主度。',
531
+ '- remember:記住長期偏好/界線/專案常識。',
532
+ '',
533
+ '信任界線(重要):',
534
+ '- 引導(送 prompt)是可逆的,放手做。',
535
+ '- 不可逆的動作——回覆權限提示、放寬自主度——你「不自己決定」。先用講的說明它要做什麼並詢問使用者,取得明確的口頭同意後,才呼叫 respond_to_permission/set_permission_mode 把使用者的決定送出去。',
536
+ '- push、刪除、部署、對外送出這類,務必先取得清楚的口頭「好」。',
537
+ '',
538
+ '記憶:使用者講到「以後都…」「這專案不准…」「測試指令是…」這類長期規則時,用 remember 記下來。',
539
+ '',
540
+ memory
541
+ ? `以下是你已經記住的事,請遵守:\n\n${memory}`
542
+ : '(你目前還沒有記住任何事。)',
543
+ ].join('\n');
544
+ }
545
+ function buildCompactionMessage(summary) {
546
+ return `以下是較早語音對話的壓縮摘要;完整 JSONL 歷史可用 read_voice_history 查詢。\n${summary}`;
547
+ }
548
+ function isCompactionMessage(message) {
549
+ return message?.role === 'system' && typeof message.content === 'string' && message.content.startsWith('以下是較早語音對話的壓縮摘要');
550
+ }
551
+ function summarizeCompactedMessages(existingSummary, dropped) {
552
+ const lines = [
553
+ existingSummary.replace(/^以下是較早語音對話的壓縮摘要;完整 JSONL 歷史可用 read_voice_history 查詢。\n?/, '').trim(),
554
+ ...dropped.map((message) => `- ${message.role}: ${compactMessageText(message)}`),
555
+ ].filter(Boolean);
556
+ const text = lines.join('\n');
557
+ return text.length > VOICE_COMPACTION_SUMMARY_CHARS
558
+ ? `…${text.slice(-VOICE_COMPACTION_SUMMARY_CHARS)}`
559
+ : text;
560
+ }
561
+ function compactMessageText(message) {
562
+ const calls = message.tool_calls?.map((c) => `${c.function.name}(${c.function.arguments})`).join(' ') ?? '';
563
+ const text = [message.content ?? '', calls].filter(Boolean).join(' ');
564
+ const normalized = text.replace(/\s+/g, ' ').trim();
565
+ return normalized.length > 240 ? `${normalized.slice(0, 240)}…` : normalized;
566
+ }
567
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/ai/voiceIntermediary/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The voice intermediary's tool layer. Silent tools, mostly bound to EXISTING
3
+ * `SessionManager` methods (only `sendUserMessageToSession` is new) plus the
4
+ * workspace memory file. Speaking is NOT a tool — assistant text is synthesized
5
+ * by the session loop; tools are the silent actions the coworker can take.
6
+ *
7
+ * Trust boundary (the user picked "可下指令引導"): steering is free (reversible);
8
+ * irreversible moves — answering a permission prompt, widening autonomy — must
9
+ * only RELAY the user's explicit spoken decision. The schemas say so loudly; the
10
+ * loop additionally never invents a request id.
11
+ */
12
+ import type { Card, CardHistoryResponse, ClaudeUserInputRequestPayload, ClaudeUserInputResponsePayload } from '@sumicom/quicksave-shared';
13
+ import type { ToolSchema } from './llm.js';
14
+ import { type VoiceHistoryReadOptions, type VoiceHistoryEvent } from './historyStore.js';
15
+ /**
16
+ * The slice of `SessionManager` the tools depend on. `SessionManager`
17
+ * structurally satisfies this, but narrowing it keeps the tools unit-testable
18
+ * with a tiny fake.
19
+ */
20
+ export interface CodingSessionBridge {
21
+ sendUserMessageToSession(sessionId: string, prompt: string, opts?: {
22
+ interrupt?: boolean;
23
+ }): boolean;
24
+ interruptSession(sessionId: string): Promise<boolean>;
25
+ resolveUserInput(response: ClaudeUserInputResponsePayload): boolean;
26
+ setPermissionLevel(sessionId: string, level: string): Promise<boolean>;
27
+ getCards(sessionId: string, cwd: string, offset?: number, limit?: number): Promise<CardHistoryResponse>;
28
+ getPendingInputRequests(): ClaudeUserInputRequestPayload[];
29
+ getPermissionLevel(sessionId: string): string;
30
+ getActiveSessions(): Array<{
31
+ sessionId: string;
32
+ isStreaming?: boolean;
33
+ hasPendingInput?: boolean;
34
+ permissionMode?: string;
35
+ }>;
36
+ isStreaming(sessionId: string): boolean;
37
+ }
38
+ export interface VoiceToolContext {
39
+ sessionId: string;
40
+ cwd: string;
41
+ bridge: CodingSessionBridge;
42
+ /** Recent live card events already observed by the voice intermediary. */
43
+ liveContext?: string;
44
+ /** Read prior voice-agent JSONL history, including compacted context. */
45
+ readVoiceHistory?: (opts: VoiceHistoryReadOptions) => Promise<VoiceHistoryEvent[]>;
46
+ /** Narrate a side effect to the UI log (not spoken). */
47
+ emitAction: (summary: string) => void;
48
+ }
49
+ export declare const VOICE_AGENT_TOOLS: ToolSchema[];
50
+ /** One compact line per card for the brain to reason over (not for TTS). */
51
+ export declare function formatCardForBrain(card: Card): string;
52
+ /**
53
+ * Execute one tool call and return the string result fed back to the model.
54
+ * Never throws on expected failures (returns an explanatory string) so the loop
55
+ * keeps going; only programmer errors propagate.
56
+ */
57
+ export declare function executeTool(name: string, args: Record<string, unknown>, ctx: VoiceToolContext): Promise<string>;
58
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/ai/voiceIntermediary/tools.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EACV,IAAI,EACJ,mBAAmB,EACnB,6BAA6B,EAC7B,8BAA8B,EAC/B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAA2B,KAAK,uBAAuB,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAElH;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC;IACrG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,gBAAgB,CAAC,QAAQ,EAAE,8BAA8B,GAAG,OAAO,CAAC;IACpE,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvE,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACxG,uBAAuB,IAAI,6BAA6B,EAAE,CAAC;IAC3D,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9C,iBAAiB,IAAI,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,eAAe,CAAC,EAAE,OAAO,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7H,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;CACzC;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,mBAAmB,CAAC;IAC5B,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,uBAAuB,KAAK,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACnF,wDAAwD;IACxD,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,eAAO,MAAM,iBAAiB,EAAE,UAAU,EAkHzC,CAAC;AAkBF,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CA2BrD;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,MAAM,CAAC,CA6GjB"}