@absolutejs/voice 0.0.22-beta.248 → 0.0.22-beta.249

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
@@ -2794,6 +2794,17 @@ app.use(
2794
2794
 
2795
2795
  `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.
2796
2796
 
2797
+ 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:
2798
+
2799
+ ```ts
2800
+ const report = assertVoiceOperationsRecordGuardrails(record, {
2801
+ minBlocked: 1,
2802
+ proofs: ['live-guardrails-runtime'],
2803
+ ruleIds: ['support.no-medical-advice'],
2804
+ stages: ['assistant-output', 'tool-input']
2805
+ });
2806
+ ```
2807
+
2797
2808
  Most proof surfaces can link to the same record by passing an operations-record URL template such as `/voice-operations/:sessionId`. Use that template anywhere a report emits session-level failures: production readiness, ops recovery, trace timelines, session lists, reviews, campaign attempts, eval reports, simulation-suite actions, tool-contract cases, and outcome-contract matched sessions. The goal is that no operator has to guess which trace, review, task, or delivery queue belongs to the failing call.
2798
2809
 
2799
2810
  If a customer asks for "the call log," send the operations-record URL. If engineering needs reproducible context, send the incident Markdown URL. If a deploy gate fails, start at readiness or ops recovery and follow the linked operations record instead of searching storage manually.
package/dist/index.d.ts CHANGED
@@ -56,7 +56,7 @@ export { buildVoiceProductionReadinessGate, buildVoiceProductionReadinessReport,
56
56
  export { createVoiceReadinessProfile, recommendVoiceReadinessProfile } from './readinessProfiles';
57
57
  export { buildVoiceProviderContractMatrix, createVoiceProviderContractMatrixHTMLHandler, createVoiceProviderContractMatrixJSONHandler, createVoiceProviderContractMatrixPreset, createVoiceProviderContractMatrixRoutes, evaluateVoiceProviderStackGaps, renderVoiceProviderContractMatrixHTML, recommendVoiceProviderStack } from './providerStackRecommendations';
58
58
  export { buildVoiceOpsConsoleReport, createVoiceOpsConsoleRoutes, renderVoiceOpsConsoleHTML } from './opsConsoleRoutes';
59
- export { buildVoiceOperationsRecord, createVoiceOperationsRecordRoutes, renderVoiceOperationsRecordGuardrailMarkdown, renderVoiceOperationsRecordHTML, renderVoiceOperationsRecordIncidentMarkdown } from './operationsRecord';
59
+ export { assertVoiceOperationsRecordGuardrails, buildVoiceOperationsRecord, createVoiceOperationsRecordRoutes, evaluateVoiceOperationsRecordGuardrails, renderVoiceOperationsRecordGuardrailMarkdown, renderVoiceOperationsRecordHTML, renderVoiceOperationsRecordIncidentMarkdown } from './operationsRecord';
60
60
  export { assertVoiceObservabilityExportRecord, buildVoiceObservabilityArtifactIndex, buildVoiceObservabilityExportDeliveryHistory, buildVoiceObservabilityExportReplayReport, buildVoiceObservabilityExport, assertVoiceObservabilityExportSchema, createVoiceObservabilityExportSchema, createVoiceFileObservabilityExportDeliveryReceiptStore, createVoiceMemoryObservabilityExportDeliveryReceiptStore, createVoiceObservabilityExportRoutes, createVoiceObservabilityExportReplayRoutes, deliverVoiceObservabilityExport, loadVoiceObservabilityExportReplaySource, replayVoiceObservabilityExport, renderVoiceObservabilityExportReplayHTML, renderVoiceObservabilityExportMarkdown, validateVoiceObservabilityExportRecord, voiceObservabilityExportSchemaId, voiceObservabilityExportSchemaVersion } from './observabilityExport';
61
61
  export { buildVoiceOpsRecoveryReadinessCheck, buildVoiceOpsRecoveryReport, createVoiceOpsRecoveryRoutes, renderVoiceOpsRecoveryHTML, renderVoiceOpsRecoveryMarkdown } from './opsRecovery';
62
62
  export { buildVoiceIncidentBundle, createStoredVoiceIncidentBundleArtifact, createVoiceIncidentBundleRoutes, createVoiceMemoryIncidentBundleStore, pruneVoiceIncidentBundleArtifacts, saveVoiceIncidentBundleArtifact } from './incidentBundle';
@@ -123,7 +123,7 @@ export type { VoiceOpsStatus, VoiceOpsStatusLink, VoiceOpsStatusOptions, VoiceOp
123
123
  export type { VoiceProductionReadinessAction, VoiceProductionReadinessAuditOptions, VoiceProductionReadinessAuditRequirement, VoiceProductionReadinessAuditSummary, VoiceProductionReadinessCheck, VoiceProductionReadinessGateIssue, VoiceProductionReadinessGateOptions, VoiceProductionReadinessGateProfile, VoiceProductionReadinessGateProfileSurface, VoiceProductionReadinessGateReport, VoiceProductionReadinessOpsActionHistoryOptions, VoiceProductionReadinessOpsActionHistorySummary, VoiceProductionReadinessOperationsRecordLink, VoiceProductionReadinessOperationsRecordLinks, VoiceProductionReadinessProfileExplanation, VoiceProductionReadinessProfileSurface, VoiceProductionReadinessProofSource, VoiceProductionReadinessReport, VoiceProductionReadinessRoutesOptions, VoiceProductionReadinessTraceDeliverySummary, VoiceProductionReadinessAuditDeliveryOptions, VoiceProductionReadinessAuditDeliverySummary, VoiceProductionReadinessTraceDeliveryOptions, VoiceProductionReadinessStatus } from './productionReadiness';
124
124
  export type { VoiceReadinessProfileName, VoiceReadinessProfileOptions, VoiceReadinessProfileRecommendation, VoiceReadinessProfileRecommendationScore, VoiceReadinessProfileRoutesOptions } from './readinessProfiles';
125
125
  export type { VoiceProviderStackChoice, VoiceProviderStackCapabilities, VoiceProviderStackCapabilityGap, VoiceProviderStackCapabilityGapInput, VoiceProviderStackCapabilityGapReport, VoiceProviderContractCheck, VoiceProviderContractCheckStatus, VoiceProviderContractDefinition, VoiceProviderContractMatrixHandlerOptions, VoiceProviderContractMatrixHTMLHandlerOptions, VoiceProviderContractMatrixInput, VoiceProviderContractMatrixPresetOptions, VoiceProviderContractMatrixReport, VoiceProviderContractMatrixRoutesOptions, VoiceProviderContractMatrixRow, VoiceProviderStackInput, VoiceProviderStackKind, VoiceProviderStackRecommendation } from './providerStackRecommendations';
126
- export type { VoiceOperationsRecord, VoiceOperationsRecordAgentHandoff, VoiceOperationsRecordAuditSummary, VoiceOperationsRecordGuardrailDecision, VoiceOperationsRecordGuardrailFinding, VoiceOperationsRecordGuardrailSummary, VoiceOperationsRecordIntegrationEventSummary, VoiceOperationsRecordOptions, VoiceOperationsRecordOutcome, VoiceOperationsRecordProviderDecision, VoiceOperationsRecordReviewSummary, VoiceOperationsRecordRoutesOptions, VoiceOperationsRecordStatus, VoiceOperationsRecordTaskSummary, VoiceOperationsRecordTranscriptTurn, VoiceOperationsRecordTool } from './operationsRecord';
126
+ export type { VoiceOperationsRecord, VoiceOperationsRecordAgentHandoff, VoiceOperationsRecordAuditSummary, VoiceOperationsRecordGuardrailAssertionInput, VoiceOperationsRecordGuardrailAssertionReport, VoiceOperationsRecordGuardrailDecision, VoiceOperationsRecordGuardrailFinding, VoiceOperationsRecordGuardrailSummary, VoiceOperationsRecordIntegrationEventSummary, VoiceOperationsRecordOptions, VoiceOperationsRecordOutcome, VoiceOperationsRecordProviderDecision, VoiceOperationsRecordReviewSummary, VoiceOperationsRecordRoutesOptions, VoiceOperationsRecordStatus, VoiceOperationsRecordTaskSummary, VoiceOperationsRecordTranscriptTurn, VoiceOperationsRecordTool } from './operationsRecord';
127
127
  export type { VoiceObservabilityExportArtifact, VoiceObservabilityExportArtifactChecksum, VoiceObservabilityExportArtifactFreshness, VoiceObservabilityExportArtifactIndex, VoiceObservabilityExportArtifactIndexItem, VoiceObservabilityExportArtifactKind, VoiceObservabilityExportDeliverySummary, VoiceObservabilityExportDeliveryDestination, VoiceObservabilityExportDeliveryDestinationResult, VoiceObservabilityExportDeliveryHistory, VoiceObservabilityExportDeliveryOptions, VoiceObservabilityExportDeliveryReceipt, VoiceObservabilityExportDeliveryReceiptStore, VoiceObservabilityExportDeliveryReport, VoiceObservabilityExportEnvelope, VoiceObservabilityExportIssue, VoiceObservabilityExportIssueCode, VoiceObservabilityExportOptions, VoiceObservabilityExportIngestedRecordKind, VoiceObservabilityExportRedactionSummary, VoiceObservabilityExportRecordValidationOptions, VoiceObservabilityExportReplayIssue, VoiceObservabilityExportReplayIssueCode, VoiceObservabilityExportReplayRecords, VoiceObservabilityExportReplayReport, VoiceObservabilityExportReplayRoutesOptions, VoiceObservabilityExportReplaySource, VoiceObservabilityExportReport, VoiceObservabilityExportRoutesOptions, VoiceObservabilityExportSchema, VoiceObservabilityExportStatus, VoiceObservabilityExportValidationIssue, VoiceObservabilityExportValidationResult } from './observabilityExport';
128
128
  export type { VoiceOpsRecoveryFailedSession, VoiceOpsRecoveryInterventionSummary, VoiceOpsRecoveryIssue, VoiceOpsRecoveryIssueCode, VoiceOpsRecoveryLinks, VoiceOpsRecoveryProviderSummary, VoiceOpsRecoveryReport, VoiceOpsRecoveryReportOptions, VoiceOpsRecoveryRoutesOptions, VoiceOpsRecoveryStatus } from './opsRecovery';
129
129
  export type { StoredVoiceIncidentBundleArtifact, VoiceIncidentBundle, VoiceIncidentBundleArtifactOptions, VoiceIncidentBundleFormat, VoiceIncidentBundleOptions, VoiceIncidentBundleRetentionOptions, VoiceIncidentBundleRetentionReport, VoiceIncidentBundleRoutesOptions, VoiceIncidentBundleStore, VoiceIncidentBundleStoreFilter, VoiceIncidentBundleSummary } from './incidentBundle';
package/dist/index.js CHANGED
@@ -22880,6 +22880,15 @@ var hasPayloadValue = (payload, key, values) => {
22880
22880
  return typeof value === "string" && values.has(value);
22881
22881
  };
22882
22882
  var countIntegrationDeliveryStatus = (events, status) => events.filter((event) => event.deliveryStatus === status).length;
22883
+ var uniqueSorted = (values) => [
22884
+ ...new Set(values.filter((value) => typeof value === "string"))
22885
+ ].sort();
22886
+ var pushMissingValuesIssue = (input) => {
22887
+ const missing = (input.expected ?? []).filter((value) => !input.actual.includes(value));
22888
+ if (missing.length > 0) {
22889
+ input.issues.push(`Missing guardrail ${input.label}: ${missing.join(", ")}`);
22890
+ }
22891
+ };
22883
22892
  var resolveRoutePath = (path, sessionId) => path.replace(":sessionId", encodeURIComponent(sessionId));
22884
22893
  var toHandoff = (event) => ({
22885
22894
  at: event.at,
@@ -23047,6 +23056,78 @@ var buildVoiceOperationsRecord = async (options) => {
23047
23056
  transcript: buildTranscript(replay)
23048
23057
  };
23049
23058
  };
23059
+ var evaluateVoiceOperationsRecordGuardrails = (record, input = {}) => {
23060
+ const issues = [];
23061
+ const decisions = record.guardrails.decisions;
23062
+ const proofs = uniqueSorted(decisions.map((decision) => decision.proof));
23063
+ const ruleIds = uniqueSorted(decisions.flatMap((decision) => decision.findings.map((finding) => finding.ruleId)));
23064
+ const stages = uniqueSorted(decisions.map((decision) => decision.stage));
23065
+ const statuses = uniqueSorted(decisions.map((decision) => decision.status));
23066
+ const toolNames = uniqueSorted(decisions.map((decision) => decision.toolName));
23067
+ const minDecisions = input.minDecisions ?? 1;
23068
+ if (record.guardrails.total < minDecisions) {
23069
+ issues.push(`Expected at least ${String(minDecisions)} guardrail decisions, found ${String(record.guardrails.total)}.`);
23070
+ }
23071
+ if (input.minBlocked !== undefined && record.guardrails.blocked < input.minBlocked) {
23072
+ issues.push(`Expected at least ${String(input.minBlocked)} blocked guardrail decisions, found ${String(record.guardrails.blocked)}.`);
23073
+ }
23074
+ if (input.minWarned !== undefined && record.guardrails.warned < input.minWarned) {
23075
+ issues.push(`Expected at least ${String(input.minWarned)} warned guardrail decisions, found ${String(record.guardrails.warned)}.`);
23076
+ }
23077
+ if (input.minPassed !== undefined && record.guardrails.passed < input.minPassed) {
23078
+ issues.push(`Expected at least ${String(input.minPassed)} passed guardrail decisions, found ${String(record.guardrails.passed)}.`);
23079
+ }
23080
+ pushMissingValuesIssue({
23081
+ actual: proofs,
23082
+ expected: input.proofs,
23083
+ issues,
23084
+ label: "proofs"
23085
+ });
23086
+ pushMissingValuesIssue({
23087
+ actual: ruleIds,
23088
+ expected: input.ruleIds,
23089
+ issues,
23090
+ label: "rule IDs"
23091
+ });
23092
+ pushMissingValuesIssue({
23093
+ actual: stages,
23094
+ expected: input.stages,
23095
+ issues,
23096
+ label: "stages"
23097
+ });
23098
+ pushMissingValuesIssue({
23099
+ actual: statuses,
23100
+ expected: input.statuses,
23101
+ issues,
23102
+ label: "statuses"
23103
+ });
23104
+ pushMissingValuesIssue({
23105
+ actual: toolNames,
23106
+ expected: input.toolNames,
23107
+ issues,
23108
+ label: "tool names"
23109
+ });
23110
+ return {
23111
+ blocked: record.guardrails.blocked,
23112
+ decisions: record.guardrails.total,
23113
+ issues,
23114
+ ok: issues.length === 0,
23115
+ passed: record.guardrails.passed,
23116
+ proofs,
23117
+ ruleIds,
23118
+ stages,
23119
+ statuses,
23120
+ toolNames,
23121
+ warned: record.guardrails.warned
23122
+ };
23123
+ };
23124
+ var assertVoiceOperationsRecordGuardrails = (record, input = {}) => {
23125
+ const report = evaluateVoiceOperationsRecordGuardrails(record, input);
23126
+ if (!report.ok) {
23127
+ throw new Error(`Voice operations record guardrail assertion failed for ${record.sessionId}: ${report.issues.join(" ")}`);
23128
+ }
23129
+ return report;
23130
+ };
23050
23131
  var escapeHtml39 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
23051
23132
  var formatMs4 = (value) => value === undefined ? "n/a" : `${String(value)}ms`;
23052
23133
  var outcomeLabels = (outcome) => [
@@ -29905,6 +29986,7 @@ export {
29905
29986
  evaluateVoiceTelephonyContract,
29906
29987
  evaluateVoiceQuality,
29907
29988
  evaluateVoiceProviderStackGaps,
29989
+ evaluateVoiceOperationsRecordGuardrails,
29908
29990
  evaluateVoiceGuardrailPolicy,
29909
29991
  encodeTwilioMulawBase64,
29910
29992
  deliverVoiceTraceEventsToSinks,
@@ -30218,6 +30300,7 @@ export {
30218
30300
  buildEmptyVoiceProofTrendReport,
30219
30301
  assignVoiceOpsTask,
30220
30302
  assertVoiceProviderRoutingContract,
30303
+ assertVoiceOperationsRecordGuardrails,
30221
30304
  assertVoiceObservabilityExportSchema,
30222
30305
  assertVoiceObservabilityExportRecord,
30223
30306
  assertVoiceLatencySLOGate,
@@ -105,6 +105,30 @@ export type VoiceOperationsRecordGuardrailSummary = {
105
105
  total: number;
106
106
  warned: number;
107
107
  };
108
+ export type VoiceOperationsRecordGuardrailAssertionInput = {
109
+ minBlocked?: number;
110
+ minDecisions?: number;
111
+ minPassed?: number;
112
+ minWarned?: number;
113
+ proofs?: string[];
114
+ ruleIds?: string[];
115
+ stages?: string[];
116
+ statuses?: string[];
117
+ toolNames?: string[];
118
+ };
119
+ export type VoiceOperationsRecordGuardrailAssertionReport = {
120
+ blocked: number;
121
+ decisions: number;
122
+ issues: string[];
123
+ ok: boolean;
124
+ passed: number;
125
+ proofs: string[];
126
+ ruleIds: string[];
127
+ stages: string[];
128
+ statuses: string[];
129
+ toolNames: string[];
130
+ warned: number;
131
+ };
108
132
  export type VoiceOperationsRecord = {
109
133
  audit?: VoiceOperationsRecordAuditSummary;
110
134
  checkedAt: number;
@@ -148,6 +172,8 @@ export type VoiceOperationsRecordRoutesOptions = Omit<VoiceOperationsRecordOptio
148
172
  title?: string;
149
173
  };
150
174
  export declare const buildVoiceOperationsRecord: (options: VoiceOperationsRecordOptions) => Promise<VoiceOperationsRecord>;
175
+ export declare const evaluateVoiceOperationsRecordGuardrails: (record: VoiceOperationsRecord, input?: VoiceOperationsRecordGuardrailAssertionInput) => VoiceOperationsRecordGuardrailAssertionReport;
176
+ export declare const assertVoiceOperationsRecordGuardrails: (record: VoiceOperationsRecord, input?: VoiceOperationsRecordGuardrailAssertionInput) => VoiceOperationsRecordGuardrailAssertionReport;
151
177
  export declare const renderVoiceOperationsRecordIncidentMarkdown: (record: VoiceOperationsRecord) => string;
152
178
  export declare const renderVoiceOperationsRecordGuardrailMarkdown: (record: VoiceOperationsRecord) => string;
153
179
  export declare const renderVoiceOperationsRecordHTML: (record: VoiceOperationsRecord, options?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.248",
3
+ "version": "0.0.22-beta.249",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",