@absolutejs/voice 0.0.22-beta.64 → 0.0.22-beta.65
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/dist/appKit.d.ts +3 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +142 -13
- package/dist/providerCapabilities.d.ts +92 -0
- package/package.json +1 -1
package/dist/appKit.d.ts
CHANGED
|
@@ -5,11 +5,12 @@ import { type VoiceEvalRoutesOptions, type VoiceEvalLink } from './evalRoutes';
|
|
|
5
5
|
import { type VoiceHandoffHealthRoutesOptions } from './handoffHealth';
|
|
6
6
|
import { type VoiceOpsConsoleRoutesOptions } from './opsConsoleRoutes';
|
|
7
7
|
import { type VoiceProviderHealthRoutesOptions } from './providerHealth';
|
|
8
|
+
import { type VoiceProviderCapabilityRoutesOptions } from './providerCapabilities';
|
|
8
9
|
import { type VoiceQualityRoutesOptions } from './qualityRoutes';
|
|
9
10
|
import { type VoiceResilienceRoutesOptions } from './resilienceRoutes';
|
|
10
11
|
import { type VoiceSessionListRoutesOptions, type VoiceSessionReplayRoutesOptions } from './sessionReplay';
|
|
11
12
|
import { type VoiceTraceEventStore } from './trace';
|
|
12
|
-
export type VoiceAppKitSurface = 'assistantHealth' | 'diagnostics' | 'evals' | 'handoffs' | 'opsConsole' | 'providerHealth' | 'quality' | 'resilience' | 'sessionReplay' | 'sessions';
|
|
13
|
+
export type VoiceAppKitSurface = 'assistantHealth' | 'diagnostics' | 'evals' | 'handoffs' | 'opsConsole' | 'providerCapabilities' | 'providerHealth' | 'quality' | 'resilience' | 'sessionReplay' | 'sessions';
|
|
13
14
|
export type VoiceAppKitLink = VoiceEvalLink & {
|
|
14
15
|
description?: string;
|
|
15
16
|
statusHref?: string;
|
|
@@ -25,6 +26,7 @@ export type VoiceAppKitRoutesOptions<TProvider extends string = string> = {
|
|
|
25
26
|
llmProviders?: readonly TProvider[];
|
|
26
27
|
name?: string;
|
|
27
28
|
opsConsole?: false | Partial<VoiceOpsConsoleRoutesOptions>;
|
|
29
|
+
providerCapabilities?: false | Partial<VoiceProviderCapabilityRoutesOptions<TProvider>>;
|
|
28
30
|
providerHealth?: false | Partial<VoiceProviderHealthRoutesOptions<TProvider>>;
|
|
29
31
|
quality?: false | Partial<VoiceQualityRoutesOptions>;
|
|
30
32
|
resilience?: false | Partial<VoiceResilienceRoutesOptions>;
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export { createStoredVoiceCallReviewArtifact, createStoredVoiceExternalObjectMap
|
|
|
13
13
|
export { createVoiceAssistantMemoryHandle, createVoiceAssistantMemoryRecord, createVoiceMemoryAssistantMemoryStore, resolveVoiceAssistantMemoryNamespace } from './assistantMemory';
|
|
14
14
|
export { createAnthropicVoiceAssistantModel, createGeminiVoiceAssistantModel, createJSONVoiceAssistantModel, createOpenAIVoiceAssistantModel, resolveVoiceProviderRoutingPolicyPreset, createVoiceProviderRouter } from './modelAdapters';
|
|
15
15
|
export { createVoiceProviderHealthHTMLHandler, createVoiceProviderHealthJSONHandler, createVoiceProviderHealthRoutes, renderVoiceProviderHealthHTML, summarizeVoiceProviderHealth } from './providerHealth';
|
|
16
|
+
export { createVoiceProviderCapabilityHTMLHandler, createVoiceProviderCapabilityJSONHandler, createVoiceProviderCapabilityRoutes, renderVoiceProviderCapabilityHTML, summarizeVoiceProviderCapabilities } from './providerCapabilities';
|
|
16
17
|
export { buildVoiceOpsConsoleReport, createVoiceOpsConsoleRoutes, renderVoiceOpsConsoleHTML } from './opsConsoleRoutes';
|
|
17
18
|
export { createVoiceQualityRoutes, evaluateVoiceQuality, renderVoiceQualityHTML } from './qualityRoutes';
|
|
18
19
|
export { createVoiceResilienceRoutes, createVoiceRoutingDecisionSummary, listVoiceRoutingEvents, renderVoiceResilienceHTML, summarizeVoiceRoutingDecision } from './resilienceRoutes';
|
|
@@ -50,6 +51,7 @@ export type { VoiceWorkflowContract, VoiceWorkflowContractDefinition, VoiceWorkf
|
|
|
50
51
|
export type { VoiceSessionListHTMLHandlerOptions, VoiceSessionListItem, VoiceSessionListOptions, VoiceSessionListRoutesOptions, VoiceSessionListStatus, VoiceSessionReplay, VoiceSessionReplayHTMLHandlerOptions, VoiceSessionReplayOptions, VoiceSessionReplayRoutesOptions, VoiceSessionReplayTurn } from './sessionReplay';
|
|
51
52
|
export type { AnthropicVoiceAssistantModelOptions, GeminiVoiceAssistantModelOptions, OpenAIVoiceAssistantModelOptions, VoiceProviderRouterEvent, VoiceProviderRouterFallbackMode, VoiceProviderRouterHealthOptions, VoiceProviderRouterOptions, VoiceProviderRouterPolicy, VoiceProviderRouterPolicyPreset, VoiceProviderRouterPolicyWeights, VoiceProviderRouterProviderHealth, VoiceProviderRouterProviderProfile, VoiceProviderRouterStrategy, VoiceJSONAssistantModelHandler, VoiceJSONAssistantModelOptions } from './modelAdapters';
|
|
52
53
|
export type { VoiceProviderHealthStatus, VoiceProviderHealthSummary, VoiceProviderHealthSummaryOptions } from './providerHealth';
|
|
54
|
+
export type { VoiceProviderCapabilityDefinition, VoiceProviderCapabilityHandlerOptions, VoiceProviderCapabilityHTMLHandlerOptions, VoiceProviderCapabilityKind, VoiceProviderCapabilityOptions, VoiceProviderCapabilityReport, VoiceProviderCapabilityRoutesOptions, VoiceProviderCapabilitySummary } from './providerCapabilities';
|
|
53
55
|
export type { VoiceOpsConsoleLink, VoiceOpsConsoleReport, VoiceOpsConsoleRoutesOptions } from './opsConsoleRoutes';
|
|
54
56
|
export type { VoiceQualityLink, VoiceQualityMetric, VoiceQualityReport, VoiceQualityRoutesOptions, VoiceQualityStatus, VoiceQualityThresholds } from './qualityRoutes';
|
|
55
57
|
export type { VoiceResilienceIOSimulator, VoiceResilienceLink, VoiceResiliencePageData, VoiceResilienceRoutesOptions, VoiceResilienceSimulationProvider, VoiceRoutingDecisionSummary, VoiceRoutingDecisionSummaryOptions, VoiceRoutingEvent, VoiceRoutingEventKind } from './resilienceRoutes';
|
package/dist/index.js
CHANGED
|
@@ -5474,7 +5474,7 @@ var voice = (config) => {
|
|
|
5474
5474
|
}).use(htmxRoutes());
|
|
5475
5475
|
};
|
|
5476
5476
|
// src/appKit.ts
|
|
5477
|
-
import { Elysia as
|
|
5477
|
+
import { Elysia as Elysia12 } from "elysia";
|
|
5478
5478
|
|
|
5479
5479
|
// src/assistantHealth.ts
|
|
5480
5480
|
import { Elysia as Elysia3 } from "elysia";
|
|
@@ -9186,6 +9186,117 @@ var createVoiceOpsConsoleRoutes = (options) => {
|
|
|
9186
9186
|
return routes;
|
|
9187
9187
|
};
|
|
9188
9188
|
|
|
9189
|
+
// src/providerCapabilities.ts
|
|
9190
|
+
import { Elysia as Elysia11 } from "elysia";
|
|
9191
|
+
var escapeHtml13 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9192
|
+
var fromProviderList = (kind, providers, options) => (providers ?? []).map((provider) => ({
|
|
9193
|
+
configured: true,
|
|
9194
|
+
features: options.features?.[provider],
|
|
9195
|
+
kind,
|
|
9196
|
+
model: options.models?.[provider],
|
|
9197
|
+
provider,
|
|
9198
|
+
selected: options.selected?.[kind] === provider
|
|
9199
|
+
}));
|
|
9200
|
+
var resolveCapabilityDefinitions = (options) => {
|
|
9201
|
+
const definitions = [
|
|
9202
|
+
...fromProviderList("llm", options.llmProviders, options),
|
|
9203
|
+
...fromProviderList("stt", options.sttProviders, options),
|
|
9204
|
+
...fromProviderList("tts", options.ttsProviders, options),
|
|
9205
|
+
...options.providers ?? []
|
|
9206
|
+
];
|
|
9207
|
+
const seen = new Set;
|
|
9208
|
+
return definitions.filter((definition) => {
|
|
9209
|
+
const key = `${definition.kind}:${definition.provider}`;
|
|
9210
|
+
if (seen.has(key)) {
|
|
9211
|
+
return false;
|
|
9212
|
+
}
|
|
9213
|
+
seen.add(key);
|
|
9214
|
+
return true;
|
|
9215
|
+
});
|
|
9216
|
+
};
|
|
9217
|
+
var summarizeVoiceProviderCapabilities = async (options) => {
|
|
9218
|
+
const definitions = resolveCapabilityDefinitions(options);
|
|
9219
|
+
const providerNames = [...new Set(definitions.map((entry) => entry.provider))];
|
|
9220
|
+
const health = await summarizeVoiceProviderHealth({
|
|
9221
|
+
events: options.events,
|
|
9222
|
+
now: options.now,
|
|
9223
|
+
providers: providerNames,
|
|
9224
|
+
store: options.store
|
|
9225
|
+
});
|
|
9226
|
+
const healthByProvider = new Map(health.map((entry) => [entry.provider, entry]));
|
|
9227
|
+
const capabilities = definitions.map((definition) => {
|
|
9228
|
+
const configured = definition.configured !== false;
|
|
9229
|
+
const providerHealth = healthByProvider.get(definition.provider);
|
|
9230
|
+
const selected = definition.selected === true || options.selected?.[definition.kind] === definition.provider;
|
|
9231
|
+
const status = !configured ? "unconfigured" : selected ? "selected" : providerHealth?.status ?? "idle";
|
|
9232
|
+
return {
|
|
9233
|
+
...definition,
|
|
9234
|
+
configured,
|
|
9235
|
+
features: definition.features ?? options.features?.[definition.provider],
|
|
9236
|
+
health: providerHealth,
|
|
9237
|
+
model: definition.model ?? options.models?.[definition.provider],
|
|
9238
|
+
selected,
|
|
9239
|
+
status
|
|
9240
|
+
};
|
|
9241
|
+
});
|
|
9242
|
+
return {
|
|
9243
|
+
capabilities,
|
|
9244
|
+
checkedAt: Date.now(),
|
|
9245
|
+
configured: capabilities.filter((entry) => entry.configured).length,
|
|
9246
|
+
selected: capabilities.filter((entry) => entry.selected).length,
|
|
9247
|
+
total: capabilities.length,
|
|
9248
|
+
unconfigured: capabilities.filter((entry) => !entry.configured).length
|
|
9249
|
+
};
|
|
9250
|
+
};
|
|
9251
|
+
var renderVoiceProviderCapabilityHTML = (report, options = {}) => {
|
|
9252
|
+
const title = options.title ?? "Voice Provider Capabilities";
|
|
9253
|
+
const cards = report.capabilities.map((capability) => {
|
|
9254
|
+
const features = (capability.features ?? []).map((feature) => `<span class="pill">${escapeHtml13(feature)}</span>`).join("");
|
|
9255
|
+
return `<article class="card ${escapeHtml13(capability.status)}">
|
|
9256
|
+
<div class="card-header">
|
|
9257
|
+
<div>
|
|
9258
|
+
<p class="eyebrow">${escapeHtml13(capability.kind)}</p>
|
|
9259
|
+
<h2>${escapeHtml13(capability.label ?? capability.provider)}</h2>
|
|
9260
|
+
</div>
|
|
9261
|
+
<strong>${escapeHtml13(capability.status)}</strong>
|
|
9262
|
+
</div>
|
|
9263
|
+
${capability.description ? `<p>${escapeHtml13(capability.description)}</p>` : ""}
|
|
9264
|
+
<dl>
|
|
9265
|
+
<div><dt>Configured</dt><dd>${capability.configured ? "yes" : "no"}</dd></div>
|
|
9266
|
+
<div><dt>Selected</dt><dd>${capability.selected ? "yes" : "no"}</dd></div>
|
|
9267
|
+
<div><dt>Model</dt><dd>${escapeHtml13(capability.model ?? "default")}</dd></div>
|
|
9268
|
+
<div><dt>Runs</dt><dd>${String(capability.health?.runCount ?? 0)}</dd></div>
|
|
9269
|
+
<div><dt>Errors</dt><dd>${String(capability.health?.errorCount ?? 0)}</dd></div>
|
|
9270
|
+
</dl>
|
|
9271
|
+
${features ? `<div class="features">${features}</div>` : ""}
|
|
9272
|
+
</article>`;
|
|
9273
|
+
}).join("");
|
|
9274
|
+
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,.card{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(14,165,233,.16),rgba(34,197,94,.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 1rem}.summary,.features{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.card-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.selected,.healthy{color:#86efac}.unconfigured,.degraded,.rate-limited,.suppressed{color:#fca5a5}.idle,.recoverable{color:#fde68a}dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{margin:0}@media(max-width:800px){main{padding:18px}.card-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Provider Discovery</p><h1>${escapeHtml13(title)}</h1><div class="summary"><span class="pill">${String(report.configured)} configured</span><span class="pill">${String(report.selected)} selected</span><span class="pill">${String(report.unconfigured)} missing</span><span class="pill">${String(report.total)} total</span></div></section><section class="grid">${cards || '<article class="card"><p>No provider capabilities configured.</p></article>'}</section></main></body></html>`;
|
|
9275
|
+
};
|
|
9276
|
+
var createVoiceProviderCapabilityJSONHandler = (options) => async () => summarizeVoiceProviderCapabilities(options);
|
|
9277
|
+
var createVoiceProviderCapabilityHTMLHandler = (options) => async () => {
|
|
9278
|
+
const report = await summarizeVoiceProviderCapabilities(options);
|
|
9279
|
+
const render = options.render ?? ((input) => renderVoiceProviderCapabilityHTML(input, options));
|
|
9280
|
+
const body = await render(report);
|
|
9281
|
+
return new Response(body, {
|
|
9282
|
+
headers: {
|
|
9283
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
9284
|
+
...options.headers
|
|
9285
|
+
}
|
|
9286
|
+
});
|
|
9287
|
+
};
|
|
9288
|
+
var createVoiceProviderCapabilityRoutes = (options) => {
|
|
9289
|
+
const path = options.path ?? "/api/provider-capabilities";
|
|
9290
|
+
const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
|
|
9291
|
+
const routes = new Elysia11({
|
|
9292
|
+
name: options.name ?? "absolutejs-voice-provider-capabilities"
|
|
9293
|
+
}).get(path, createVoiceProviderCapabilityJSONHandler(options));
|
|
9294
|
+
if (htmlPath) {
|
|
9295
|
+
routes.get(htmlPath, createVoiceProviderCapabilityHTMLHandler(options));
|
|
9296
|
+
}
|
|
9297
|
+
return routes;
|
|
9298
|
+
};
|
|
9299
|
+
|
|
9189
9300
|
// src/appKit.ts
|
|
9190
9301
|
var DEFAULT_LINKS2 = [
|
|
9191
9302
|
{
|
|
@@ -9342,7 +9453,7 @@ var summarizeVoiceAppKitStatus = async (options) => {
|
|
|
9342
9453
|
};
|
|
9343
9454
|
};
|
|
9344
9455
|
var createVoiceAppKitRoutes = (options) => {
|
|
9345
|
-
const routes = new
|
|
9456
|
+
const routes = new Elysia12({
|
|
9346
9457
|
name: options.name ?? "absolutejs-voice-app-kit"
|
|
9347
9458
|
});
|
|
9348
9459
|
const links = resolveLinks(options.links);
|
|
@@ -9362,6 +9473,19 @@ var createVoiceAppKitRoutes = (options) => {
|
|
|
9362
9473
|
...options.providerHealth
|
|
9363
9474
|
}));
|
|
9364
9475
|
}
|
|
9476
|
+
if (options.providerCapabilities !== false) {
|
|
9477
|
+
surfaces.push("providerCapabilities");
|
|
9478
|
+
routes.use(createVoiceProviderCapabilityRoutes({
|
|
9479
|
+
...common,
|
|
9480
|
+
htmlPath: "/provider-capabilities",
|
|
9481
|
+
llmProviders: options.llmProviders,
|
|
9482
|
+
path: "/api/provider-capabilities",
|
|
9483
|
+
sttProviders: options.sttProviders,
|
|
9484
|
+
title: options.title ? `${options.title} Provider Capabilities` : undefined,
|
|
9485
|
+
ttsProviders: options.ttsProviders,
|
|
9486
|
+
...options.providerCapabilities
|
|
9487
|
+
}));
|
|
9488
|
+
}
|
|
9365
9489
|
if (options.assistantHealth !== false) {
|
|
9366
9490
|
surfaces.push("assistantHealth");
|
|
9367
9491
|
routes.use(createVoiceAssistantHealthRoutes({
|
|
@@ -9947,7 +10071,7 @@ var createVoiceToolIdempotencyKey = (input) => {
|
|
|
9947
10071
|
].join(":");
|
|
9948
10072
|
};
|
|
9949
10073
|
// src/toolContract.ts
|
|
9950
|
-
import { Elysia as
|
|
10074
|
+
import { Elysia as Elysia13 } from "elysia";
|
|
9951
10075
|
var createDefaultSession = (contractId, caseId) => createVoiceSessionRecord(`tool-contract-${contractId}-${caseId}`);
|
|
9952
10076
|
var createDefaultTurn = (caseId) => ({
|
|
9953
10077
|
committedAt: Date.now(),
|
|
@@ -9957,7 +10081,7 @@ var createDefaultTurn = (caseId) => ({
|
|
|
9957
10081
|
});
|
|
9958
10082
|
var defaultApi = {};
|
|
9959
10083
|
var sameJSON = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
9960
|
-
var
|
|
10084
|
+
var escapeHtml14 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9961
10085
|
var evaluateExpectation = (input) => {
|
|
9962
10086
|
const issues = [];
|
|
9963
10087
|
const expect = input.expect;
|
|
@@ -10123,19 +10247,19 @@ var renderVoiceToolContractHTML = (report, options = {}) => {
|
|
|
10123
10247
|
const title = options.title ?? "Voice Tool Contracts";
|
|
10124
10248
|
const contracts = report.contracts.map((contract) => {
|
|
10125
10249
|
const cases = contract.cases.map((testCase) => `<tr>
|
|
10126
|
-
<td>${
|
|
10250
|
+
<td>${escapeHtml14(testCase.label ?? testCase.caseId)}</td>
|
|
10127
10251
|
<td class="${testCase.pass ? "pass" : "fail"}">${testCase.pass ? "pass" : "fail"}</td>
|
|
10128
|
-
<td>${
|
|
10252
|
+
<td>${escapeHtml14(testCase.status)}</td>
|
|
10129
10253
|
<td>${String(testCase.attempts)}</td>
|
|
10130
10254
|
<td>${String(testCase.elapsedMs)}ms</td>
|
|
10131
10255
|
<td>${testCase.timedOut ? "yes" : "no"}</td>
|
|
10132
|
-
<td>${
|
|
10256
|
+
<td>${escapeHtml14(testCase.issues.map((issue) => issue.message).join(" ") || testCase.error || "")}</td>
|
|
10133
10257
|
</tr>`).join("");
|
|
10134
10258
|
return `<section class="contract ${contract.pass ? "pass" : "fail"}">
|
|
10135
10259
|
<div class="contract-header">
|
|
10136
10260
|
<div>
|
|
10137
|
-
<p class="eyebrow">${
|
|
10138
|
-
<h2>${
|
|
10261
|
+
<p class="eyebrow">${escapeHtml14(contract.toolName)}</p>
|
|
10262
|
+
<h2>${escapeHtml14(contract.label ?? contract.contractId)}</h2>
|
|
10139
10263
|
</div>
|
|
10140
10264
|
<strong class="${contract.pass ? "pass" : "fail"}">${contract.pass ? "Passing" : "Failing"}</strong>
|
|
10141
10265
|
</div>
|
|
@@ -10145,7 +10269,7 @@ var renderVoiceToolContractHTML = (report, options = {}) => {
|
|
|
10145
10269
|
</table>
|
|
10146
10270
|
</section>`;
|
|
10147
10271
|
}).join("");
|
|
10148
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
10272
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml14(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>${escapeHtml14(title)}</h1><div class="summary"><span class="pill ${report.status === "pass" ? "pass" : "fail"}">${escapeHtml14(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
10273
|
};
|
|
10150
10274
|
var createVoiceToolContractJSONHandler = (options) => () => runVoiceToolContractSuite(options);
|
|
10151
10275
|
var createVoiceToolContractHTMLHandler = (options) => async () => {
|
|
@@ -10162,7 +10286,7 @@ var createVoiceToolContractHTMLHandler = (options) => async () => {
|
|
|
10162
10286
|
var createVoiceToolContractRoutes = (options) => {
|
|
10163
10287
|
const path = options.path ?? "/api/tool-contracts";
|
|
10164
10288
|
const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
|
|
10165
|
-
const routes = new
|
|
10289
|
+
const routes = new Elysia13({
|
|
10166
10290
|
name: options.name ?? "absolutejs-voice-tool-contracts"
|
|
10167
10291
|
}).get(path, createVoiceToolContractJSONHandler(options));
|
|
10168
10292
|
if (htmlPath) {
|
|
@@ -12263,7 +12387,7 @@ var createVoiceMemoryStore = () => {
|
|
|
12263
12387
|
return { get, getOrCreate, list, remove, set };
|
|
12264
12388
|
};
|
|
12265
12389
|
// src/opsWebhook.ts
|
|
12266
|
-
import { Elysia as
|
|
12390
|
+
import { Elysia as Elysia14 } from "elysia";
|
|
12267
12391
|
var toHex5 = (bytes) => Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
12268
12392
|
var signVoiceOpsWebhookBody = async (input) => {
|
|
12269
12393
|
const encoder = new TextEncoder;
|
|
@@ -12393,7 +12517,7 @@ var verifyVoiceOpsWebhookSignature = async (input) => {
|
|
|
12393
12517
|
};
|
|
12394
12518
|
var createVoiceOpsWebhookReceiverRoutes = (options = {}) => {
|
|
12395
12519
|
const path = options.path ?? "/api/voice-ops/webhook";
|
|
12396
|
-
return new
|
|
12520
|
+
return new Elysia14().post(path, async ({ body, request, set }) => {
|
|
12397
12521
|
const bodyText = typeof body === "string" ? body : JSON.stringify(body);
|
|
12398
12522
|
if (options.signingSecret) {
|
|
12399
12523
|
const verification = await verifyVoiceOpsWebhookSignature({
|
|
@@ -14546,6 +14670,7 @@ export {
|
|
|
14546
14670
|
summarizeVoiceSessionReplay,
|
|
14547
14671
|
summarizeVoiceRoutingDecision,
|
|
14548
14672
|
summarizeVoiceProviderHealth,
|
|
14673
|
+
summarizeVoiceProviderCapabilities,
|
|
14549
14674
|
summarizeVoiceOpsTasks,
|
|
14550
14675
|
summarizeVoiceOpsTaskQueue,
|
|
14551
14676
|
summarizeVoiceOpsTaskAnalytics,
|
|
@@ -14587,6 +14712,7 @@ export {
|
|
|
14587
14712
|
renderVoiceResilienceHTML,
|
|
14588
14713
|
renderVoiceQualityHTML,
|
|
14589
14714
|
renderVoiceProviderHealthHTML,
|
|
14715
|
+
renderVoiceProviderCapabilityHTML,
|
|
14590
14716
|
renderVoiceOpsConsoleHTML,
|
|
14591
14717
|
renderVoiceHandoffHealthHTML,
|
|
14592
14718
|
renderVoiceEvalHTML,
|
|
@@ -14679,6 +14805,9 @@ export {
|
|
|
14679
14805
|
createVoiceProviderHealthRoutes,
|
|
14680
14806
|
createVoiceProviderHealthJSONHandler,
|
|
14681
14807
|
createVoiceProviderHealthHTMLHandler,
|
|
14808
|
+
createVoiceProviderCapabilityRoutes,
|
|
14809
|
+
createVoiceProviderCapabilityJSONHandler,
|
|
14810
|
+
createVoiceProviderCapabilityHTMLHandler,
|
|
14682
14811
|
createVoicePostgresTraceSinkDeliveryStore,
|
|
14683
14812
|
createVoicePostgresTraceEventStore,
|
|
14684
14813
|
createVoicePostgresTaskStore,
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Elysia } from 'elysia';
|
|
2
|
+
import { type VoiceProviderHealthStatus, type VoiceProviderHealthSummary, type VoiceProviderHealthSummaryOptions } from './providerHealth';
|
|
3
|
+
export type VoiceProviderCapabilityKind = 'llm' | 'stt' | 'tts' | 'custom';
|
|
4
|
+
export type VoiceProviderCapabilityDefinition<TProvider extends string = string> = {
|
|
5
|
+
configured?: boolean;
|
|
6
|
+
description?: string;
|
|
7
|
+
features?: string[];
|
|
8
|
+
kind: VoiceProviderCapabilityKind;
|
|
9
|
+
label?: string;
|
|
10
|
+
model?: string;
|
|
11
|
+
provider: TProvider;
|
|
12
|
+
selected?: boolean;
|
|
13
|
+
};
|
|
14
|
+
export type VoiceProviderCapabilitySummary<TProvider extends string = string> = VoiceProviderCapabilityDefinition<TProvider> & {
|
|
15
|
+
configured: boolean;
|
|
16
|
+
health?: VoiceProviderHealthSummary<TProvider>;
|
|
17
|
+
status: VoiceProviderHealthStatus | 'selected' | 'unconfigured';
|
|
18
|
+
};
|
|
19
|
+
export type VoiceProviderCapabilityReport<TProvider extends string = string> = {
|
|
20
|
+
capabilities: VoiceProviderCapabilitySummary<TProvider>[];
|
|
21
|
+
checkedAt: number;
|
|
22
|
+
configured: number;
|
|
23
|
+
selected: number;
|
|
24
|
+
total: number;
|
|
25
|
+
unconfigured: number;
|
|
26
|
+
};
|
|
27
|
+
export type VoiceProviderCapabilityOptions<TProvider extends string = string> = VoiceProviderHealthSummaryOptions<TProvider> & {
|
|
28
|
+
features?: Partial<Record<TProvider, string[]>>;
|
|
29
|
+
llmProviders?: readonly TProvider[];
|
|
30
|
+
models?: Partial<Record<TProvider, string>>;
|
|
31
|
+
providers?: readonly VoiceProviderCapabilityDefinition<TProvider>[];
|
|
32
|
+
selected?: Partial<Record<VoiceProviderCapabilityKind, TProvider>>;
|
|
33
|
+
sttProviders?: readonly TProvider[];
|
|
34
|
+
ttsProviders?: readonly TProvider[];
|
|
35
|
+
};
|
|
36
|
+
export type VoiceProviderCapabilityHandlerOptions<TProvider extends string = string> = VoiceProviderCapabilityOptions<TProvider>;
|
|
37
|
+
export type VoiceProviderCapabilityHTMLHandlerOptions<TProvider extends string = string> = VoiceProviderCapabilityHandlerOptions<TProvider> & {
|
|
38
|
+
headers?: HeadersInit;
|
|
39
|
+
render?: (report: VoiceProviderCapabilityReport<TProvider>) => string | Promise<string>;
|
|
40
|
+
title?: string;
|
|
41
|
+
};
|
|
42
|
+
export type VoiceProviderCapabilityRoutesOptions<TProvider extends string = string> = VoiceProviderCapabilityHTMLHandlerOptions<TProvider> & {
|
|
43
|
+
htmlPath?: false | string;
|
|
44
|
+
name?: string;
|
|
45
|
+
path?: string;
|
|
46
|
+
};
|
|
47
|
+
export declare const summarizeVoiceProviderCapabilities: <TProvider extends string = string>(options: VoiceProviderCapabilityOptions<TProvider>) => Promise<VoiceProviderCapabilityReport<TProvider>>;
|
|
48
|
+
export declare const renderVoiceProviderCapabilityHTML: <TProvider extends string = string>(report: VoiceProviderCapabilityReport<TProvider>, options?: {
|
|
49
|
+
title?: string;
|
|
50
|
+
}) => string;
|
|
51
|
+
export declare const createVoiceProviderCapabilityJSONHandler: <TProvider extends string = string>(options: VoiceProviderCapabilityHandlerOptions<TProvider>) => () => Promise<VoiceProviderCapabilityReport<TProvider>>;
|
|
52
|
+
export declare const createVoiceProviderCapabilityHTMLHandler: <TProvider extends string = string>(options: VoiceProviderCapabilityHTMLHandlerOptions<TProvider>) => () => Promise<Response>;
|
|
53
|
+
export declare const createVoiceProviderCapabilityRoutes: <TProvider extends string = string>(options: VoiceProviderCapabilityRoutesOptions<TProvider>) => Elysia<"", {
|
|
54
|
+
decorator: {};
|
|
55
|
+
store: {};
|
|
56
|
+
derive: {};
|
|
57
|
+
resolve: {};
|
|
58
|
+
}, {
|
|
59
|
+
typebox: {};
|
|
60
|
+
error: {};
|
|
61
|
+
}, {
|
|
62
|
+
schema: {};
|
|
63
|
+
standaloneSchema: {};
|
|
64
|
+
macro: {};
|
|
65
|
+
macroFn: {};
|
|
66
|
+
parser: {};
|
|
67
|
+
response: {};
|
|
68
|
+
}, {
|
|
69
|
+
[x: string]: {
|
|
70
|
+
get: {
|
|
71
|
+
body: unknown;
|
|
72
|
+
params: {};
|
|
73
|
+
query: unknown;
|
|
74
|
+
headers: unknown;
|
|
75
|
+
response: {
|
|
76
|
+
200: VoiceProviderCapabilityReport<TProvider>;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
}, {
|
|
81
|
+
derive: {};
|
|
82
|
+
resolve: {};
|
|
83
|
+
schema: {};
|
|
84
|
+
standaloneSchema: {};
|
|
85
|
+
response: {};
|
|
86
|
+
}, {
|
|
87
|
+
derive: {};
|
|
88
|
+
resolve: {};
|
|
89
|
+
schema: {};
|
|
90
|
+
standaloneSchema: {};
|
|
91
|
+
response: {};
|
|
92
|
+
}>;
|