modular-voice-agent-sdk 1.0.0
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.
- package/README.md +102 -0
- package/USAGE.md +567 -0
- package/dist/backends/cloud/index.d.ts +7 -0
- package/dist/backends/cloud/index.d.ts.map +1 -0
- package/dist/backends/cloud/index.js +6 -0
- package/dist/backends/cloud/index.js.map +1 -0
- package/dist/backends/cloud/llm.d.ts +22 -0
- package/dist/backends/cloud/llm.d.ts.map +1 -0
- package/dist/backends/cloud/llm.js +234 -0
- package/dist/backends/cloud/llm.js.map +1 -0
- package/dist/backends/index.d.ts +2 -0
- package/dist/backends/index.d.ts.map +1 -0
- package/dist/backends/index.js +6 -0
- package/dist/backends/index.js.map +1 -0
- package/dist/backends/native/index.d.ts +5 -0
- package/dist/backends/native/index.d.ts.map +1 -0
- package/dist/backends/native/index.js +6 -0
- package/dist/backends/native/index.js.map +1 -0
- package/dist/backends/native/llm.d.ts +71 -0
- package/dist/backends/native/llm.d.ts.map +1 -0
- package/dist/backends/native/llm.js +435 -0
- package/dist/backends/native/llm.js.map +1 -0
- package/dist/backends/native/stt.d.ts +15 -0
- package/dist/backends/native/stt.d.ts.map +1 -0
- package/dist/backends/native/stt.js +94 -0
- package/dist/backends/native/stt.js.map +1 -0
- package/dist/backends/native/tts.d.ts +21 -0
- package/dist/backends/native/tts.d.ts.map +1 -0
- package/dist/backends/native/tts.js +105 -0
- package/dist/backends/native/tts.js.map +1 -0
- package/dist/backends/transformers/index.d.ts +4 -0
- package/dist/backends/transformers/index.d.ts.map +1 -0
- package/dist/backends/transformers/index.js +4 -0
- package/dist/backends/transformers/index.js.map +1 -0
- package/dist/backends/transformers/llm.d.ts +29 -0
- package/dist/backends/transformers/llm.d.ts.map +1 -0
- package/dist/backends/transformers/llm.js +117 -0
- package/dist/backends/transformers/llm.js.map +1 -0
- package/dist/backends/transformers/stt.d.ts +17 -0
- package/dist/backends/transformers/stt.d.ts.map +1 -0
- package/dist/backends/transformers/stt.js +43 -0
- package/dist/backends/transformers/stt.js.map +1 -0
- package/dist/backends/transformers/tts.d.ts +17 -0
- package/dist/backends/transformers/tts.d.ts.map +1 -0
- package/dist/backends/transformers/tts.js +40 -0
- package/dist/backends/transformers/tts.js.map +1 -0
- package/dist/cache.d.ts +37 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +49 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +392 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/audio-player.d.ts +45 -0
- package/dist/client/audio-player.d.ts.map +1 -0
- package/dist/client/audio-player.js +90 -0
- package/dist/client/audio-player.js.map +1 -0
- package/dist/client/audio-recorder.d.ts +42 -0
- package/dist/client/audio-recorder.d.ts.map +1 -0
- package/dist/client/audio-recorder.js +128 -0
- package/dist/client/audio-recorder.js.map +1 -0
- package/dist/client/index.d.ts +34 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +33 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/protocol.d.ts +80 -0
- package/dist/client/protocol.d.ts.map +1 -0
- package/dist/client/protocol.js +29 -0
- package/dist/client/protocol.js.map +1 -0
- package/dist/client/voice-client.d.ts +249 -0
- package/dist/client/voice-client.d.ts.map +1 -0
- package/dist/client/voice-client.js +826 -0
- package/dist/client/voice-client.js.map +1 -0
- package/dist/client/web-speech-stt.d.ts +65 -0
- package/dist/client/web-speech-stt.d.ts.map +1 -0
- package/dist/client/web-speech-stt.js +122 -0
- package/dist/client/web-speech-stt.js.map +1 -0
- package/dist/client/web-speech-tts.d.ts +59 -0
- package/dist/client/web-speech-tts.d.ts.map +1 -0
- package/dist/client/web-speech-tts.js +145 -0
- package/dist/client/web-speech-tts.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/server/encoding.d.ts +18 -0
- package/dist/server/encoding.d.ts.map +1 -0
- package/dist/server/encoding.js +41 -0
- package/dist/server/encoding.js.map +1 -0
- package/dist/server/handler.d.ts +86 -0
- package/dist/server/handler.d.ts.map +1 -0
- package/dist/server/handler.js +224 -0
- package/dist/server/handler.js.map +1 -0
- package/dist/server/index.d.ts +31 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +32 -0
- package/dist/server/index.js.map +1 -0
- package/dist/services/function-service.d.ts +17 -0
- package/dist/services/function-service.d.ts.map +1 -0
- package/dist/services/function-service.js +82 -0
- package/dist/services/function-service.js.map +1 -0
- package/dist/services/index.d.ts +4 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +3 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/llm-logger.d.ts +136 -0
- package/dist/services/llm-logger.d.ts.map +1 -0
- package/dist/services/llm-logger.js +275 -0
- package/dist/services/llm-logger.js.map +1 -0
- package/dist/services/text-normalizer.d.ts +17 -0
- package/dist/services/text-normalizer.d.ts.map +1 -0
- package/dist/services/text-normalizer.js +100 -0
- package/dist/services/text-normalizer.js.map +1 -0
- package/dist/types.d.ts +195 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +48 -0
- package/dist/types.js.map +1 -0
- package/dist/voice-pipeline.d.ts +125 -0
- package/dist/voice-pipeline.d.ts.map +1 -0
- package/dist/voice-pipeline.js +390 -0
- package/dist/voice-pipeline.js.map +1 -0
- package/package.json +96 -0
- package/scripts/setup-binaries.sh +159 -0
- package/scripts/setup.sh +201 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline Handler
|
|
3
|
+
*
|
|
4
|
+
* Framework-agnostic session handler for voice pipeline servers.
|
|
5
|
+
* Supports capability negotiation - skips STT/TTS when client handles them.
|
|
6
|
+
* Each session has its own conversation history and conversation ID.
|
|
7
|
+
*/
|
|
8
|
+
import { float32ToBase64Node, base64ToFloat32Node, concatFloat32Arrays } from './encoding';
|
|
9
|
+
/**
|
|
10
|
+
* Generate a unique conversation ID
|
|
11
|
+
*/
|
|
12
|
+
function generateConversationId() {
|
|
13
|
+
return `conv-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A session represents a single client connection.
|
|
17
|
+
* Each session has its own conversation history and ID.
|
|
18
|
+
*/
|
|
19
|
+
export class PipelineSession {
|
|
20
|
+
pipeline;
|
|
21
|
+
audioChunks = [];
|
|
22
|
+
destroyed = false;
|
|
23
|
+
capabilities = {
|
|
24
|
+
hasSTT: false,
|
|
25
|
+
hasTTS: false,
|
|
26
|
+
};
|
|
27
|
+
/** Session's conversation history */
|
|
28
|
+
history = [];
|
|
29
|
+
/** Unique conversation ID for this session */
|
|
30
|
+
conversationId;
|
|
31
|
+
constructor(pipeline) {
|
|
32
|
+
this.pipeline = pipeline;
|
|
33
|
+
this.conversationId = generateConversationId();
|
|
34
|
+
// Initialize history with system prompt
|
|
35
|
+
this.history = [{ role: 'system', content: this.pipeline.getSystemPrompt() }];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get the conversation context for this session
|
|
39
|
+
*/
|
|
40
|
+
getContext() {
|
|
41
|
+
return {
|
|
42
|
+
conversationId: this.conversationId,
|
|
43
|
+
history: this.history,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Handle an incoming message and yield response messages
|
|
48
|
+
*/
|
|
49
|
+
async *handle(message) {
|
|
50
|
+
if (this.destroyed)
|
|
51
|
+
return;
|
|
52
|
+
switch (message.type) {
|
|
53
|
+
case 'capabilities':
|
|
54
|
+
// Client is telling us what it handles locally
|
|
55
|
+
this.capabilities = {
|
|
56
|
+
hasSTT: message.hasSTT,
|
|
57
|
+
hasTTS: message.hasTTS,
|
|
58
|
+
};
|
|
59
|
+
break;
|
|
60
|
+
case 'audio':
|
|
61
|
+
this.audioChunks.push(base64ToFloat32Node(message.data));
|
|
62
|
+
break;
|
|
63
|
+
case 'end_audio':
|
|
64
|
+
yield* this.processAudio();
|
|
65
|
+
break;
|
|
66
|
+
case 'text':
|
|
67
|
+
// Client did STT locally - process text directly
|
|
68
|
+
yield* this.processText(message.text);
|
|
69
|
+
break;
|
|
70
|
+
case 'clear_history':
|
|
71
|
+
// Reset session history and get a new conversation ID
|
|
72
|
+
this.conversationId = generateConversationId();
|
|
73
|
+
this.history = [{ role: 'system', content: this.pipeline.getSystemPrompt() }];
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get client capabilities
|
|
79
|
+
*/
|
|
80
|
+
getCapabilities() {
|
|
81
|
+
return { ...this.capabilities };
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Process accumulated audio through the pipeline (STT → LLM → TTS)
|
|
85
|
+
*/
|
|
86
|
+
async *processAudio() {
|
|
87
|
+
if (this.audioChunks.length === 0)
|
|
88
|
+
return;
|
|
89
|
+
if (!this.pipeline.hasSTT()) {
|
|
90
|
+
yield { type: 'error', message: 'No STT backend configured on server. Client should use local STT and send text.' };
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const audio = concatFloat32Arrays(this.audioChunks);
|
|
94
|
+
this.audioChunks = [];
|
|
95
|
+
yield* this.runPipeline((callbacks) => this.pipeline.processAudio(audio, this.getContext(), callbacks));
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Process text through the pipeline (LLM → TTS)
|
|
99
|
+
*/
|
|
100
|
+
async *processText(text) {
|
|
101
|
+
// Emit the transcript so client knows what was received
|
|
102
|
+
// (useful for debugging, client can ignore if it already has transcript)
|
|
103
|
+
yield { type: 'transcript', text };
|
|
104
|
+
yield* this.runPipeline((callbacks) => this.pipeline.processText(text, this.getContext(), callbacks));
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Run the pipeline and yield messages as they arrive
|
|
108
|
+
*/
|
|
109
|
+
async *runPipeline(run) {
|
|
110
|
+
const messageQueue = [];
|
|
111
|
+
let resolveWaiting = null;
|
|
112
|
+
let isComplete = false;
|
|
113
|
+
const enqueue = (msg) => {
|
|
114
|
+
messageQueue.push(msg);
|
|
115
|
+
if (resolveWaiting) {
|
|
116
|
+
resolveWaiting();
|
|
117
|
+
resolveWaiting = null;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
// Determine what to skip based on client capabilities
|
|
121
|
+
const skipTTS = this.capabilities.hasTTS || !this.pipeline.hasTTS();
|
|
122
|
+
// Start pipeline processing
|
|
123
|
+
const pipelinePromise = run({
|
|
124
|
+
onTranscript: (text) => enqueue({ type: 'transcript', text }),
|
|
125
|
+
onResponseChunk: (text) => enqueue({ type: 'response_chunk', text }),
|
|
126
|
+
onAudio: (playable) => {
|
|
127
|
+
// Skip audio if client handles TTS locally
|
|
128
|
+
if (skipTTS)
|
|
129
|
+
return;
|
|
130
|
+
const raw = playable.getRawAudio();
|
|
131
|
+
if (!raw) {
|
|
132
|
+
// TTS backend doesn't provide raw audio (e.g., WebSpeechTTS)
|
|
133
|
+
// This is a config error - server TTS must produce raw audio
|
|
134
|
+
enqueue({
|
|
135
|
+
type: 'error',
|
|
136
|
+
message: 'Server TTS backend does not provide raw audio. Use a TTS backend that produces raw audio (TransformersTTS, NativeTTS), or configure client with localTTS.',
|
|
137
|
+
});
|
|
138
|
+
isComplete = true;
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
enqueue({
|
|
142
|
+
type: 'audio',
|
|
143
|
+
data: float32ToBase64Node(raw.audio),
|
|
144
|
+
sampleRate: raw.sampleRate,
|
|
145
|
+
});
|
|
146
|
+
},
|
|
147
|
+
onToolCall: (toolCall) => {
|
|
148
|
+
enqueue({
|
|
149
|
+
type: 'tool_call',
|
|
150
|
+
toolCallId: toolCall.id,
|
|
151
|
+
name: toolCall.name,
|
|
152
|
+
arguments: toolCall.arguments,
|
|
153
|
+
});
|
|
154
|
+
},
|
|
155
|
+
onToolResult: (toolCallId, result) => {
|
|
156
|
+
enqueue({
|
|
157
|
+
type: 'tool_result',
|
|
158
|
+
toolCallId,
|
|
159
|
+
result,
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
onComplete: () => {
|
|
163
|
+
enqueue({ type: 'complete' });
|
|
164
|
+
isComplete = true;
|
|
165
|
+
},
|
|
166
|
+
onError: (err) => {
|
|
167
|
+
enqueue({ type: 'error', message: err.message });
|
|
168
|
+
isComplete = true;
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
// Yield messages as they arrive
|
|
172
|
+
while (!isComplete || messageQueue.length > 0) {
|
|
173
|
+
if (messageQueue.length > 0) {
|
|
174
|
+
yield messageQueue.shift();
|
|
175
|
+
}
|
|
176
|
+
else if (!isComplete) {
|
|
177
|
+
await new Promise((resolve) => {
|
|
178
|
+
resolveWaiting = resolve;
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
await pipelinePromise;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Clean up session resources
|
|
186
|
+
*/
|
|
187
|
+
destroy() {
|
|
188
|
+
this.destroyed = true;
|
|
189
|
+
this.audioChunks = [];
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Pipeline handler factory
|
|
194
|
+
*/
|
|
195
|
+
export class PipelineHandler {
|
|
196
|
+
pipeline;
|
|
197
|
+
constructor(pipeline, _config = {}) {
|
|
198
|
+
this.pipeline = pipeline;
|
|
199
|
+
// Config reserved for future options
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Create a new session for a client connection.
|
|
203
|
+
* Each session has its own conversation history.
|
|
204
|
+
*/
|
|
205
|
+
createSession() {
|
|
206
|
+
return new PipelineSession(this.pipeline);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get info about what the pipeline handles
|
|
210
|
+
*/
|
|
211
|
+
getPipelineInfo() {
|
|
212
|
+
return {
|
|
213
|
+
hasSTT: this.pipeline.hasSTT(),
|
|
214
|
+
hasTTS: this.pipeline.hasTTS(),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Create a pipeline handler
|
|
220
|
+
*/
|
|
221
|
+
export function createPipelineHandler(pipeline, config) {
|
|
222
|
+
return new PipelineHandler(pipeline, config);
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/server/handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAc3F;;GAEG;AACH,SAAS,sBAAsB;IAC7B,OAAO,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AACzE,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,eAAe;IAchB;IAbF,WAAW,GAAmB,EAAE,CAAC;IACjC,SAAS,GAAG,KAAK,CAAC;IAClB,YAAY,GAAuB;QACzC,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,KAAK;KACd,CAAC;IAEF,qCAAqC;IAC7B,OAAO,GAAc,EAAE,CAAC;IAChC,8CAA8C;IACtC,cAAc,CAAS;IAE/B,YACU,QAAuB;QAAvB,aAAQ,GAAR,QAAQ,CAAe;QAE/B,IAAI,CAAC,cAAc,GAAG,sBAAsB,EAAE,CAAC;QAC/C,wCAAwC;QACxC,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IAChF,CAAC;IAED;;OAEG;IACK,UAAU;QAChB,OAAO;YACL,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,CAAC,MAAM,CAAC,OAAsB;QAClC,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAE3B,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,KAAK,cAAc;gBACjB,+CAA+C;gBAC/C,IAAI,CAAC,YAAY,GAAG;oBAClB,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,MAAM,EAAE,OAAO,CAAC,MAAM;iBACvB,CAAC;gBACF,MAAM;YAER,KAAK,OAAO;gBACV,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;gBACzD,MAAM;YAER,KAAK,WAAW;gBACd,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;gBAC3B,MAAM;YAER,KAAK,MAAM;gBACT,iDAAiD;gBACjD,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACtC,MAAM;YAER,KAAK,eAAe;gBAClB,sDAAsD;gBACtD,IAAI,CAAC,cAAc,GAAG,sBAAsB,EAAE,CAAC;gBAC/C,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;gBAC9E,MAAM;QACV,CAAC;IACH,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;IAClC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,CAAC,YAAY;QACzB,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAE1C,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5B,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,iFAAiF,EAAE,CAAC;YACpH,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACpD,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QAEtB,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,SAAS,EAAE,EAAE,CACpC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,CAAC,CAChE,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,CAAC,WAAW,CAAC,IAAY;QACrC,wDAAwD;QACxD,yEAAyE;QACzE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QAEnC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,SAAS,EAAE,EAAE,CACpC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,CAAC,CAC9D,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,CAAC,WAAW,CACxB,GAAoF;QAEpF,MAAM,YAAY,GAAoB,EAAE,CAAC;QACzC,IAAI,cAAc,GAAwB,IAAI,CAAC;QAC/C,IAAI,UAAU,GAAG,KAAK,CAAC;QAEvB,MAAM,OAAO,GAAG,CAAC,GAAkB,EAAE,EAAE;YACrC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvB,IAAI,cAAc,EAAE,CAAC;gBACnB,cAAc,EAAE,CAAC;gBACjB,cAAc,GAAG,IAAI,CAAC;YACxB,CAAC;QACH,CAAC,CAAC;QAEF,sDAAsD;QACtD,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAEpE,4BAA4B;QAC5B,MAAM,eAAe,GAAG,GAAG,CAAC;YAC1B,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;YAC7D,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC;YACpE,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE;gBACpB,2CAA2C;gBAC3C,IAAI,OAAO;oBAAE,OAAO;gBAEpB,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;gBACnC,IAAI,CAAC,GAAG,EAAE,CAAC;oBACT,6DAA6D;oBAC7D,6DAA6D;oBAC7D,OAAO,CAAC;wBACN,IAAI,EAAE,OAAO;wBACb,OAAO,EAAE,2JAA2J;qBACrK,CAAC,CAAC;oBACH,UAAU,GAAG,IAAI,CAAC;oBAClB,OAAO;gBACT,CAAC;gBACD,OAAO,CAAC;oBACN,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC;oBACpC,UAAU,EAAE,GAAG,CAAC,UAAU;iBAC3B,CAAC,CAAC;YACL,CAAC;YACD,UAAU,EAAE,CAAC,QAAQ,EAAE,EAAE;gBACvB,OAAO,CAAC;oBACN,IAAI,EAAE,WAAW;oBACjB,UAAU,EAAE,QAAQ,CAAC,EAAE;oBACvB,IAAI,EAAE,QAAQ,CAAC,IAAI;oBACnB,SAAS,EAAE,QAAQ,CAAC,SAAS;iBAC9B,CAAC,CAAC;YACL,CAAC;YACD,YAAY,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE;gBACnC,OAAO,CAAC;oBACN,IAAI,EAAE,aAAa;oBACnB,UAAU;oBACV,MAAM;iBACP,CAAC,CAAC;YACL,CAAC;YACD,UAAU,EAAE,GAAG,EAAE;gBACf,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;gBAC9B,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;YACD,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACf,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBACjD,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;SACF,CAAC,CAAC;QAEH,gCAAgC;QAChC,OAAO,CAAC,UAAU,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5B,MAAM,YAAY,CAAC,KAAK,EAAG,CAAC;YAC9B,CAAC;iBAAM,IAAI,CAAC,UAAU,EAAE,CAAC;gBACvB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;oBAClC,cAAc,GAAG,OAAO,CAAC;gBAC3B,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,MAAM,eAAe,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;IACxB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,eAAe;IAEhB;IADV,YACU,QAAuB,EAC/B,UAAiC,EAAE;QAD3B,aAAQ,GAAR,QAAQ,CAAe;QAG/B,qCAAqC;IACvC,CAAC;IAED;;;OAGG;IACH,aAAa;QACX,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;YAC9B,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;SAC/B,CAAC;IACJ,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAuB,EACvB,MAA8B;IAE9B,OAAO,IAAI,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modular Voice Agent SDK - Server Utilities
|
|
3
|
+
*
|
|
4
|
+
* Framework-agnostic handlers for building voice assistant servers.
|
|
5
|
+
* Works with any WebSocket library (ws, Socket.io, Bun, Deno, etc.)
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { VoicePipeline } from 'modular-voice-agent-sdk';
|
|
10
|
+
* import { createPipelineHandler } from 'modular-voice-agent-sdk/server';
|
|
11
|
+
* import { WebSocketServer } from 'ws';
|
|
12
|
+
*
|
|
13
|
+
* const pipeline = new VoicePipeline({ stt, llm, tts, systemPrompt });
|
|
14
|
+
* const handler = createPipelineHandler(pipeline);
|
|
15
|
+
*
|
|
16
|
+
* wss.on('connection', (ws) => {
|
|
17
|
+
* const session = handler.createSession();
|
|
18
|
+
* ws.on('message', async (data) => {
|
|
19
|
+
* for await (const msg of session.handle(JSON.parse(data))) {
|
|
20
|
+
* ws.send(JSON.stringify(msg));
|
|
21
|
+
* }
|
|
22
|
+
* });
|
|
23
|
+
* ws.on('close', () => session.destroy());
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export { createPipelineHandler, PipelineHandler, PipelineSession } from './handler';
|
|
28
|
+
export type { PipelineHandlerConfig } from './handler';
|
|
29
|
+
export { float32ToBase64, base64ToFloat32, type ClientMessage, type ServerMessage, type AudioMessage, type EndAudioMessage, type ClearHistoryMessage, type TranscriptMessage, type ResponseChunkMessage, type AudioResponseMessage, type CompleteMessage, type ErrorMessage, } from '../client/protocol';
|
|
30
|
+
export { float32ToBase64Node, base64ToFloat32Node } from './encoding';
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACpF,YAAY,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAGvD,OAAO,EACL,eAAe,EACf,eAAe,EACf,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modular Voice Agent SDK - Server Utilities
|
|
3
|
+
*
|
|
4
|
+
* Framework-agnostic handlers for building voice assistant servers.
|
|
5
|
+
* Works with any WebSocket library (ws, Socket.io, Bun, Deno, etc.)
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { VoicePipeline } from 'modular-voice-agent-sdk';
|
|
10
|
+
* import { createPipelineHandler } from 'modular-voice-agent-sdk/server';
|
|
11
|
+
* import { WebSocketServer } from 'ws';
|
|
12
|
+
*
|
|
13
|
+
* const pipeline = new VoicePipeline({ stt, llm, tts, systemPrompt });
|
|
14
|
+
* const handler = createPipelineHandler(pipeline);
|
|
15
|
+
*
|
|
16
|
+
* wss.on('connection', (ws) => {
|
|
17
|
+
* const session = handler.createSession();
|
|
18
|
+
* ws.on('message', async (data) => {
|
|
19
|
+
* for await (const msg of session.handle(JSON.parse(data))) {
|
|
20
|
+
* ws.send(JSON.stringify(msg));
|
|
21
|
+
* }
|
|
22
|
+
* });
|
|
23
|
+
* ws.on('close', () => session.destroy());
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export { createPipelineHandler, PipelineHandler, PipelineSession } from './handler';
|
|
28
|
+
// Re-export protocol types for server use
|
|
29
|
+
export { float32ToBase64, base64ToFloat32, } from '../client/protocol';
|
|
30
|
+
// Server-side encoding utilities (use Buffer for efficiency in Node.js)
|
|
31
|
+
export { float32ToBase64Node, base64ToFloat32Node } from './encoding';
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAGpF,0CAA0C;AAC1C,OAAO,EACL,eAAe,EACf,eAAe,GAWhB,MAAM,oBAAoB,CAAC;AAE5B,wEAAwE;AACxE,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Function Service
|
|
3
|
+
* Registry and executor for LLM tool/function calls
|
|
4
|
+
*/
|
|
5
|
+
import type { ToolDefinition, FunctionCall, FunctionResult } from '../types';
|
|
6
|
+
export declare class FunctionService {
|
|
7
|
+
private tools;
|
|
8
|
+
constructor(tools?: ToolDefinition[]);
|
|
9
|
+
register(tool: ToolDefinition): void;
|
|
10
|
+
has(name: string): boolean;
|
|
11
|
+
getDefinitions(): ToolDefinition[];
|
|
12
|
+
execute(call: FunctionCall): Promise<FunctionResult>;
|
|
13
|
+
formatForSystemPrompt(): string;
|
|
14
|
+
}
|
|
15
|
+
export declare function containsFunctionCall(text: string): boolean;
|
|
16
|
+
export declare function parseFunctionCall(text: string): FunctionCall;
|
|
17
|
+
//# sourceMappingURL=function-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function-service.d.ts","sourceRoot":"","sources":["../../src/services/function-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE7E,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAqC;gBAEtC,KAAK,GAAE,cAAc,EAAO;IAMxC,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAIpC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,cAAc,IAAI,cAAc,EAAE;IAI5B,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC;IAe1D,qBAAqB,IAAI,MAAM;CAmChC;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAc5D"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Function Service
|
|
3
|
+
* Registry and executor for LLM tool/function calls
|
|
4
|
+
*/
|
|
5
|
+
export class FunctionService {
|
|
6
|
+
tools = new Map();
|
|
7
|
+
constructor(tools = []) {
|
|
8
|
+
for (const tool of tools) {
|
|
9
|
+
this.register(tool);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
register(tool) {
|
|
13
|
+
this.tools.set(tool.name, tool);
|
|
14
|
+
}
|
|
15
|
+
has(name) {
|
|
16
|
+
return this.tools.has(name);
|
|
17
|
+
}
|
|
18
|
+
getDefinitions() {
|
|
19
|
+
return Array.from(this.tools.values());
|
|
20
|
+
}
|
|
21
|
+
async execute(call) {
|
|
22
|
+
const tool = this.tools.get(call.name);
|
|
23
|
+
if (!tool) {
|
|
24
|
+
return { name: call.name, result: `Unknown tool: "${call.name}"` };
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const result = await tool.handler(call.arguments);
|
|
28
|
+
return { name: call.name, result };
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
32
|
+
return { name: call.name, result: `Error: ${message}` };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
formatForSystemPrompt() {
|
|
36
|
+
const defs = this.getDefinitions();
|
|
37
|
+
if (defs.length === 0)
|
|
38
|
+
return '';
|
|
39
|
+
const tools = defs.map((def) => ({
|
|
40
|
+
type: 'function',
|
|
41
|
+
function: {
|
|
42
|
+
name: def.name,
|
|
43
|
+
description: def.description,
|
|
44
|
+
parameters: {
|
|
45
|
+
type: 'object',
|
|
46
|
+
properties: def.parameters
|
|
47
|
+
? Object.fromEntries(Object.entries(def.parameters).map(([k, v]) => [
|
|
48
|
+
k,
|
|
49
|
+
{ type: v.type, description: v.description },
|
|
50
|
+
]))
|
|
51
|
+
: {},
|
|
52
|
+
required: def.parameters
|
|
53
|
+
? Object.entries(def.parameters)
|
|
54
|
+
.filter(([, v]) => v.required)
|
|
55
|
+
.map(([k]) => k)
|
|
56
|
+
: [],
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
}));
|
|
60
|
+
let prompt = '\n\nYou have access to these tools:\n';
|
|
61
|
+
prompt += JSON.stringify(tools, null, 2);
|
|
62
|
+
prompt += '\n\nWhen you need to use a tool, respond with ONLY:\n';
|
|
63
|
+
prompt += '<tool_call>[{"name": "function_name", "arguments": {}}]</tool_call>';
|
|
64
|
+
return prompt;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export function containsFunctionCall(text) {
|
|
68
|
+
return /<tool_call>/.test(text);
|
|
69
|
+
}
|
|
70
|
+
export function parseFunctionCall(text) {
|
|
71
|
+
const match = text.match(/<tool_call>([\s\S]*?)<\/tool_call>/);
|
|
72
|
+
if (!match) {
|
|
73
|
+
throw new Error('No <tool_call> tag found');
|
|
74
|
+
}
|
|
75
|
+
const parsed = JSON.parse(match[1].trim());
|
|
76
|
+
if (Array.isArray(parsed)) {
|
|
77
|
+
const call = parsed[0];
|
|
78
|
+
return { name: call.name ?? call.function, arguments: call.arguments ?? {} };
|
|
79
|
+
}
|
|
80
|
+
return { name: parsed.name ?? parsed.function, arguments: parsed.arguments ?? {} };
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=function-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function-service.js","sourceRoot":"","sources":["../../src/services/function-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtG,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM Logger Service
|
|
3
|
+
*
|
|
4
|
+
* Provides structured, backend-agnostic logging for LLM interactions.
|
|
5
|
+
* Backends emit structured events, the logger handles all formatting.
|
|
6
|
+
*/
|
|
7
|
+
export type LLMLogEvent = {
|
|
8
|
+
type: 'new_conversation';
|
|
9
|
+
} | {
|
|
10
|
+
type: 'llm_call_start';
|
|
11
|
+
isFirstCall: boolean;
|
|
12
|
+
} | {
|
|
13
|
+
type: 'llm_call_output';
|
|
14
|
+
} | {
|
|
15
|
+
type: 'llm_call_end';
|
|
16
|
+
} | {
|
|
17
|
+
type: 'system';
|
|
18
|
+
content: string;
|
|
19
|
+
} | {
|
|
20
|
+
type: 'user';
|
|
21
|
+
content: string;
|
|
22
|
+
} | {
|
|
23
|
+
type: 'tool_call';
|
|
24
|
+
name: string;
|
|
25
|
+
args: Record<string, unknown>;
|
|
26
|
+
} | {
|
|
27
|
+
type: 'tool_result';
|
|
28
|
+
content: string;
|
|
29
|
+
} | {
|
|
30
|
+
type: 'assistant';
|
|
31
|
+
content: string;
|
|
32
|
+
} | {
|
|
33
|
+
type: 'response';
|
|
34
|
+
content: string;
|
|
35
|
+
} | {
|
|
36
|
+
type: 'error';
|
|
37
|
+
message: string;
|
|
38
|
+
};
|
|
39
|
+
/** Message interface for the tracker - mirrors the library's Message type */
|
|
40
|
+
export interface TrackerMessage {
|
|
41
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
42
|
+
content: string;
|
|
43
|
+
toolCalls?: Array<{
|
|
44
|
+
id: string;
|
|
45
|
+
name: string;
|
|
46
|
+
arguments: Record<string, unknown>;
|
|
47
|
+
}>;
|
|
48
|
+
toolCallId?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Formats and displays structured LLM log events
|
|
52
|
+
* All formatting (colors, icons, layout) is centralized here
|
|
53
|
+
*/
|
|
54
|
+
export declare class LLMLogger {
|
|
55
|
+
private static readonly COLORS;
|
|
56
|
+
private static readonly ICONS;
|
|
57
|
+
private enabled;
|
|
58
|
+
constructor(options?: {
|
|
59
|
+
enabled?: boolean;
|
|
60
|
+
});
|
|
61
|
+
/**
|
|
62
|
+
* Log a structured event
|
|
63
|
+
*/
|
|
64
|
+
log(event: LLMLogEvent): void;
|
|
65
|
+
/**
|
|
66
|
+
* Format tool arguments for display
|
|
67
|
+
*/
|
|
68
|
+
private formatArgs;
|
|
69
|
+
/**
|
|
70
|
+
* Enable or disable logging
|
|
71
|
+
*/
|
|
72
|
+
setEnabled(enabled: boolean): void;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Tracks conversation state and emits structured events for new messages.
|
|
76
|
+
* Works with Message[] arrays directly - used by all backends.
|
|
77
|
+
* Supports multiple simultaneous conversations via conversation IDs.
|
|
78
|
+
*/
|
|
79
|
+
export declare class LLMConversationTracker {
|
|
80
|
+
private conversations;
|
|
81
|
+
private logger;
|
|
82
|
+
constructor(logger: LLMLogger);
|
|
83
|
+
/**
|
|
84
|
+
* Get or create state for a conversation
|
|
85
|
+
*/
|
|
86
|
+
private getState;
|
|
87
|
+
/**
|
|
88
|
+
* Process messages array and emit events for new messages
|
|
89
|
+
*/
|
|
90
|
+
logInput(conversationId: string, messages: TrackerMessage[]): void;
|
|
91
|
+
/**
|
|
92
|
+
* Log an LLM response (text content and/or tool calls)
|
|
93
|
+
*/
|
|
94
|
+
logOutput(conversationId: string, content: string, toolCalls?: Array<{
|
|
95
|
+
name: string;
|
|
96
|
+
arguments: Record<string, unknown>;
|
|
97
|
+
}>): void;
|
|
98
|
+
/**
|
|
99
|
+
* Log a raw response string (for backends that return tool calls as formatted strings)
|
|
100
|
+
* Parses <tool_call> tags and handles accordingly
|
|
101
|
+
*/
|
|
102
|
+
logRawOutput(conversationId: string, response: string): void;
|
|
103
|
+
/**
|
|
104
|
+
* Remove a conversation's tracking state (called when session ends)
|
|
105
|
+
*/
|
|
106
|
+
removeConversation(conversationId: string): void;
|
|
107
|
+
/**
|
|
108
|
+
* Reset tracker state for a specific conversation
|
|
109
|
+
*/
|
|
110
|
+
resetConversation(conversationId: string): void;
|
|
111
|
+
/**
|
|
112
|
+
* Reset all tracker state (e.g., for testing)
|
|
113
|
+
*/
|
|
114
|
+
reset(): void;
|
|
115
|
+
/**
|
|
116
|
+
* Generate a unique key for a message (for deduplication)
|
|
117
|
+
*/
|
|
118
|
+
private messageKey;
|
|
119
|
+
/**
|
|
120
|
+
* Emit the appropriate log event for a message
|
|
121
|
+
*/
|
|
122
|
+
private emitMessageEvent;
|
|
123
|
+
/**
|
|
124
|
+
* Parse tool call from SmolLM2/HuggingFace format: <tool_call>[...]</tool_call>
|
|
125
|
+
*/
|
|
126
|
+
private parseToolCall;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get the default logger instance (creates one if needed)
|
|
130
|
+
*/
|
|
131
|
+
export declare function getDefaultLogger(): LLMLogger;
|
|
132
|
+
/**
|
|
133
|
+
* Get the default tracker instance (creates one if needed)
|
|
134
|
+
*/
|
|
135
|
+
export declare function getDefaultTracker(): LLMConversationTracker;
|
|
136
|
+
//# sourceMappingURL=llm-logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-logger.d.ts","sourceRoot":"","sources":["../../src/services/llm-logger.ts"],"names":[],"mappings":"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"}
|