@absolutejs/voice 0.0.22-beta.203 → 0.0.22-beta.205
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/README.md +374 -0
- package/dist/angular/index.d.ts +1 -0
- package/dist/angular/index.js +150 -31
- package/dist/angular/voice-agent-squad-status.service.d.ts +12 -0
- package/dist/client/agentSquadStatus.d.ts +37 -0
- package/dist/client/agentSquadStatusWidget.d.ts +24 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.js +170 -0
- package/dist/index.js +53 -12
- package/dist/outcomeContract.d.ts +3 -0
- package/dist/react/VoiceAgentSquadStatus.d.ts +5 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +349 -97
- package/dist/react/useVoiceAgentSquadStatus.d.ts +8 -0
- package/dist/svelte/createVoiceAgentSquadStatus.d.ts +9 -0
- package/dist/svelte/index.d.ts +1 -0
- package/dist/svelte/index.js +211 -33
- package/dist/toolContract.d.ts +4 -1
- package/dist/traceTimeline.d.ts +1 -0
- package/dist/vue/index.d.ts +1 -0
- package/dist/vue/index.js +255 -145
- package/dist/vue/useVoiceAgentSquadStatus.d.ts +9 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14095,6 +14095,17 @@ import { Elysia as Elysia21 } from "elysia";
|
|
|
14095
14095
|
// src/outcomeContract.ts
|
|
14096
14096
|
import { Elysia as Elysia19 } from "elysia";
|
|
14097
14097
|
var escapeHtml21 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
14098
|
+
var resolveSessionHref2 = (value, sessionId) => {
|
|
14099
|
+
if (value === false) {
|
|
14100
|
+
return;
|
|
14101
|
+
}
|
|
14102
|
+
const href = value ?? "/voice-operations/:sessionId";
|
|
14103
|
+
if (typeof href === "function") {
|
|
14104
|
+
return href(sessionId);
|
|
14105
|
+
}
|
|
14106
|
+
const encoded = encodeURIComponent(sessionId);
|
|
14107
|
+
return href.includes(":sessionId") ? href.replace(":sessionId", encoded) : `${href.replace(/\/$/, "")}/${encoded}`;
|
|
14108
|
+
};
|
|
14098
14109
|
var getPayloadString = (event, key) => typeof event.payload[key] === "string" ? event.payload[key] : undefined;
|
|
14099
14110
|
var toList = async (input) => Array.isArray(input) ? input : await input?.list() ?? [];
|
|
14100
14111
|
var hydrateSessions = async (input) => {
|
|
@@ -14118,6 +14129,7 @@ var reportContract = (input) => {
|
|
|
14118
14129
|
const { contract } = input;
|
|
14119
14130
|
const sessions = input.sessions.filter((session) => (!contract.scenarioId || session.scenarioId === contract.scenarioId) && matchesDisposition(dispositionForSession(session), contract.expectedDisposition));
|
|
14120
14131
|
const sessionIds = new Set(sessions.map((session) => session.id));
|
|
14132
|
+
const operationsRecordHrefs = [...sessionIds].map((sessionId) => resolveSessionHref2(input.operationsRecordHref, sessionId)).filter((href) => Boolean(href));
|
|
14121
14133
|
const reviews = input.reviews.filter((review) => matchesDisposition(review.summary.outcome, contract.expectedDisposition));
|
|
14122
14134
|
const tasks = input.tasks.filter((task) => matchesDisposition(task.outcome, contract.expectedDisposition));
|
|
14123
14135
|
const handoffs = input.handoffs.filter((handoff) => (!contract.expectedDisposition || handoff.action === contract.expectedDisposition || contract.expectedDisposition === "transferred" && handoff.action === "transfer" || contract.expectedDisposition === "escalated" && handoff.action === "escalate") && (sessionIds.size === 0 || sessionIds.has(handoff.sessionId)));
|
|
@@ -14174,7 +14186,9 @@ var reportContract = (input) => {
|
|
|
14174
14186
|
sessions: sessions.length,
|
|
14175
14187
|
tasks: tasks.length
|
|
14176
14188
|
},
|
|
14177
|
-
|
|
14189
|
+
operationsRecordHrefs,
|
|
14190
|
+
pass: issues.length === 0,
|
|
14191
|
+
sessionIds: [...sessionIds]
|
|
14178
14192
|
};
|
|
14179
14193
|
};
|
|
14180
14194
|
var runVoiceOutcomeContractSuite = async (options) => {
|
|
@@ -14185,7 +14199,15 @@ var runVoiceOutcomeContractSuite = async (options) => {
|
|
|
14185
14199
|
toList(options.events),
|
|
14186
14200
|
toList(options.handoffs)
|
|
14187
14201
|
]);
|
|
14188
|
-
const contracts = options.contracts.map((contract) => reportContract({
|
|
14202
|
+
const contracts = options.contracts.map((contract) => reportContract({
|
|
14203
|
+
contract,
|
|
14204
|
+
events,
|
|
14205
|
+
handoffs,
|
|
14206
|
+
operationsRecordHref: options.operationsRecordHref,
|
|
14207
|
+
reviews,
|
|
14208
|
+
sessions,
|
|
14209
|
+
tasks
|
|
14210
|
+
}));
|
|
14189
14211
|
const passed = contracts.filter((contract) => contract.pass).length;
|
|
14190
14212
|
const failed = contracts.length - passed;
|
|
14191
14213
|
return {
|
|
@@ -14199,12 +14221,15 @@ var runVoiceOutcomeContractSuite = async (options) => {
|
|
|
14199
14221
|
};
|
|
14200
14222
|
var renderVoiceOutcomeContractHTML = (report, options = {}) => {
|
|
14201
14223
|
const title = options.title ?? "Voice Outcome Contracts";
|
|
14202
|
-
const contracts = report.contracts.map((contract) =>
|
|
14224
|
+
const contracts = report.contracts.map((contract) => {
|
|
14225
|
+
const sessionLinks = contract.operationsRecordHrefs.length ? `<p>${contract.operationsRecordHrefs.map((href, index) => `<a href="${escapeHtml21(href)}">${escapeHtml21(contract.sessionIds[index] ?? href)}</a>`).join(" \xB7 ")}</p>` : "";
|
|
14226
|
+
return `<section class="contract ${contract.pass ? "pass" : "fail"}">
|
|
14203
14227
|
<div class="contract-header">
|
|
14204
14228
|
<div>
|
|
14205
14229
|
<p class="eyebrow">${escapeHtml21(contract.contractId)}</p>
|
|
14206
14230
|
<h2>${escapeHtml21(contract.label ?? contract.contractId)}</h2>
|
|
14207
14231
|
${contract.description ? `<p>${escapeHtml21(contract.description)}</p>` : ""}
|
|
14232
|
+
${sessionLinks}
|
|
14208
14233
|
</div>
|
|
14209
14234
|
<strong>${contract.pass ? "pass" : "fail"}</strong>
|
|
14210
14235
|
</div>
|
|
@@ -14216,7 +14241,8 @@ var renderVoiceOutcomeContractHTML = (report, options = {}) => {
|
|
|
14216
14241
|
<span>events ${String(contract.matched.integrationEvents)}</span>
|
|
14217
14242
|
</div>
|
|
14218
14243
|
${contract.issues.length ? `<ul>${contract.issues.map((issue) => `<li>${escapeHtml21(issue.message)}</li>`).join("")}</ul>` : ""}
|
|
14219
|
-
</section
|
|
14244
|
+
</section>`;
|
|
14245
|
+
}).join("");
|
|
14220
14246
|
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml21(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.contract{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.14),rgba(14,165,233,.12))}.eyebrow{color:#7dd3fc;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0}.summary,.grid{display:flex;flex-wrap:wrap;gap:10px}.pill,.grid span{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.contract-header{display:flex;gap:16px;justify-content:space-between}.pass{color:#86efac}.fail{color:#fca5a5}.contract.fail{border-color:rgba(248,113,113,.45)}li{margin:8px 0}@media(max-width:800px){main{padding:18px}.contract-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Business Outcome Verification</p><h1>${escapeHtml21(title)}</h1><div class="summary"><span class="pill ${report.status}">${report.status}</span><span class="pill">${String(report.passed)} passing</span><span class="pill">${String(report.failed)} failing</span><span class="pill">${String(report.total)} contracts</span></div></section>${contracts || '<section class="contract"><p>No outcome contracts configured.</p></section>'}</main></body></html>`;
|
|
14221
14247
|
};
|
|
14222
14248
|
var createVoiceOutcomeContractJSONHandler = (options) => async () => runVoiceOutcomeContractSuite(options);
|
|
@@ -14453,6 +14479,17 @@ var createDefaultTurn = (caseId) => ({
|
|
|
14453
14479
|
var defaultApi = {};
|
|
14454
14480
|
var sameJSON = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
14455
14481
|
var escapeHtml22 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
14482
|
+
var resolveSessionHref3 = (value, sessionId) => {
|
|
14483
|
+
if (value === false) {
|
|
14484
|
+
return;
|
|
14485
|
+
}
|
|
14486
|
+
const href = value ?? "/voice-operations/:sessionId";
|
|
14487
|
+
if (typeof href === "function") {
|
|
14488
|
+
return href(sessionId);
|
|
14489
|
+
}
|
|
14490
|
+
const encoded = encodeURIComponent(sessionId);
|
|
14491
|
+
return href.includes(":sessionId") ? href.replace(":sessionId", encoded) : `${href.replace(/\/$/, "")}/${encoded}`;
|
|
14492
|
+
};
|
|
14456
14493
|
var evaluateExpectation = (input) => {
|
|
14457
14494
|
const issues = [];
|
|
14458
14495
|
const expect = input.expect;
|
|
@@ -14503,7 +14540,7 @@ var evaluateExpectation = (input) => {
|
|
|
14503
14540
|
}
|
|
14504
14541
|
return issues;
|
|
14505
14542
|
};
|
|
14506
|
-
var runVoiceToolContract = async (definition) => {
|
|
14543
|
+
var runVoiceToolContract = async (definition, options = {}) => {
|
|
14507
14544
|
const cases = [];
|
|
14508
14545
|
for (const testCase of definition.cases) {
|
|
14509
14546
|
const session = testCase.session ?? createDefaultSession(definition.id, testCase.id);
|
|
@@ -14563,7 +14600,9 @@ var runVoiceToolContract = async (definition) => {
|
|
|
14563
14600
|
error: result.error,
|
|
14564
14601
|
issues: issues2,
|
|
14565
14602
|
label: testCase.label,
|
|
14603
|
+
operationsRecordHref: resolveSessionHref3(options.operationsRecordHref, session.id),
|
|
14566
14604
|
pass: issues2.length === 0,
|
|
14605
|
+
sessionId: session.id,
|
|
14567
14606
|
status: result.status,
|
|
14568
14607
|
timedOut: result.timedOut
|
|
14569
14608
|
});
|
|
@@ -14602,7 +14641,7 @@ var createVoiceToolRuntimeContractDefaults = () => ({
|
|
|
14602
14641
|
timeoutMs: 5000
|
|
14603
14642
|
});
|
|
14604
14643
|
var runVoiceToolContractSuite = async (options) => {
|
|
14605
|
-
const contracts = await Promise.all(options.contracts.map((contract) => runVoiceToolContract(contract)));
|
|
14644
|
+
const contracts = await Promise.all(options.contracts.map((contract) => runVoiceToolContract(contract, options)));
|
|
14606
14645
|
const passed = contracts.filter((contract) => contract.pass).length;
|
|
14607
14646
|
const failed = contracts.length - passed;
|
|
14608
14647
|
return {
|
|
@@ -14642,9 +14681,10 @@ var renderVoiceToolContractHTML = (report, options = {}) => {
|
|
|
14642
14681
|
);`);
|
|
14643
14682
|
const contracts = report.contracts.map((contract) => {
|
|
14644
14683
|
const cases = contract.cases.map((testCase) => `<tr>
|
|
14645
|
-
<td>${escapeHtml22(testCase.label ?? testCase.caseId)}</td>
|
|
14684
|
+
<td>${testCase.operationsRecordHref ? `<a href="${escapeHtml22(testCase.operationsRecordHref)}">${escapeHtml22(testCase.label ?? testCase.caseId)}</a>` : escapeHtml22(testCase.label ?? testCase.caseId)}</td>
|
|
14646
14685
|
<td class="${testCase.pass ? "pass" : "fail"}">${testCase.pass ? "pass" : "fail"}</td>
|
|
14647
14686
|
<td>${escapeHtml22(testCase.status)}</td>
|
|
14687
|
+
<td>${escapeHtml22(testCase.sessionId)}</td>
|
|
14648
14688
|
<td>${String(testCase.attempts)}</td>
|
|
14649
14689
|
<td>${String(testCase.elapsedMs)}ms</td>
|
|
14650
14690
|
<td>${testCase.timedOut ? "yes" : "no"}</td>
|
|
@@ -14659,7 +14699,7 @@ var renderVoiceToolContractHTML = (report, options = {}) => {
|
|
|
14659
14699
|
<strong class="${contract.pass ? "pass" : "fail"}">${contract.pass ? "Passing" : "Failing"}</strong>
|
|
14660
14700
|
</div>
|
|
14661
14701
|
<table>
|
|
14662
|
-
<thead><tr><th>Case</th><th>Status</th><th>Result</th><th>Attempts</th><th>Elapsed</th><th>Timed out</th><th>Issues</th></tr></thead>
|
|
14702
|
+
<thead><tr><th>Case</th><th>Status</th><th>Result</th><th>Session</th><th>Attempts</th><th>Elapsed</th><th>Timed out</th><th>Issues</th></tr></thead>
|
|
14663
14703
|
<tbody>${cases}</tbody>
|
|
14664
14704
|
</table>
|
|
14665
14705
|
</section>`;
|
|
@@ -15196,7 +15236,7 @@ var escapeHtml24 = (value) => value.replaceAll("&", "&").replaceAll("<", "&l
|
|
|
15196
15236
|
var increment4 = (record, key) => {
|
|
15197
15237
|
record[key] = (record[key] ?? 0) + 1;
|
|
15198
15238
|
};
|
|
15199
|
-
var
|
|
15239
|
+
var resolveSessionHref4 = (value, session) => {
|
|
15200
15240
|
if (value === false) {
|
|
15201
15241
|
return;
|
|
15202
15242
|
}
|
|
@@ -15360,7 +15400,7 @@ var summarizeVoiceSessions = async (options = {}) => {
|
|
|
15360
15400
|
const replayHref = options.replayHref === false ? "" : typeof options.replayHref === "function" ? options.replayHref(item) : `${options.replayHref ?? "/api/voice-sessions"}/${encodeURIComponent(sessionId)}/replay/htmx`;
|
|
15361
15401
|
return {
|
|
15362
15402
|
...item,
|
|
15363
|
-
operationsRecordHref:
|
|
15403
|
+
operationsRecordHref: resolveSessionHref4(options.operationsRecordHref, item),
|
|
15364
15404
|
replayHref
|
|
15365
15405
|
};
|
|
15366
15406
|
});
|
|
@@ -23985,7 +24025,7 @@ var eventStatus = (event) => firstString3(event.payload, [
|
|
|
23985
24025
|
"reason"
|
|
23986
24026
|
]);
|
|
23987
24027
|
var eventElapsedMs2 = (event) => firstNumber3(event.payload, ["elapsedMs", "latencyMs", "durationMs"]);
|
|
23988
|
-
var
|
|
24028
|
+
var resolveSessionHref5 = (value, sessionId) => {
|
|
23989
24029
|
if (value === false) {
|
|
23990
24030
|
return;
|
|
23991
24031
|
}
|
|
@@ -24109,13 +24149,14 @@ var summarizeVoiceTraceTimeline = (events, options = {}) => {
|
|
|
24109
24149
|
id: event.id,
|
|
24110
24150
|
label: timelineLabel(event),
|
|
24111
24151
|
offsetMs: Math.max(0, event.at - startedAt),
|
|
24152
|
+
payload: event.payload,
|
|
24112
24153
|
provider: eventProvider(event),
|
|
24113
24154
|
status: eventStatus(event),
|
|
24114
24155
|
turnId: event.turnId,
|
|
24115
24156
|
type: event.type
|
|
24116
24157
|
})),
|
|
24117
24158
|
lastEventAt: sorted.at(-1)?.at,
|
|
24118
|
-
operationsRecordHref:
|
|
24159
|
+
operationsRecordHref: resolveSessionHref5(options.operationsRecordHref, sessionId),
|
|
24119
24160
|
providers: summarizeProviders(sorted),
|
|
24120
24161
|
sessionId,
|
|
24121
24162
|
startedAt: summary.startedAt,
|
|
@@ -32,7 +32,9 @@ export type VoiceOutcomeContractReport = {
|
|
|
32
32
|
sessions: number;
|
|
33
33
|
tasks: number;
|
|
34
34
|
};
|
|
35
|
+
operationsRecordHrefs: string[];
|
|
35
36
|
pass: boolean;
|
|
37
|
+
sessionIds: string[];
|
|
36
38
|
};
|
|
37
39
|
export type VoiceOutcomeContractSuiteReport = {
|
|
38
40
|
checkedAt: number;
|
|
@@ -49,6 +51,7 @@ export type VoiceOutcomeContractOptions<TSession extends VoiceSessionRecord = Vo
|
|
|
49
51
|
contracts: VoiceOutcomeContractDefinition[];
|
|
50
52
|
events?: StoredVoiceIntegrationEvent[] | ListStore<StoredVoiceIntegrationEvent>;
|
|
51
53
|
handoffs?: StoredVoiceHandoffDelivery[] | VoiceHandoffDeliveryStore;
|
|
54
|
+
operationsRecordHref?: false | string | ((sessionId: string) => string);
|
|
52
55
|
reviews?: StoredVoiceCallReviewArtifact[] | ListStore<StoredVoiceCallReviewArtifact>;
|
|
53
56
|
sessions?: TSession[] | VoiceSessionStore<TSession>;
|
|
54
57
|
tasks?: StoredVoiceOpsTask[] | ListStore<StoredVoiceOpsTask>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type VoiceAgentSquadStatusWidgetOptions } from '../client/agentSquadStatusWidget';
|
|
2
|
+
export type VoiceAgentSquadStatusProps = VoiceAgentSquadStatusWidgetOptions & {
|
|
3
|
+
path?: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function VoiceAgentSquadStatus({ path, ...options }: VoiceAgentSquadStatusProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { VoiceProviderContracts } from './VoiceProviderContracts';
|
|
|
7
7
|
export { VoiceProviderStatus } from './VoiceProviderStatus';
|
|
8
8
|
export { VoiceRoutingStatus } from './VoiceRoutingStatus';
|
|
9
9
|
export { VoiceTraceTimeline } from './VoiceTraceTimeline';
|
|
10
|
+
export { VoiceAgentSquadStatus } from './VoiceAgentSquadStatus';
|
|
10
11
|
export { VoiceTurnLatency } from './VoiceTurnLatency';
|
|
11
12
|
export { VoiceTurnQuality } from './VoiceTurnQuality';
|
|
12
13
|
export { useVoiceOpsStatus } from './useVoiceOpsStatus';
|
|
@@ -22,6 +23,7 @@ export { useVoiceProviderContracts } from './useVoiceProviderContracts';
|
|
|
22
23
|
export { useVoiceProviderSimulationControls } from './useVoiceProviderSimulationControls';
|
|
23
24
|
export { useVoiceRoutingStatus } from './useVoiceRoutingStatus';
|
|
24
25
|
export { useVoiceTraceTimeline } from './useVoiceTraceTimeline';
|
|
26
|
+
export { useVoiceAgentSquadStatus } from './useVoiceAgentSquadStatus';
|
|
25
27
|
export { useVoiceTurnLatency } from './useVoiceTurnLatency';
|
|
26
28
|
export { useVoiceTurnQuality } from './useVoiceTurnQuality';
|
|
27
29
|
export { useVoiceWorkflowStatus } from './useVoiceWorkflowStatus';
|