@kognitivedev/voice-tracing 0.2.29

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.
@@ -0,0 +1,177 @@
1
+ import type { KognitiveUIMessage, Metadata, ResourceId } from "@kognitivedev/shared";
2
+ export interface VoiceTracingUsageSnapshot {
3
+ type: "tokens" | "seconds";
4
+ inputTokens?: number;
5
+ outputTokens?: number;
6
+ totalTokens?: number;
7
+ cachedInputTokens?: number;
8
+ inputAudioTokens?: number;
9
+ inputTextTokens?: number;
10
+ outputAudioTokens?: number;
11
+ outputTextTokens?: number;
12
+ cachedAudioTokens?: number;
13
+ cachedTextTokens?: number;
14
+ seconds?: number;
15
+ }
16
+ export type VoiceTracingTelemetryEvent = {
17
+ type: "voice.call.started";
18
+ at: string;
19
+ callId: string;
20
+ modelId: string;
21
+ voice: string;
22
+ } | {
23
+ type: "voice.call.ended";
24
+ at: string;
25
+ callId?: string;
26
+ reason?: string;
27
+ } | {
28
+ type: "voice.session.updated";
29
+ at: string;
30
+ callId?: string;
31
+ session: Record<string, unknown>;
32
+ } | {
33
+ type: "voice.response.created";
34
+ at: string;
35
+ callId?: string;
36
+ responseId: string;
37
+ } | {
38
+ type: "voice.response.output.completed";
39
+ at: string;
40
+ callId?: string;
41
+ responseId?: string;
42
+ itemId?: string;
43
+ outputText?: string;
44
+ status?: string;
45
+ rawEvent: Record<string, unknown>;
46
+ } | {
47
+ type: "voice.response.done";
48
+ at: string;
49
+ callId?: string;
50
+ responseId: string;
51
+ status: string;
52
+ outputText?: string;
53
+ usage?: VoiceTracingUsageSnapshot;
54
+ rawEvent: Record<string, unknown>;
55
+ } | {
56
+ type: "voice.user.transcribed";
57
+ at: string;
58
+ callId?: string;
59
+ itemId?: string;
60
+ transcript: string;
61
+ usage?: VoiceTracingUsageSnapshot;
62
+ rawEvent: Record<string, unknown>;
63
+ } | {
64
+ type: "voice.assistant.started";
65
+ at: string;
66
+ callId?: string;
67
+ responseId?: string;
68
+ rawEvent: Record<string, unknown>;
69
+ } | {
70
+ type: "voice.assistant.stopped";
71
+ at: string;
72
+ callId?: string;
73
+ responseId?: string;
74
+ rawEvent: Record<string, unknown>;
75
+ } | {
76
+ type: "voice.tool.started";
77
+ at: string;
78
+ callId?: string;
79
+ responseId?: string;
80
+ toolCallId: string;
81
+ toolName: string;
82
+ input?: unknown;
83
+ rawEvent: Record<string, unknown>;
84
+ } | {
85
+ type: "voice.tool.completed";
86
+ at: string;
87
+ callId?: string;
88
+ responseId?: string;
89
+ toolCallId: string;
90
+ toolName: string;
91
+ output?: unknown;
92
+ } | {
93
+ type: "voice.tool.failed";
94
+ at: string;
95
+ callId?: string;
96
+ responseId?: string;
97
+ toolCallId: string;
98
+ toolName: string;
99
+ error: string;
100
+ } | {
101
+ type: "voice.interrupted";
102
+ at: string;
103
+ callId?: string;
104
+ responseId?: string;
105
+ reason?: string;
106
+ rawEvent?: Record<string, unknown>;
107
+ } | {
108
+ type: "voice.error";
109
+ at: string;
110
+ callId?: string;
111
+ error: string;
112
+ rawEvent?: Record<string, unknown>;
113
+ } | {
114
+ type: "voice.raw";
115
+ at: string;
116
+ callId?: string;
117
+ rawEvent: Record<string, unknown>;
118
+ };
119
+ type VoiceTracingSessionStateShape = {
120
+ callId?: string;
121
+ messages: KognitiveUIMessage[];
122
+ toolInvocations: unknown[];
123
+ connectionStatus?: string;
124
+ agentState?: string;
125
+ speechState?: string;
126
+ transcriptionStatus?: string;
127
+ };
128
+ export type VoiceTracingSessionEvent = {
129
+ type: "state.updated";
130
+ state: VoiceTracingSessionStateShape;
131
+ } | {
132
+ type: "tool-call";
133
+ toolCall: {
134
+ toolName: string;
135
+ };
136
+ state: VoiceTracingSessionStateShape;
137
+ } | {
138
+ type: "tool-result";
139
+ toolResult: {
140
+ toolName: string;
141
+ isError?: boolean;
142
+ };
143
+ state: VoiceTracingSessionStateShape;
144
+ } | {
145
+ type: "raw";
146
+ event: Record<string, unknown>;
147
+ state: VoiceTracingSessionStateShape;
148
+ } | {
149
+ type: "error";
150
+ error: unknown;
151
+ state: VoiceTracingSessionStateShape;
152
+ };
153
+ export type PersistedConversationPart = Record<string, unknown>;
154
+ export type PersistedConversationMessage = {
155
+ role: "system" | "user" | "assistant" | "tool";
156
+ content: string | PersistedConversationPart[];
157
+ metadata?: Metadata;
158
+ };
159
+ export interface VoiceTracingAdapter {
160
+ reportAgentRun(data: Record<string, unknown>): Promise<unknown> | unknown;
161
+ reportConversationLog(data: Record<string, unknown>): Promise<unknown> | unknown;
162
+ reportTraceEvents(data: Record<string, unknown>): Promise<{
163
+ traceDbId?: string | null;
164
+ } | null>;
165
+ }
166
+ export interface VoiceTracingReporterConfig {
167
+ adapter: VoiceTracingAdapter;
168
+ agentName: string;
169
+ callId: string;
170
+ modelId: string;
171
+ transcriptionModelId?: string;
172
+ voice: string;
173
+ resourceId: ResourceId;
174
+ metadata?: Metadata;
175
+ transport?: string;
176
+ }
177
+ export {};
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@kognitivedev/voice-tracing",
3
+ "version": "0.2.29",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "dev": "tsc -w --noCheck",
12
+ "prepublishOnly": "npm run build",
13
+ "test": "vitest run"
14
+ },
15
+ "dependencies": {
16
+ "@kognitivedev/shared": "^0.2.29"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^20.0.0",
20
+ "typescript": "^5.0.0",
21
+ "vitest": "^3.0.0"
22
+ },
23
+ "description": "Voice tracing adapters and reporter for Kognitive",
24
+ "keywords": [
25
+ "kognitive",
26
+ "voice",
27
+ "tracing",
28
+ "observability"
29
+ ],
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/kognitivedev/kognitive",
34
+ "directory": "packages/voice-tracing"
35
+ },
36
+ "homepage": "https://kognitive.dev"
37
+ }
@@ -0,0 +1,341 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import {
3
+ createKognitiveBackendVoiceTracingAdapter,
4
+ createKognitiveVoiceTracingAdapter,
5
+ createVoiceTracingReporter,
6
+ } from "../index";
7
+
8
+ function flushAsyncWork() {
9
+ return new Promise((resolve) => setTimeout(resolve, 0));
10
+ }
11
+
12
+ function makeBaseState() {
13
+ return {
14
+ callId: "rtc_test_1",
15
+ messages: [] as Array<Record<string, unknown>>,
16
+ toolInvocations: [],
17
+ connectionStatus: "connected",
18
+ agentState: "listening",
19
+ micState: "ready",
20
+ speechState: "idle",
21
+ transcriptionStatus: "completed",
22
+ };
23
+ }
24
+
25
+ describe("@kognitivedev/voice-tracing reporter", () => {
26
+ it("bootstraps the session run before starting traces and carries backend ids forward", async () => {
27
+ const adapter = {
28
+ reportAgentRun: vi.fn().mockResolvedValue({
29
+ runDbId: "run-db-1",
30
+ sessionDbId: "session-db-1",
31
+ }),
32
+ reportConversationLog: vi.fn(),
33
+ reportTraceEvents: vi.fn().mockResolvedValue({ traceDbId: "trace-db-1" }),
34
+ };
35
+
36
+ const reporter = createVoiceTracingReporter({
37
+ adapter,
38
+ agentName: "voice-demo",
39
+ callId: "rtc_bootstrap_1",
40
+ modelId: "gpt-realtime-1.5",
41
+ transcriptionModelId: "gpt-4o-transcribe",
42
+ voice: "marin",
43
+ resourceId: { userId: "user-1" },
44
+ transport: "webrtc",
45
+ });
46
+
47
+ reporter.handleSessionEvent({
48
+ type: "state.updated",
49
+ state: {
50
+ ...makeBaseState(),
51
+ callId: "rtc_bootstrap_1",
52
+ messages: [
53
+ {
54
+ id: "user-msg-1",
55
+ role: "user",
56
+ parts: [{ type: "text", text: "hello" }],
57
+ },
58
+ ],
59
+ },
60
+ });
61
+ await flushAsyncWork();
62
+
63
+ const firstTraceCall = adapter.reportTraceEvents.mock.calls[0]?.[0];
64
+ expect(adapter.reportAgentRun).toHaveBeenCalled();
65
+ expect(firstTraceCall).toEqual(expect.objectContaining({
66
+ sessionDbId: "session-db-1",
67
+ agentRunDbId: "run-db-1",
68
+ start: expect.objectContaining({
69
+ sessionDbId: "session-db-1",
70
+ agentRunDbId: "run-db-1",
71
+ }),
72
+ }));
73
+ });
74
+
75
+ it("normalizes voice messages for persistence and avoids placeholder trace logs", async () => {
76
+ const adapter = {
77
+ reportAgentRun: vi.fn(),
78
+ reportConversationLog: vi.fn(),
79
+ reportTraceEvents: vi.fn().mockResolvedValue({ traceDbId: "trace-db-1" }),
80
+ };
81
+
82
+ const reporter = createVoiceTracingReporter({
83
+ adapter,
84
+ agentName: "voice-demo",
85
+ callId: "rtc_test_1",
86
+ modelId: "gpt-realtime-1.5",
87
+ transcriptionModelId: "gpt-4o-transcribe",
88
+ voice: "marin",
89
+ resourceId: { userId: "user-1" },
90
+ transport: "webrtc",
91
+ });
92
+
93
+ reporter.handleSessionEvent({
94
+ type: "state.updated",
95
+ state: {
96
+ ...makeBaseState(),
97
+ messages: [
98
+ {
99
+ id: "user-msg-1",
100
+ role: "user",
101
+ parts: [{ type: "text", text: "What is the weather in Paris?" }],
102
+ },
103
+ {
104
+ id: "assistant-msg-1",
105
+ role: "assistant",
106
+ parts: [
107
+ { type: "text", text: "Checking that now." },
108
+ { type: "tool-call", toolCallId: "tool-1", toolName: "weather-tool", input: { city: "Paris" } },
109
+ { type: "tool-result", toolCallId: "tool-1", toolName: "weather-tool", result: { temperature: 22 } },
110
+ { type: "text", text: "It is 22 degrees." },
111
+ ],
112
+ },
113
+ ],
114
+ },
115
+ });
116
+
117
+ await reporter.handleTelemetry({
118
+ type: "voice.response.done",
119
+ at: "2026-04-06T13:16:53.000Z",
120
+ callId: "rtc_test_1",
121
+ responseId: "resp_1",
122
+ status: "completed",
123
+ outputText: "It is 22 degrees.",
124
+ usage: {
125
+ type: "tokens",
126
+ inputTokens: 120,
127
+ outputTokens: 24,
128
+ totalTokens: 144,
129
+ cachedInputTokens: 15,
130
+ inputTextTokens: 20,
131
+ inputAudioTokens: 100,
132
+ cachedTextTokens: 5,
133
+ cachedAudioTokens: 10,
134
+ outputTextTokens: 4,
135
+ outputAudioTokens: 20,
136
+ },
137
+ rawEvent: {},
138
+ });
139
+
140
+ expect(adapter.reportTraceEvents).toHaveBeenCalledWith(expect.objectContaining({
141
+ start: expect.objectContaining({
142
+ traceId: expect.stringContaining("agent:voice-demo:"),
143
+ metadata: expect.objectContaining({ source: "voice" }),
144
+ }),
145
+ }));
146
+
147
+ const completedLogPayload = adapter.reportConversationLog.mock.calls
148
+ .map(([payload]) => payload)
149
+ .find((payload) => Array.isArray(payload?.sessionEvents) && payload.sessionEvents.some((sessionEvent: { eventType: string }) => sessionEvent.eventType === "voice.turn.completed"));
150
+
151
+ expect(completedLogPayload).toEqual(expect.objectContaining({
152
+ skipTraceTracking: true,
153
+ turnIndex: 0,
154
+ sessionEvents: [
155
+ expect.objectContaining({
156
+ eventType: "voice.turn.completed",
157
+ traceId: expect.stringContaining("agent:voice-demo:"),
158
+ }),
159
+ ],
160
+ }));
161
+ });
162
+
163
+ it("recovers completed turns from conversation history on disconnect", async () => {
164
+ const adapter = {
165
+ reportAgentRun: vi.fn(),
166
+ reportConversationLog: vi.fn(),
167
+ reportTraceEvents: vi.fn().mockResolvedValue({ traceDbId: "trace-db-fallback" }),
168
+ };
169
+
170
+ const reporter = createVoiceTracingReporter({
171
+ adapter,
172
+ agentName: "voice-demo",
173
+ callId: "rtc_test_fallback",
174
+ modelId: "gpt-realtime-1.5",
175
+ transcriptionModelId: "gpt-4o-transcribe",
176
+ voice: "marin",
177
+ resourceId: { userId: "user-1" },
178
+ transport: "webrtc",
179
+ });
180
+
181
+ reporter.handleSessionEvent({
182
+ type: "state.updated",
183
+ state: {
184
+ ...makeBaseState(),
185
+ callId: "rtc_test_fallback",
186
+ messages: [
187
+ {
188
+ id: "user-msg-1",
189
+ role: "user",
190
+ parts: [{ type: "data", data: "What is the weather in Paris right now?" }],
191
+ },
192
+ {
193
+ id: "assistant-msg-1",
194
+ role: "assistant",
195
+ parts: [
196
+ { type: "text", text: "Checking now." },
197
+ { type: "tool-call", toolCallId: "tool-1", toolName: "weather-tool", input: { city: "Paris" } },
198
+ { type: "tool-result", toolCallId: "tool-1", toolName: "weather-tool", result: { tempC: 18 } },
199
+ { type: "text", text: "It is 18C." },
200
+ ],
201
+ },
202
+ ],
203
+ },
204
+ });
205
+
206
+ reporter.flushCallEnd("disconnect");
207
+ await flushAsyncWork();
208
+
209
+ expect(adapter.reportTraceEvents).toHaveBeenCalledWith(expect.objectContaining({
210
+ start: expect.objectContaining({
211
+ metadata: expect.objectContaining({
212
+ source: "voice",
213
+ synthetic: true,
214
+ }),
215
+ }),
216
+ finish: expect.objectContaining({
217
+ state: "completed",
218
+ }),
219
+ }));
220
+ });
221
+
222
+ it("does not replay the full transcript again on disconnect flush when nothing changed", async () => {
223
+ const adapter = {
224
+ reportAgentRun: vi.fn().mockResolvedValue({
225
+ runDbId: "run-db-1",
226
+ sessionDbId: "session-db-1",
227
+ }),
228
+ reportConversationLog: vi.fn(),
229
+ reportTraceEvents: vi.fn().mockResolvedValue({ traceDbId: "trace-db-1" }),
230
+ };
231
+
232
+ const reporter = createVoiceTracingReporter({
233
+ adapter,
234
+ agentName: "voice-demo",
235
+ callId: "rtc_test_flush_dedupe",
236
+ modelId: "gpt-realtime-1.5",
237
+ transcriptionModelId: "gpt-4o-transcribe",
238
+ voice: "marin",
239
+ resourceId: { userId: "user-1" },
240
+ transport: "webrtc",
241
+ });
242
+
243
+ reporter.handleSessionEvent({
244
+ type: "state.updated",
245
+ state: {
246
+ ...makeBaseState(),
247
+ callId: "rtc_test_flush_dedupe",
248
+ messages: [
249
+ {
250
+ id: "user-msg-1",
251
+ role: "user",
252
+ parts: [{ type: "text", text: "hello" }],
253
+ },
254
+ {
255
+ id: "assistant-msg-1",
256
+ role: "assistant",
257
+ parts: [{ type: "text", text: "hi there" }],
258
+ },
259
+ ],
260
+ },
261
+ });
262
+
263
+ await reporter.handleTelemetry({
264
+ type: "voice.response.done",
265
+ at: "2026-04-06T13:16:53.000Z",
266
+ callId: "rtc_test_flush_dedupe",
267
+ responseId: "resp_1",
268
+ status: "completed",
269
+ outputText: "hi there",
270
+ usage: {
271
+ type: "tokens",
272
+ inputTokens: 10,
273
+ outputTokens: 4,
274
+ totalTokens: 14,
275
+ },
276
+ rawEvent: {},
277
+ });
278
+
279
+ reporter.flushCallEnd("disconnect");
280
+ await flushAsyncWork();
281
+
282
+ const conversationLogPayloads = adapter.reportConversationLog.mock.calls.map(([payload]) => payload);
283
+ const payloadWithTranscript = conversationLogPayloads.find((payload) => Array.isArray(payload.messages) && payload.messages.length === 2);
284
+ const disconnectFlushPayload = conversationLogPayloads
285
+ .filter((payload) => Array.isArray(payload.sessionEvents) && payload.sessionEvents.some((event: { eventType: string }) => event.eventType === "voice.call.ended"))
286
+ .at(-1);
287
+
288
+ expect(payloadWithTranscript).toBeTruthy();
289
+ expect(disconnectFlushPayload).toEqual(expect.objectContaining({
290
+ messages: [],
291
+ sessionEvents: expect.arrayContaining([
292
+ expect.objectContaining({ eventType: "voice.call.ended" }),
293
+ ]),
294
+ }));
295
+ });
296
+ });
297
+
298
+ describe("@kognitivedev/voice-tracing adapters", () => {
299
+ it("posts backend payloads to the configured endpoints", async () => {
300
+ const fetchMock = vi.fn().mockResolvedValue({
301
+ ok: true,
302
+ json: async () => ({ traceDbId: "trace-db-1" }),
303
+ });
304
+
305
+ const adapter = createKognitiveBackendVoiceTracingAdapter({
306
+ baseUrl: "https://example.test",
307
+ apiKey: "secret",
308
+ fetch: fetchMock as unknown as typeof fetch,
309
+ });
310
+
311
+ adapter.reportAgentRun({ runId: "run-1" });
312
+ adapter.reportConversationLog({ sessionId: "session-1" });
313
+ const result = await adapter.reportTraceEvents({ traceId: "trace-1" });
314
+
315
+ expect(fetchMock).toHaveBeenCalledTimes(3);
316
+ expect(fetchMock).toHaveBeenNthCalledWith(1, "https://example.test/api/kognitive/cognitive/agent-run", expect.any(Object));
317
+ expect(fetchMock).toHaveBeenNthCalledWith(2, "https://example.test/api/kognitive/cognitive/log", expect.objectContaining({
318
+ body: JSON.stringify({ type: "voice", sessionId: "session-1" }),
319
+ }));
320
+ expect(fetchMock).toHaveBeenNthCalledWith(3, "https://example.test/api/kognitive/cognitive/trace-events", expect.any(Object));
321
+ expect(result).toEqual({ traceDbId: "trace-db-1" });
322
+ });
323
+
324
+ it("forwards through the Kognitive bridge adapter", async () => {
325
+ const kognitive = {
326
+ reportAgentRun: vi.fn(),
327
+ reportConversationLog: vi.fn(),
328
+ reportTraceEvents: vi.fn().mockResolvedValue({ traceDbId: "trace-db-kognitive" }),
329
+ };
330
+
331
+ const adapter = createKognitiveVoiceTracingAdapter(kognitive);
332
+ adapter.reportAgentRun({ runId: "run-1" });
333
+ adapter.reportConversationLog({ sessionId: "session-1" });
334
+ const result = await adapter.reportTraceEvents({ traceId: "trace-1" });
335
+
336
+ expect(kognitive.reportAgentRun).toHaveBeenCalledWith({ runId: "run-1" });
337
+ expect(kognitive.reportConversationLog).toHaveBeenCalledWith({ sessionId: "session-1" });
338
+ expect(kognitive.reportTraceEvents).toHaveBeenCalledWith({ traceId: "trace-1" });
339
+ expect(result).toEqual({ traceDbId: "trace-db-kognitive" });
340
+ });
341
+ });
@@ -0,0 +1,82 @@
1
+ import type { VoiceTracingAdapter } from "./types";
2
+
3
+ type Logger = Pick<Console, "log" | "error" | "warn">;
4
+
5
+ export interface KognitiveBackendVoiceTracingAdapterConfig {
6
+ baseUrl: string;
7
+ apiKey?: string;
8
+ getBearerToken?: () => Promise<string | null | undefined> | string | null | undefined;
9
+ fetch?: typeof globalThis.fetch;
10
+ logger?: Logger;
11
+ endpoints?: {
12
+ agentRun?: string;
13
+ log?: string;
14
+ traceEvents?: string;
15
+ };
16
+ }
17
+
18
+ function trimTrailingSlash(value: string): string {
19
+ return value.endsWith("/") ? value.slice(0, -1) : value;
20
+ }
21
+
22
+ export function createKognitiveBackendVoiceTracingAdapter(
23
+ config: KognitiveBackendVoiceTracingAdapterConfig,
24
+ ): VoiceTracingAdapter {
25
+ const fetchImpl = config.fetch ?? globalThis.fetch;
26
+ const logger = config.logger;
27
+ const baseUrl = trimTrailingSlash(config.baseUrl);
28
+ const endpoints = {
29
+ agentRun: config.endpoints?.agentRun ?? "/api/kognitive/cognitive/agent-run",
30
+ log: config.endpoints?.log ?? "/api/kognitive/cognitive/log",
31
+ traceEvents: config.endpoints?.traceEvents ?? "/api/kognitive/cognitive/trace-events",
32
+ };
33
+
34
+ const post = async (endpoint: string, payload: Record<string, unknown>) => {
35
+ try {
36
+ const bearerToken = await config.getBearerToken?.();
37
+ const response = await fetchImpl(`${baseUrl}${endpoint}`, {
38
+ method: "POST",
39
+ headers: {
40
+ "Content-Type": "application/json",
41
+ ...(bearerToken || config.apiKey
42
+ ? { Authorization: `Bearer ${bearerToken ?? config.apiKey}` }
43
+ : {}),
44
+ },
45
+ body: JSON.stringify(payload),
46
+ });
47
+
48
+ if (!response.ok) {
49
+ const errorText = await response.text().catch(() => "");
50
+ logger?.warn?.("[VoiceTracing:backend-adapter] request failed", {
51
+ endpoint,
52
+ status: response.status,
53
+ body: errorText.slice(0, 400),
54
+ });
55
+ return null;
56
+ }
57
+
58
+ return await response.json().catch(() => null);
59
+ } catch (error) {
60
+ logger?.error?.("[VoiceTracing:backend-adapter] request error", {
61
+ endpoint,
62
+ error: error instanceof Error ? error.message : String(error),
63
+ });
64
+ return null;
65
+ }
66
+ };
67
+
68
+ return {
69
+ async reportAgentRun(data) {
70
+ return await post(endpoints.agentRun, data);
71
+ },
72
+ async reportConversationLog(data) {
73
+ return await post(endpoints.log, {
74
+ type: "voice",
75
+ ...data,
76
+ });
77
+ },
78
+ async reportTraceEvents(data) {
79
+ return await post(endpoints.traceEvents, data) as { traceDbId?: string | null } | null;
80
+ },
81
+ };
82
+ }
package/src/index.ts ADDED
@@ -0,0 +1,12 @@
1
+ export type {
2
+ VoiceTracingAdapter,
3
+ VoiceTracingReporterConfig,
4
+ VoiceTracingSessionEvent,
5
+ VoiceTracingTelemetryEvent,
6
+ VoiceTracingUsageSnapshot,
7
+ PersistedConversationMessage,
8
+ } from "./types";
9
+
10
+ export { createVoiceTracingReporter, createVoiceTelemetryReporter } from "./reporter";
11
+ export { createKognitiveBackendVoiceTracingAdapter } from "./backend-adapter";
12
+ export { createKognitiveVoiceTracingAdapter } from "./kognitive-adapter";
@@ -0,0 +1,22 @@
1
+ import type { VoiceTracingAdapter } from "./types";
2
+
3
+ type KognitiveLike = {
4
+ reportAgentRun(data: Record<string, unknown>): Promise<unknown> | unknown;
5
+ reportConversationLog(data: Record<string, unknown>): Promise<unknown> | unknown;
6
+ reportTraceEvents(data: Record<string, unknown>): Promise<unknown> | unknown;
7
+ };
8
+
9
+ export function createKognitiveVoiceTracingAdapter(kognitive: KognitiveLike): VoiceTracingAdapter {
10
+ return {
11
+ async reportAgentRun(data) {
12
+ return await kognitive.reportAgentRun(data);
13
+ },
14
+ async reportConversationLog(data) {
15
+ return await kognitive.reportConversationLog(data);
16
+ },
17
+ async reportTraceEvents(data) {
18
+ const result = await kognitive.reportTraceEvents(data);
19
+ return (result ?? null) as { traceDbId?: string | null } | null;
20
+ },
21
+ };
22
+ }