@absolutejs/voice 0.0.22-beta.0 → 0.0.22-beta.2

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,236 @@
1
+ export type VoiceTraceEventType = 'agent.handoff' | 'agent.model' | 'agent.result' | 'agent.tool' | 'call.lifecycle' | 'session.error' | 'turn.assistant' | 'turn.committed' | 'turn.cost' | 'turn.transcript';
2
+ export type VoiceTraceEvent<TPayload extends Record<string, unknown> = Record<string, unknown>> = {
3
+ at: number;
4
+ id?: string;
5
+ metadata?: Record<string, unknown>;
6
+ payload: TPayload;
7
+ scenarioId?: string;
8
+ sessionId: string;
9
+ traceId?: string;
10
+ turnId?: string;
11
+ type: VoiceTraceEventType;
12
+ };
13
+ export type StoredVoiceTraceEvent<TPayload extends Record<string, unknown> = Record<string, unknown>> = VoiceTraceEvent<TPayload> & {
14
+ id: string;
15
+ };
16
+ export type VoiceTraceEventFilter = {
17
+ limit?: number;
18
+ scenarioId?: string;
19
+ sessionId?: string;
20
+ traceId?: string;
21
+ turnId?: string;
22
+ type?: VoiceTraceEventType | VoiceTraceEventType[];
23
+ };
24
+ export type VoiceTraceEventStore<TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent> = {
25
+ append: (event: VoiceTraceEvent | TEvent) => Promise<TEvent>;
26
+ get: (id: string) => Promise<TEvent | undefined>;
27
+ list: (filter?: VoiceTraceEventFilter) => Promise<TEvent[]>;
28
+ remove: (id: string) => Promise<void>;
29
+ };
30
+ export type VoiceTracePruneFilter = Omit<VoiceTraceEventFilter, 'limit'>;
31
+ export type VoiceTracePruneOptions = {
32
+ before?: number;
33
+ beforeOrAt?: number;
34
+ dryRun?: boolean;
35
+ filter?: VoiceTracePruneFilter;
36
+ keepNewest?: number;
37
+ limit?: number;
38
+ store: VoiceTraceEventStore;
39
+ };
40
+ export type VoiceTracePruneResult = {
41
+ deleted: StoredVoiceTraceEvent[];
42
+ deletedCount: number;
43
+ dryRun: boolean;
44
+ scannedCount: number;
45
+ };
46
+ export type VoiceTraceSinkDeliveryStatus = 'delivered' | 'failed' | 'skipped';
47
+ export type VoiceTraceSinkDeliveryQueueStatus = VoiceTraceSinkDeliveryStatus | 'pending';
48
+ export type VoiceTraceSinkDeliveryResult = {
49
+ attempts: number;
50
+ deliveredAt?: number;
51
+ deliveredTo?: string;
52
+ error?: string;
53
+ eventCount: number;
54
+ responseBody?: unknown;
55
+ status: VoiceTraceSinkDeliveryStatus;
56
+ };
57
+ export type VoiceTraceSink = {
58
+ deliver: (input: {
59
+ events: StoredVoiceTraceEvent[];
60
+ }) => Promise<VoiceTraceSinkDeliveryResult> | VoiceTraceSinkDeliveryResult;
61
+ eventTypes?: VoiceTraceEventType[];
62
+ id: string;
63
+ kind?: string;
64
+ };
65
+ export type VoiceTraceSinkFanoutResult = {
66
+ deliveredAt: number;
67
+ eventCount: number;
68
+ sinkDeliveries: Record<string, VoiceTraceSinkDeliveryResult>;
69
+ status: VoiceTraceSinkDeliveryStatus;
70
+ };
71
+ export type VoiceTraceSinkDeliveryRecord = {
72
+ createdAt: number;
73
+ deliveredAt?: number;
74
+ deliveryAttempts?: number;
75
+ deliveryError?: string;
76
+ deliveryStatus: VoiceTraceSinkDeliveryQueueStatus;
77
+ events: StoredVoiceTraceEvent[];
78
+ id: string;
79
+ sinkDeliveries?: Record<string, VoiceTraceSinkDeliveryResult>;
80
+ updatedAt: number;
81
+ };
82
+ export type VoiceTraceSinkDeliveryStore<TDelivery extends VoiceTraceSinkDeliveryRecord = VoiceTraceSinkDeliveryRecord> = {
83
+ get: (id: string) => Promise<TDelivery | undefined> | TDelivery | undefined;
84
+ list: () => Promise<TDelivery[]> | TDelivery[];
85
+ remove: (id: string) => Promise<void> | void;
86
+ set: (id: string, delivery: TDelivery) => Promise<void> | void;
87
+ };
88
+ export type VoiceTraceHTTPSinkOptions<TBody extends Record<string, unknown> = Record<string, unknown>> = {
89
+ backoffMs?: number;
90
+ body?: (input: {
91
+ events: StoredVoiceTraceEvent[];
92
+ }) => Promise<TBody> | TBody;
93
+ eventTypes?: VoiceTraceEventType[];
94
+ fetch?: typeof fetch;
95
+ headers?: Record<string, string>;
96
+ id: string;
97
+ kind?: string;
98
+ method?: 'POST' | 'PUT' | 'PATCH';
99
+ retries?: number;
100
+ signingSecret?: string;
101
+ timeoutMs?: number;
102
+ url: string;
103
+ };
104
+ export type VoiceTraceSinkStoreOptions<TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent> = {
105
+ awaitDelivery?: boolean;
106
+ deliveryQueue?: VoiceTraceSinkDeliveryStore;
107
+ onDelivery?: (result: VoiceTraceSinkFanoutResult) => Promise<void> | void;
108
+ onError?: (error: unknown) => Promise<void> | void;
109
+ redact?: VoiceTraceRedactionConfig;
110
+ sinks: VoiceTraceSink[];
111
+ store: VoiceTraceEventStore<TEvent>;
112
+ };
113
+ export type VoiceTraceSummary = {
114
+ assistantReplyCount: number;
115
+ callDurationMs?: number;
116
+ cost: {
117
+ estimatedRelativeCostUnits: number;
118
+ totalBillableAudioMs: number;
119
+ };
120
+ endedAt?: number;
121
+ errorCount: number;
122
+ eventCount: number;
123
+ failed: boolean;
124
+ handoffCount: number;
125
+ modelCallCount: number;
126
+ sessionId?: string;
127
+ startedAt?: number;
128
+ toolCallCount: number;
129
+ toolErrorCount: number;
130
+ traceId?: string;
131
+ transcriptCount: number;
132
+ turnCount: number;
133
+ };
134
+ export type VoiceTraceIssueSeverity = 'error' | 'warning';
135
+ export type VoiceTraceIssue = {
136
+ code: string;
137
+ message: string;
138
+ severity: VoiceTraceIssueSeverity;
139
+ };
140
+ export type VoiceTraceEvaluationOptions = {
141
+ maxHandoffs?: number;
142
+ maxModelCallsPerTurn?: number;
143
+ maxToolErrors?: number;
144
+ requireAssistantReply?: boolean;
145
+ requireCompletedCall?: boolean;
146
+ requireTranscript?: boolean;
147
+ requireTurn?: boolean;
148
+ };
149
+ export type VoiceTraceEvaluation = {
150
+ issues: VoiceTraceIssue[];
151
+ pass: boolean;
152
+ summary: VoiceTraceSummary;
153
+ };
154
+ export type VoiceTraceRedactionReplacement = string | ((input: {
155
+ key?: string;
156
+ path: string[];
157
+ value: string;
158
+ }) => string);
159
+ export type VoiceTraceRedactionOptions = {
160
+ keys?: string[];
161
+ redactEmails?: boolean;
162
+ redactPhoneNumbers?: boolean;
163
+ redactText?: boolean;
164
+ replacement?: VoiceTraceRedactionReplacement;
165
+ textKeys?: string[];
166
+ };
167
+ export type VoiceTraceRedactionConfig = boolean | VoiceTraceRedactionOptions;
168
+ export type VoiceResolvedTraceRedactionOptions = Required<Pick<VoiceTraceRedactionOptions, 'redactEmails' | 'redactPhoneNumbers' | 'redactText'>> & {
169
+ keys: string[];
170
+ replacement: VoiceTraceRedactionReplacement;
171
+ textKeys: string[];
172
+ };
173
+ export declare const createVoiceTraceEventId: (event: {
174
+ at?: number;
175
+ sessionId: string;
176
+ turnId?: string;
177
+ type: VoiceTraceEventType;
178
+ }) => string;
179
+ export declare const createVoiceTraceEvent: <TEvent extends VoiceTraceEvent = VoiceTraceEvent>(event: TEvent) => StoredVoiceTraceEvent<TEvent["payload"]>;
180
+ export declare const createVoiceTraceSinkDeliveryId: (events: StoredVoiceTraceEvent[]) => string;
181
+ export declare const createVoiceTraceSinkDeliveryRecord: (input: {
182
+ createdAt?: number;
183
+ events: StoredVoiceTraceEvent[];
184
+ id?: string;
185
+ } & Partial<Omit<VoiceTraceSinkDeliveryRecord, "createdAt" | "events" | "id">>) => VoiceTraceSinkDeliveryRecord;
186
+ export declare const filterVoiceTraceEvents: <TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent>(events: TEvent[], filter?: VoiceTraceEventFilter) => TEvent[];
187
+ export declare const selectVoiceTraceEventsForPrune: <TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent>(events: TEvent[], options?: Omit<VoiceTracePruneOptions, "store">) => TEvent[];
188
+ export declare const pruneVoiceTraceEvents: (options: VoiceTracePruneOptions) => Promise<VoiceTracePruneResult>;
189
+ export declare const createVoiceTraceHTTPSink: <TBody extends Record<string, unknown> = Record<string, unknown>>(options: VoiceTraceHTTPSinkOptions<TBody>) => VoiceTraceSink;
190
+ export declare const deliverVoiceTraceEventsToSinks: (input: {
191
+ events: StoredVoiceTraceEvent[];
192
+ redact?: VoiceTraceRedactionConfig;
193
+ sinks: VoiceTraceSink[];
194
+ }) => Promise<VoiceTraceSinkFanoutResult>;
195
+ export declare const createVoiceTraceSinkStore: <TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent>(options: VoiceTraceSinkStoreOptions<TEvent>) => VoiceTraceEventStore<TEvent>;
196
+ export declare const createVoiceMemoryTraceSinkDeliveryStore: <TDelivery extends VoiceTraceSinkDeliveryRecord = VoiceTraceSinkDeliveryRecord>() => VoiceTraceSinkDeliveryStore<TDelivery>;
197
+ export declare const createVoiceMemoryTraceEventStore: <TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent>() => VoiceTraceEventStore<TEvent>;
198
+ export declare const exportVoiceTrace: (input: {
199
+ filter?: VoiceTraceEventFilter;
200
+ redact?: VoiceTraceRedactionConfig;
201
+ store: VoiceTraceEventStore;
202
+ }) => Promise<{
203
+ exportedAt: number;
204
+ events: StoredVoiceTraceEvent<Record<string, unknown>>[];
205
+ filter: VoiceTraceEventFilter | undefined;
206
+ redacted: boolean;
207
+ }>;
208
+ export declare const resolveVoiceTraceRedactionOptions: (options?: VoiceTraceRedactionConfig) => VoiceResolvedTraceRedactionOptions;
209
+ export declare const redactVoiceTraceText: (value: string, options?: VoiceTraceRedactionConfig, input?: {
210
+ key?: string;
211
+ path?: string[];
212
+ }) => string;
213
+ export declare const redactVoiceTraceEvent: <TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent>(event: TEvent, options?: VoiceTraceRedactionConfig) => TEvent;
214
+ export declare const redactVoiceTraceEvents: <TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent>(events: TEvent[], options?: VoiceTraceRedactionConfig) => TEvent[];
215
+ export declare const summarizeVoiceTrace: (events: StoredVoiceTraceEvent[]) => VoiceTraceSummary;
216
+ export declare const evaluateVoiceTrace: (events: StoredVoiceTraceEvent[], options?: VoiceTraceEvaluationOptions) => VoiceTraceEvaluation;
217
+ export declare const renderVoiceTraceMarkdown: (events: StoredVoiceTraceEvent[], options?: {
218
+ title?: string;
219
+ evaluation?: VoiceTraceEvaluationOptions;
220
+ redact?: VoiceTraceRedactionConfig;
221
+ }) => string;
222
+ export declare const renderVoiceTraceHTML: (events: StoredVoiceTraceEvent[], options?: {
223
+ title?: string;
224
+ evaluation?: VoiceTraceEvaluationOptions;
225
+ redact?: VoiceTraceRedactionConfig;
226
+ }) => string;
227
+ export declare const buildVoiceTraceReplay: (events: StoredVoiceTraceEvent[], options?: {
228
+ evaluation?: VoiceTraceEvaluationOptions;
229
+ redact?: VoiceTraceRedactionConfig;
230
+ title?: string;
231
+ }) => {
232
+ evaluation: VoiceTraceEvaluation;
233
+ html: string;
234
+ markdown: string;
235
+ summary: VoiceTraceSummary;
236
+ };
package/dist/types.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import type { SessionStore } from '@absolutejs/absolute';
2
- import type { StoredVoiceIntegrationEvent, StoredVoiceOpsTask, VoiceIntegrationEventStore, VoiceOpsTask, VoiceOpsTaskStore } from './ops';
2
+ import type { VoiceOpsDispositionTaskPolicies, VoiceOpsTaskAssignmentRule, VoiceOpsTaskAssignmentRules, VoiceIntegrationWebhookConfig, StoredVoiceIntegrationEvent, StoredVoiceOpsTask, VoiceIntegrationEventStore, VoiceOpsTaskPolicy, VoiceOpsTask, VoiceOpsTaskStore } from './ops';
3
+ import type { VoiceIntegrationSink } from './opsSinks';
3
4
  import type { StoredVoiceCallReviewArtifact, VoiceCallReviewArtifact, VoiceCallReviewStore } from './testing/review';
5
+ import type { VoiceTraceEventStore } from './trace';
4
6
  export type AudioFormat = {
5
7
  container: 'raw';
6
8
  encoding: 'alaw' | 'mulaw' | 'pcm_s16le';
@@ -499,6 +501,30 @@ export type VoiceRuntimeOpsConfig<TContext = unknown, TSession extends VoiceSess
499
501
  review: StoredVoiceCallReviewArtifact;
500
502
  session: TSession;
501
503
  }) => Promise<Omit<VoiceOpsTask, 'id'> | VoiceOpsTask | StoredVoiceOpsTask | null | void> | Omit<VoiceOpsTask, 'id'> | VoiceOpsTask | StoredVoiceOpsTask | null | void;
504
+ resolveTaskPolicy?: (input: {
505
+ api: VoiceSessionHandle<TContext, TSession, TResult>;
506
+ context: TContext;
507
+ disposition: VoiceCallDisposition;
508
+ metadata?: Record<string, unknown>;
509
+ reason?: string;
510
+ review?: StoredVoiceCallReviewArtifact;
511
+ session: TSession;
512
+ target?: string;
513
+ task: StoredVoiceOpsTask;
514
+ }) => Promise<VoiceOpsTaskPolicy | void> | VoiceOpsTaskPolicy | void;
515
+ resolveTaskAssignment?: (input: {
516
+ api: VoiceSessionHandle<TContext, TSession, TResult>;
517
+ context: TContext;
518
+ disposition: VoiceCallDisposition;
519
+ metadata?: Record<string, unknown>;
520
+ reason?: string;
521
+ review?: StoredVoiceCallReviewArtifact;
522
+ session: TSession;
523
+ target?: string;
524
+ task: StoredVoiceOpsTask;
525
+ }) => Promise<VoiceOpsTaskAssignmentRule | void> | VoiceOpsTaskAssignmentRule | void;
526
+ taskAssignmentRules?: VoiceOpsTaskAssignmentRules;
527
+ taskPolicies?: VoiceOpsDispositionTaskPolicies;
502
528
  events?: VoiceIntegrationEventStore;
503
529
  onEvent?: (input: {
504
530
  api: VoiceSessionHandle<TContext, TSession, TResult>;
@@ -507,7 +533,9 @@ export type VoiceRuntimeOpsConfig<TContext = unknown, TSession extends VoiceSess
507
533
  session: TSession;
508
534
  }) => Promise<void> | void;
509
535
  reviews?: VoiceCallReviewStore;
536
+ sinks?: VoiceIntegrationSink[];
510
537
  tasks?: VoiceOpsTaskStore;
538
+ webhook?: VoiceIntegrationWebhookConfig;
511
539
  };
512
540
  export type VoiceNormalizedRouteConfig<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = Omit<VoiceRouteConfig<TContext, TSession, TResult>, 'onTurn'> & {
513
541
  onTurn: VoiceOnTurnObjectHandler<TContext, TSession, TResult>;
@@ -540,6 +568,7 @@ export type VoicePluginConfig<TContext = unknown, TSession extends VoiceSessionR
540
568
  logger?: VoiceLogger;
541
569
  htmx?: boolean | VoiceHTMXConfig<TSession, NoInfer<TResult>>;
542
570
  ops?: VoiceRuntimeOpsConfig<TContext, TSession, TResult>;
571
+ trace?: VoiceTraceEventStore;
543
572
  } & VoiceRouteConfig<TContext, TSession, TResult>;
544
573
  export type CreateVoiceSessionOptions<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
545
574
  costTelemetry?: VoiceCostTelemetryConfig<TContext, TSession, TResult>;
@@ -552,6 +581,7 @@ export type CreateVoiceSessionOptions<TContext = unknown, TSession extends Voice
552
581
  lexicon?: VoiceLexiconEntry[];
553
582
  sttFallback?: VoiceResolvedSTTFallbackConfig;
554
583
  store: VoiceSessionStore<TSession>;
584
+ trace?: VoiceTraceEventStore;
555
585
  reconnect: Required<VoiceReconnectConfig>;
556
586
  phraseHints?: VoicePhraseHint[];
557
587
  scenarioId?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.0",
3
+ "version": "0.0.22-beta.2",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",