@absolutejs/voice 0.0.22-beta.62 → 0.0.22-beta.63
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/index.d.ts +2 -0
- package/dist/index.js +160 -0
- package/dist/toolContract.d.ts +61 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +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
12
|
export { createStoredVoiceCallReviewArtifact, createStoredVoiceExternalObjectMap, createStoredVoiceIntegrationEvent, createStoredVoiceOpsTask, createVoiceFileExternalObjectMapStore, createVoiceFileAssistantMemoryStore, createVoiceFileIntegrationEventStore, createVoiceFileReviewStore, createVoiceFileRuntimeStorage, createVoiceFileSessionStore, createVoiceFileTaskStore, createVoiceFileTraceSinkDeliveryStore, createVoiceFileTraceEventStore } from './fileStore';
|
|
12
13
|
export { createVoiceAssistantMemoryHandle, createVoiceAssistantMemoryRecord, createVoiceMemoryAssistantMemoryStore, resolveVoiceAssistantMemoryNamespace } from './assistantMemory';
|
|
13
14
|
export { createAnthropicVoiceAssistantModel, createGeminiVoiceAssistantModel, createJSONVoiceAssistantModel, createOpenAIVoiceAssistantModel, resolveVoiceProviderRoutingPolicyPreset, createVoiceProviderRouter } from './modelAdapters';
|
|
@@ -55,6 +56,7 @@ export type { VoiceResilienceIOSimulator, VoiceResilienceLink, VoiceResiliencePa
|
|
|
55
56
|
export type { VoiceIOProviderRouterEvent, VoiceIOProviderRouterOptions, VoiceIOProviderRouterPolicy, VoiceIOProviderRouterPolicyConfig, VoiceSTTProviderRouterOptions, VoiceTTSProviderRouterOptions } from './providerAdapters';
|
|
56
57
|
export type { VoiceAgent, VoiceAgentMessage, VoiceAgentMessageRole, VoiceAgentModel, VoiceAgentModelInput, VoiceAgentModelOutput, VoiceAgentOptions, VoiceAgentRunResult, VoiceAgentSquadOptions, VoiceAgentTool, VoiceAgentToolCall, VoiceAgentToolResult } from './agent';
|
|
57
58
|
export type { VoiceToolRetryDelay, VoiceToolRuntime, VoiceToolRuntimeExecuteInput, VoiceToolRuntimeOptions, VoiceToolRuntimeResult } from './toolRuntime';
|
|
59
|
+
export type { VoiceToolContractCase, VoiceToolContractCaseReport, VoiceToolContractDefinition, VoiceToolContractExpectation, VoiceToolContractIssue, VoiceToolContractReport } from './toolContract';
|
|
58
60
|
export type { VoiceOpsRuntime, VoiceOpsRuntimeConfig, VoiceOpsRuntimeSummary, VoiceOpsRuntimeSinkWorkerConfig, VoiceOpsRuntimeTaskWorkerConfig, VoiceOpsRuntimeTickResult, VoiceOpsRuntimeWebhookWorkerConfig } from './opsRuntime';
|
|
59
61
|
export type { VoiceOpsPresetName, VoiceOpsPresetOverrides, VoiceResolvedOpsPreset } from './opsPresets';
|
|
60
62
|
export type { VoiceOutcomeRecipe, VoiceOutcomeRecipeName, VoiceOutcomeRecipeOptions } from './outcomeRecipes';
|
package/dist/index.js
CHANGED
|
@@ -9946,6 +9946,163 @@ var createVoiceToolIdempotencyKey = (input) => {
|
|
|
9946
9946
|
args
|
|
9947
9947
|
].join(":");
|
|
9948
9948
|
};
|
|
9949
|
+
// src/toolContract.ts
|
|
9950
|
+
var createDefaultSession = (contractId, caseId) => createVoiceSessionRecord(`tool-contract-${contractId}-${caseId}`);
|
|
9951
|
+
var createDefaultTurn = (caseId) => ({
|
|
9952
|
+
committedAt: Date.now(),
|
|
9953
|
+
id: `turn-${caseId}`,
|
|
9954
|
+
text: `Run tool contract case ${caseId}.`,
|
|
9955
|
+
transcripts: []
|
|
9956
|
+
});
|
|
9957
|
+
var defaultApi = {};
|
|
9958
|
+
var sameJSON = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
9959
|
+
var evaluateExpectation = (input) => {
|
|
9960
|
+
const issues = [];
|
|
9961
|
+
const expect = input.expect;
|
|
9962
|
+
if (!expect) {
|
|
9963
|
+
return issues;
|
|
9964
|
+
}
|
|
9965
|
+
if (expect.expectStatus && input.status !== expect.expectStatus) {
|
|
9966
|
+
issues.push({
|
|
9967
|
+
caseId: input.caseId,
|
|
9968
|
+
code: "tool.status_mismatch",
|
|
9969
|
+
message: `Expected ${expect.expectStatus}, saw ${input.status}.`
|
|
9970
|
+
});
|
|
9971
|
+
}
|
|
9972
|
+
if (typeof expect.expectedAttempts === "number" && input.attempts !== expect.expectedAttempts) {
|
|
9973
|
+
issues.push({
|
|
9974
|
+
caseId: input.caseId,
|
|
9975
|
+
code: "tool.attempt_mismatch",
|
|
9976
|
+
message: `Expected ${expect.expectedAttempts} attempts, saw ${input.attempts}.`
|
|
9977
|
+
});
|
|
9978
|
+
}
|
|
9979
|
+
if (expect.expectedResult !== undefined && !sameJSON(input.result, expect.expectedResult)) {
|
|
9980
|
+
issues.push({
|
|
9981
|
+
caseId: input.caseId,
|
|
9982
|
+
code: "tool.result_mismatch",
|
|
9983
|
+
message: "Tool result did not match expected result."
|
|
9984
|
+
});
|
|
9985
|
+
}
|
|
9986
|
+
if (expect.expectedErrorIncludes && !input.error?.includes(expect.expectedErrorIncludes)) {
|
|
9987
|
+
issues.push({
|
|
9988
|
+
caseId: input.caseId,
|
|
9989
|
+
code: "tool.error_mismatch",
|
|
9990
|
+
message: `Expected error to include ${expect.expectedErrorIncludes}.`
|
|
9991
|
+
});
|
|
9992
|
+
}
|
|
9993
|
+
if (typeof expect.expectTimedOut === "boolean" && input.timedOut !== expect.expectTimedOut) {
|
|
9994
|
+
issues.push({
|
|
9995
|
+
caseId: input.caseId,
|
|
9996
|
+
code: "tool.timeout_mismatch",
|
|
9997
|
+
message: `Expected timedOut=${String(expect.expectTimedOut)}, saw ${String(input.timedOut)}.`
|
|
9998
|
+
});
|
|
9999
|
+
}
|
|
10000
|
+
if (typeof expect.maxElapsedMs === "number" && input.elapsedMs > expect.maxElapsedMs) {
|
|
10001
|
+
issues.push({
|
|
10002
|
+
caseId: input.caseId,
|
|
10003
|
+
code: "tool.elapsed_exceeded",
|
|
10004
|
+
message: `Expected elapsed <= ${expect.maxElapsedMs}ms, saw ${input.elapsedMs}ms.`
|
|
10005
|
+
});
|
|
10006
|
+
}
|
|
10007
|
+
return issues;
|
|
10008
|
+
};
|
|
10009
|
+
var runVoiceToolContract = async (definition) => {
|
|
10010
|
+
const cases = [];
|
|
10011
|
+
for (const testCase of definition.cases) {
|
|
10012
|
+
const session = testCase.session ?? createDefaultSession(definition.id, testCase.id);
|
|
10013
|
+
const turn = testCase.turn ?? createDefaultTurn(testCase.id);
|
|
10014
|
+
const context = testCase.context ?? {};
|
|
10015
|
+
const runtimeOptions = {
|
|
10016
|
+
...definition.defaultRuntime,
|
|
10017
|
+
...testCase.runtime
|
|
10018
|
+
};
|
|
10019
|
+
const runtime = createVoiceToolRuntime(runtimeOptions);
|
|
10020
|
+
const toolCall = {
|
|
10021
|
+
args: testCase.args,
|
|
10022
|
+
id: testCase.toolCallId ?? testCase.id,
|
|
10023
|
+
name: definition.tool.name
|
|
10024
|
+
};
|
|
10025
|
+
const executeOnce = () => runtime.execute({
|
|
10026
|
+
api: defaultApi,
|
|
10027
|
+
args: toolCall.args,
|
|
10028
|
+
context,
|
|
10029
|
+
session,
|
|
10030
|
+
tool: definition.tool,
|
|
10031
|
+
toolCallId: toolCall.id,
|
|
10032
|
+
turn
|
|
10033
|
+
});
|
|
10034
|
+
const result = await executeOnce();
|
|
10035
|
+
let issues2 = evaluateExpectation({
|
|
10036
|
+
attempts: result.attempts,
|
|
10037
|
+
caseId: testCase.id,
|
|
10038
|
+
elapsedMs: result.elapsedMs,
|
|
10039
|
+
error: result.error,
|
|
10040
|
+
expect: testCase.expect,
|
|
10041
|
+
result: result.result,
|
|
10042
|
+
status: result.status,
|
|
10043
|
+
timedOut: result.timedOut
|
|
10044
|
+
});
|
|
10045
|
+
if (testCase.expect?.expectIdempotent) {
|
|
10046
|
+
const second = await executeOnce();
|
|
10047
|
+
if (second.result !== result.result && !sameJSON(second.result, result.result)) {
|
|
10048
|
+
issues2.push({
|
|
10049
|
+
caseId: testCase.id,
|
|
10050
|
+
code: "tool.idempotency_result_mismatch",
|
|
10051
|
+
message: "Repeated idempotent execution returned a different result."
|
|
10052
|
+
});
|
|
10053
|
+
}
|
|
10054
|
+
if (second.idempotencyKey !== result.idempotencyKey) {
|
|
10055
|
+
issues2.push({
|
|
10056
|
+
caseId: testCase.id,
|
|
10057
|
+
code: "tool.idempotency_key_mismatch",
|
|
10058
|
+
message: "Repeated idempotent execution used a different idempotency key."
|
|
10059
|
+
});
|
|
10060
|
+
}
|
|
10061
|
+
}
|
|
10062
|
+
cases.push({
|
|
10063
|
+
attempts: result.attempts,
|
|
10064
|
+
caseId: testCase.id,
|
|
10065
|
+
elapsedMs: result.elapsedMs,
|
|
10066
|
+
error: result.error,
|
|
10067
|
+
issues: issues2,
|
|
10068
|
+
label: testCase.label,
|
|
10069
|
+
pass: issues2.length === 0,
|
|
10070
|
+
status: result.status,
|
|
10071
|
+
timedOut: result.timedOut
|
|
10072
|
+
});
|
|
10073
|
+
}
|
|
10074
|
+
const issues = cases.flatMap((testCase) => testCase.issues);
|
|
10075
|
+
return {
|
|
10076
|
+
cases,
|
|
10077
|
+
contractId: definition.id,
|
|
10078
|
+
issues,
|
|
10079
|
+
pass: issues.length === 0,
|
|
10080
|
+
toolName: definition.tool.name
|
|
10081
|
+
};
|
|
10082
|
+
};
|
|
10083
|
+
var createVoiceToolContract = (definition) => ({
|
|
10084
|
+
assert: async () => {
|
|
10085
|
+
const report = await runVoiceToolContract(definition);
|
|
10086
|
+
if (!report.pass) {
|
|
10087
|
+
throw new Error(`Voice tool contract ${definition.id} failed: ${report.issues.map((issue) => issue.message).join(" ")}`);
|
|
10088
|
+
}
|
|
10089
|
+
return report;
|
|
10090
|
+
},
|
|
10091
|
+
definition,
|
|
10092
|
+
run: () => runVoiceToolContract(definition)
|
|
10093
|
+
});
|
|
10094
|
+
var createVoiceToolRuntimeContractDefaults = () => ({
|
|
10095
|
+
idempotencyKey: ({ args, session, toolCallId, toolName, turn }) => createVoiceToolIdempotencyKey({
|
|
10096
|
+
args,
|
|
10097
|
+
sessionId: session.id,
|
|
10098
|
+
toolCallId,
|
|
10099
|
+
toolName,
|
|
10100
|
+
turnId: turn.id
|
|
10101
|
+
}),
|
|
10102
|
+
idempotencyTtlMs: 60000,
|
|
10103
|
+
maxRetries: 1,
|
|
10104
|
+
timeoutMs: 5000
|
|
10105
|
+
});
|
|
9949
10106
|
// src/fileStore.ts
|
|
9950
10107
|
import { mkdir as mkdir2, readFile, readdir, rename, rm, writeFile } from "fs/promises";
|
|
9951
10108
|
import { join } from "path";
|
|
@@ -14334,6 +14491,7 @@ export {
|
|
|
14334
14491
|
startVoiceOpsTask,
|
|
14335
14492
|
shapeTelephonyAssistantText,
|
|
14336
14493
|
selectVoiceTraceEventsForPrune,
|
|
14494
|
+
runVoiceToolContract,
|
|
14337
14495
|
runVoiceSessionEvals,
|
|
14338
14496
|
runVoiceScenarioFixtureEvals,
|
|
14339
14497
|
runVoiceScenarioEvals,
|
|
@@ -14412,8 +14570,10 @@ export {
|
|
|
14412
14570
|
createVoiceTraceHTTPSink,
|
|
14413
14571
|
createVoiceTraceEventId,
|
|
14414
14572
|
createVoiceTraceEvent,
|
|
14573
|
+
createVoiceToolRuntimeContractDefaults,
|
|
14415
14574
|
createVoiceToolRuntime,
|
|
14416
14575
|
createVoiceToolIdempotencyKey,
|
|
14576
|
+
createVoiceToolContract,
|
|
14417
14577
|
createVoiceTaskUpdatedEvent,
|
|
14418
14578
|
createVoiceTaskSLABreachedEvent,
|
|
14419
14579
|
createVoiceTaskCreatedEvent,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { VoiceAgentTool } from './agent';
|
|
2
|
+
import { type VoiceToolRuntimeOptions } from './toolRuntime';
|
|
3
|
+
import type { VoiceSessionRecord, VoiceTurnRecord } from './types';
|
|
4
|
+
export type VoiceToolContractExpectation = {
|
|
5
|
+
expectedAttempts?: number;
|
|
6
|
+
expectedErrorIncludes?: string;
|
|
7
|
+
expectedResult?: unknown;
|
|
8
|
+
expectIdempotent?: boolean;
|
|
9
|
+
expectStatus?: 'error' | 'ok';
|
|
10
|
+
expectTimedOut?: boolean;
|
|
11
|
+
maxElapsedMs?: number;
|
|
12
|
+
};
|
|
13
|
+
export type VoiceToolContractCase<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TArgs = Record<string, unknown>, TToolResult = unknown, TRouteResult = unknown> = {
|
|
14
|
+
args: TArgs;
|
|
15
|
+
context?: TContext;
|
|
16
|
+
expect?: VoiceToolContractExpectation;
|
|
17
|
+
id: string;
|
|
18
|
+
label?: string;
|
|
19
|
+
runtime?: VoiceToolRuntimeOptions<TContext, TSession, TRouteResult>;
|
|
20
|
+
session?: TSession;
|
|
21
|
+
toolCallId?: string;
|
|
22
|
+
turn?: VoiceTurnRecord;
|
|
23
|
+
};
|
|
24
|
+
export type VoiceToolContractDefinition<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TArgs = Record<string, unknown>, TToolResult = unknown, TRouteResult = unknown> = {
|
|
25
|
+
cases: Array<VoiceToolContractCase<TContext, TSession, TArgs, TToolResult, TRouteResult>>;
|
|
26
|
+
defaultRuntime?: VoiceToolRuntimeOptions<TContext, TSession, TRouteResult>;
|
|
27
|
+
description?: string;
|
|
28
|
+
id: string;
|
|
29
|
+
label?: string;
|
|
30
|
+
tool: VoiceAgentTool<TContext, TSession, TArgs, TToolResult, TRouteResult>;
|
|
31
|
+
};
|
|
32
|
+
export type VoiceToolContractIssue = {
|
|
33
|
+
caseId: string;
|
|
34
|
+
code: string;
|
|
35
|
+
message: string;
|
|
36
|
+
};
|
|
37
|
+
export type VoiceToolContractCaseReport = {
|
|
38
|
+
attempts: number;
|
|
39
|
+
caseId: string;
|
|
40
|
+
elapsedMs: number;
|
|
41
|
+
error?: string;
|
|
42
|
+
issues: VoiceToolContractIssue[];
|
|
43
|
+
label?: string;
|
|
44
|
+
pass: boolean;
|
|
45
|
+
status: 'error' | 'ok';
|
|
46
|
+
timedOut: boolean;
|
|
47
|
+
};
|
|
48
|
+
export type VoiceToolContractReport = {
|
|
49
|
+
cases: VoiceToolContractCaseReport[];
|
|
50
|
+
contractId: string;
|
|
51
|
+
issues: VoiceToolContractIssue[];
|
|
52
|
+
pass: boolean;
|
|
53
|
+
toolName: string;
|
|
54
|
+
};
|
|
55
|
+
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
|
+
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
|
+
assert: () => Promise<VoiceToolContractReport>;
|
|
58
|
+
definition: VoiceToolContractDefinition<TContext, TSession, TArgs, TToolResult, TRouteResult>;
|
|
59
|
+
run: () => Promise<VoiceToolContractReport>;
|
|
60
|
+
};
|
|
61
|
+
export declare const createVoiceToolRuntimeContractDefaults: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TRouteResult = unknown>() => VoiceToolRuntimeOptions<TContext, TSession, TRouteResult>;
|