@absolutejs/voice 0.0.22-beta.485 → 0.0.22-beta.486
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.d.ts +2 -0
- package/dist/index.js +142 -0
- package/dist/otelExporter.d.ts +83 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -81,6 +81,8 @@ export { describeVoiceAssistantMode, resolveVoiceAssistantMode, } from "./assist
|
|
|
81
81
|
export type { VoiceAssistantMode, VoiceAssistantModality, VoiceAssistantModeDescriptor, VoiceSemanticVADConfig, } from "./assistantMode";
|
|
82
82
|
export { createPunctuationSemanticTurnDetector, createRegexSemanticTurnDetector, } from "./semanticTurn";
|
|
83
83
|
export { VOICE_WEBHOOK_SIGNATURE_HEADER, VOICE_WEBHOOK_TIMESTAMP_HEADER, extractVoiceWebhookSignatureFromHeaders, signVoiceWebhookBody, verifyVoiceWebhookSignature, } from "./webhookVerification";
|
|
84
|
+
export { aggregateVoiceTurnLatencySpans, buildOTELSpanId, buildOTELTraceId, buildVoiceOTELPayload, createVoiceOTELHTTPExporter, } from "./otelExporter";
|
|
85
|
+
export type { VoiceOTELAttribute, VoiceOTELExporter, VoiceOTELExporterOptions, VoiceOTELPayload, VoiceOTELResourceSpans, VoiceOTELSpan, VoiceTurnLatencySpanSet, VoiceTurnLatencySpanStage, } from "./otelExporter";
|
|
84
86
|
export type { VoiceWebhookVerificationInput, VoiceWebhookVerificationReason, VoiceWebhookVerificationResult, } from "./webhookVerification";
|
|
85
87
|
export type { CreatePunctuationSemanticTurnDetectorOptions, CreateRegexSemanticTurnDetectorOptions, VoiceSemanticTurnDetector, VoiceSemanticTurnInput, VoiceSemanticTurnVerdict, } from "./semanticTurn";
|
|
86
88
|
export { createMonologueAMDDetector } from "./amdDetector";
|
package/dist/index.js
CHANGED
|
@@ -35475,6 +35475,143 @@ var extractVoiceWebhookSignatureFromHeaders = (headers) => {
|
|
|
35475
35475
|
timestamp: get(VOICE_WEBHOOK_TIMESTAMP_HEADER)
|
|
35476
35476
|
};
|
|
35477
35477
|
};
|
|
35478
|
+
// src/otelExporter.ts
|
|
35479
|
+
var SCOPE_NAME = "@absolutejs/voice";
|
|
35480
|
+
var SPAN_KIND_INTERNAL = 1;
|
|
35481
|
+
var STATUS_OK = 1;
|
|
35482
|
+
var HEX_CHARS = "0123456789abcdef";
|
|
35483
|
+
var hashToHex = (input, length) => {
|
|
35484
|
+
let hash = 0xcbf29ce4_84222325n;
|
|
35485
|
+
const prime = 0x100000001_b3n;
|
|
35486
|
+
for (let index = 0;index < input.length; index += 1) {
|
|
35487
|
+
hash ^= BigInt(input.charCodeAt(index));
|
|
35488
|
+
hash = hash * prime & 0xffffffffffffffffn;
|
|
35489
|
+
}
|
|
35490
|
+
let hex = hash.toString(16).padStart(16, "0");
|
|
35491
|
+
while (hex.length < length) {
|
|
35492
|
+
let next = 0n;
|
|
35493
|
+
for (const ch of hex) {
|
|
35494
|
+
next = next * 31n + BigInt(HEX_CHARS.indexOf(ch)) & 0xffffffffffffffffn;
|
|
35495
|
+
}
|
|
35496
|
+
hex += next.toString(16).padStart(16, "0");
|
|
35497
|
+
}
|
|
35498
|
+
return hex.slice(0, length);
|
|
35499
|
+
};
|
|
35500
|
+
var buildOTELTraceId = (sessionId) => hashToHex(`voice-trace:${sessionId}`, 32);
|
|
35501
|
+
var buildOTELSpanId = (sessionId, suffix) => hashToHex(`voice-span:${sessionId}:${suffix}`, 16);
|
|
35502
|
+
var toUnixNano = (ms) => `${Math.trunc(ms * 1e6)}`;
|
|
35503
|
+
var stringAttr = (key, value) => ({
|
|
35504
|
+
key,
|
|
35505
|
+
value: { stringValue: value }
|
|
35506
|
+
});
|
|
35507
|
+
var aggregateVoiceTurnLatencySpans = (events) => {
|
|
35508
|
+
const byTurn = new Map;
|
|
35509
|
+
for (const event of events) {
|
|
35510
|
+
if (event.type !== "turn_latency.stage" || !event.turnId) {
|
|
35511
|
+
continue;
|
|
35512
|
+
}
|
|
35513
|
+
const stage = typeof event.payload?.stage === "string" ? event.payload.stage : undefined;
|
|
35514
|
+
if (!stage) {
|
|
35515
|
+
continue;
|
|
35516
|
+
}
|
|
35517
|
+
const key = `${event.sessionId}::${event.turnId}`;
|
|
35518
|
+
const existing = byTurn.get(key);
|
|
35519
|
+
if (!existing) {
|
|
35520
|
+
byTurn.set(key, {
|
|
35521
|
+
endedAt: event.at,
|
|
35522
|
+
scenarioId: event.scenarioId,
|
|
35523
|
+
sessionId: event.sessionId,
|
|
35524
|
+
stages: [{ at: event.at, stage }],
|
|
35525
|
+
startedAt: event.at,
|
|
35526
|
+
turnId: event.turnId
|
|
35527
|
+
});
|
|
35528
|
+
continue;
|
|
35529
|
+
}
|
|
35530
|
+
existing.stages.push({ at: event.at, stage });
|
|
35531
|
+
existing.startedAt = Math.min(existing.startedAt, event.at);
|
|
35532
|
+
existing.endedAt = Math.max(existing.endedAt, event.at);
|
|
35533
|
+
}
|
|
35534
|
+
return Array.from(byTurn.values()).sort((left, right) => left.startedAt - right.startedAt);
|
|
35535
|
+
};
|
|
35536
|
+
var buildVoiceOTELPayload = (spanSets, options = {}) => {
|
|
35537
|
+
const resourceAttributes = [
|
|
35538
|
+
stringAttr("service.name", options.serviceName ?? "absolutejs-voice")
|
|
35539
|
+
];
|
|
35540
|
+
for (const [key, value] of Object.entries(options.resourceAttributes ?? {})) {
|
|
35541
|
+
resourceAttributes.push(stringAttr(key, value));
|
|
35542
|
+
}
|
|
35543
|
+
const spans = [];
|
|
35544
|
+
for (const set of spanSets) {
|
|
35545
|
+
const traceId = buildOTELTraceId(set.sessionId);
|
|
35546
|
+
const parentSpanId = buildOTELSpanId(set.sessionId, `turn:${set.turnId}`);
|
|
35547
|
+
spans.push({
|
|
35548
|
+
attributes: [
|
|
35549
|
+
stringAttr("voice.session_id", set.sessionId),
|
|
35550
|
+
stringAttr("voice.turn_id", set.turnId),
|
|
35551
|
+
...set.scenarioId ? [stringAttr("voice.scenario_id", set.scenarioId)] : []
|
|
35552
|
+
],
|
|
35553
|
+
endTimeUnixNano: toUnixNano(set.endedAt),
|
|
35554
|
+
kind: SPAN_KIND_INTERNAL,
|
|
35555
|
+
name: "voice.turn",
|
|
35556
|
+
spanId: parentSpanId,
|
|
35557
|
+
startTimeUnixNano: toUnixNano(set.startedAt),
|
|
35558
|
+
status: { code: STATUS_OK },
|
|
35559
|
+
traceId
|
|
35560
|
+
});
|
|
35561
|
+
for (let index = 0;index < set.stages.length; index += 1) {
|
|
35562
|
+
const stage = set.stages[index];
|
|
35563
|
+
const next = set.stages[index + 1];
|
|
35564
|
+
const endsAt = next ? next.at : set.endedAt;
|
|
35565
|
+
spans.push({
|
|
35566
|
+
attributes: [
|
|
35567
|
+
stringAttr("voice.session_id", set.sessionId),
|
|
35568
|
+
stringAttr("voice.turn_id", set.turnId),
|
|
35569
|
+
stringAttr("voice.stage", stage.stage)
|
|
35570
|
+
],
|
|
35571
|
+
endTimeUnixNano: toUnixNano(endsAt),
|
|
35572
|
+
kind: SPAN_KIND_INTERNAL,
|
|
35573
|
+
name: `voice.turn.stage.${stage.stage}`,
|
|
35574
|
+
parentSpanId,
|
|
35575
|
+
spanId: buildOTELSpanId(set.sessionId, `${set.turnId}:${stage.stage}:${index}`),
|
|
35576
|
+
startTimeUnixNano: toUnixNano(stage.at),
|
|
35577
|
+
status: { code: STATUS_OK },
|
|
35578
|
+
traceId
|
|
35579
|
+
});
|
|
35580
|
+
}
|
|
35581
|
+
}
|
|
35582
|
+
return {
|
|
35583
|
+
resourceSpans: [
|
|
35584
|
+
{
|
|
35585
|
+
resource: { attributes: resourceAttributes },
|
|
35586
|
+
scopeSpans: [{ scope: { name: SCOPE_NAME }, spans }]
|
|
35587
|
+
}
|
|
35588
|
+
]
|
|
35589
|
+
};
|
|
35590
|
+
};
|
|
35591
|
+
var createVoiceOTELHTTPExporter = (options) => {
|
|
35592
|
+
const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
35593
|
+
return {
|
|
35594
|
+
export: async (events) => {
|
|
35595
|
+
const spanSets = aggregateVoiceTurnLatencySpans(events);
|
|
35596
|
+
if (spanSets.length === 0) {
|
|
35597
|
+
return { ok: true };
|
|
35598
|
+
}
|
|
35599
|
+
const payload = buildVoiceOTELPayload(spanSets, {
|
|
35600
|
+
resourceAttributes: options.resourceAttributes,
|
|
35601
|
+
serviceName: options.serviceName
|
|
35602
|
+
});
|
|
35603
|
+
const response = await fetchImpl(options.url, {
|
|
35604
|
+
body: JSON.stringify(payload),
|
|
35605
|
+
headers: {
|
|
35606
|
+
"content-type": "application/json",
|
|
35607
|
+
...options.headers
|
|
35608
|
+
},
|
|
35609
|
+
method: "POST"
|
|
35610
|
+
});
|
|
35611
|
+
return { ok: response.ok, status: response.status };
|
|
35612
|
+
}
|
|
35613
|
+
};
|
|
35614
|
+
};
|
|
35478
35615
|
// src/amdDetector.ts
|
|
35479
35616
|
var createMonologueAMDDetector = (options = {}) => {
|
|
35480
35617
|
const minMonologueMs = options.minMonologueMs ?? 8000;
|
|
@@ -46540,6 +46677,7 @@ export {
|
|
|
46540
46677
|
createVoiceObservabilityExportSchema,
|
|
46541
46678
|
createVoiceObservabilityExportRoutes,
|
|
46542
46679
|
createVoiceObservabilityExportReplayRoutes,
|
|
46680
|
+
createVoiceOTELHTTPExporter,
|
|
46543
46681
|
createVoiceMonitorWebhookNotifier,
|
|
46544
46682
|
createVoiceMonitorSession,
|
|
46545
46683
|
createVoiceMonitorRuntimeBinding,
|
|
@@ -46758,6 +46896,7 @@ export {
|
|
|
46758
46896
|
buildVoiceObservabilityExportDeliveryHistory,
|
|
46759
46897
|
buildVoiceObservabilityExport,
|
|
46760
46898
|
buildVoiceObservabilityArtifactIndex,
|
|
46899
|
+
buildVoiceOTELPayload,
|
|
46761
46900
|
buildVoiceMultilingualProofReadinessCheck,
|
|
46762
46901
|
buildVoiceMonitorRunReport,
|
|
46763
46902
|
buildVoiceMonitorPlan,
|
|
@@ -46788,6 +46927,8 @@ export {
|
|
|
46788
46927
|
buildVoiceAuditTrailReport,
|
|
46789
46928
|
buildVoiceAuditExport,
|
|
46790
46929
|
buildVoiceAuditDeliveryReport,
|
|
46930
|
+
buildOTELTraceId,
|
|
46931
|
+
buildOTELSpanId,
|
|
46791
46932
|
buildEmptyVoiceProofTrendReport,
|
|
46792
46933
|
assignVoiceOpsTask,
|
|
46793
46934
|
assertVoiceToolContractEvidence,
|
|
@@ -46838,6 +46979,7 @@ export {
|
|
|
46838
46979
|
appendVoiceRealCallProfileRecoveryEvidence,
|
|
46839
46980
|
appendVoiceProviderRouterTraceEvent,
|
|
46840
46981
|
appendVoiceIOProviderRouterTraceEvent,
|
|
46982
|
+
aggregateVoiceTurnLatencySpans,
|
|
46841
46983
|
acknowledgeVoiceMonitorIssue,
|
|
46842
46984
|
VOICE_WEBHOOK_TIMESTAMP_HEADER,
|
|
46843
46985
|
VOICE_WEBHOOK_SIGNATURE_HEADER,
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { StoredVoiceTraceEvent } from "./trace";
|
|
2
|
+
export type VoiceOTELAttribute = {
|
|
3
|
+
key: string;
|
|
4
|
+
value: {
|
|
5
|
+
boolValue: boolean;
|
|
6
|
+
};
|
|
7
|
+
} | {
|
|
8
|
+
key: string;
|
|
9
|
+
value: {
|
|
10
|
+
doubleValue: number;
|
|
11
|
+
};
|
|
12
|
+
} | {
|
|
13
|
+
key: string;
|
|
14
|
+
value: {
|
|
15
|
+
intValue: string;
|
|
16
|
+
};
|
|
17
|
+
} | {
|
|
18
|
+
key: string;
|
|
19
|
+
value: {
|
|
20
|
+
stringValue: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export type VoiceOTELSpan = {
|
|
24
|
+
attributes: VoiceOTELAttribute[];
|
|
25
|
+
endTimeUnixNano: string;
|
|
26
|
+
kind: number;
|
|
27
|
+
name: string;
|
|
28
|
+
parentSpanId?: string;
|
|
29
|
+
spanId: string;
|
|
30
|
+
startTimeUnixNano: string;
|
|
31
|
+
status: {
|
|
32
|
+
code: number;
|
|
33
|
+
};
|
|
34
|
+
traceId: string;
|
|
35
|
+
};
|
|
36
|
+
export type VoiceOTELResourceSpans = {
|
|
37
|
+
resource: {
|
|
38
|
+
attributes: VoiceOTELAttribute[];
|
|
39
|
+
};
|
|
40
|
+
scopeSpans: ReadonlyArray<{
|
|
41
|
+
scope: {
|
|
42
|
+
name: string;
|
|
43
|
+
version?: string;
|
|
44
|
+
};
|
|
45
|
+
spans: VoiceOTELSpan[];
|
|
46
|
+
}>;
|
|
47
|
+
};
|
|
48
|
+
export type VoiceOTELPayload = {
|
|
49
|
+
resourceSpans: VoiceOTELResourceSpans[];
|
|
50
|
+
};
|
|
51
|
+
export type VoiceTurnLatencySpanStage = {
|
|
52
|
+
at: number;
|
|
53
|
+
stage: string;
|
|
54
|
+
};
|
|
55
|
+
export type VoiceTurnLatencySpanSet = {
|
|
56
|
+
endedAt: number;
|
|
57
|
+
scenarioId?: string;
|
|
58
|
+
sessionId: string;
|
|
59
|
+
stages: VoiceTurnLatencySpanStage[];
|
|
60
|
+
startedAt: number;
|
|
61
|
+
turnId: string;
|
|
62
|
+
};
|
|
63
|
+
export declare const buildOTELTraceId: (sessionId: string) => string;
|
|
64
|
+
export declare const buildOTELSpanId: (sessionId: string, suffix: string) => string;
|
|
65
|
+
export declare const aggregateVoiceTurnLatencySpans: (events: StoredVoiceTraceEvent[]) => VoiceTurnLatencySpanSet[];
|
|
66
|
+
export type VoiceOTELExporterOptions = {
|
|
67
|
+
fetch?: typeof fetch;
|
|
68
|
+
headers?: Record<string, string>;
|
|
69
|
+
resourceAttributes?: Record<string, string>;
|
|
70
|
+
serviceName?: string;
|
|
71
|
+
url: string;
|
|
72
|
+
};
|
|
73
|
+
export declare const buildVoiceOTELPayload: (spanSets: VoiceTurnLatencySpanSet[], options?: {
|
|
74
|
+
resourceAttributes?: Record<string, string>;
|
|
75
|
+
serviceName?: string;
|
|
76
|
+
}) => VoiceOTELPayload;
|
|
77
|
+
export type VoiceOTELExporter = {
|
|
78
|
+
export: (events: StoredVoiceTraceEvent[]) => Promise<{
|
|
79
|
+
ok: boolean;
|
|
80
|
+
status?: number;
|
|
81
|
+
}>;
|
|
82
|
+
};
|
|
83
|
+
export declare const createVoiceOTELHTTPExporter: (options: VoiceOTELExporterOptions) => VoiceOTELExporter;
|