@absolutejs/voice 0.0.22-beta.22 → 0.0.22-beta.23
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 +134 -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,131 @@ 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
|
+
for (const event of sorted) {
|
|
7171
|
+
const provider = getString3(event.payload.provider);
|
|
7172
|
+
if (provider) {
|
|
7173
|
+
providers.add(provider);
|
|
7174
|
+
}
|
|
7175
|
+
if (event.type === "session.error" && (event.payload.providerStatus === "error" || typeof event.payload.error === "string")) {
|
|
7176
|
+
increment2(providerErrors, provider ?? "unknown");
|
|
7177
|
+
}
|
|
7178
|
+
const outcome = getString3(event.payload.outcome);
|
|
7179
|
+
if (outcome) {
|
|
7180
|
+
latestOutcome = outcome;
|
|
7181
|
+
}
|
|
7182
|
+
}
|
|
7183
|
+
const item = {
|
|
7184
|
+
endedAt: summary.endedAt,
|
|
7185
|
+
errorCount: summary.errorCount,
|
|
7186
|
+
eventCount: summary.eventCount,
|
|
7187
|
+
latestOutcome,
|
|
7188
|
+
providerErrors,
|
|
7189
|
+
providers: [...providers].sort(),
|
|
7190
|
+
sessionId,
|
|
7191
|
+
startedAt: summary.startedAt,
|
|
7192
|
+
status: summary.failed ? "failed" : "healthy",
|
|
7193
|
+
transcriptCount: summary.transcriptCount,
|
|
7194
|
+
turnCount: summary.turnCount
|
|
7195
|
+
};
|
|
7196
|
+
const replayHref = options.replayHref === false ? "" : typeof options.replayHref === "function" ? options.replayHref(item) : `${options.replayHref ?? "/api/voice-sessions"}/${encodeURIComponent(sessionId)}/replay/htmx`;
|
|
7197
|
+
return {
|
|
7198
|
+
...item,
|
|
7199
|
+
replayHref
|
|
7200
|
+
};
|
|
7201
|
+
});
|
|
7202
|
+
const search = options.q?.trim().toLowerCase();
|
|
7203
|
+
return sessions.filter((session) => {
|
|
7204
|
+
if (options.status && options.status !== "all" && session.status !== options.status) {
|
|
7205
|
+
return false;
|
|
7206
|
+
}
|
|
7207
|
+
if (options.provider && !session.providers.includes(options.provider)) {
|
|
7208
|
+
return false;
|
|
7209
|
+
}
|
|
7210
|
+
if (!search) {
|
|
7211
|
+
return true;
|
|
7212
|
+
}
|
|
7213
|
+
return [
|
|
7214
|
+
session.sessionId,
|
|
7215
|
+
session.latestOutcome,
|
|
7216
|
+
session.status,
|
|
7217
|
+
...session.providers
|
|
7218
|
+
].some((value) => value?.toLowerCase().includes(search));
|
|
7219
|
+
}).sort((left, right) => (right.endedAt ?? right.startedAt ?? 0) - (left.endedAt ?? left.startedAt ?? 0)).slice(0, options.limit ?? 50);
|
|
7220
|
+
};
|
|
7221
|
+
var renderVoiceSessionsHTML = (sessions) => sessions.length === 0 ? '<p class="voice-sessions-empty">No voice sessions found.</p>' : [
|
|
7222
|
+
'<div class="voice-sessions-list">',
|
|
7223
|
+
...sessions.map((session) => [
|
|
7224
|
+
`<article class="voice-session-card ${escapeHtml6(session.status)}">`,
|
|
7225
|
+
'<div class="voice-session-card-header">',
|
|
7226
|
+
`<strong>${escapeHtml6(session.sessionId)}</strong>`,
|
|
7227
|
+
`<span>${escapeHtml6(session.status)}</span>`,
|
|
7228
|
+
"</div>",
|
|
7229
|
+
"<dl>",
|
|
7230
|
+
`<div><dt>Events</dt><dd>${String(session.eventCount)}</dd></div>`,
|
|
7231
|
+
`<div><dt>Turns</dt><dd>${String(session.turnCount)}</dd></div>`,
|
|
7232
|
+
`<div><dt>Transcripts</dt><dd>${String(session.transcriptCount)}</dd></div>`,
|
|
7233
|
+
`<div><dt>Errors</dt><dd>${String(session.errorCount)}</dd></div>`,
|
|
7234
|
+
"</dl>",
|
|
7235
|
+
session.latestOutcome ? `<p>Outcome: ${escapeHtml6(session.latestOutcome)}</p>` : "",
|
|
7236
|
+
session.providers.length ? `<p>Providers: ${session.providers.map(escapeHtml6).join(", ")}</p>` : "",
|
|
7237
|
+
session.replayHref ? `<p><a href="${escapeHtml6(session.replayHref)}">Open replay</a></p>` : "",
|
|
7238
|
+
"</article>"
|
|
7239
|
+
].join("")),
|
|
7240
|
+
"</div>"
|
|
7241
|
+
].join("");
|
|
7242
|
+
var createVoiceSessionsJSONHandler = (options = {}) => async ({ query }) => summarizeVoiceSessions({
|
|
7243
|
+
...options,
|
|
7244
|
+
limit: typeof query?.limit === "string" ? Number(query.limit) : options.limit,
|
|
7245
|
+
provider: query?.provider ?? options.provider,
|
|
7246
|
+
q: query?.q ?? options.q,
|
|
7247
|
+
status: query?.status === "failed" || query?.status === "healthy" || query?.status === "all" ? query.status : options.status
|
|
7248
|
+
});
|
|
7249
|
+
var createVoiceSessionsHTMLHandler = (options = {}) => async ({ query }) => {
|
|
7250
|
+
const sessions = await summarizeVoiceSessions({
|
|
7251
|
+
...options,
|
|
7252
|
+
limit: typeof query?.limit === "string" ? Number(query.limit) : options.limit,
|
|
7253
|
+
provider: query?.provider ?? options.provider,
|
|
7254
|
+
q: query?.q ?? options.q,
|
|
7255
|
+
status: query?.status === "failed" || query?.status === "healthy" || query?.status === "all" ? query.status : options.status
|
|
7256
|
+
});
|
|
7257
|
+
const body = await (options.render?.(sessions) ?? renderVoiceSessionsHTML(sessions));
|
|
7258
|
+
return new Response(body, {
|
|
7259
|
+
headers: {
|
|
7260
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
7261
|
+
...options.headers
|
|
7262
|
+
}
|
|
7263
|
+
});
|
|
7264
|
+
};
|
|
7265
|
+
var createVoiceSessionListRoutes = (options = {}) => {
|
|
7266
|
+
const path = options.path ?? "/api/voice-sessions";
|
|
7267
|
+
const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
|
|
7268
|
+
const routes = new Elysia4({
|
|
7269
|
+
name: options.name ?? "absolutejs-voice-session-list"
|
|
7270
|
+
}).get(path, createVoiceSessionsJSONHandler(options));
|
|
7271
|
+
if (htmlPath) {
|
|
7272
|
+
routes.get(htmlPath, createVoiceSessionsHTMLHandler(options));
|
|
7273
|
+
}
|
|
7274
|
+
return routes;
|
|
7275
|
+
};
|
|
7147
7276
|
var createVoiceSessionReplayJSONHandler = (options) => async ({ params }) => summarizeVoiceSessionReplay({
|
|
7148
7277
|
...options,
|
|
7149
7278
|
sessionId: params.sessionId ?? ""
|
|
@@ -10710,6 +10839,7 @@ export {
|
|
|
10710
10839
|
transcodePCMToTwilioOutboundPayload,
|
|
10711
10840
|
summarizeVoiceTraceSinkDeliveries,
|
|
10712
10841
|
summarizeVoiceTrace,
|
|
10842
|
+
summarizeVoiceSessions,
|
|
10713
10843
|
summarizeVoiceSessionReplay,
|
|
10714
10844
|
summarizeVoiceProviderHealth,
|
|
10715
10845
|
summarizeVoiceOpsTasks,
|
|
@@ -10736,6 +10866,7 @@ export {
|
|
|
10736
10866
|
reopenVoiceOpsTask,
|
|
10737
10867
|
renderVoiceTraceMarkdown,
|
|
10738
10868
|
renderVoiceTraceHTML,
|
|
10869
|
+
renderVoiceSessionsHTML,
|
|
10739
10870
|
renderVoiceProviderHealthHTML,
|
|
10740
10871
|
renderVoiceCallReviewMarkdown,
|
|
10741
10872
|
renderVoiceCallReviewHTML,
|
|
@@ -10777,10 +10908,13 @@ export {
|
|
|
10777
10908
|
createVoiceTaskUpdatedEvent,
|
|
10778
10909
|
createVoiceTaskSLABreachedEvent,
|
|
10779
10910
|
createVoiceTaskCreatedEvent,
|
|
10911
|
+
createVoiceSessionsJSONHandler,
|
|
10912
|
+
createVoiceSessionsHTMLHandler,
|
|
10780
10913
|
createVoiceSessionReplayRoutes,
|
|
10781
10914
|
createVoiceSessionReplayJSONHandler,
|
|
10782
10915
|
createVoiceSessionReplayHTMLHandler,
|
|
10783
10916
|
createVoiceSessionRecord,
|
|
10917
|
+
createVoiceSessionListRoutes,
|
|
10784
10918
|
createVoiceSession,
|
|
10785
10919
|
createVoiceSTTRoutingCorrectionHandler,
|
|
10786
10920
|
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>;
|