@absolutejs/voice 0.0.22-beta.294 → 0.0.22-beta.296

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 CHANGED
@@ -2807,7 +2807,7 @@ app.use(
2807
2807
  );
2808
2808
  ```
2809
2809
 
2810
- `createVoiceOperationsRecordRoutes(...)` links the call/session timeline, transcript, replay, provider decisions, tools, handoffs, guardrail decisions, 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, blocked assistant output, blocked tool payloads, 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, including an `assistant.guardrail` blocked-stage summary when guardrail trace events exist.
2810
+ `createVoiceOperationsRecordRoutes(...)` links the call/session timeline, transcript, replay, provider decisions, tools, handoffs, guardrail decisions, audit, reviews, ops tasks, integration events, and sink delivery attempts into one debuggable object. Provider decisions include both older provider-routing events and explicit `provider.decision` traces, so the call log can show the surface, selected provider, fallback provider, and human-readable reason for each runtime choice. Use `/voice-operations/:sessionId` as the first place to investigate failed calls, blocked assistant output, blocked tool payloads, 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, including provider-decision summaries and an `assistant.guardrail` blocked-stage summary when those trace events exist.
2811
2811
 
2812
2812
  Use `evaluateVoiceOperationsRecordGuardrails(...)` when a proof pack or deploy gate needs JSON evidence that guardrails actually ran, blocked the expected stages, and produced named proofs/rule IDs. Use `assertVoiceOperationsRecordGuardrails(...)` in tests or smoke scripts when missing guardrail evidence should fail fast:
2813
2813
 
package/dist/index.js CHANGED
@@ -26252,10 +26252,12 @@ var toProviderDecision = (event) => {
26252
26252
  elapsedMs,
26253
26253
  error,
26254
26254
  fallbackProvider: getString17(event.payload.fallbackProvider),
26255
+ kind: getString17(event.payload.kind),
26255
26256
  provider,
26256
26257
  reason: getString17(event.payload.reason),
26257
26258
  selectedProvider: getString17(event.payload.selectedProvider),
26258
26259
  status,
26260
+ surface: getString17(event.payload.surface),
26259
26261
  type: event.type,
26260
26262
  turnId: event.turnId
26261
26263
  };
@@ -26433,6 +26435,18 @@ var renderVoiceOperationsRecordIncidentMarkdown = (record) => {
26433
26435
  const outcomes = outcomeLabels(record.outcome);
26434
26436
  const topErrors = record.traceEvents.filter((event) => event.type === "session.error").map((event) => getString17(event.payload.error)).filter((error) => typeof error === "string").slice(0, 3);
26435
26437
  const openTasks = record.tasks?.tasks.filter((task) => task.status !== "done").map((task) => task.title).slice(0, 3) ?? [];
26438
+ const providerDecisions = record.providerDecisions.filter((decision) => decision.provider || decision.selectedProvider || decision.fallbackProvider || decision.reason).slice(0, 5);
26439
+ const providerDecisionLines = providerDecisions.length ? providerDecisions.map((decision) => {
26440
+ const provider = decision.provider ?? decision.selectedProvider ?? decision.fallbackProvider ?? "provider";
26441
+ const parts = [
26442
+ decision.surface ? `surface=${decision.surface}` : undefined,
26443
+ decision.status ? `status=${decision.status}` : undefined,
26444
+ decision.selectedProvider ? `selected=${decision.selectedProvider}` : undefined,
26445
+ decision.fallbackProvider ? `fallback=${decision.fallbackProvider}` : undefined,
26446
+ decision.reason ? `reason=${decision.reason}` : undefined
26447
+ ].filter((part) => typeof part === "string");
26448
+ return `- ${provider}: ${parts.join("; ") || "decision recorded"}`;
26449
+ }) : ["- none recorded"];
26436
26450
  return [
26437
26451
  `# Voice incident handoff: ${record.sessionId}`,
26438
26452
  "",
@@ -26446,6 +26460,10 @@ var renderVoiceOperationsRecordIncidentMarkdown = (record) => {
26446
26460
  `- Top errors: ${topErrors.join("; ") || "none"}`,
26447
26461
  `- Guardrails: ${String(record.guardrails.blocked)} blocked / ${String(record.guardrails.warned)} warned / ${String(record.guardrails.total)} decisions`,
26448
26462
  "",
26463
+ "## Provider decisions",
26464
+ "",
26465
+ ...providerDecisionLines,
26466
+ "",
26449
26467
  renderVoiceOperationsRecordGuardrailMarkdown(record),
26450
26468
  "",
26451
26469
  "## Next checks",
@@ -26477,7 +26495,7 @@ var renderVoiceOperationsRecordGuardrailMarkdown = (record) => {
26477
26495
  var renderVoiceOperationsRecordHTML = (record, options = {}) => {
26478
26496
  const providers = record.providers.length ? record.providers.map((provider) => `<article><strong>${escapeHtml42(provider.provider)}</strong><span>${String(provider.eventCount)} events</span><span>${formatMs5(provider.averageElapsedMs)} avg</span><span>${String(provider.errorCount)} errors</span></article>`).join("") : '<p class="muted">No provider events recorded.</p>';
26479
26497
  const transcript = record.transcript.length ? record.transcript.map((turn) => `<li><strong>${escapeHtml42(turn.id)}</strong>${turn.committedText ? `<p><span class="label">Caller</span>${escapeHtml42(turn.committedText)}</p>` : ""}${turn.assistantReplies.map((reply) => `<p><span class="label">Assistant</span>${escapeHtml42(reply)}</p>`).join("")}${turn.errors.map((error) => `<p class="error"><span class="label">Error</span>${escapeHtml42(error)}</p>`).join("")}</li>`).join("") : "<li>No transcript turns recorded.</li>";
26480
- const providerDecisions = record.providerDecisions.length ? record.providerDecisions.map((decision) => `<li><strong>${escapeHtml42(decision.provider ?? decision.selectedProvider ?? decision.fallbackProvider ?? "provider")}</strong> <span>${escapeHtml42(decision.status ?? decision.type)}</span> ${formatMs5(decision.elapsedMs)}${decision.fallbackProvider ? `<p>Fallback: ${escapeHtml42(decision.fallbackProvider)}</p>` : ""}${decision.error ? `<p class="error">${escapeHtml42(decision.error)}</p>` : ""}${decision.reason ? `<p>${escapeHtml42(decision.reason)}</p>` : ""}</li>`).join("") : "<li>No provider decisions recorded.</li>";
26498
+ const providerDecisions = record.providerDecisions.length ? record.providerDecisions.map((decision) => `<li><strong>${escapeHtml42(decision.provider ?? decision.selectedProvider ?? decision.fallbackProvider ?? "provider")}</strong> <span>${escapeHtml42(decision.status ?? decision.type)}</span> ${formatMs5(decision.elapsedMs)}${decision.surface ? `<p><span class="label">Surface</span>${escapeHtml42(decision.surface)}</p>` : ""}${decision.kind ? `<p><span class="label">Kind</span>${escapeHtml42(decision.kind)}</p>` : ""}${decision.selectedProvider ? `<p>Selected: ${escapeHtml42(decision.selectedProvider)}</p>` : ""}${decision.fallbackProvider ? `<p>Fallback: ${escapeHtml42(decision.fallbackProvider)}</p>` : ""}${decision.error ? `<p class="error">${escapeHtml42(decision.error)}</p>` : ""}${decision.reason ? `<p>${escapeHtml42(decision.reason)}</p>` : ""}</li>`).join("") : "<li>No provider decisions recorded.</li>";
26481
26499
  const handoffs = record.handoffs.length ? record.handoffs.map((handoff) => `<li><strong>${escapeHtml42(handoff.fromAgentId ?? "unknown")}</strong> to <strong>${escapeHtml42(handoff.targetAgentId ?? "unknown")}</strong> <span>${escapeHtml42(handoff.status ?? "")}</span><p>${escapeHtml42(handoff.summary ?? handoff.reason ?? "")}</p></li>`).join("") : "<li>No agent handoffs recorded.</li>";
26482
26500
  const tools = record.tools.length ? record.tools.map((tool) => `<li><strong>${escapeHtml42(tool.toolName ?? "tool")}</strong> <span>${escapeHtml42(tool.status ?? "")}</span> ${formatMs5(tool.elapsedMs)} ${tool.error ? `<p>${escapeHtml42(tool.error)}</p>` : ""}</li>`).join("") : "<li>No tool calls recorded.</li>";
26483
26501
  const reviews = record.reviews?.reviews.length ? record.reviews.reviews.map((review) => `<li><strong>${escapeHtml42(review.title)}</strong> <span>${escapeHtml42(review.summary.outcome ?? "")}</span><p>${escapeHtml42(review.postCall?.summary ?? review.transcript.actual)}</p></li>`).join("") : "<li>No call reviews recorded.</li>";
@@ -45,10 +45,12 @@ export type VoiceOperationsRecordProviderDecision = {
45
45
  elapsedMs?: number;
46
46
  error?: string;
47
47
  fallbackProvider?: string;
48
+ kind?: string;
48
49
  provider?: string;
49
50
  reason?: string;
50
51
  selectedProvider?: string;
51
52
  status?: string;
53
+ surface?: string;
52
54
  type: StoredVoiceTraceEvent['type'];
53
55
  turnId?: string;
54
56
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.294",
3
+ "version": "0.0.22-beta.296",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",