@absolutejs/voice 0.0.22-beta.200 → 0.0.22-beta.201
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 +1 -1
- package/dist/index.js +4 -1
- package/dist/operationsRecord.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1378,7 +1378,7 @@ app.use(
|
|
|
1378
1378
|
);
|
|
1379
1379
|
```
|
|
1380
1380
|
|
|
1381
|
-
`createVoiceOperationsRecordRoutes(...)` links the call/session timeline, replay, provider
|
|
1381
|
+
`createVoiceOperationsRecordRoutes(...)` links the call/session timeline, transcript, replay, provider decisions, tools, handoffs, audit, reviews, ops tasks, integration events, and sink delivery attempts into one debuggable object. Use `/voice-operations/:sessionId` as the first place to investigate failed calls, provider failures, handoff failures, slow turns, and campaign attempts. The same mount also exposes incident handoff Markdown at `/voice-operations/:sessionId/incident.md` and `/api/voice-operations/:sessionId/incident.md` for support tooling.
|
|
1382
1382
|
|
|
1383
1383
|
Mount `createVoiceOpsRecoveryRoutes(...)` beside it when operators need one deploy-checkable recovery signal:
|
|
1384
1384
|
|
package/dist/index.js
CHANGED
|
@@ -24207,6 +24207,7 @@ var hasPayloadValue = (payload, key, values) => {
|
|
|
24207
24207
|
return typeof value === "string" && values.has(value);
|
|
24208
24208
|
};
|
|
24209
24209
|
var countIntegrationDeliveryStatus = (events, status) => events.filter((event) => event.deliveryStatus === status).length;
|
|
24210
|
+
var resolveRoutePath = (path, sessionId) => path.replace(":sessionId", encodeURIComponent(sessionId));
|
|
24210
24211
|
var toHandoff = (event) => ({
|
|
24211
24212
|
at: event.at,
|
|
24212
24213
|
fromAgentId: getString17(event.payload.fromAgentId),
|
|
@@ -24390,7 +24391,8 @@ var renderVoiceOperationsRecordHTML = (record, options = {}) => {
|
|
|
24390
24391
|
})
|
|
24391
24392
|
);`);
|
|
24392
24393
|
const incidentMarkdown = escapeHtml41(renderVoiceOperationsRecordIncidentMarkdown(record));
|
|
24393
|
-
|
|
24394
|
+
const incidentLink = options.incidentHref ? `<a href="${escapeHtml41(options.incidentHref)}">Download incident.md</a>` : "";
|
|
24395
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml41(options.title ?? "Voice Operations Record")}</title><style>body{background:#101417;color:#f9f4e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.eyebrow{color:#fbbf24;font-size:.8rem;font-weight:900;letter-spacing:.14em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,4.8rem);line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #475569;border-radius:999px;display:inline-flex;padding:8px 12px}.healthy{color:#86efac}.warning{color:#fbbf24}.failed,.error{color:#fca5a5}.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin:20px 0}.card,.primitive{background:#182025;border:1px solid #2d3a43;border-radius:20px;padding:16px}.card span,.muted,.label{color:#a9b4bd}.label{display:block;font-size:.72rem;font-weight:900;letter-spacing:.12em;text-transform:uppercase}.card strong{display:block;font-size:2rem}section{margin-top:28px}article{display:grid;gap:8px}ul{display:grid;gap:10px;list-style:none;padding:0}li{background:#182025;border:1px solid #2d3a43;border-radius:16px;padding:14px}pre{background:#080d10;border:1px solid #2d3a43;border-radius:16px;color:#dbeafe;overflow:auto;padding:14px}.hero-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:16px}.hero-actions a{background:#fbbf24;border-radius:999px;color:#111827;font-weight:900;padding:10px 14px;text-decoration:none}.two-column{display:grid;gap:18px;grid-template-columns:minmax(0,1.15fr) minmax(280px,.85fr)}@media(max-width:860px){main{padding:20px}.two-column{grid-template-columns:1fr}}</style></head><body><main><p class="eyebrow">Call log replacement</p><h1>${escapeHtml41(options.title ?? "Voice Operations Record")}</h1><p class="status ${escapeHtml41(record.status)}">${escapeHtml41(record.status)}</p><div class="hero-actions"><a href="#transcript">Transcript</a><a href="#provider-decisions">Provider decisions</a><a href="#incident-handoff">Incident handoff</a>${incidentLink}</div><section class="grid"><div class="card"><span>Events</span><strong>${String(record.summary.eventCount)}</strong></div><div class="card"><span>Turns</span><strong>${String(record.summary.turnCount)}</strong></div><div class="card"><span>Errors</span><strong>${String(record.summary.errorCount)}</strong></div><div class="card"><span>Duration</span><strong>${formatMs4(record.summary.callDurationMs)}</strong></div><div class="card"><span>Audit</span><strong>${String(record.audit?.total ?? 0)}</strong></div><div class="card"><span>Reviews</span><strong>${String(record.reviews?.total ?? 0)}</strong></div><div class="card"><span>Tasks</span><strong>${String(record.tasks?.total ?? 0)}</strong></div><div class="card"><span>Integrations</span><strong>${String(record.integrationEvents?.total ?? 0)}</strong></div></section><section class="two-column"><div><h2 id="transcript">Transcript</h2><ul>${transcript}</ul></div><div><h2 id="provider-decisions">Provider Decisions</h2><ul>${providerDecisions}</ul></div></section><section id="incident-handoff"><h2>Copyable Incident Handoff</h2><p class="muted">Paste this into Slack, Linear, Zendesk, or an incident review. ${incidentLink}</p><pre><code>${incidentMarkdown}</code></pre></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceOperationsRecordRoutes(...)</code> gives every call one debuggable object</h2><p class="muted">Use this as the support/debug payload across traces, provider routing, tools, handoffs, audit, latency, replay, reviews, tasks, and webhook delivery.</p><pre><code>${snippet}</code></pre></section><section><h2>Provider Summary</h2><div class="grid">${providers}</div></section><section><h2>Handoffs</h2><ul>${handoffs}</ul></section><section><h2>Tools</h2><ul>${tools}</ul></section><section><h2>Reviews</h2><ul>${reviews}</ul></section><section><h2>Tasks</h2><ul>${tasks}</ul></section><section><h2>Integration Events</h2><ul>${integrationEvents}</ul></section></main></body></html>`;
|
|
24394
24396
|
};
|
|
24395
24397
|
var createVoiceOperationsRecordRoutes = (options) => {
|
|
24396
24398
|
const path = options.path ?? "/api/voice-operations/:sessionId";
|
|
@@ -24432,6 +24434,7 @@ var createVoiceOperationsRecordRoutes = (options) => {
|
|
|
24432
24434
|
routes.get(htmlPath, async ({ params }) => {
|
|
24433
24435
|
const record = await buildRecord(getSessionId(params));
|
|
24434
24436
|
const body = await (options.render ?? ((input) => renderVoiceOperationsRecordHTML(input, {
|
|
24437
|
+
incidentHref: incidentHtmlPath ? resolveRoutePath(incidentHtmlPath, input.sessionId) : undefined,
|
|
24435
24438
|
title: options.title
|
|
24436
24439
|
})))(record);
|
|
24437
24440
|
return new Response(body, {
|
|
@@ -125,6 +125,7 @@ export type VoiceOperationsRecordRoutesOptions = Omit<VoiceOperationsRecordOptio
|
|
|
125
125
|
export declare const buildVoiceOperationsRecord: (options: VoiceOperationsRecordOptions) => Promise<VoiceOperationsRecord>;
|
|
126
126
|
export declare const renderVoiceOperationsRecordIncidentMarkdown: (record: VoiceOperationsRecord) => string;
|
|
127
127
|
export declare const renderVoiceOperationsRecordHTML: (record: VoiceOperationsRecord, options?: {
|
|
128
|
+
incidentHref?: string;
|
|
128
129
|
title?: string;
|
|
129
130
|
}) => string;
|
|
130
131
|
export declare const createVoiceOperationsRecordRoutes: (options: VoiceOperationsRecordRoutesOptions) => Elysia<"", {
|