@absolutejs/voice 0.0.22-beta.63 → 0.0.22-beta.64

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.
@@ -29,7 +29,7 @@ export type VoiceOpsStatusWidgetOptions = VoiceAppKitStatusClientOptions & {
29
29
  includeLinks?: boolean;
30
30
  title?: string;
31
31
  };
32
- export declare const getVoiceOpsStatusLabel: (report?: VoiceAppKitStatusReport | null, error?: string | null) => "Unavailable" | "Checking" | "Passing" | "Needs attention";
32
+ export declare const getVoiceOpsStatusLabel: (report?: VoiceAppKitStatusReport | null, error?: string | null) => "Passing" | "Unavailable" | "Checking" | "Needs attention";
33
33
  export declare const createVoiceOpsStatusViewModel: (snapshot: VoiceAppKitStatusSnapshot, options?: VoiceOpsStatusWidgetOptions) => VoiceOpsStatusViewModel;
34
34
  export declare const renderVoiceOpsStatusHTML: (snapshot: VoiceAppKitStatusSnapshot, options?: VoiceOpsStatusWidgetOptions) => string;
35
35
  export declare const getVoiceOpsStatusCSS: () => string;
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export { createVoiceWorkflowContract, createVoiceWorkflowContractHandler, create
8
8
  export { createVoiceSessionListRoutes, createVoiceSessionReplayHTMLHandler, createVoiceSessionReplayJSONHandler, createVoiceSessionReplayRoutes, createVoiceSessionsHTMLHandler, createVoiceSessionsJSONHandler, renderVoiceSessionsHTML, summarizeVoiceSessions, summarizeVoiceSessionReplay } from './sessionReplay';
9
9
  export { createVoiceAgent, createVoiceAgentSquad, createVoiceAgentTool } from './agent';
10
10
  export { createVoiceToolIdempotencyKey, createVoiceToolRuntime } from './toolRuntime';
11
- export { createVoiceToolContract, createVoiceToolRuntimeContractDefaults, runVoiceToolContract } from './toolContract';
11
+ export { createVoiceToolContract, createVoiceToolContractHTMLHandler, createVoiceToolContractJSONHandler, createVoiceToolContractRoutes, createVoiceToolRuntimeContractDefaults, renderVoiceToolContractHTML, runVoiceToolContractSuite, runVoiceToolContract } from './toolContract';
12
12
  export { createStoredVoiceCallReviewArtifact, createStoredVoiceExternalObjectMap, createStoredVoiceIntegrationEvent, createStoredVoiceOpsTask, createVoiceFileExternalObjectMapStore, createVoiceFileAssistantMemoryStore, createVoiceFileIntegrationEventStore, createVoiceFileReviewStore, createVoiceFileRuntimeStorage, createVoiceFileSessionStore, createVoiceFileTaskStore, createVoiceFileTraceSinkDeliveryStore, createVoiceFileTraceEventStore } from './fileStore';
13
13
  export { createVoiceAssistantMemoryHandle, createVoiceAssistantMemoryRecord, createVoiceMemoryAssistantMemoryStore, resolveVoiceAssistantMemoryNamespace } from './assistantMemory';
14
14
  export { createAnthropicVoiceAssistantModel, createGeminiVoiceAssistantModel, createJSONVoiceAssistantModel, createOpenAIVoiceAssistantModel, resolveVoiceProviderRoutingPolicyPreset, createVoiceProviderRouter } from './modelAdapters';
@@ -56,7 +56,7 @@ export type { VoiceResilienceIOSimulator, VoiceResilienceLink, VoiceResiliencePa
56
56
  export type { VoiceIOProviderRouterEvent, VoiceIOProviderRouterOptions, VoiceIOProviderRouterPolicy, VoiceIOProviderRouterPolicyConfig, VoiceSTTProviderRouterOptions, VoiceTTSProviderRouterOptions } from './providerAdapters';
57
57
  export type { VoiceAgent, VoiceAgentMessage, VoiceAgentMessageRole, VoiceAgentModel, VoiceAgentModelInput, VoiceAgentModelOutput, VoiceAgentOptions, VoiceAgentRunResult, VoiceAgentSquadOptions, VoiceAgentTool, VoiceAgentToolCall, VoiceAgentToolResult } from './agent';
58
58
  export type { VoiceToolRetryDelay, VoiceToolRuntime, VoiceToolRuntimeExecuteInput, VoiceToolRuntimeOptions, VoiceToolRuntimeResult } from './toolRuntime';
59
- export type { VoiceToolContractCase, VoiceToolContractCaseReport, VoiceToolContractDefinition, VoiceToolContractExpectation, VoiceToolContractIssue, VoiceToolContractReport } from './toolContract';
59
+ export type { VoiceToolContractCase, VoiceToolContractCaseReport, VoiceToolContractDefinition, VoiceToolContractExpectation, VoiceToolContractHandlerOptions, VoiceToolContractHTMLHandlerOptions, VoiceToolContractIssue, VoiceToolContractReport, VoiceToolContractRoutesOptions, VoiceToolContractSuiteReport } from './toolContract';
60
60
  export type { VoiceOpsRuntime, VoiceOpsRuntimeConfig, VoiceOpsRuntimeSummary, VoiceOpsRuntimeSinkWorkerConfig, VoiceOpsRuntimeTaskWorkerConfig, VoiceOpsRuntimeTickResult, VoiceOpsRuntimeWebhookWorkerConfig } from './opsRuntime';
61
61
  export type { VoiceOpsPresetName, VoiceOpsPresetOverrides, VoiceResolvedOpsPreset } from './opsPresets';
62
62
  export type { VoiceOutcomeRecipe, VoiceOutcomeRecipeName, VoiceOutcomeRecipeOptions } from './outcomeRecipes';
package/dist/index.js CHANGED
@@ -9947,6 +9947,7 @@ var createVoiceToolIdempotencyKey = (input) => {
9947
9947
  ].join(":");
9948
9948
  };
9949
9949
  // src/toolContract.ts
9950
+ import { Elysia as Elysia12 } from "elysia";
9950
9951
  var createDefaultSession = (contractId, caseId) => createVoiceSessionRecord(`tool-contract-${contractId}-${caseId}`);
9951
9952
  var createDefaultTurn = (caseId) => ({
9952
9953
  committedAt: Date.now(),
@@ -9956,6 +9957,7 @@ var createDefaultTurn = (caseId) => ({
9956
9957
  });
9957
9958
  var defaultApi = {};
9958
9959
  var sameJSON = (left, right) => JSON.stringify(left) === JSON.stringify(right);
9960
+ var escapeHtml13 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9959
9961
  var evaluateExpectation = (input) => {
9960
9962
  const issues = [];
9961
9963
  const expect = input.expect;
@@ -10075,6 +10077,7 @@ var runVoiceToolContract = async (definition) => {
10075
10077
  return {
10076
10078
  cases,
10077
10079
  contractId: definition.id,
10080
+ label: definition.label,
10078
10081
  issues,
10079
10082
  pass: issues.length === 0,
10080
10083
  toolName: definition.tool.name
@@ -10103,6 +10106,70 @@ var createVoiceToolRuntimeContractDefaults = () => ({
10103
10106
  maxRetries: 1,
10104
10107
  timeoutMs: 5000
10105
10108
  });
10109
+ var runVoiceToolContractSuite = async (options) => {
10110
+ const contracts = await Promise.all(options.contracts.map((contract) => runVoiceToolContract(contract)));
10111
+ const passed = contracts.filter((contract) => contract.pass).length;
10112
+ const failed = contracts.length - passed;
10113
+ return {
10114
+ checkedAt: Date.now(),
10115
+ contracts,
10116
+ failed,
10117
+ passed,
10118
+ status: failed > 0 ? "fail" : "pass",
10119
+ total: contracts.length
10120
+ };
10121
+ };
10122
+ var renderVoiceToolContractHTML = (report, options = {}) => {
10123
+ const title = options.title ?? "Voice Tool Contracts";
10124
+ const contracts = report.contracts.map((contract) => {
10125
+ const cases = contract.cases.map((testCase) => `<tr>
10126
+ <td>${escapeHtml13(testCase.label ?? testCase.caseId)}</td>
10127
+ <td class="${testCase.pass ? "pass" : "fail"}">${testCase.pass ? "pass" : "fail"}</td>
10128
+ <td>${escapeHtml13(testCase.status)}</td>
10129
+ <td>${String(testCase.attempts)}</td>
10130
+ <td>${String(testCase.elapsedMs)}ms</td>
10131
+ <td>${testCase.timedOut ? "yes" : "no"}</td>
10132
+ <td>${escapeHtml13(testCase.issues.map((issue) => issue.message).join(" ") || testCase.error || "")}</td>
10133
+ </tr>`).join("");
10134
+ return `<section class="contract ${contract.pass ? "pass" : "fail"}">
10135
+ <div class="contract-header">
10136
+ <div>
10137
+ <p class="eyebrow">${escapeHtml13(contract.toolName)}</p>
10138
+ <h2>${escapeHtml13(contract.label ?? contract.contractId)}</h2>
10139
+ </div>
10140
+ <strong class="${contract.pass ? "pass" : "fail"}">${contract.pass ? "Passing" : "Failing"}</strong>
10141
+ </div>
10142
+ <table>
10143
+ <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>
10144
+ <tbody>${cases}</tbody>
10145
+ </table>
10146
+ </section>`;
10147
+ }).join("");
10148
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml13(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(245,158,11,.12))}.eyebrow{color:#fbbf24;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}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.contract-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}h2{margin:.2rem 0 1rem}.pass{color:#86efac}.fail{color:#fca5a5}.contract.fail{border-color:rgba(248,113,113,.45)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #2a323a;padding:12px;text-align:left;vertical-align:top}th{color:#a8b0b8;font-size:.82rem}@media(max-width:800px){main{padding:18px}table{display:block;overflow:auto}.contract-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Tool Reliability</p><h1>${escapeHtml13(title)}</h1><div class="summary"><span class="pill ${report.status === "pass" ? "pass" : "fail"}">${escapeHtml13(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 tool contracts configured.</p></section>'}</main></body></html>`;
10149
+ };
10150
+ var createVoiceToolContractJSONHandler = (options) => () => runVoiceToolContractSuite(options);
10151
+ var createVoiceToolContractHTMLHandler = (options) => async () => {
10152
+ const report = await runVoiceToolContractSuite(options);
10153
+ const render = options.render ?? ((input) => renderVoiceToolContractHTML(input, options));
10154
+ const body = await render(report);
10155
+ return new Response(body, {
10156
+ headers: {
10157
+ "Content-Type": "text/html; charset=utf-8",
10158
+ ...options.headers
10159
+ }
10160
+ });
10161
+ };
10162
+ var createVoiceToolContractRoutes = (options) => {
10163
+ const path = options.path ?? "/api/tool-contracts";
10164
+ const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
10165
+ const routes = new Elysia12({
10166
+ name: options.name ?? "absolutejs-voice-tool-contracts"
10167
+ }).get(path, createVoiceToolContractJSONHandler(options));
10168
+ if (htmlPath) {
10169
+ routes.get(htmlPath, createVoiceToolContractHTMLHandler(options));
10170
+ }
10171
+ return routes;
10172
+ };
10106
10173
  // src/fileStore.ts
10107
10174
  import { mkdir as mkdir2, readFile, readdir, rename, rm, writeFile } from "fs/promises";
10108
10175
  import { join } from "path";
@@ -12196,7 +12263,7 @@ var createVoiceMemoryStore = () => {
12196
12263
  return { get, getOrCreate, list, remove, set };
12197
12264
  };
12198
12265
  // src/opsWebhook.ts
12199
- import { Elysia as Elysia12 } from "elysia";
12266
+ import { Elysia as Elysia13 } from "elysia";
12200
12267
  var toHex5 = (bytes) => Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
12201
12268
  var signVoiceOpsWebhookBody = async (input) => {
12202
12269
  const encoder = new TextEncoder;
@@ -12326,7 +12393,7 @@ var verifyVoiceOpsWebhookSignature = async (input) => {
12326
12393
  };
12327
12394
  var createVoiceOpsWebhookReceiverRoutes = (options = {}) => {
12328
12395
  const path = options.path ?? "/api/voice-ops/webhook";
12329
- return new Elysia12().post(path, async ({ body, request, set }) => {
12396
+ return new Elysia13().post(path, async ({ body, request, set }) => {
12330
12397
  const bodyText = typeof body === "string" ? body : JSON.stringify(body);
12331
12398
  if (options.signingSecret) {
12332
12399
  const verification = await verifyVoiceOpsWebhookSignature({
@@ -14491,6 +14558,7 @@ export {
14491
14558
  startVoiceOpsTask,
14492
14559
  shapeTelephonyAssistantText,
14493
14560
  selectVoiceTraceEventsForPrune,
14561
+ runVoiceToolContractSuite,
14494
14562
  runVoiceToolContract,
14495
14563
  runVoiceSessionEvals,
14496
14564
  runVoiceScenarioFixtureEvals,
@@ -14512,6 +14580,7 @@ export {
14512
14580
  reopenVoiceOpsTask,
14513
14581
  renderVoiceTraceMarkdown,
14514
14582
  renderVoiceTraceHTML,
14583
+ renderVoiceToolContractHTML,
14515
14584
  renderVoiceSessionsHTML,
14516
14585
  renderVoiceScenarioFixtureEvalHTML,
14517
14586
  renderVoiceScenarioEvalHTML,
@@ -14573,6 +14642,9 @@ export {
14573
14642
  createVoiceToolRuntimeContractDefaults,
14574
14643
  createVoiceToolRuntime,
14575
14644
  createVoiceToolIdempotencyKey,
14645
+ createVoiceToolContractRoutes,
14646
+ createVoiceToolContractJSONHandler,
14647
+ createVoiceToolContractHTMLHandler,
14576
14648
  createVoiceToolContract,
14577
14649
  createVoiceTaskUpdatedEvent,
14578
14650
  createVoiceTaskSLABreachedEvent,
@@ -1,3 +1,4 @@
1
+ import { Elysia } from 'elysia';
1
2
  import type { VoiceAgentTool } from './agent';
2
3
  import { type VoiceToolRuntimeOptions } from './toolRuntime';
3
4
  import type { VoiceSessionRecord, VoiceTurnRecord } from './types';
@@ -48,10 +49,32 @@ export type VoiceToolContractCaseReport = {
48
49
  export type VoiceToolContractReport = {
49
50
  cases: VoiceToolContractCaseReport[];
50
51
  contractId: string;
52
+ label?: string;
51
53
  issues: VoiceToolContractIssue[];
52
54
  pass: boolean;
53
55
  toolName: string;
54
56
  };
57
+ export type VoiceToolContractSuiteReport = {
58
+ checkedAt: number;
59
+ contracts: VoiceToolContractReport[];
60
+ failed: number;
61
+ passed: number;
62
+ status: 'fail' | 'pass';
63
+ total: number;
64
+ };
65
+ export type VoiceToolContractHandlerOptions = {
66
+ contracts: VoiceToolContractDefinition[];
67
+ };
68
+ export type VoiceToolContractHTMLHandlerOptions = VoiceToolContractHandlerOptions & {
69
+ headers?: HeadersInit;
70
+ render?: (report: VoiceToolContractSuiteReport) => string | Promise<string>;
71
+ title?: string;
72
+ };
73
+ export type VoiceToolContractRoutesOptions = VoiceToolContractHTMLHandlerOptions & {
74
+ htmlPath?: false | string;
75
+ name?: string;
76
+ path?: string;
77
+ };
55
78
  export declare const runVoiceToolContract: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TArgs = Record<string, unknown>, TToolResult = unknown, TRouteResult = unknown>(definition: VoiceToolContractDefinition<TContext, TSession, TArgs, TToolResult, TRouteResult>) => Promise<VoiceToolContractReport>;
56
79
  export declare const createVoiceToolContract: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TArgs = Record<string, unknown>, TToolResult = unknown, TRouteResult = unknown>(definition: VoiceToolContractDefinition<TContext, TSession, TArgs, TToolResult, TRouteResult>) => {
57
80
  assert: () => Promise<VoiceToolContractReport>;
@@ -59,3 +82,49 @@ export declare const createVoiceToolContract: <TContext = unknown, TSession exte
59
82
  run: () => Promise<VoiceToolContractReport>;
60
83
  };
61
84
  export declare const createVoiceToolRuntimeContractDefaults: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TRouteResult = unknown>() => VoiceToolRuntimeOptions<TContext, TSession, TRouteResult>;
85
+ export declare const runVoiceToolContractSuite: (options: VoiceToolContractHandlerOptions) => Promise<VoiceToolContractSuiteReport>;
86
+ export declare const renderVoiceToolContractHTML: (report: VoiceToolContractSuiteReport, options?: {
87
+ title?: string;
88
+ }) => string;
89
+ export declare const createVoiceToolContractJSONHandler: (options: VoiceToolContractHandlerOptions) => () => Promise<VoiceToolContractSuiteReport>;
90
+ export declare const createVoiceToolContractHTMLHandler: (options: VoiceToolContractHTMLHandlerOptions) => () => Promise<Response>;
91
+ export declare const createVoiceToolContractRoutes: (options: VoiceToolContractRoutesOptions) => Elysia<"", {
92
+ decorator: {};
93
+ store: {};
94
+ derive: {};
95
+ resolve: {};
96
+ }, {
97
+ typebox: {};
98
+ error: {};
99
+ }, {
100
+ schema: {};
101
+ standaloneSchema: {};
102
+ macro: {};
103
+ macroFn: {};
104
+ parser: {};
105
+ response: {};
106
+ }, {
107
+ [x: string]: {
108
+ get: {
109
+ body: unknown;
110
+ params: {};
111
+ query: unknown;
112
+ headers: unknown;
113
+ response: {
114
+ 200: VoiceToolContractSuiteReport;
115
+ };
116
+ };
117
+ };
118
+ }, {
119
+ derive: {};
120
+ resolve: {};
121
+ schema: {};
122
+ standaloneSchema: {};
123
+ response: {};
124
+ }, {
125
+ derive: {};
126
+ resolve: {};
127
+ schema: {};
128
+ standaloneSchema: {};
129
+ response: {};
130
+ }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.63",
3
+ "version": "0.0.22-beta.64",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",