@absolutejs/voice 0.0.22-beta.22 → 0.0.22-beta.24
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 -2
- package/dist/index.js +136 -0
- package/dist/sessionReplay.d.ts +81 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { voice } from './plugin';
|
|
2
2
|
export { createVoiceAssistant, createVoiceExperiment, summarizeVoiceAssistantRuns } from './assistant';
|
|
3
3
|
export { createVoiceAssistantHealthHTMLHandler, createVoiceAssistantHealthJSONHandler, createVoiceAssistantHealthRoutes, renderVoiceAssistantHealthHTML, summarizeVoiceAssistantHealth } from './assistantHealth';
|
|
4
|
-
export { createVoiceSessionReplayHTMLHandler, createVoiceSessionReplayJSONHandler, createVoiceSessionReplayRoutes, summarizeVoiceSessionReplay } from './sessionReplay';
|
|
4
|
+
export { createVoiceSessionListRoutes, createVoiceSessionReplayHTMLHandler, createVoiceSessionReplayJSONHandler, createVoiceSessionReplayRoutes, createVoiceSessionsHTMLHandler, createVoiceSessionsJSONHandler, renderVoiceSessionsHTML, summarizeVoiceSessions, summarizeVoiceSessionReplay } from './sessionReplay';
|
|
5
5
|
export { createVoiceAgent, createVoiceAgentSquad, createVoiceAgentTool } from './agent';
|
|
6
6
|
export { createStoredVoiceCallReviewArtifact, createStoredVoiceExternalObjectMap, createStoredVoiceIntegrationEvent, createStoredVoiceOpsTask, createVoiceFileExternalObjectMapStore, createVoiceFileAssistantMemoryStore, createVoiceFileIntegrationEventStore, createVoiceFileReviewStore, createVoiceFileRuntimeStorage, createVoiceFileSessionStore, createVoiceFileTaskStore, createVoiceFileTraceSinkDeliveryStore, createVoiceFileTraceEventStore } from './fileStore';
|
|
7
7
|
export { createVoiceAssistantMemoryHandle, createVoiceAssistantMemoryRecord, createVoiceMemoryAssistantMemoryStore, resolveVoiceAssistantMemoryNamespace } from './assistantMemory';
|
|
@@ -30,7 +30,7 @@ export { createVoiceCallReviewFromLiveTelephonyReport, createVoiceCallReviewReco
|
|
|
30
30
|
export type { VoiceAssistant, VoiceAssistantArtifactPlan, VoiceAssistantExperiment, VoiceAssistantExperimentOptions, VoiceAssistantGuardrailInput, VoiceAssistantGuardrails, VoiceAssistantMemoryLifecycle, VoiceAssistantMemoryLifecycleInput, VoiceAssistantOptions, VoiceAssistantOutputGuardrailInput, VoiceAssistantPreset, VoiceAssistantRunsSummary, VoiceAssistantRunSummary, VoiceAssistantVariant } from './assistant';
|
|
31
31
|
export type { VoiceAssistantHealthFailure, VoiceAssistantHealthHTMLHandlerOptions, VoiceAssistantHealthRoutesOptions, VoiceAssistantHealthSummary, VoiceAssistantHealthSummaryOptions } from './assistantHealth';
|
|
32
32
|
export type { VoiceAssistantMemoryBinding, VoiceAssistantMemoryHandle, VoiceAssistantMemoryOptions, VoiceAssistantMemoryRecord, VoiceAssistantMemoryStore } from './assistantMemory';
|
|
33
|
-
export type { VoiceSessionReplay, VoiceSessionReplayHTMLHandlerOptions, VoiceSessionReplayOptions, VoiceSessionReplayRoutesOptions, VoiceSessionReplayTurn } from './sessionReplay';
|
|
33
|
+
export type { VoiceSessionListHTMLHandlerOptions, VoiceSessionListItem, VoiceSessionListOptions, VoiceSessionListRoutesOptions, VoiceSessionListStatus, VoiceSessionReplay, VoiceSessionReplayHTMLHandlerOptions, VoiceSessionReplayOptions, VoiceSessionReplayRoutesOptions, VoiceSessionReplayTurn } from './sessionReplay';
|
|
34
34
|
export type { AnthropicVoiceAssistantModelOptions, GeminiVoiceAssistantModelOptions, OpenAIVoiceAssistantModelOptions, VoiceProviderRouterEvent, VoiceProviderRouterFallbackMode, VoiceProviderRouterHealthOptions, VoiceProviderRouterOptions, VoiceProviderRouterPolicy, VoiceProviderRouterProviderHealth, VoiceProviderRouterProviderProfile, VoiceJSONAssistantModelHandler, VoiceJSONAssistantModelOptions } from './modelAdapters';
|
|
35
35
|
export type { VoiceProviderHealthStatus, VoiceProviderHealthSummary, VoiceProviderHealthSummaryOptions } from './providerHealth';
|
|
36
36
|
export type { VoiceAgent, VoiceAgentMessage, VoiceAgentMessageRole, VoiceAgentModel, VoiceAgentModelInput, VoiceAgentModelOutput, VoiceAgentOptions, VoiceAgentRunResult, VoiceAgentSquadOptions, VoiceAgentTool, VoiceAgentToolCall, VoiceAgentToolResult } from './agent';
|
package/dist/index.js
CHANGED
|
@@ -7064,6 +7064,10 @@ var buildVoiceTraceReplay = (events, options = {}) => ({
|
|
|
7064
7064
|
|
|
7065
7065
|
// src/sessionReplay.ts
|
|
7066
7066
|
var getString3 = (value) => typeof value === "string" ? value : undefined;
|
|
7067
|
+
var escapeHtml6 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7068
|
+
var increment2 = (record, key) => {
|
|
7069
|
+
record[key] = (record[key] ?? 0) + 1;
|
|
7070
|
+
};
|
|
7067
7071
|
var buildReplayTurns = (events) => {
|
|
7068
7072
|
const turns = new Map;
|
|
7069
7073
|
const getTurn = (turnId) => {
|
|
@@ -7144,6 +7148,133 @@ var summarizeVoiceSessionReplay = async (options) => {
|
|
|
7144
7148
|
turns: buildReplayTurns(events)
|
|
7145
7149
|
};
|
|
7146
7150
|
};
|
|
7151
|
+
var summarizeVoiceSessions = async (options = {}) => {
|
|
7152
|
+
const events = options.events ?? await options.store?.list() ?? [];
|
|
7153
|
+
const grouped = new Map;
|
|
7154
|
+
for (const event of events) {
|
|
7155
|
+
grouped.set(event.sessionId, [...grouped.get(event.sessionId) ?? [], event]);
|
|
7156
|
+
}
|
|
7157
|
+
const sessions = [...grouped.entries()].map(([sessionId, sessionEvents]) => {
|
|
7158
|
+
const sorted = filterVoiceTraceEvents(sessionEvents);
|
|
7159
|
+
const summary = buildVoiceTraceReplay(sorted, {
|
|
7160
|
+
evaluation: {
|
|
7161
|
+
requireAssistantReply: false,
|
|
7162
|
+
requireCompletedCall: false,
|
|
7163
|
+
requireTranscript: false,
|
|
7164
|
+
requireTurn: false
|
|
7165
|
+
}
|
|
7166
|
+
}).summary;
|
|
7167
|
+
const providerErrors = {};
|
|
7168
|
+
const providers = new Set;
|
|
7169
|
+
let latestOutcome;
|
|
7170
|
+
let errorCount = 0;
|
|
7171
|
+
for (const event of sorted) {
|
|
7172
|
+
const provider = getString3(event.payload.provider);
|
|
7173
|
+
if (provider) {
|
|
7174
|
+
providers.add(provider);
|
|
7175
|
+
}
|
|
7176
|
+
if (event.type === "session.error" && (event.payload.providerStatus === "error" || typeof event.payload.error === "string")) {
|
|
7177
|
+
errorCount += 1;
|
|
7178
|
+
increment2(providerErrors, provider ?? "unknown");
|
|
7179
|
+
}
|
|
7180
|
+
const outcome = getString3(event.payload.outcome);
|
|
7181
|
+
if (outcome) {
|
|
7182
|
+
latestOutcome = outcome;
|
|
7183
|
+
}
|
|
7184
|
+
}
|
|
7185
|
+
const item = {
|
|
7186
|
+
endedAt: summary.endedAt,
|
|
7187
|
+
errorCount,
|
|
7188
|
+
eventCount: summary.eventCount,
|
|
7189
|
+
latestOutcome,
|
|
7190
|
+
providerErrors,
|
|
7191
|
+
providers: [...providers].sort(),
|
|
7192
|
+
sessionId,
|
|
7193
|
+
startedAt: summary.startedAt,
|
|
7194
|
+
status: errorCount > 0 ? "failed" : "healthy",
|
|
7195
|
+
transcriptCount: summary.transcriptCount,
|
|
7196
|
+
turnCount: summary.turnCount
|
|
7197
|
+
};
|
|
7198
|
+
const replayHref = options.replayHref === false ? "" : typeof options.replayHref === "function" ? options.replayHref(item) : `${options.replayHref ?? "/api/voice-sessions"}/${encodeURIComponent(sessionId)}/replay/htmx`;
|
|
7199
|
+
return {
|
|
7200
|
+
...item,
|
|
7201
|
+
replayHref
|
|
7202
|
+
};
|
|
7203
|
+
});
|
|
7204
|
+
const search = options.q?.trim().toLowerCase();
|
|
7205
|
+
return sessions.filter((session) => {
|
|
7206
|
+
if (options.status && options.status !== "all" && session.status !== options.status) {
|
|
7207
|
+
return false;
|
|
7208
|
+
}
|
|
7209
|
+
if (options.provider && !session.providers.includes(options.provider)) {
|
|
7210
|
+
return false;
|
|
7211
|
+
}
|
|
7212
|
+
if (!search) {
|
|
7213
|
+
return true;
|
|
7214
|
+
}
|
|
7215
|
+
return [
|
|
7216
|
+
session.sessionId,
|
|
7217
|
+
session.latestOutcome,
|
|
7218
|
+
session.status,
|
|
7219
|
+
...session.providers
|
|
7220
|
+
].some((value) => value?.toLowerCase().includes(search));
|
|
7221
|
+
}).sort((left, right) => (right.endedAt ?? right.startedAt ?? 0) - (left.endedAt ?? left.startedAt ?? 0)).slice(0, options.limit ?? 50);
|
|
7222
|
+
};
|
|
7223
|
+
var renderVoiceSessionsHTML = (sessions) => sessions.length === 0 ? '<p class="voice-sessions-empty">No voice sessions found.</p>' : [
|
|
7224
|
+
'<div class="voice-sessions-list">',
|
|
7225
|
+
...sessions.map((session) => [
|
|
7226
|
+
`<article class="voice-session-card ${escapeHtml6(session.status)}">`,
|
|
7227
|
+
'<div class="voice-session-card-header">',
|
|
7228
|
+
`<strong>${escapeHtml6(session.sessionId)}</strong>`,
|
|
7229
|
+
`<span>${escapeHtml6(session.status)}</span>`,
|
|
7230
|
+
"</div>",
|
|
7231
|
+
"<dl>",
|
|
7232
|
+
`<div><dt>Events</dt><dd>${String(session.eventCount)}</dd></div>`,
|
|
7233
|
+
`<div><dt>Turns</dt><dd>${String(session.turnCount)}</dd></div>`,
|
|
7234
|
+
`<div><dt>Transcripts</dt><dd>${String(session.transcriptCount)}</dd></div>`,
|
|
7235
|
+
`<div><dt>Errors</dt><dd>${String(session.errorCount)}</dd></div>`,
|
|
7236
|
+
"</dl>",
|
|
7237
|
+
session.latestOutcome ? `<p>Outcome: ${escapeHtml6(session.latestOutcome)}</p>` : "",
|
|
7238
|
+
session.providers.length ? `<p>Providers: ${session.providers.map(escapeHtml6).join(", ")}</p>` : "",
|
|
7239
|
+
session.replayHref ? `<p><a href="${escapeHtml6(session.replayHref)}">Open replay</a></p>` : "",
|
|
7240
|
+
"</article>"
|
|
7241
|
+
].join("")),
|
|
7242
|
+
"</div>"
|
|
7243
|
+
].join("");
|
|
7244
|
+
var createVoiceSessionsJSONHandler = (options = {}) => async ({ query }) => summarizeVoiceSessions({
|
|
7245
|
+
...options,
|
|
7246
|
+
limit: typeof query?.limit === "string" ? Number(query.limit) : options.limit,
|
|
7247
|
+
provider: query?.provider ?? options.provider,
|
|
7248
|
+
q: query?.q ?? options.q,
|
|
7249
|
+
status: query?.status === "failed" || query?.status === "healthy" || query?.status === "all" ? query.status : options.status
|
|
7250
|
+
});
|
|
7251
|
+
var createVoiceSessionsHTMLHandler = (options = {}) => async ({ query }) => {
|
|
7252
|
+
const sessions = await summarizeVoiceSessions({
|
|
7253
|
+
...options,
|
|
7254
|
+
limit: typeof query?.limit === "string" ? Number(query.limit) : options.limit,
|
|
7255
|
+
provider: query?.provider ?? options.provider,
|
|
7256
|
+
q: query?.q ?? options.q,
|
|
7257
|
+
status: query?.status === "failed" || query?.status === "healthy" || query?.status === "all" ? query.status : options.status
|
|
7258
|
+
});
|
|
7259
|
+
const body = await (options.render?.(sessions) ?? renderVoiceSessionsHTML(sessions));
|
|
7260
|
+
return new Response(body, {
|
|
7261
|
+
headers: {
|
|
7262
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
7263
|
+
...options.headers
|
|
7264
|
+
}
|
|
7265
|
+
});
|
|
7266
|
+
};
|
|
7267
|
+
var createVoiceSessionListRoutes = (options = {}) => {
|
|
7268
|
+
const path = options.path ?? "/api/voice-sessions";
|
|
7269
|
+
const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
|
|
7270
|
+
const routes = new Elysia4({
|
|
7271
|
+
name: options.name ?? "absolutejs-voice-session-list"
|
|
7272
|
+
}).get(path, createVoiceSessionsJSONHandler(options));
|
|
7273
|
+
if (htmlPath) {
|
|
7274
|
+
routes.get(htmlPath, createVoiceSessionsHTMLHandler(options));
|
|
7275
|
+
}
|
|
7276
|
+
return routes;
|
|
7277
|
+
};
|
|
7147
7278
|
var createVoiceSessionReplayJSONHandler = (options) => async ({ params }) => summarizeVoiceSessionReplay({
|
|
7148
7279
|
...options,
|
|
7149
7280
|
sessionId: params.sessionId ?? ""
|
|
@@ -10710,6 +10841,7 @@ export {
|
|
|
10710
10841
|
transcodePCMToTwilioOutboundPayload,
|
|
10711
10842
|
summarizeVoiceTraceSinkDeliveries,
|
|
10712
10843
|
summarizeVoiceTrace,
|
|
10844
|
+
summarizeVoiceSessions,
|
|
10713
10845
|
summarizeVoiceSessionReplay,
|
|
10714
10846
|
summarizeVoiceProviderHealth,
|
|
10715
10847
|
summarizeVoiceOpsTasks,
|
|
@@ -10736,6 +10868,7 @@ export {
|
|
|
10736
10868
|
reopenVoiceOpsTask,
|
|
10737
10869
|
renderVoiceTraceMarkdown,
|
|
10738
10870
|
renderVoiceTraceHTML,
|
|
10871
|
+
renderVoiceSessionsHTML,
|
|
10739
10872
|
renderVoiceProviderHealthHTML,
|
|
10740
10873
|
renderVoiceCallReviewMarkdown,
|
|
10741
10874
|
renderVoiceCallReviewHTML,
|
|
@@ -10777,10 +10910,13 @@ export {
|
|
|
10777
10910
|
createVoiceTaskUpdatedEvent,
|
|
10778
10911
|
createVoiceTaskSLABreachedEvent,
|
|
10779
10912
|
createVoiceTaskCreatedEvent,
|
|
10913
|
+
createVoiceSessionsJSONHandler,
|
|
10914
|
+
createVoiceSessionsHTMLHandler,
|
|
10780
10915
|
createVoiceSessionReplayRoutes,
|
|
10781
10916
|
createVoiceSessionReplayJSONHandler,
|
|
10782
10917
|
createVoiceSessionReplayHTMLHandler,
|
|
10783
10918
|
createVoiceSessionRecord,
|
|
10919
|
+
createVoiceSessionListRoutes,
|
|
10784
10920
|
createVoiceSession,
|
|
10785
10921
|
createVoiceSTTRoutingCorrectionHandler,
|
|
10786
10922
|
createVoiceSQLiteTraceSinkDeliveryStore,
|
package/dist/sessionReplay.d.ts
CHANGED
|
@@ -28,6 +28,39 @@ export type VoiceSessionReplay = {
|
|
|
28
28
|
}>;
|
|
29
29
|
turns: VoiceSessionReplayTurn[];
|
|
30
30
|
};
|
|
31
|
+
export type VoiceSessionListStatus = 'failed' | 'healthy';
|
|
32
|
+
export type VoiceSessionListItem = {
|
|
33
|
+
endedAt?: number;
|
|
34
|
+
errorCount: number;
|
|
35
|
+
eventCount: number;
|
|
36
|
+
latestOutcome?: string;
|
|
37
|
+
providerErrors: Record<string, number>;
|
|
38
|
+
providers: string[];
|
|
39
|
+
replayHref: string;
|
|
40
|
+
sessionId: string;
|
|
41
|
+
startedAt?: number;
|
|
42
|
+
status: VoiceSessionListStatus;
|
|
43
|
+
transcriptCount: number;
|
|
44
|
+
turnCount: number;
|
|
45
|
+
};
|
|
46
|
+
export type VoiceSessionListOptions = {
|
|
47
|
+
events?: StoredVoiceTraceEvent[];
|
|
48
|
+
limit?: number;
|
|
49
|
+
provider?: string;
|
|
50
|
+
q?: string;
|
|
51
|
+
replayHref?: false | string | ((session: Omit<VoiceSessionListItem, 'replayHref'>) => string);
|
|
52
|
+
status?: VoiceSessionListStatus | 'all';
|
|
53
|
+
store?: VoiceTraceEventStore;
|
|
54
|
+
};
|
|
55
|
+
export type VoiceSessionListHTMLHandlerOptions = VoiceSessionListOptions & {
|
|
56
|
+
headers?: HeadersInit;
|
|
57
|
+
render?: (sessions: VoiceSessionListItem[]) => string | Promise<string>;
|
|
58
|
+
};
|
|
59
|
+
export type VoiceSessionListRoutesOptions = VoiceSessionListHTMLHandlerOptions & {
|
|
60
|
+
htmlPath?: false | string;
|
|
61
|
+
name?: string;
|
|
62
|
+
path?: string;
|
|
63
|
+
};
|
|
31
64
|
export type VoiceSessionReplayOptions = {
|
|
32
65
|
evaluation?: VoiceTraceEvaluationOptions;
|
|
33
66
|
events?: StoredVoiceTraceEvent[];
|
|
@@ -46,6 +79,54 @@ export type VoiceSessionReplayRoutesOptions = VoiceSessionReplayHTMLHandlerOptio
|
|
|
46
79
|
path?: string;
|
|
47
80
|
};
|
|
48
81
|
export declare const summarizeVoiceSessionReplay: (options: VoiceSessionReplayOptions) => Promise<VoiceSessionReplay>;
|
|
82
|
+
export declare const summarizeVoiceSessions: (options?: VoiceSessionListOptions) => Promise<VoiceSessionListItem[]>;
|
|
83
|
+
export declare const renderVoiceSessionsHTML: (sessions: VoiceSessionListItem[]) => string;
|
|
84
|
+
export declare const createVoiceSessionsJSONHandler: (options?: VoiceSessionListOptions) => ({ query }: {
|
|
85
|
+
query?: Record<string, string | undefined>;
|
|
86
|
+
}) => Promise<VoiceSessionListItem[]>;
|
|
87
|
+
export declare const createVoiceSessionsHTMLHandler: (options?: VoiceSessionListHTMLHandlerOptions) => ({ query }: {
|
|
88
|
+
query?: Record<string, string | undefined>;
|
|
89
|
+
}) => Promise<Response>;
|
|
90
|
+
export declare const createVoiceSessionListRoutes: (options?: VoiceSessionListRoutesOptions) => Elysia<"", {
|
|
91
|
+
decorator: {};
|
|
92
|
+
store: {};
|
|
93
|
+
derive: {};
|
|
94
|
+
resolve: {};
|
|
95
|
+
}, {
|
|
96
|
+
typebox: {};
|
|
97
|
+
error: {};
|
|
98
|
+
}, {
|
|
99
|
+
schema: {};
|
|
100
|
+
standaloneSchema: {};
|
|
101
|
+
macro: {};
|
|
102
|
+
macroFn: {};
|
|
103
|
+
parser: {};
|
|
104
|
+
response: {};
|
|
105
|
+
}, {
|
|
106
|
+
[x: string]: {
|
|
107
|
+
get: {
|
|
108
|
+
body: unknown;
|
|
109
|
+
params: {};
|
|
110
|
+
query: unknown;
|
|
111
|
+
headers: unknown;
|
|
112
|
+
response: {
|
|
113
|
+
200: VoiceSessionListItem[];
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
}, {
|
|
118
|
+
derive: {};
|
|
119
|
+
resolve: {};
|
|
120
|
+
schema: {};
|
|
121
|
+
standaloneSchema: {};
|
|
122
|
+
response: {};
|
|
123
|
+
}, {
|
|
124
|
+
derive: {};
|
|
125
|
+
resolve: {};
|
|
126
|
+
schema: {};
|
|
127
|
+
standaloneSchema: {};
|
|
128
|
+
response: {};
|
|
129
|
+
}>;
|
|
49
130
|
export declare const createVoiceSessionReplayJSONHandler: (options: Omit<VoiceSessionReplayOptions, "sessionId">) => ({ params }: {
|
|
50
131
|
params: Record<string, string | undefined>;
|
|
51
132
|
}) => Promise<VoiceSessionReplay>;
|