@absolutejs/voice 0.0.22-beta.63 → 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/client/opsStatusWidget.d.ts +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +205 -4
- package/dist/providerCapabilities.d.ts +92 -0
- package/dist/toolContract.d.ts +69 -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>;
|
|
@@ -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) => "
|
|
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,11 +8,12 @@ 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';
|
|
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,13 +51,14 @@ 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';
|
|
56
58
|
export type { VoiceIOProviderRouterEvent, VoiceIOProviderRouterOptions, VoiceIOProviderRouterPolicy, VoiceIOProviderRouterPolicyConfig, VoiceSTTProviderRouterOptions, VoiceTTSProviderRouterOptions } from './providerAdapters';
|
|
57
59
|
export type { VoiceAgent, VoiceAgentMessage, VoiceAgentMessageRole, VoiceAgentModel, VoiceAgentModelInput, VoiceAgentModelOutput, VoiceAgentOptions, VoiceAgentRunResult, VoiceAgentSquadOptions, VoiceAgentTool, VoiceAgentToolCall, VoiceAgentToolResult } from './agent';
|
|
58
60
|
export type { VoiceToolRetryDelay, VoiceToolRuntime, VoiceToolRuntimeExecuteInput, VoiceToolRuntimeOptions, VoiceToolRuntimeResult } from './toolRuntime';
|
|
59
|
-
export type { VoiceToolContractCase, VoiceToolContractCaseReport, VoiceToolContractDefinition, VoiceToolContractExpectation, VoiceToolContractIssue, VoiceToolContractReport } from './toolContract';
|
|
61
|
+
export type { VoiceToolContractCase, VoiceToolContractCaseReport, VoiceToolContractDefinition, VoiceToolContractExpectation, VoiceToolContractHandlerOptions, VoiceToolContractHTMLHandlerOptions, VoiceToolContractIssue, VoiceToolContractReport, VoiceToolContractRoutesOptions, VoiceToolContractSuiteReport } from './toolContract';
|
|
60
62
|
export type { VoiceOpsRuntime, VoiceOpsRuntimeConfig, VoiceOpsRuntimeSummary, VoiceOpsRuntimeSinkWorkerConfig, VoiceOpsRuntimeTaskWorkerConfig, VoiceOpsRuntimeTickResult, VoiceOpsRuntimeWebhookWorkerConfig } from './opsRuntime';
|
|
61
63
|
export type { VoiceOpsPresetName, VoiceOpsPresetOverrides, VoiceResolvedOpsPreset } from './opsPresets';
|
|
62
64
|
export type { VoiceOutcomeRecipe, VoiceOutcomeRecipeName, VoiceOutcomeRecipeOptions } from './outcomeRecipes';
|
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,6 +10071,7 @@ var createVoiceToolIdempotencyKey = (input) => {
|
|
|
9947
10071
|
].join(":");
|
|
9948
10072
|
};
|
|
9949
10073
|
// src/toolContract.ts
|
|
10074
|
+
import { Elysia as Elysia13 } from "elysia";
|
|
9950
10075
|
var createDefaultSession = (contractId, caseId) => createVoiceSessionRecord(`tool-contract-${contractId}-${caseId}`);
|
|
9951
10076
|
var createDefaultTurn = (caseId) => ({
|
|
9952
10077
|
committedAt: Date.now(),
|
|
@@ -9956,6 +10081,7 @@ var createDefaultTurn = (caseId) => ({
|
|
|
9956
10081
|
});
|
|
9957
10082
|
var defaultApi = {};
|
|
9958
10083
|
var sameJSON = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
10084
|
+
var escapeHtml14 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
9959
10085
|
var evaluateExpectation = (input) => {
|
|
9960
10086
|
const issues = [];
|
|
9961
10087
|
const expect = input.expect;
|
|
@@ -10075,6 +10201,7 @@ var runVoiceToolContract = async (definition) => {
|
|
|
10075
10201
|
return {
|
|
10076
10202
|
cases,
|
|
10077
10203
|
contractId: definition.id,
|
|
10204
|
+
label: definition.label,
|
|
10078
10205
|
issues,
|
|
10079
10206
|
pass: issues.length === 0,
|
|
10080
10207
|
toolName: definition.tool.name
|
|
@@ -10103,6 +10230,70 @@ var createVoiceToolRuntimeContractDefaults = () => ({
|
|
|
10103
10230
|
maxRetries: 1,
|
|
10104
10231
|
timeoutMs: 5000
|
|
10105
10232
|
});
|
|
10233
|
+
var runVoiceToolContractSuite = async (options) => {
|
|
10234
|
+
const contracts = await Promise.all(options.contracts.map((contract) => runVoiceToolContract(contract)));
|
|
10235
|
+
const passed = contracts.filter((contract) => contract.pass).length;
|
|
10236
|
+
const failed = contracts.length - passed;
|
|
10237
|
+
return {
|
|
10238
|
+
checkedAt: Date.now(),
|
|
10239
|
+
contracts,
|
|
10240
|
+
failed,
|
|
10241
|
+
passed,
|
|
10242
|
+
status: failed > 0 ? "fail" : "pass",
|
|
10243
|
+
total: contracts.length
|
|
10244
|
+
};
|
|
10245
|
+
};
|
|
10246
|
+
var renderVoiceToolContractHTML = (report, options = {}) => {
|
|
10247
|
+
const title = options.title ?? "Voice Tool Contracts";
|
|
10248
|
+
const contracts = report.contracts.map((contract) => {
|
|
10249
|
+
const cases = contract.cases.map((testCase) => `<tr>
|
|
10250
|
+
<td>${escapeHtml14(testCase.label ?? testCase.caseId)}</td>
|
|
10251
|
+
<td class="${testCase.pass ? "pass" : "fail"}">${testCase.pass ? "pass" : "fail"}</td>
|
|
10252
|
+
<td>${escapeHtml14(testCase.status)}</td>
|
|
10253
|
+
<td>${String(testCase.attempts)}</td>
|
|
10254
|
+
<td>${String(testCase.elapsedMs)}ms</td>
|
|
10255
|
+
<td>${testCase.timedOut ? "yes" : "no"}</td>
|
|
10256
|
+
<td>${escapeHtml14(testCase.issues.map((issue) => issue.message).join(" ") || testCase.error || "")}</td>
|
|
10257
|
+
</tr>`).join("");
|
|
10258
|
+
return `<section class="contract ${contract.pass ? "pass" : "fail"}">
|
|
10259
|
+
<div class="contract-header">
|
|
10260
|
+
<div>
|
|
10261
|
+
<p class="eyebrow">${escapeHtml14(contract.toolName)}</p>
|
|
10262
|
+
<h2>${escapeHtml14(contract.label ?? contract.contractId)}</h2>
|
|
10263
|
+
</div>
|
|
10264
|
+
<strong class="${contract.pass ? "pass" : "fail"}">${contract.pass ? "Passing" : "Failing"}</strong>
|
|
10265
|
+
</div>
|
|
10266
|
+
<table>
|
|
10267
|
+
<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>
|
|
10268
|
+
<tbody>${cases}</tbody>
|
|
10269
|
+
</table>
|
|
10270
|
+
</section>`;
|
|
10271
|
+
}).join("");
|
|
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>`;
|
|
10273
|
+
};
|
|
10274
|
+
var createVoiceToolContractJSONHandler = (options) => () => runVoiceToolContractSuite(options);
|
|
10275
|
+
var createVoiceToolContractHTMLHandler = (options) => async () => {
|
|
10276
|
+
const report = await runVoiceToolContractSuite(options);
|
|
10277
|
+
const render = options.render ?? ((input) => renderVoiceToolContractHTML(input, options));
|
|
10278
|
+
const body = await render(report);
|
|
10279
|
+
return new Response(body, {
|
|
10280
|
+
headers: {
|
|
10281
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
10282
|
+
...options.headers
|
|
10283
|
+
}
|
|
10284
|
+
});
|
|
10285
|
+
};
|
|
10286
|
+
var createVoiceToolContractRoutes = (options) => {
|
|
10287
|
+
const path = options.path ?? "/api/tool-contracts";
|
|
10288
|
+
const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
|
|
10289
|
+
const routes = new Elysia13({
|
|
10290
|
+
name: options.name ?? "absolutejs-voice-tool-contracts"
|
|
10291
|
+
}).get(path, createVoiceToolContractJSONHandler(options));
|
|
10292
|
+
if (htmlPath) {
|
|
10293
|
+
routes.get(htmlPath, createVoiceToolContractHTMLHandler(options));
|
|
10294
|
+
}
|
|
10295
|
+
return routes;
|
|
10296
|
+
};
|
|
10106
10297
|
// src/fileStore.ts
|
|
10107
10298
|
import { mkdir as mkdir2, readFile, readdir, rename, rm, writeFile } from "fs/promises";
|
|
10108
10299
|
import { join } from "path";
|
|
@@ -12196,7 +12387,7 @@ var createVoiceMemoryStore = () => {
|
|
|
12196
12387
|
return { get, getOrCreate, list, remove, set };
|
|
12197
12388
|
};
|
|
12198
12389
|
// src/opsWebhook.ts
|
|
12199
|
-
import { Elysia as
|
|
12390
|
+
import { Elysia as Elysia14 } from "elysia";
|
|
12200
12391
|
var toHex5 = (bytes) => Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
12201
12392
|
var signVoiceOpsWebhookBody = async (input) => {
|
|
12202
12393
|
const encoder = new TextEncoder;
|
|
@@ -12326,7 +12517,7 @@ var verifyVoiceOpsWebhookSignature = async (input) => {
|
|
|
12326
12517
|
};
|
|
12327
12518
|
var createVoiceOpsWebhookReceiverRoutes = (options = {}) => {
|
|
12328
12519
|
const path = options.path ?? "/api/voice-ops/webhook";
|
|
12329
|
-
return new
|
|
12520
|
+
return new Elysia14().post(path, async ({ body, request, set }) => {
|
|
12330
12521
|
const bodyText = typeof body === "string" ? body : JSON.stringify(body);
|
|
12331
12522
|
if (options.signingSecret) {
|
|
12332
12523
|
const verification = await verifyVoiceOpsWebhookSignature({
|
|
@@ -14479,6 +14670,7 @@ export {
|
|
|
14479
14670
|
summarizeVoiceSessionReplay,
|
|
14480
14671
|
summarizeVoiceRoutingDecision,
|
|
14481
14672
|
summarizeVoiceProviderHealth,
|
|
14673
|
+
summarizeVoiceProviderCapabilities,
|
|
14482
14674
|
summarizeVoiceOpsTasks,
|
|
14483
14675
|
summarizeVoiceOpsTaskQueue,
|
|
14484
14676
|
summarizeVoiceOpsTaskAnalytics,
|
|
@@ -14491,6 +14683,7 @@ export {
|
|
|
14491
14683
|
startVoiceOpsTask,
|
|
14492
14684
|
shapeTelephonyAssistantText,
|
|
14493
14685
|
selectVoiceTraceEventsForPrune,
|
|
14686
|
+
runVoiceToolContractSuite,
|
|
14494
14687
|
runVoiceToolContract,
|
|
14495
14688
|
runVoiceSessionEvals,
|
|
14496
14689
|
runVoiceScenarioFixtureEvals,
|
|
@@ -14512,12 +14705,14 @@ export {
|
|
|
14512
14705
|
reopenVoiceOpsTask,
|
|
14513
14706
|
renderVoiceTraceMarkdown,
|
|
14514
14707
|
renderVoiceTraceHTML,
|
|
14708
|
+
renderVoiceToolContractHTML,
|
|
14515
14709
|
renderVoiceSessionsHTML,
|
|
14516
14710
|
renderVoiceScenarioFixtureEvalHTML,
|
|
14517
14711
|
renderVoiceScenarioEvalHTML,
|
|
14518
14712
|
renderVoiceResilienceHTML,
|
|
14519
14713
|
renderVoiceQualityHTML,
|
|
14520
14714
|
renderVoiceProviderHealthHTML,
|
|
14715
|
+
renderVoiceProviderCapabilityHTML,
|
|
14521
14716
|
renderVoiceOpsConsoleHTML,
|
|
14522
14717
|
renderVoiceHandoffHealthHTML,
|
|
14523
14718
|
renderVoiceEvalHTML,
|
|
@@ -14573,6 +14768,9 @@ export {
|
|
|
14573
14768
|
createVoiceToolRuntimeContractDefaults,
|
|
14574
14769
|
createVoiceToolRuntime,
|
|
14575
14770
|
createVoiceToolIdempotencyKey,
|
|
14771
|
+
createVoiceToolContractRoutes,
|
|
14772
|
+
createVoiceToolContractJSONHandler,
|
|
14773
|
+
createVoiceToolContractHTMLHandler,
|
|
14576
14774
|
createVoiceToolContract,
|
|
14577
14775
|
createVoiceTaskUpdatedEvent,
|
|
14578
14776
|
createVoiceTaskSLABreachedEvent,
|
|
@@ -14607,6 +14805,9 @@ export {
|
|
|
14607
14805
|
createVoiceProviderHealthRoutes,
|
|
14608
14806
|
createVoiceProviderHealthJSONHandler,
|
|
14609
14807
|
createVoiceProviderHealthHTMLHandler,
|
|
14808
|
+
createVoiceProviderCapabilityRoutes,
|
|
14809
|
+
createVoiceProviderCapabilityJSONHandler,
|
|
14810
|
+
createVoiceProviderCapabilityHTMLHandler,
|
|
14610
14811
|
createVoicePostgresTraceSinkDeliveryStore,
|
|
14611
14812
|
createVoicePostgresTraceEventStore,
|
|
14612
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
|
+
}>;
|
package/dist/toolContract.d.ts
CHANGED
|
@@ -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
|
+
}>;
|