@machina.ai/cell-cli-core 1.40.1-rc2 → 1.41.1-rc1

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 (175) hide show
  1. package/dist/docs/AFTER_MERGE_PROMPT.md +1 -1
  2. package/dist/docs/changelogs/index.md +18 -0
  3. package/dist/docs/changelogs/latest.md +243 -255
  4. package/dist/docs/changelogs/preview.md +168 -18
  5. package/dist/docs/cli/sandbox.md +162 -45
  6. package/dist/docs/cli/settings.md +19 -13
  7. package/dist/docs/reference/configuration.md +77 -0
  8. package/dist/docs/reference/keyboard-shortcuts.md +1 -0
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.js +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/package.json +2 -1
  13. package/dist/src/agents/local-executor.js +8 -0
  14. package/dist/src/agents/local-executor.js.map +1 -1
  15. package/dist/src/agents/skill-extraction-agent.js +5 -4
  16. package/dist/src/agents/skill-extraction-agent.js.map +1 -1
  17. package/dist/src/agents/skill-extraction-agent.test.js +4 -2
  18. package/dist/src/agents/skill-extraction-agent.test.js.map +1 -1
  19. package/dist/src/agents/types.d.ts +2 -0
  20. package/dist/src/agents/types.js.map +1 -1
  21. package/dist/src/code_assist/server.js +16 -0
  22. package/dist/src/code_assist/server.js.map +1 -1
  23. package/dist/src/code_assist/server.test.js +18 -0
  24. package/dist/src/code_assist/server.test.js.map +1 -1
  25. package/dist/src/config/config.d.ts +6 -0
  26. package/dist/src/config/config.js +26 -8
  27. package/dist/src/config/config.js.map +1 -1
  28. package/dist/src/config/config.test.js +39 -1
  29. package/dist/src/config/config.test.js.map +1 -1
  30. package/dist/src/config/defaultModelConfigs.js +34 -0
  31. package/dist/src/config/defaultModelConfigs.js.map +1 -1
  32. package/dist/src/config/models.d.ts +3 -1
  33. package/dist/src/config/models.js +21 -4
  34. package/dist/src/config/models.js.map +1 -1
  35. package/dist/src/config/models.test.js +23 -1
  36. package/dist/src/config/models.test.js.map +1 -1
  37. package/dist/src/context/config/configLoader.d.ts +1 -2
  38. package/dist/src/context/config/configLoader.js +12 -7
  39. package/dist/src/context/config/configLoader.js.map +1 -1
  40. package/dist/src/context/config/configLoader.test.js +8 -12
  41. package/dist/src/context/config/configLoader.test.js.map +1 -1
  42. package/dist/src/context/config/profiles.d.ts +7 -1
  43. package/dist/src/context/config/profiles.js +46 -5
  44. package/dist/src/context/config/profiles.js.map +1 -1
  45. package/dist/src/context/contextManager.js +5 -3
  46. package/dist/src/context/contextManager.js.map +1 -1
  47. package/dist/src/context/eventBus.d.ts +7 -0
  48. package/dist/src/context/eventBus.js +6 -0
  49. package/dist/src/context/eventBus.js.map +1 -1
  50. package/dist/src/context/graph/builtinBehaviors.js +3 -3
  51. package/dist/src/context/graph/builtinBehaviors.js.map +1 -1
  52. package/dist/src/context/graph/mapper.d.ts +4 -2
  53. package/dist/src/context/graph/mapper.js +15 -3
  54. package/dist/src/context/graph/mapper.js.map +1 -1
  55. package/dist/src/context/graph/toGraph.d.ts +13 -2
  56. package/dist/src/context/graph/toGraph.js +88 -32
  57. package/dist/src/context/graph/toGraph.js.map +1 -1
  58. package/dist/src/context/historyObserver.d.ts +1 -0
  59. package/dist/src/context/historyObserver.js +25 -26
  60. package/dist/src/context/historyObserver.js.map +1 -1
  61. package/dist/src/context/initializer.d.ts +9 -0
  62. package/dist/src/context/initializer.js +75 -0
  63. package/dist/src/context/initializer.js.map +1 -0
  64. package/dist/src/context/pipeline/contextWorkingBuffer.js +12 -6
  65. package/dist/src/context/pipeline/contextWorkingBuffer.js.map +1 -1
  66. package/dist/src/context/pipeline/contextWorkingBuffer.test.js +1 -1
  67. package/dist/src/context/pipeline/environmentImpl.d.ts +3 -2
  68. package/dist/src/context/pipeline/environmentImpl.js +6 -3
  69. package/dist/src/context/pipeline/environmentImpl.js.map +1 -1
  70. package/dist/src/context/pipeline/environmentImpl.test.js +1 -1
  71. package/dist/src/context/pipeline/environmentImpl.test.js.map +1 -1
  72. package/dist/src/context/pipeline/orchestrator.js +5 -0
  73. package/dist/src/context/pipeline/orchestrator.js.map +1 -1
  74. package/dist/src/context/processors/toolMaskingProcessor.js +21 -5
  75. package/dist/src/context/processors/toolMaskingProcessor.js.map +1 -1
  76. package/dist/src/context/processors/toolMaskingProcessor.test.js +22 -0
  77. package/dist/src/context/processors/toolMaskingProcessor.test.js.map +1 -1
  78. package/dist/src/context/system-tests/lifecycle.golden.test.js +5 -0
  79. package/dist/src/context/system-tests/lifecycle.golden.test.js.map +1 -1
  80. package/dist/src/context/system-tests/simulationHarness.js +1 -1
  81. package/dist/src/context/system-tests/simulationHarness.js.map +1 -1
  82. package/dist/src/context/testing/contextTestUtils.js +7 -3
  83. package/dist/src/context/testing/contextTestUtils.js.map +1 -1
  84. package/dist/src/context/tracer.js +3 -1
  85. package/dist/src/context/tracer.js.map +1 -1
  86. package/dist/src/context/tracer.test.js +4 -2
  87. package/dist/src/context/tracer.test.js.map +1 -1
  88. package/dist/src/context/utils/contextTokenCalculator.d.ts +2 -1
  89. package/dist/src/context/utils/contextTokenCalculator.js +13 -11
  90. package/dist/src/context/utils/contextTokenCalculator.js.map +1 -1
  91. package/dist/src/core/client.d.ts +1 -0
  92. package/dist/src/core/client.js +9 -8
  93. package/dist/src/core/client.js.map +1 -1
  94. package/dist/src/core/client.test.js +0 -3
  95. package/dist/src/core/client.test.js.map +1 -1
  96. package/dist/src/core/geminiChat.d.ts +2 -1
  97. package/dist/src/core/geminiChat.js +72 -20
  98. package/dist/src/core/geminiChat.js.map +1 -1
  99. package/dist/src/core/geminiChat.test.js +1 -0
  100. package/dist/src/core/geminiChat.test.js.map +1 -1
  101. package/dist/src/core/geminiChat_network_retry.test.js +1 -0
  102. package/dist/src/core/geminiChat_network_retry.test.js.map +1 -1
  103. package/dist/src/core/tokenLimits.d.ts +1 -0
  104. package/dist/src/core/tokenLimits.js +5 -1
  105. package/dist/src/core/tokenLimits.js.map +1 -1
  106. package/dist/src/generated/git-commit.d.ts +2 -2
  107. package/dist/src/generated/git-commit.js +2 -2
  108. package/dist/src/index.d.ts +9 -1
  109. package/dist/src/index.js +10 -1
  110. package/dist/src/index.js.map +1 -1
  111. package/dist/src/policy/policy-engine.js +12 -7
  112. package/dist/src/policy/policy-engine.js.map +1 -1
  113. package/dist/src/policy/policy-engine.test.js +69 -1
  114. package/dist/src/policy/policy-engine.test.js.map +1 -1
  115. package/dist/src/prompts/snippets.js +2 -1
  116. package/dist/src/prompts/snippets.js.map +1 -1
  117. package/dist/src/prompts/snippets.legacy.js +2 -1
  118. package/dist/src/prompts/snippets.legacy.js.map +1 -1
  119. package/dist/src/services/chatRecordingService.d.ts +1 -0
  120. package/dist/src/services/chatRecordingService.js +23 -0
  121. package/dist/src/services/chatRecordingService.js.map +1 -1
  122. package/dist/src/services/chatRecordingTypes.d.ts +13 -0
  123. package/dist/src/services/memoryService.d.ts +5 -0
  124. package/dist/src/services/memoryService.js +76 -53
  125. package/dist/src/services/memoryService.js.map +1 -1
  126. package/dist/src/services/memoryService.test.js +256 -12
  127. package/dist/src/services/memoryService.test.js.map +1 -1
  128. package/dist/src/services/sessionScratchpadUtils.d.ts +7 -0
  129. package/dist/src/services/sessionScratchpadUtils.js +121 -0
  130. package/dist/src/services/sessionScratchpadUtils.js.map +1 -0
  131. package/dist/src/services/sessionScratchpadUtils.test.d.ts +6 -0
  132. package/dist/src/services/sessionScratchpadUtils.test.js +27 -0
  133. package/dist/src/services/sessionScratchpadUtils.test.js.map +1 -0
  134. package/dist/src/services/sessionSummaryUtils.d.ts +3 -3
  135. package/dist/src/services/sessionSummaryUtils.js +232 -27
  136. package/dist/src/services/sessionSummaryUtils.js.map +1 -1
  137. package/dist/src/services/sessionSummaryUtils.test.js +449 -10
  138. package/dist/src/services/sessionSummaryUtils.test.js.map +1 -1
  139. package/dist/src/services/test-data/resolved-aliases-retry.golden.json +24 -0
  140. package/dist/src/services/test-data/resolved-aliases.golden.json +24 -0
  141. package/dist/src/tools/trackerTools.test.js +7 -2
  142. package/dist/src/tools/trackerTools.test.js.map +1 -1
  143. package/dist/src/utils/binaryCheck.d.ts +9 -0
  144. package/dist/src/utils/binaryCheck.js +13 -0
  145. package/dist/src/utils/binaryCheck.js.map +1 -0
  146. package/dist/src/utils/fsErrorMessages.js +4 -0
  147. package/dist/src/utils/fsErrorMessages.js.map +1 -1
  148. package/dist/src/utils/fsErrorMessages.test.js +21 -0
  149. package/dist/src/utils/fsErrorMessages.test.js.map +1 -1
  150. package/dist/src/utils/tokenCalculation.d.ts +2 -2
  151. package/dist/src/utils/tokenCalculation.js +15 -14
  152. package/dist/src/utils/tokenCalculation.js.map +1 -1
  153. package/dist/src/voice/audioRecorder.d.ts +27 -0
  154. package/dist/src/voice/audioRecorder.js +95 -0
  155. package/dist/src/voice/audioRecorder.js.map +1 -0
  156. package/dist/src/voice/geminiLiveTranscriptionProvider.d.ts +20 -0
  157. package/dist/src/voice/geminiLiveTranscriptionProvider.js +140 -0
  158. package/dist/src/voice/geminiLiveTranscriptionProvider.js.map +1 -0
  159. package/dist/src/voice/transcriptionFactory.d.ts +12 -0
  160. package/dist/src/voice/transcriptionFactory.js +32 -0
  161. package/dist/src/voice/transcriptionFactory.js.map +1 -0
  162. package/dist/src/voice/transcriptionProvider.d.ts +29 -0
  163. package/dist/src/voice/transcriptionProvider.js +7 -0
  164. package/dist/src/voice/transcriptionProvider.js.map +1 -0
  165. package/dist/src/voice/whisperModelManager.d.ts +26 -0
  166. package/dist/src/voice/whisperModelManager.js +79 -0
  167. package/dist/src/voice/whisperModelManager.js.map +1 -0
  168. package/dist/src/voice/whisperTranscriptionProvider.d.ts +34 -0
  169. package/dist/src/voice/whisperTranscriptionProvider.js +151 -0
  170. package/dist/src/voice/whisperTranscriptionProvider.js.map +1 -0
  171. package/dist/src/voice/whisperTranscriptionProvider.test.d.ts +6 -0
  172. package/dist/src/voice/whisperTranscriptionProvider.test.js +24 -0
  173. package/dist/src/voice/whisperTranscriptionProvider.test.js.map +1 -0
  174. package/dist/tsconfig.tsbuildinfo +1 -1
  175. package/package.json +2 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geminiLiveTranscriptionProvider.js","sourceRoot":"","sources":["../../../src/voice/geminiLiveTranscriptionProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { TranscriptionProvider } from './transcriptionProvider.js';
7
+ export declare class TranscriptionFactory {
8
+ static createProvider(voiceConfig: {
9
+ backend?: string;
10
+ whisperModel?: string;
11
+ } | undefined, apiKey: string): TranscriptionProvider;
12
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import * as path from 'node:path';
7
+ import * as fs from 'node:fs';
8
+ import { homedir, CELL_DIR } from '../utils/paths.js';
9
+ import { GeminiLiveTranscriptionProvider } from './geminiLiveTranscriptionProvider.js';
10
+ import { WhisperTranscriptionProvider } from './whisperTranscriptionProvider.js';
11
+ export class TranscriptionFactory {
12
+ static createProvider(voiceConfig, apiKey) {
13
+ const backend = voiceConfig?.backend ?? 'gemini-live';
14
+ if (backend === 'whisper') {
15
+ const modelsDir = path.join(homedir(), CELL_DIR, 'whisper_models');
16
+ if (!fs.existsSync(modelsDir)) {
17
+ fs.mkdirSync(modelsDir, { recursive: true });
18
+ }
19
+ const modelName = voiceConfig?.whisperModel ?? 'ggml-base.en.bin';
20
+ const modelPath = path.join(modelsDir, modelName);
21
+ return new WhisperTranscriptionProvider({
22
+ modelPath,
23
+ threads: 4,
24
+ step: 0,
25
+ length: 5000,
26
+ });
27
+ }
28
+ // Default to Gemini Live
29
+ return new GeminiLiveTranscriptionProvider(apiKey);
30
+ }
31
+ }
32
+ //# sourceMappingURL=transcriptionFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcriptionFactory.js","sourceRoot":"","sources":["../../../src/voice/transcriptionFactory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC;AACvF,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AAGjF,MAAM,OAAO,oBAAoB;IAC/B,MAAM,CAAC,cAAc,CACnB,WAAoE,EACpE,MAAc;QAEd,MAAM,OAAO,GAAG,WAAW,EAAE,OAAO,IAAI,aAAa,CAAC;QAEtD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;YACnE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/C,CAAC;YAED,MAAM,SAAS,GAAG,WAAW,EAAE,YAAY,IAAI,kBAAkB,CAAC;YAClE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAElD,OAAO,IAAI,4BAA4B,CAAC;gBACtC,SAAS;gBACT,OAAO,EAAE,CAAC;gBACV,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,IAAI;aACb,CAAC,CAAC;QACL,CAAC;QAED,yBAAyB;QACzB,OAAO,IAAI,+BAA+B,CAAC,MAAM,CAAC,CAAC;IACrD,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { EventEmitter } from 'node:events';
7
+ export interface TranscriptionEvents {
8
+ /** Emitted when partial or full transcription text is available. */
9
+ transcription: [string];
10
+ /** Emitted when a speaking turn is considered complete. */
11
+ turnComplete: [];
12
+ /** Emitted when an error occurs during transcription. */
13
+ error: [Error];
14
+ /** Emitted when the transcription service connection is closed. */
15
+ close: [];
16
+ }
17
+ /**
18
+ * Common interface for all transcription backends (Cloud or Local).
19
+ */
20
+ export interface TranscriptionProvider extends EventEmitter<TranscriptionEvents> {
21
+ /** Establish connection to the transcription service. */
22
+ connect(): Promise<void>;
23
+ /** Send a chunk of raw audio data to the service. */
24
+ sendAudioChunk(chunk: Buffer): void;
25
+ /** Disconnect from the transcription service. */
26
+ disconnect(): void;
27
+ /** Get the current full transcription for the session. */
28
+ getTranscription(): string;
29
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=transcriptionProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcriptionProvider.js","sourceRoot":"","sources":["../../../src/voice/transcriptionProvider.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { EventEmitter } from 'node:events';
7
+ export interface WhisperModelProgress {
8
+ modelName: string;
9
+ transferred: number;
10
+ total: number;
11
+ percentage: number;
12
+ }
13
+ export interface WhisperModelManagerEvents {
14
+ progress: [WhisperModelProgress];
15
+ }
16
+ /**
17
+ * Manages Whisper models (checking existence, downloading).
18
+ */
19
+ export declare class WhisperModelManager extends EventEmitter<WhisperModelManagerEvents> {
20
+ private readonly modelsDir;
21
+ constructor();
22
+ isModelInstalled(modelName: string): boolean;
23
+ getModelPath(modelName: string): string;
24
+ downloadModel(modelName: string): Promise<void>;
25
+ private validateModelName;
26
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import * as path from 'node:path';
7
+ import * as fs from 'node:fs';
8
+ import { EventEmitter } from 'node:events';
9
+ import { homedir, CELL_DIR } from '../utils/paths.js';
10
+ import { debugLogger } from '../utils/debugLogger.js';
11
+ const ALLOWED_MODELS = [
12
+ 'ggml-tiny.en.bin',
13
+ 'ggml-base.en.bin',
14
+ 'ggml-large-v3-turbo-q5_0.bin',
15
+ 'ggml-large-v3-turbo-q8_0.bin',
16
+ ];
17
+ /**
18
+ * Manages Whisper models (checking existence, downloading).
19
+ */
20
+ export class WhisperModelManager extends EventEmitter {
21
+ modelsDir;
22
+ constructor() {
23
+ super();
24
+ this.modelsDir = path.join(homedir(), CELL_DIR, 'whisper_models');
25
+ }
26
+ isModelInstalled(modelName) {
27
+ this.validateModelName(modelName);
28
+ return fs.existsSync(path.join(this.modelsDir, modelName));
29
+ }
30
+ getModelPath(modelName) {
31
+ this.validateModelName(modelName);
32
+ return path.join(this.modelsDir, modelName);
33
+ }
34
+ async downloadModel(modelName) {
35
+ this.validateModelName(modelName);
36
+ if (!fs.existsSync(this.modelsDir)) {
37
+ fs.mkdirSync(this.modelsDir, { recursive: true });
38
+ }
39
+ const destination = path.join(this.modelsDir, modelName);
40
+ const url = `https://huggingface.co/ggerganov/whisper.cpp/resolve/main/${modelName}`;
41
+ debugLogger.debug(`[WhisperModelManager] Downloading ${modelName} from ${url}`);
42
+ const response = await fetch(url);
43
+ if (!response.ok) {
44
+ throw new Error(`Failed to download model: ${response.statusText}`);
45
+ }
46
+ const total = parseInt(response.headers.get('content-length') || '0', 10);
47
+ let transferred = 0;
48
+ const reader = response.body?.getReader();
49
+ if (!reader) {
50
+ throw new Error('Response body is not readable');
51
+ }
52
+ const writer = fs.createWriteStream(destination);
53
+ try {
54
+ while (true) {
55
+ const { done, value } = await reader.read();
56
+ if (done)
57
+ break;
58
+ transferred += value.length;
59
+ writer.write(value);
60
+ const percentage = total > 0 ? transferred / total : 0;
61
+ this.emit('progress', {
62
+ modelName,
63
+ transferred,
64
+ total,
65
+ percentage,
66
+ });
67
+ }
68
+ }
69
+ finally {
70
+ writer.end();
71
+ }
72
+ }
73
+ validateModelName(modelName) {
74
+ if (!ALLOWED_MODELS.includes(modelName)) {
75
+ throw new Error(`Unauthorized model name: ${modelName}`);
76
+ }
77
+ }
78
+ }
79
+ //# sourceMappingURL=whisperModelManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whisperModelManager.js","sourceRoot":"","sources":["../../../src/voice/whisperModelManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAatD,MAAM,cAAc,GAAG;IACrB,kBAAkB;IAClB,kBAAkB;IAClB,8BAA8B;IAC9B,8BAA8B;CAC/B,CAAC;AAEF;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,YAAuC;IAC7D,SAAS,CAAS;IAEnC;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IACpE,CAAC;IAED,gBAAgB,CAAC,SAAiB;QAChC,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAClC,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,YAAY,CAAC,SAAiB;QAC5B,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,SAAiB;QACnC,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAElC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACnC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACzD,MAAM,GAAG,GAAG,6DAA6D,SAAS,EAAE,CAAC;QAErF,WAAW,CAAC,KAAK,CACf,qCAAqC,SAAS,SAAS,GAAG,EAAE,CAC7D,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;QAC1E,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;QAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;QAEjD,IAAI,CAAC;YACH,OAAO,IAAI,EAAE,CAAC;gBACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;gBAC5C,IAAI,IAAI;oBAAE,MAAM;gBAEhB,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC;gBAC5B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBAEpB,MAAM,UAAU,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACvD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;oBACpB,SAAS;oBACT,WAAW;oBACX,KAAK;oBACL,UAAU;iBACX,CAAC,CAAC;YACL,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,GAAG,EAAE,CAAC;QACf,CAAC;IACH,CAAC;IAEO,iBAAiB,CAAC,SAAiB;QACzC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,4BAA4B,SAAS,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { EventEmitter } from 'node:events';
7
+ import type { TranscriptionProvider, TranscriptionEvents } from './transcriptionProvider.js';
8
+ export interface WhisperProviderOptions {
9
+ modelPath: string;
10
+ threads?: number;
11
+ step?: number;
12
+ length?: number;
13
+ }
14
+ /**
15
+ * Local transcription provider using `whisper-stream` from whisper.cpp.
16
+ *
17
+ * Uses the Sliding Window Mode with VAD (--step 0) for stable,
18
+ * non-overlapping transcription blocks that can be appended directly.
19
+ */
20
+ export declare class WhisperTranscriptionProvider extends EventEmitter<TranscriptionEvents> implements TranscriptionProvider {
21
+ private readonly options;
22
+ private process;
23
+ private currentTranscription;
24
+ constructor(options: WhisperProviderOptions);
25
+ /**
26
+ * Checks if `whisper-stream` is available on the system.
27
+ */
28
+ static isAvailable(): Promise<boolean>;
29
+ connect(): Promise<void>;
30
+ private parseOutput;
31
+ sendAudioChunk(_chunk: Buffer): void;
32
+ getTranscription(): string;
33
+ disconnect(): void;
34
+ }
@@ -0,0 +1,151 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { spawn } from 'node:child_process';
7
+ import { EventEmitter } from 'node:events';
8
+ import commandExists from 'command-exists';
9
+ import { debugLogger } from '../utils/debugLogger.js';
10
+ /**
11
+ * Local transcription provider using `whisper-stream` from whisper.cpp.
12
+ *
13
+ * Uses the Sliding Window Mode with VAD (--step 0) for stable,
14
+ * non-overlapping transcription blocks that can be appended directly.
15
+ */
16
+ export class WhisperTranscriptionProvider extends EventEmitter {
17
+ options;
18
+ process = null;
19
+ currentTranscription = '';
20
+ constructor(options) {
21
+ super();
22
+ this.options = options;
23
+ }
24
+ /**
25
+ * Checks if `whisper-stream` is available on the system.
26
+ */
27
+ static async isAvailable() {
28
+ try {
29
+ await commandExists('whisper-stream');
30
+ return true;
31
+ }
32
+ catch {
33
+ return false;
34
+ }
35
+ }
36
+ async connect() {
37
+ const { modelPath, threads = 4, step = 0, length = 5000 } = this.options;
38
+ this.currentTranscription = '';
39
+ const available = await WhisperTranscriptionProvider.isAvailable();
40
+ if (!available) {
41
+ return Promise.reject(new Error('The `whisper-stream` command is required for local voice mode. Please install it (e.g., `brew install whisper-cpp` on macOS).'));
42
+ }
43
+ debugLogger.debug(`[WhisperTranscription] Starting whisper-stream with model: ${modelPath} (VAD mode: step=${step}, length=${length})`);
44
+ return new Promise((resolve, reject) => {
45
+ let isResolved = false;
46
+ try {
47
+ // whisper-stream -m <model_path> -t <threads> --step 0 --length <length> -vth 0.6
48
+ // Setting step == 0 enables sliding window mode with VAD, which outputs
49
+ // non-overlapping transcription blocks suitable for appending.
50
+ this.process = spawn('whisper-stream', [
51
+ '-m',
52
+ modelPath,
53
+ '-t',
54
+ threads.toString(),
55
+ '--step',
56
+ step.toString(),
57
+ '--length',
58
+ length.toString(),
59
+ '-vth',
60
+ '0.6',
61
+ ]);
62
+ this.process.stdout.on('data', (data) => {
63
+ const output = data.toString();
64
+ this.parseOutput(output);
65
+ });
66
+ this.process.stderr.on('data', (data) => {
67
+ const msg = data.toString();
68
+ if (msg.includes('error')) {
69
+ debugLogger.error(`[WhisperTranscription] stderr: ${msg}`);
70
+ if (!isResolved) {
71
+ isResolved = true;
72
+ reject(new Error(msg));
73
+ }
74
+ }
75
+ // whisper-stream prints "whisper_init_from_file_with_params_no_state: loading model from..."
76
+ // and finally "main: processing, press Ctrl+C to stop" when ready.
77
+ if (!isResolved && msg.includes('main: processing')) {
78
+ debugLogger.debug('[WhisperTranscription] whisper-stream is ready');
79
+ isResolved = true;
80
+ resolve();
81
+ }
82
+ });
83
+ this.process.on('error', (err) => {
84
+ debugLogger.error('[WhisperTranscription] Process error:', err);
85
+ this.emit('error', err);
86
+ if (!isResolved) {
87
+ isResolved = true;
88
+ reject(err);
89
+ }
90
+ });
91
+ this.process.on('close', (code) => {
92
+ debugLogger.debug(`[WhisperTranscription] Process closed with code ${code}`);
93
+ this.emit('close');
94
+ this.process = null;
95
+ });
96
+ // Fallback timeout in case "main: processing" is never seen
97
+ setTimeout(() => {
98
+ if (!isResolved) {
99
+ debugLogger.warn('[WhisperTranscription] Connection timeout (fallback resolve)');
100
+ isResolved = true;
101
+ resolve();
102
+ }
103
+ }, 10000);
104
+ }
105
+ catch (err) {
106
+ debugLogger.error('[WhisperTranscription] Failed to spawn process:', err);
107
+ if (!isResolved) {
108
+ isResolved = true;
109
+ reject(err);
110
+ }
111
+ }
112
+ });
113
+ }
114
+ parseOutput(output) {
115
+ // whisper-stream output format: "[00:00:00.000 --> 00:00:02.000] Hello world."
116
+ const lines = output.split('\n');
117
+ for (const line of lines) {
118
+ const match = line.match(/\[.* --> .*\]\s+(.*)/);
119
+ if (match && match[1]) {
120
+ let text = match[1].trim();
121
+ // Filter out [Silence], [music], (laughter), etc.
122
+ text = text
123
+ .replace(/\[[^\]]*\]/g, '')
124
+ .replace(/\([^)]*\)/g, '')
125
+ .trim();
126
+ if (text) {
127
+ // In VAD mode (step=0), each line is a completed speech block.
128
+ // Append it to the buffer to ensure it doesn't disappear.
129
+ this.currentTranscription = this.currentTranscription
130
+ ? `${this.currentTranscription} ${text}`
131
+ : text;
132
+ debugLogger.debug(`[WhisperTranscription] Transcription updated (Local-VAD): "${this.currentTranscription}"`);
133
+ this.emit('transcription', this.currentTranscription);
134
+ }
135
+ }
136
+ }
137
+ }
138
+ sendAudioChunk(_chunk) {
139
+ // whisper-stream handles its own audio capture.
140
+ }
141
+ getTranscription() {
142
+ return this.currentTranscription;
143
+ }
144
+ disconnect() {
145
+ if (this.process) {
146
+ this.process.kill('SIGTERM');
147
+ this.process = null;
148
+ }
149
+ }
150
+ }
151
+ //# sourceMappingURL=whisperTranscriptionProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whisperTranscriptionProvider.js","sourceRoot":"","sources":["../../../src/voice/whisperTranscriptionProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export {};
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
7
+ import { WhisperTranscriptionProvider } from './whisperTranscriptionProvider.js';
8
+ import commandExists from 'command-exists';
9
+ vi.mock('command-exists', () => ({
10
+ default: vi.fn(),
11
+ }));
12
+ describe('WhisperTranscriptionProvider', () => {
13
+ beforeEach(() => {
14
+ vi.clearAllMocks();
15
+ });
16
+ it('should throw a friendly error if whisper-stream is not available', async () => {
17
+ vi.mocked(commandExists).mockRejectedValue(new Error('not found'));
18
+ const provider = new WhisperTranscriptionProvider({
19
+ modelPath: 'test-model.bin',
20
+ });
21
+ await expect(provider.connect()).rejects.toThrow('The `whisper-stream` command is required for local voice mode. Please install it (e.g., `brew install whisper-cpp` on macOS).');
22
+ });
23
+ });
24
+ //# sourceMappingURL=whisperTranscriptionProvider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whisperTranscriptionProvider.test.js","sourceRoot":"","sources":["../../../src/voice/whisperTranscriptionProvider.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAE3C,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/B,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE;CACjB,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;QAEnE,MAAM,QAAQ,GAAG,IAAI,4BAA4B,CAAC;YAChD,SAAS,EAAE,gBAAgB;SAC5B,CAAC,CAAC;QAEH,MAAM,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAC9C,+HAA+H,CAChI,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}