@voice-kit/core 0.1.1 → 0.1.3
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/dist/index.cjs +2137 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1466 -3
- package/dist/index.d.ts +1466 -3
- package/dist/index.js +2102 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -26
- package/dist/compliance.cjs +0 -343
- package/dist/compliance.cjs.map +0 -1
- package/dist/compliance.d.cts +0 -163
- package/dist/compliance.d.ts +0 -163
- package/dist/compliance.js +0 -335
- package/dist/compliance.js.map +0 -1
- package/dist/errors.cjs +0 -284
- package/dist/errors.cjs.map +0 -1
- package/dist/errors.d.cts +0 -175
- package/dist/errors.d.ts +0 -175
- package/dist/errors.js +0 -262
- package/dist/errors.js.map +0 -1
- package/dist/index-CkTG6DOa.d.cts +0 -319
- package/dist/index-CkTG6DOa.d.ts +0 -319
- package/dist/memory.cjs +0 -121
- package/dist/memory.cjs.map +0 -1
- package/dist/memory.d.cts +0 -29
- package/dist/memory.d.ts +0 -29
- package/dist/memory.js +0 -115
- package/dist/memory.js.map +0 -1
- package/dist/observability.cjs +0 -229
- package/dist/observability.cjs.map +0 -1
- package/dist/observability.d.cts +0 -122
- package/dist/observability.d.ts +0 -122
- package/dist/observability.js +0 -222
- package/dist/observability.js.map +0 -1
- package/dist/stt.cjs +0 -828
- package/dist/stt.cjs.map +0 -1
- package/dist/stt.d.cts +0 -308
- package/dist/stt.d.ts +0 -308
- package/dist/stt.js +0 -815
- package/dist/stt.js.map +0 -1
- package/dist/tts.cjs +0 -429
- package/dist/tts.cjs.map +0 -1
- package/dist/tts.d.cts +0 -151
- package/dist/tts.d.ts +0 -151
- package/dist/tts.js +0 -418
- package/dist/tts.js.map +0 -1
package/dist/observability.cjs
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var lruCache = require('lru-cache');
|
|
4
|
-
var pino = require('pino');
|
|
5
|
-
var sdkTraceNode = require('@opentelemetry/sdk-trace-node');
|
|
6
|
-
var exporterTraceOtlpHttp = require('@opentelemetry/exporter-trace-otlp-http');
|
|
7
|
-
var sdkTraceBase = require('@opentelemetry/sdk-trace-base');
|
|
8
|
-
var semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
9
|
-
var api = require('@opentelemetry/api');
|
|
10
|
-
var resources = require('@opentelemetry/resources');
|
|
11
|
-
|
|
12
|
-
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
-
|
|
14
|
-
var pino__default = /*#__PURE__*/_interopDefault(pino);
|
|
15
|
-
|
|
16
|
-
// src/observability/metric/index.ts
|
|
17
|
-
var logger = pino__default.default({ name: "@voice-kit/core:metrics" });
|
|
18
|
-
var TOKEN_COSTS_PER_M = {
|
|
19
|
-
"gpt-4o": { input: 5, output: 15 },
|
|
20
|
-
"gpt-4o-mini": { input: 0.15, output: 0.6 },
|
|
21
|
-
"claude-3-5-sonnet": { input: 3, output: 15 },
|
|
22
|
-
"llama-3.3-70b": { input: 0.59, output: 0.79 }
|
|
23
|
-
};
|
|
24
|
-
function p95(values) {
|
|
25
|
-
if (values.length === 0) return 0;
|
|
26
|
-
const sorted = [...values].sort((a, b) => a - b);
|
|
27
|
-
const idx = Math.floor(sorted.length * 0.95);
|
|
28
|
-
return sorted[Math.min(idx, sorted.length - 1)] ?? 0;
|
|
29
|
-
}
|
|
30
|
-
function avg(values) {
|
|
31
|
-
if (values.length === 0) return 0;
|
|
32
|
-
return values.reduce((a, b) => a + b, 0) / values.length;
|
|
33
|
-
}
|
|
34
|
-
var CallMetrics = class {
|
|
35
|
-
store;
|
|
36
|
-
constructor() {
|
|
37
|
-
this.store = new lruCache.LRUCache({
|
|
38
|
-
max: 1e4,
|
|
39
|
-
ttl: 2 * 60 * 60 * 1e3
|
|
40
|
-
// 2 hours
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
getOrCreate(callId) {
|
|
44
|
-
const existing = this.store.get(callId);
|
|
45
|
-
if (existing) return existing;
|
|
46
|
-
const data = {
|
|
47
|
-
sttFirstByteMs: [],
|
|
48
|
-
ttsFirstByteMs: [],
|
|
49
|
-
llmFirstTokenMs: [],
|
|
50
|
-
turnLatencyMs: [],
|
|
51
|
-
interruptionCount: 0,
|
|
52
|
-
interruptionPositions: [],
|
|
53
|
-
tokenCost: []
|
|
54
|
-
};
|
|
55
|
-
this.store.set(callId, data);
|
|
56
|
-
return data;
|
|
57
|
-
}
|
|
58
|
-
/** Record time from audio start to first STT partial result. */
|
|
59
|
-
recordSTTFirstByte(callId, ms) {
|
|
60
|
-
this.getOrCreate(callId).sttFirstByteMs.push(ms);
|
|
61
|
-
logger.debug({ callId, ms }, "Metric: STT TTFB");
|
|
62
|
-
}
|
|
63
|
-
/** Record time from TTS request to first audio chunk. */
|
|
64
|
-
recordTTSFirstByte(callId, ms) {
|
|
65
|
-
this.getOrCreate(callId).ttsFirstByteMs.push(ms);
|
|
66
|
-
logger.debug({ callId, ms }, "Metric: TTS TTFB");
|
|
67
|
-
}
|
|
68
|
-
/** Record time from LLM request to first token. */
|
|
69
|
-
recordLLMFirstToken(callId, ms) {
|
|
70
|
-
this.getOrCreate(callId).llmFirstTokenMs.push(ms);
|
|
71
|
-
logger.debug({ callId, ms }, "Metric: LLM first token");
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Record end-to-end turn latency: speech_end → first TTS audio byte.
|
|
75
|
-
* This is the primary latency metric for voice agent quality.
|
|
76
|
-
*/
|
|
77
|
-
recordTurnLatency(callId, ms) {
|
|
78
|
-
this.getOrCreate(callId).turnLatencyMs.push(ms);
|
|
79
|
-
logger.debug({ callId, ms }, "Metric: turn latency");
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Record an interruption event.
|
|
83
|
-
*
|
|
84
|
-
* @param callId Call identifier
|
|
85
|
-
* @param positionPct 0–1, how far through the TTS stream the interruption occurred
|
|
86
|
-
*/
|
|
87
|
-
recordInterruption(callId, positionPct) {
|
|
88
|
-
const data = this.getOrCreate(callId);
|
|
89
|
-
data.interruptionCount++;
|
|
90
|
-
data.interruptionPositions.push(positionPct);
|
|
91
|
-
logger.debug({ callId, positionPct }, "Metric: interruption");
|
|
92
|
-
}
|
|
93
|
-
/** Record token usage and estimated cost for a model call. */
|
|
94
|
-
recordTokenCost(callId, model, inputTokens, outputTokens) {
|
|
95
|
-
const costs = TOKEN_COSTS_PER_M[model] ?? { input: 0, output: 0 };
|
|
96
|
-
const estimatedUsdCost = inputTokens / 1e6 * costs.input + outputTokens / 1e6 * costs.output;
|
|
97
|
-
this.getOrCreate(callId).tokenCost.push({
|
|
98
|
-
model,
|
|
99
|
-
inputTokens,
|
|
100
|
-
outputTokens,
|
|
101
|
-
estimatedUsdCost
|
|
102
|
-
});
|
|
103
|
-
logger.debug({ callId, model, inputTokens, outputTokens, estimatedUsdCost }, "Metric: token cost");
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Get a full summary of metrics for a call.
|
|
107
|
-
*
|
|
108
|
-
* @param callId The call identifier
|
|
109
|
-
* @returns Aggregated metrics summary
|
|
110
|
-
*/
|
|
111
|
-
getCallSummary(callId) {
|
|
112
|
-
const data = this.getOrCreate(callId);
|
|
113
|
-
return {
|
|
114
|
-
callId,
|
|
115
|
-
sttFirstByteMs: [...data.sttFirstByteMs],
|
|
116
|
-
ttsFirstByteMs: [...data.ttsFirstByteMs],
|
|
117
|
-
llmFirstTokenMs: [...data.llmFirstTokenMs],
|
|
118
|
-
turnLatencyMs: [...data.turnLatencyMs],
|
|
119
|
-
interruptionCount: data.interruptionCount,
|
|
120
|
-
interruptionPositions: [...data.interruptionPositions],
|
|
121
|
-
tokenCost: [...data.tokenCost],
|
|
122
|
-
avgTurnLatencyMs: Math.round(avg(data.turnLatencyMs)),
|
|
123
|
-
p95TurnLatencyMs: Math.round(p95(data.turnLatencyMs))
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
/** Remove metrics for a call. Call on call.ended to free memory. */
|
|
127
|
-
clearCall(callId) {
|
|
128
|
-
this.store.delete(callId);
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
var logger2 = pino__default.default({ name: "@voice-kit/core:observability" });
|
|
132
|
-
var _provider = null;
|
|
133
|
-
function getOrInitProvider() {
|
|
134
|
-
if (_provider) return _provider;
|
|
135
|
-
const endpoint = process.env["OTEL_EXPORTER_OTLP_ENDPOINT"];
|
|
136
|
-
_provider = new sdkTraceNode.NodeTracerProvider({
|
|
137
|
-
resource: resources.resourceFromAttributes({
|
|
138
|
-
[semanticConventions.ATTR_SERVICE_NAME]: "voice-kit"
|
|
139
|
-
}),
|
|
140
|
-
// Pass span processors directly in constructor — addSpanProcessor doesn't exist in this version
|
|
141
|
-
spanProcessors: endpoint ? [new sdkTraceBase.SimpleSpanProcessor(new exporterTraceOtlpHttp.OTLPTraceExporter({ url: endpoint }))] : []
|
|
142
|
-
});
|
|
143
|
-
if (endpoint) {
|
|
144
|
-
logger2.info({ endpoint }, "OTel OTLP exporter configured");
|
|
145
|
-
}
|
|
146
|
-
_provider.register();
|
|
147
|
-
return _provider;
|
|
148
|
-
}
|
|
149
|
-
var VoiceSDKTracer = class {
|
|
150
|
-
tracer;
|
|
151
|
-
constructor() {
|
|
152
|
-
getOrInitProvider();
|
|
153
|
-
this.tracer = api.trace.getTracer("@voice-kit/core", "0.1.0");
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Trace an STT operation with provider + language attributes.
|
|
157
|
-
*/
|
|
158
|
-
async traceSTT(fn, attrs) {
|
|
159
|
-
return this.withSpan(`stt.${attrs.provider}`, fn, {
|
|
160
|
-
"stt.provider": attrs.provider,
|
|
161
|
-
"stt.language": attrs.language,
|
|
162
|
-
...attrs.callId && { "call.id": attrs.callId }
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Trace a TTS synthesis operation.
|
|
167
|
-
*/
|
|
168
|
-
async traceTTS(fn, attrs) {
|
|
169
|
-
return this.withSpan(`tts.${attrs.provider}`, fn, {
|
|
170
|
-
"tts.provider": attrs.provider,
|
|
171
|
-
"tts.voice_id": attrs.voice,
|
|
172
|
-
"tts.char_count": attrs.chars,
|
|
173
|
-
...attrs.callId && { "call.id": attrs.callId }
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Trace an LLM generation call.
|
|
178
|
-
*/
|
|
179
|
-
async traceLLM(fn, attrs) {
|
|
180
|
-
return this.withSpan(`llm.${attrs.model}`, fn, {
|
|
181
|
-
"llm.model": attrs.model,
|
|
182
|
-
"llm.input_tokens": attrs.inputTokens,
|
|
183
|
-
...attrs.callId && { "call.id": attrs.callId }
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Trace a full call lifecycle.
|
|
188
|
-
*/
|
|
189
|
-
async traceCall(fn, attrs) {
|
|
190
|
-
return this.withSpan("call", fn, {
|
|
191
|
-
"call.id": attrs.callId,
|
|
192
|
-
"call.direction": attrs.direction
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Trace a single conversation turn.
|
|
197
|
-
*/
|
|
198
|
-
async traceTurn(fn, attrs) {
|
|
199
|
-
return this.withSpan("turn", fn, {
|
|
200
|
-
"turn.index": attrs.turnIndex,
|
|
201
|
-
"call.id": attrs.callId
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
/** Generic span wrapper. @internal */
|
|
205
|
-
async withSpan(name, fn, attributes) {
|
|
206
|
-
const span = this.tracer.startSpan(name, { attributes });
|
|
207
|
-
const startMs = Date.now();
|
|
208
|
-
try {
|
|
209
|
-
const result = await fn();
|
|
210
|
-
span.setStatus({ code: api.SpanStatusCode.OK });
|
|
211
|
-
span.setAttribute("duration_ms", Date.now() - startMs);
|
|
212
|
-
return result;
|
|
213
|
-
} catch (err) {
|
|
214
|
-
span.setStatus({
|
|
215
|
-
code: api.SpanStatusCode.ERROR,
|
|
216
|
-
message: err instanceof Error ? err.message : String(err)
|
|
217
|
-
});
|
|
218
|
-
span.recordException(err instanceof Error ? err : new Error(String(err)));
|
|
219
|
-
throw err;
|
|
220
|
-
} finally {
|
|
221
|
-
span.end();
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
exports.CallMetrics = CallMetrics;
|
|
227
|
-
exports.VoiceSDKTracer = VoiceSDKTracer;
|
|
228
|
-
//# sourceMappingURL=observability.cjs.map
|
|
229
|
-
//# sourceMappingURL=observability.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/observability/metric/index.ts","../src/observability/tracer/index.ts"],"names":["pino","LRUCache","logger","NodeTracerProvider","Resource","ATTR_SERVICE_NAME","SimpleSpanProcessor","OTLPTraceExporter","trace","SpanStatusCode"],"mappings":"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","file":"observability.cjs","sourcesContent":["/**\r\n * @voice-kit/core — CallMetrics\r\n *\r\n * Records per-call performance metrics: TTFB, turn latency, token cost, interruption rate.\r\n * In-process LRU storage — exported via getCallSummary().\r\n */\r\n\r\nimport { LRUCache } from 'lru-cache'\r\nimport type { CallMetricsSummary } from '../../types'\r\nimport pino from 'pino'\r\n\r\nconst logger = pino({ name: '@voice-kit/core:metrics' })\r\n\r\n/** USD cost per 1M tokens by model. Approximate — update as pricing changes. */\r\nconst TOKEN_COSTS_PER_M: Record<string, { input: number; output: number }> = {\r\n 'gpt-4o': { input: 5.0, output: 15.0 },\r\n 'gpt-4o-mini': { input: 0.15, output: 0.6 },\r\n 'claude-3-5-sonnet': { input: 3.0, output: 15.0 },\r\n 'llama-3.3-70b': { input: 0.59, output: 0.79 },\r\n}\r\n\r\ninterface CallData {\r\n sttFirstByteMs: number[]\r\n ttsFirstByteMs: number[]\r\n llmFirstTokenMs: number[]\r\n turnLatencyMs: number[]\r\n interruptionCount: number\r\n interruptionPositions: number[]\r\n tokenCost: Array<{\r\n model: string\r\n inputTokens: number\r\n outputTokens: number\r\n estimatedUsdCost: number\r\n }>\r\n}\r\n\r\nfunction p95(values: number[]): number {\r\n if (values.length === 0) return 0\r\n const sorted = [...values].sort((a, b) => a - b)\r\n const idx = Math.floor(sorted.length * 0.95)\r\n return sorted[Math.min(idx, sorted.length - 1)] ?? 0\r\n}\r\n\r\nfunction avg(values: number[]): number {\r\n if (values.length === 0) return 0\r\n return values.reduce((a, b) => a + b, 0) / values.length\r\n}\r\n\r\n/**\r\n * Per-call performance metrics recorder.\r\n *\r\n * @example\r\n * ```ts\r\n * const metrics = new CallMetrics()\r\n * metrics.recordSTTFirstByte(callId, 180)\r\n * metrics.recordTurnLatency(callId, 340)\r\n * const summary = metrics.getCallSummary(callId)\r\n * console.log(summary.avgTurnLatencyMs) // 340\r\n * ```\r\n */\r\nexport class CallMetrics {\r\n private readonly store: LRUCache<string, CallData>\r\n\r\n constructor() {\r\n this.store = new LRUCache<string, CallData>({\r\n max: 10_000,\r\n ttl: 2 * 60 * 60 * 1_000, // 2 hours\r\n })\r\n }\r\n\r\n private getOrCreate(callId: string): CallData {\r\n const existing = this.store.get(callId)\r\n if (existing) return existing\r\n\r\n const data: CallData = {\r\n sttFirstByteMs: [],\r\n ttsFirstByteMs: [],\r\n llmFirstTokenMs: [],\r\n turnLatencyMs: [],\r\n interruptionCount: 0,\r\n interruptionPositions: [],\r\n tokenCost: [],\r\n }\r\n this.store.set(callId, data)\r\n return data\r\n }\r\n\r\n /** Record time from audio start to first STT partial result. */\r\n recordSTTFirstByte(callId: string, ms: number): void {\r\n this.getOrCreate(callId).sttFirstByteMs.push(ms)\r\n logger.debug({ callId, ms }, 'Metric: STT TTFB')\r\n }\r\n\r\n /** Record time from TTS request to first audio chunk. */\r\n recordTTSFirstByte(callId: string, ms: number): void {\r\n this.getOrCreate(callId).ttsFirstByteMs.push(ms)\r\n logger.debug({ callId, ms }, 'Metric: TTS TTFB')\r\n }\r\n\r\n /** Record time from LLM request to first token. */\r\n recordLLMFirstToken(callId: string, ms: number): void {\r\n this.getOrCreate(callId).llmFirstTokenMs.push(ms)\r\n logger.debug({ callId, ms }, 'Metric: LLM first token')\r\n }\r\n\r\n /**\r\n * Record end-to-end turn latency: speech_end → first TTS audio byte.\r\n * This is the primary latency metric for voice agent quality.\r\n */\r\n recordTurnLatency(callId: string, ms: number): void {\r\n this.getOrCreate(callId).turnLatencyMs.push(ms)\r\n logger.debug({ callId, ms }, 'Metric: turn latency')\r\n }\r\n\r\n /**\r\n * Record an interruption event.\r\n *\r\n * @param callId Call identifier\r\n * @param positionPct 0–1, how far through the TTS stream the interruption occurred\r\n */\r\n recordInterruption(callId: string, positionPct: number): void {\r\n const data = this.getOrCreate(callId)\r\n data.interruptionCount++\r\n data.interruptionPositions.push(positionPct)\r\n logger.debug({ callId, positionPct }, 'Metric: interruption')\r\n }\r\n\r\n /** Record token usage and estimated cost for a model call. */\r\n recordTokenCost(\r\n callId: string,\r\n model: string,\r\n inputTokens: number,\r\n outputTokens: number\r\n ): void {\r\n const costs = TOKEN_COSTS_PER_M[model] ?? { input: 0, output: 0 }\r\n const estimatedUsdCost =\r\n (inputTokens / 1_000_000) * costs.input +\r\n (outputTokens / 1_000_000) * costs.output\r\n\r\n this.getOrCreate(callId).tokenCost.push({\r\n model,\r\n inputTokens,\r\n outputTokens,\r\n estimatedUsdCost,\r\n })\r\n\r\n logger.debug({ callId, model, inputTokens, outputTokens, estimatedUsdCost }, 'Metric: token cost')\r\n }\r\n\r\n /**\r\n * Get a full summary of metrics for a call.\r\n *\r\n * @param callId The call identifier\r\n * @returns Aggregated metrics summary\r\n */\r\n getCallSummary(callId: string): CallMetricsSummary {\r\n const data = this.getOrCreate(callId)\r\n\r\n return {\r\n callId,\r\n sttFirstByteMs: [...data.sttFirstByteMs],\r\n ttsFirstByteMs: [...data.ttsFirstByteMs],\r\n llmFirstTokenMs: [...data.llmFirstTokenMs],\r\n turnLatencyMs: [...data.turnLatencyMs],\r\n interruptionCount: data.interruptionCount,\r\n interruptionPositions: [...data.interruptionPositions],\r\n tokenCost: [...data.tokenCost],\r\n avgTurnLatencyMs: Math.round(avg(data.turnLatencyMs)),\r\n p95TurnLatencyMs: Math.round(p95(data.turnLatencyMs)),\r\n }\r\n }\r\n\r\n /** Remove metrics for a call. Call on call.ended to free memory. */\r\n clearCall(callId: string): void {\r\n this.store.delete(callId)\r\n }\r\n}","/**\r\n * @voice-kit/core — OpenTelemetry tracing\r\n *\r\n * VoiceSDKTracer: wraps every external provider call with OTel spans.\r\n * Auto-exports to OTLP endpoint if OTEL_EXPORTER_OTLP_ENDPOINT is set.\r\n */\r\n\r\nimport { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'\r\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'\r\nimport { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'\r\nimport { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions'\r\nimport { trace, SpanStatusCode, type Tracer, type Span } from '@opentelemetry/api'\r\nimport { resourceFromAttributes as Resource } from '@opentelemetry/resources'\r\nimport pino from 'pino'\r\n\r\nconst logger = pino({ name: '@voice-kit/core:observability' })\r\n\r\nlet _provider: NodeTracerProvider | null = null\r\n\r\n/**\r\n * Initialize the global OTel trace provider.\r\n * Called once at SDK startup if OTEL_EXPORTER_OTLP_ENDPOINT is set.\r\n *\r\n * @internal\r\n */\r\nfunction getOrInitProvider(): NodeTracerProvider {\r\n if (_provider) return _provider\r\n\r\n const endpoint = process.env['OTEL_EXPORTER_OTLP_ENDPOINT']\r\n\r\n _provider = new NodeTracerProvider({\r\n resource: Resource({\r\n [ATTR_SERVICE_NAME]: 'voice-kit',\r\n }),\r\n // Pass span processors directly in constructor — addSpanProcessor doesn't exist in this version\r\n spanProcessors: endpoint\r\n ? [new SimpleSpanProcessor(new OTLPTraceExporter({ url: endpoint }))]\r\n : [],\r\n })\r\n\r\n if (endpoint) {\r\n logger.info({ endpoint }, 'OTel OTLP exporter configured')\r\n }\r\n\r\n _provider.register()\r\n return _provider\r\n}\r\n\r\n/**\r\n * OpenTelemetry tracer for VoiceKit. Wraps every external I/O with spans.\r\n *\r\n * @example\r\n * ```ts\r\n * const tracer = new VoiceSDKTracer()\r\n * const result = await tracer.traceSTT(\r\n * () => stt.transcribeBatch(audio),\r\n * { provider: 'deepgram', language: 'en-IN' }\r\n * )\r\n * ```\r\n */\r\nexport class VoiceSDKTracer {\r\n private readonly tracer: Tracer\r\n\r\n constructor() {\r\n getOrInitProvider()\r\n this.tracer = trace.getTracer('@voice-kit/core', '0.1.0')\r\n }\r\n\r\n /**\r\n * Trace an STT operation with provider + language attributes.\r\n */\r\n async traceSTT<T>(\r\n fn: () => Promise<T>,\r\n attrs: { provider: string; language: string; callId?: string }\r\n ): Promise<T> {\r\n return this.withSpan(`stt.${attrs.provider}`, fn, {\r\n 'stt.provider': attrs.provider,\r\n 'stt.language': attrs.language,\r\n ...(attrs.callId && { 'call.id': attrs.callId }),\r\n })\r\n }\r\n\r\n /**\r\n * Trace a TTS synthesis operation.\r\n */\r\n async traceTTS<T>(\r\n fn: () => Promise<T>,\r\n attrs: { provider: string; voice: string; chars: number; callId?: string }\r\n ): Promise<T> {\r\n return this.withSpan(`tts.${attrs.provider}`, fn, {\r\n 'tts.provider': attrs.provider,\r\n 'tts.voice_id': attrs.voice,\r\n 'tts.char_count': attrs.chars,\r\n ...(attrs.callId && { 'call.id': attrs.callId }),\r\n })\r\n }\r\n\r\n /**\r\n * Trace an LLM generation call.\r\n */\r\n async traceLLM<T>(\r\n fn: () => Promise<T>,\r\n attrs: { model: string; inputTokens: number; callId?: string }\r\n ): Promise<T> {\r\n return this.withSpan(`llm.${attrs.model}`, fn, {\r\n 'llm.model': attrs.model,\r\n 'llm.input_tokens': attrs.inputTokens,\r\n ...(attrs.callId && { 'call.id': attrs.callId }),\r\n })\r\n }\r\n\r\n /**\r\n * Trace a full call lifecycle.\r\n */\r\n async traceCall<T>(\r\n fn: () => Promise<T>,\r\n attrs: { callId: string; direction: 'inbound' | 'outbound' }\r\n ): Promise<T> {\r\n return this.withSpan('call', fn, {\r\n 'call.id': attrs.callId,\r\n 'call.direction': attrs.direction,\r\n })\r\n }\r\n\r\n /**\r\n * Trace a single conversation turn.\r\n */\r\n async traceTurn<T>(\r\n fn: () => Promise<T>,\r\n attrs: { turnIndex: number; callId: string }\r\n ): Promise<T> {\r\n return this.withSpan('turn', fn, {\r\n 'turn.index': attrs.turnIndex,\r\n 'call.id': attrs.callId,\r\n })\r\n }\r\n\r\n /** Generic span wrapper. @internal */\r\n private async withSpan<T>(\r\n name: string,\r\n fn: () => Promise<T>,\r\n attributes: Record<string, string | number | boolean>\r\n ): Promise<T> {\r\n const span: Span = this.tracer.startSpan(name, { attributes })\r\n const startMs = Date.now()\r\n\r\n try {\r\n const result = await fn()\r\n span.setStatus({ code: SpanStatusCode.OK })\r\n span.setAttribute('duration_ms', Date.now() - startMs)\r\n return result\r\n } catch (err) {\r\n span.setStatus({\r\n code: SpanStatusCode.ERROR,\r\n message: err instanceof Error ? err.message : String(err),\r\n })\r\n span.recordException(err instanceof Error ? err : new Error(String(err)))\r\n throw err\r\n } finally {\r\n span.end()\r\n }\r\n }\r\n}"]}
|
package/dist/observability.d.cts
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { d as CallMetricsSummary } from './index-CkTG6DOa.cjs';
|
|
2
|
-
import 'ai';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @voice-kit/core — CallMetrics
|
|
6
|
-
*
|
|
7
|
-
* Records per-call performance metrics: TTFB, turn latency, token cost, interruption rate.
|
|
8
|
-
* In-process LRU storage — exported via getCallSummary().
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Per-call performance metrics recorder.
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```ts
|
|
16
|
-
* const metrics = new CallMetrics()
|
|
17
|
-
* metrics.recordSTTFirstByte(callId, 180)
|
|
18
|
-
* metrics.recordTurnLatency(callId, 340)
|
|
19
|
-
* const summary = metrics.getCallSummary(callId)
|
|
20
|
-
* console.log(summary.avgTurnLatencyMs) // 340
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
declare class CallMetrics {
|
|
24
|
-
private readonly store;
|
|
25
|
-
constructor();
|
|
26
|
-
private getOrCreate;
|
|
27
|
-
/** Record time from audio start to first STT partial result. */
|
|
28
|
-
recordSTTFirstByte(callId: string, ms: number): void;
|
|
29
|
-
/** Record time from TTS request to first audio chunk. */
|
|
30
|
-
recordTTSFirstByte(callId: string, ms: number): void;
|
|
31
|
-
/** Record time from LLM request to first token. */
|
|
32
|
-
recordLLMFirstToken(callId: string, ms: number): void;
|
|
33
|
-
/**
|
|
34
|
-
* Record end-to-end turn latency: speech_end → first TTS audio byte.
|
|
35
|
-
* This is the primary latency metric for voice agent quality.
|
|
36
|
-
*/
|
|
37
|
-
recordTurnLatency(callId: string, ms: number): void;
|
|
38
|
-
/**
|
|
39
|
-
* Record an interruption event.
|
|
40
|
-
*
|
|
41
|
-
* @param callId Call identifier
|
|
42
|
-
* @param positionPct 0–1, how far through the TTS stream the interruption occurred
|
|
43
|
-
*/
|
|
44
|
-
recordInterruption(callId: string, positionPct: number): void;
|
|
45
|
-
/** Record token usage and estimated cost for a model call. */
|
|
46
|
-
recordTokenCost(callId: string, model: string, inputTokens: number, outputTokens: number): void;
|
|
47
|
-
/**
|
|
48
|
-
* Get a full summary of metrics for a call.
|
|
49
|
-
*
|
|
50
|
-
* @param callId The call identifier
|
|
51
|
-
* @returns Aggregated metrics summary
|
|
52
|
-
*/
|
|
53
|
-
getCallSummary(callId: string): CallMetricsSummary;
|
|
54
|
-
/** Remove metrics for a call. Call on call.ended to free memory. */
|
|
55
|
-
clearCall(callId: string): void;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* @voice-kit/core — OpenTelemetry tracing
|
|
60
|
-
*
|
|
61
|
-
* VoiceSDKTracer: wraps every external provider call with OTel spans.
|
|
62
|
-
* Auto-exports to OTLP endpoint if OTEL_EXPORTER_OTLP_ENDPOINT is set.
|
|
63
|
-
*/
|
|
64
|
-
/**
|
|
65
|
-
* OpenTelemetry tracer for VoiceKit. Wraps every external I/O with spans.
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* ```ts
|
|
69
|
-
* const tracer = new VoiceSDKTracer()
|
|
70
|
-
* const result = await tracer.traceSTT(
|
|
71
|
-
* () => stt.transcribeBatch(audio),
|
|
72
|
-
* { provider: 'deepgram', language: 'en-IN' }
|
|
73
|
-
* )
|
|
74
|
-
* ```
|
|
75
|
-
*/
|
|
76
|
-
declare class VoiceSDKTracer {
|
|
77
|
-
private readonly tracer;
|
|
78
|
-
constructor();
|
|
79
|
-
/**
|
|
80
|
-
* Trace an STT operation with provider + language attributes.
|
|
81
|
-
*/
|
|
82
|
-
traceSTT<T>(fn: () => Promise<T>, attrs: {
|
|
83
|
-
provider: string;
|
|
84
|
-
language: string;
|
|
85
|
-
callId?: string;
|
|
86
|
-
}): Promise<T>;
|
|
87
|
-
/**
|
|
88
|
-
* Trace a TTS synthesis operation.
|
|
89
|
-
*/
|
|
90
|
-
traceTTS<T>(fn: () => Promise<T>, attrs: {
|
|
91
|
-
provider: string;
|
|
92
|
-
voice: string;
|
|
93
|
-
chars: number;
|
|
94
|
-
callId?: string;
|
|
95
|
-
}): Promise<T>;
|
|
96
|
-
/**
|
|
97
|
-
* Trace an LLM generation call.
|
|
98
|
-
*/
|
|
99
|
-
traceLLM<T>(fn: () => Promise<T>, attrs: {
|
|
100
|
-
model: string;
|
|
101
|
-
inputTokens: number;
|
|
102
|
-
callId?: string;
|
|
103
|
-
}): Promise<T>;
|
|
104
|
-
/**
|
|
105
|
-
* Trace a full call lifecycle.
|
|
106
|
-
*/
|
|
107
|
-
traceCall<T>(fn: () => Promise<T>, attrs: {
|
|
108
|
-
callId: string;
|
|
109
|
-
direction: 'inbound' | 'outbound';
|
|
110
|
-
}): Promise<T>;
|
|
111
|
-
/**
|
|
112
|
-
* Trace a single conversation turn.
|
|
113
|
-
*/
|
|
114
|
-
traceTurn<T>(fn: () => Promise<T>, attrs: {
|
|
115
|
-
turnIndex: number;
|
|
116
|
-
callId: string;
|
|
117
|
-
}): Promise<T>;
|
|
118
|
-
/** Generic span wrapper. @internal */
|
|
119
|
-
private withSpan;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export { CallMetrics, VoiceSDKTracer };
|
package/dist/observability.d.ts
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { d as CallMetricsSummary } from './index-CkTG6DOa.js';
|
|
2
|
-
import 'ai';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @voice-kit/core — CallMetrics
|
|
6
|
-
*
|
|
7
|
-
* Records per-call performance metrics: TTFB, turn latency, token cost, interruption rate.
|
|
8
|
-
* In-process LRU storage — exported via getCallSummary().
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Per-call performance metrics recorder.
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```ts
|
|
16
|
-
* const metrics = new CallMetrics()
|
|
17
|
-
* metrics.recordSTTFirstByte(callId, 180)
|
|
18
|
-
* metrics.recordTurnLatency(callId, 340)
|
|
19
|
-
* const summary = metrics.getCallSummary(callId)
|
|
20
|
-
* console.log(summary.avgTurnLatencyMs) // 340
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
declare class CallMetrics {
|
|
24
|
-
private readonly store;
|
|
25
|
-
constructor();
|
|
26
|
-
private getOrCreate;
|
|
27
|
-
/** Record time from audio start to first STT partial result. */
|
|
28
|
-
recordSTTFirstByte(callId: string, ms: number): void;
|
|
29
|
-
/** Record time from TTS request to first audio chunk. */
|
|
30
|
-
recordTTSFirstByte(callId: string, ms: number): void;
|
|
31
|
-
/** Record time from LLM request to first token. */
|
|
32
|
-
recordLLMFirstToken(callId: string, ms: number): void;
|
|
33
|
-
/**
|
|
34
|
-
* Record end-to-end turn latency: speech_end → first TTS audio byte.
|
|
35
|
-
* This is the primary latency metric for voice agent quality.
|
|
36
|
-
*/
|
|
37
|
-
recordTurnLatency(callId: string, ms: number): void;
|
|
38
|
-
/**
|
|
39
|
-
* Record an interruption event.
|
|
40
|
-
*
|
|
41
|
-
* @param callId Call identifier
|
|
42
|
-
* @param positionPct 0–1, how far through the TTS stream the interruption occurred
|
|
43
|
-
*/
|
|
44
|
-
recordInterruption(callId: string, positionPct: number): void;
|
|
45
|
-
/** Record token usage and estimated cost for a model call. */
|
|
46
|
-
recordTokenCost(callId: string, model: string, inputTokens: number, outputTokens: number): void;
|
|
47
|
-
/**
|
|
48
|
-
* Get a full summary of metrics for a call.
|
|
49
|
-
*
|
|
50
|
-
* @param callId The call identifier
|
|
51
|
-
* @returns Aggregated metrics summary
|
|
52
|
-
*/
|
|
53
|
-
getCallSummary(callId: string): CallMetricsSummary;
|
|
54
|
-
/** Remove metrics for a call. Call on call.ended to free memory. */
|
|
55
|
-
clearCall(callId: string): void;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* @voice-kit/core — OpenTelemetry tracing
|
|
60
|
-
*
|
|
61
|
-
* VoiceSDKTracer: wraps every external provider call with OTel spans.
|
|
62
|
-
* Auto-exports to OTLP endpoint if OTEL_EXPORTER_OTLP_ENDPOINT is set.
|
|
63
|
-
*/
|
|
64
|
-
/**
|
|
65
|
-
* OpenTelemetry tracer for VoiceKit. Wraps every external I/O with spans.
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* ```ts
|
|
69
|
-
* const tracer = new VoiceSDKTracer()
|
|
70
|
-
* const result = await tracer.traceSTT(
|
|
71
|
-
* () => stt.transcribeBatch(audio),
|
|
72
|
-
* { provider: 'deepgram', language: 'en-IN' }
|
|
73
|
-
* )
|
|
74
|
-
* ```
|
|
75
|
-
*/
|
|
76
|
-
declare class VoiceSDKTracer {
|
|
77
|
-
private readonly tracer;
|
|
78
|
-
constructor();
|
|
79
|
-
/**
|
|
80
|
-
* Trace an STT operation with provider + language attributes.
|
|
81
|
-
*/
|
|
82
|
-
traceSTT<T>(fn: () => Promise<T>, attrs: {
|
|
83
|
-
provider: string;
|
|
84
|
-
language: string;
|
|
85
|
-
callId?: string;
|
|
86
|
-
}): Promise<T>;
|
|
87
|
-
/**
|
|
88
|
-
* Trace a TTS synthesis operation.
|
|
89
|
-
*/
|
|
90
|
-
traceTTS<T>(fn: () => Promise<T>, attrs: {
|
|
91
|
-
provider: string;
|
|
92
|
-
voice: string;
|
|
93
|
-
chars: number;
|
|
94
|
-
callId?: string;
|
|
95
|
-
}): Promise<T>;
|
|
96
|
-
/**
|
|
97
|
-
* Trace an LLM generation call.
|
|
98
|
-
*/
|
|
99
|
-
traceLLM<T>(fn: () => Promise<T>, attrs: {
|
|
100
|
-
model: string;
|
|
101
|
-
inputTokens: number;
|
|
102
|
-
callId?: string;
|
|
103
|
-
}): Promise<T>;
|
|
104
|
-
/**
|
|
105
|
-
* Trace a full call lifecycle.
|
|
106
|
-
*/
|
|
107
|
-
traceCall<T>(fn: () => Promise<T>, attrs: {
|
|
108
|
-
callId: string;
|
|
109
|
-
direction: 'inbound' | 'outbound';
|
|
110
|
-
}): Promise<T>;
|
|
111
|
-
/**
|
|
112
|
-
* Trace a single conversation turn.
|
|
113
|
-
*/
|
|
114
|
-
traceTurn<T>(fn: () => Promise<T>, attrs: {
|
|
115
|
-
turnIndex: number;
|
|
116
|
-
callId: string;
|
|
117
|
-
}): Promise<T>;
|
|
118
|
-
/** Generic span wrapper. @internal */
|
|
119
|
-
private withSpan;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export { CallMetrics, VoiceSDKTracer };
|