@absolutejs/voice 0.0.22-beta.469 → 0.0.22-beta.470
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -0
- package/dist/agentTools.d.ts +132 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +227 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,50 @@ Use it when you want Vapi/Retell/Bland-style voice-agent capability, but you wan
|
|
|
8
8
|
|
|
9
9
|
## What's new
|
|
10
10
|
|
|
11
|
+
### 0.0.22-beta.470 · Vapi parity — named tool catalog
|
|
12
|
+
|
|
13
|
+
Five named-tool factories that mirror Vapi's built-in `tools[].type` entries 1:1. Drop them straight into `createVoiceAssistant({ tools: [...] })` to get the same buyer ergonomics without writing the wiring yourself.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import {
|
|
17
|
+
createVoiceAssistant,
|
|
18
|
+
createVoiceApiRequestTool,
|
|
19
|
+
createVoiceDTMFTool,
|
|
20
|
+
createVoiceEndCallTool,
|
|
21
|
+
createVoiceTransferCallTool,
|
|
22
|
+
createVoiceVoicemailDetectionTool,
|
|
23
|
+
} from "@absolutejs/voice";
|
|
24
|
+
|
|
25
|
+
const tools = [
|
|
26
|
+
createVoiceEndCallTool({ farewell: "Thanks for calling, goodbye." }),
|
|
27
|
+
createVoiceTransferCallTool({
|
|
28
|
+
destinations: [
|
|
29
|
+
{ id: "billing", target: "+15551234567", message: "Connecting you to billing." },
|
|
30
|
+
{ id: "supervisor", target: "sip:supervisor@pbx", metadata: { queue: "vip" } },
|
|
31
|
+
],
|
|
32
|
+
}),
|
|
33
|
+
createVoiceDTMFTool({
|
|
34
|
+
send: async ({ args, api }) => api.transfer({ target: "ivr", metadata: { digits: args.digits } }),
|
|
35
|
+
}),
|
|
36
|
+
createVoiceVoicemailDetectionTool({ completeAfterMarking: true }),
|
|
37
|
+
createVoiceApiRequestTool({
|
|
38
|
+
description: "Look up a customer record",
|
|
39
|
+
name: "lookupCustomer",
|
|
40
|
+
method: "GET",
|
|
41
|
+
url: "https://api.example.com/customers",
|
|
42
|
+
buildQuery: ({ args }) => ({ email: String(args.email) }),
|
|
43
|
+
parameters: { type: "object", properties: { email: { type: "string" } }, required: ["email"] },
|
|
44
|
+
}),
|
|
45
|
+
];
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Per-tool highlights:
|
|
49
|
+
- **`createVoiceEndCallTool`** — calls `api.complete(result)` with an optional resolved result. JSON-schema `{ reason?: string }`. Custom `farewell` (static or `({args, context, session}) => string`).
|
|
50
|
+
- **`createVoiceTransferCallTool`** — multi-destination router, exposes an `enum` of destination ids to the LLM; calls `api.transfer({ target, metadata, reason, result })` with the matching destination. Pairs with `createVoiceTwilioRedirectHandoffAdapter` for live carrier transfer.
|
|
51
|
+
- **`createVoiceDTMFTool`** — caller provides a `send` hook (typically forwarding to your telephony adapter); validates digits against `allowedDigits` and `maxDigits`. Default allowed set `0123456789*#`.
|
|
52
|
+
- **`createVoiceVoicemailDetectionTool`** — LLM-callable companion to ML-based voicemail detection; calls `api.markVoicemail({ metadata })` and (by default) `api.complete()`. Use when the model hears a beep / "leave a message" prompt.
|
|
53
|
+
- **`createVoiceApiRequestTool`** — generic HTTP-call tool with `buildBody` / `buildQuery` / `buildHeaders` / `parseResponse` hooks. Supports DI of `fetch` for tests.
|
|
54
|
+
|
|
11
55
|
### 0.0.22-beta.469 · Vapi parity — RAG-as-a-tool helper
|
|
12
56
|
|
|
13
57
|
`createVoiceRAGTool(collection, options?)` wraps any `@absolutejs/rag` `RAGCollection` (or any object that satisfies `VoiceRAGCollectionLike`) into a `VoiceAgentTool` shaped like Vapi's built-in `query` / `knowledgeBaseId` flow.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { type VoiceAgentTool } from "./agent";
|
|
2
|
+
import type { VoiceRouteResult, VoiceSessionHandle, VoiceSessionRecord } from "./types";
|
|
3
|
+
export type VoiceEndCallToolArgs = {
|
|
4
|
+
reason?: string;
|
|
5
|
+
};
|
|
6
|
+
export type VoiceEndCallToolResult = {
|
|
7
|
+
farewell?: string;
|
|
8
|
+
ok: true;
|
|
9
|
+
reason?: string;
|
|
10
|
+
};
|
|
11
|
+
export type VoiceEndCallToolOptions<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
|
|
12
|
+
description?: string;
|
|
13
|
+
farewell?: string | ((input: {
|
|
14
|
+
args: VoiceEndCallToolArgs;
|
|
15
|
+
context: TContext;
|
|
16
|
+
session: TSession;
|
|
17
|
+
}) => string | undefined);
|
|
18
|
+
name?: string;
|
|
19
|
+
resolveResult?: (input: {
|
|
20
|
+
args: VoiceEndCallToolArgs;
|
|
21
|
+
context: TContext;
|
|
22
|
+
session: TSession;
|
|
23
|
+
}) => TResult | undefined;
|
|
24
|
+
};
|
|
25
|
+
export declare const createVoiceEndCallTool: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown>(options?: VoiceEndCallToolOptions<TContext, TSession, TResult>) => VoiceAgentTool<TContext, TSession, VoiceEndCallToolArgs, VoiceEndCallToolResult, TResult>;
|
|
26
|
+
export type VoiceTransferCallToolDestination = {
|
|
27
|
+
description?: string;
|
|
28
|
+
id: string;
|
|
29
|
+
message?: string;
|
|
30
|
+
metadata?: Record<string, unknown>;
|
|
31
|
+
target: string;
|
|
32
|
+
};
|
|
33
|
+
export type VoiceTransferCallToolArgs = {
|
|
34
|
+
destinationId: string;
|
|
35
|
+
reason?: string;
|
|
36
|
+
};
|
|
37
|
+
export type VoiceTransferCallToolResult = {
|
|
38
|
+
destinationId: string;
|
|
39
|
+
message?: string;
|
|
40
|
+
ok: true;
|
|
41
|
+
target: string;
|
|
42
|
+
};
|
|
43
|
+
export type VoiceTransferCallToolOptions<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
|
|
44
|
+
description?: string;
|
|
45
|
+
destinations: readonly VoiceTransferCallToolDestination[];
|
|
46
|
+
name?: string;
|
|
47
|
+
resolveResult?: (input: {
|
|
48
|
+
args: VoiceTransferCallToolArgs;
|
|
49
|
+
context: TContext;
|
|
50
|
+
destination: VoiceTransferCallToolDestination;
|
|
51
|
+
session: TSession;
|
|
52
|
+
}) => TResult | undefined;
|
|
53
|
+
};
|
|
54
|
+
export declare const createVoiceTransferCallTool: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown>(options: VoiceTransferCallToolOptions<TContext, TSession, TResult>) => VoiceAgentTool<TContext, TSession, VoiceTransferCallToolArgs, VoiceTransferCallToolResult, TResult>;
|
|
55
|
+
export type VoiceDTMFToolArgs = {
|
|
56
|
+
digits: string;
|
|
57
|
+
};
|
|
58
|
+
export type VoiceDTMFToolResult = {
|
|
59
|
+
digits: string;
|
|
60
|
+
ok: true;
|
|
61
|
+
};
|
|
62
|
+
export type VoiceDTMFToolOptions<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord> = {
|
|
63
|
+
allowedDigits?: string;
|
|
64
|
+
description?: string;
|
|
65
|
+
maxDigits?: number;
|
|
66
|
+
name?: string;
|
|
67
|
+
send: (input: {
|
|
68
|
+
api: VoiceSessionHandle<TContext, TSession>;
|
|
69
|
+
args: VoiceDTMFToolArgs;
|
|
70
|
+
context: TContext;
|
|
71
|
+
session: TSession;
|
|
72
|
+
}) => Promise<void> | void;
|
|
73
|
+
};
|
|
74
|
+
export declare const createVoiceDTMFTool: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord>(options: VoiceDTMFToolOptions<TContext, TSession>) => VoiceAgentTool<TContext, TSession, VoiceDTMFToolArgs, VoiceDTMFToolResult>;
|
|
75
|
+
export type VoiceVoicemailDetectionToolArgs = {
|
|
76
|
+
confidence?: number;
|
|
77
|
+
reason?: string;
|
|
78
|
+
};
|
|
79
|
+
export type VoiceVoicemailDetectionToolResult = {
|
|
80
|
+
confidence?: number;
|
|
81
|
+
ok: true;
|
|
82
|
+
reason?: string;
|
|
83
|
+
};
|
|
84
|
+
export type VoiceVoicemailDetectionToolOptions<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
|
|
85
|
+
completeAfterMarking?: boolean;
|
|
86
|
+
description?: string;
|
|
87
|
+
message?: string;
|
|
88
|
+
name?: string;
|
|
89
|
+
resolveResult?: (input: {
|
|
90
|
+
args: VoiceVoicemailDetectionToolArgs;
|
|
91
|
+
context: TContext;
|
|
92
|
+
session: TSession;
|
|
93
|
+
}) => TResult | undefined;
|
|
94
|
+
};
|
|
95
|
+
export declare const createVoiceVoicemailDetectionTool: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown>(options?: VoiceVoicemailDetectionToolOptions<TContext, TSession, TResult>) => VoiceAgentTool<TContext, TSession, VoiceVoicemailDetectionToolArgs, VoiceVoicemailDetectionToolResult, TResult>;
|
|
96
|
+
export type VoiceApiRequestToolHttpMethod = "DELETE" | "GET" | "PATCH" | "POST" | "PUT";
|
|
97
|
+
export type VoiceApiRequestToolArgs = Record<string, unknown>;
|
|
98
|
+
export type VoiceApiRequestToolResult<TResponse = unknown> = {
|
|
99
|
+
body: TResponse;
|
|
100
|
+
ok: boolean;
|
|
101
|
+
status: number;
|
|
102
|
+
url: string;
|
|
103
|
+
};
|
|
104
|
+
export type VoiceApiRequestToolFetch = (request: Request) => Promise<Response> | Response;
|
|
105
|
+
export type VoiceApiRequestToolOptions<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TArgs extends VoiceApiRequestToolArgs = VoiceApiRequestToolArgs, TResponse = unknown> = {
|
|
106
|
+
buildBody?: (input: {
|
|
107
|
+
args: TArgs;
|
|
108
|
+
context: TContext;
|
|
109
|
+
session: TSession;
|
|
110
|
+
}) => unknown;
|
|
111
|
+
buildHeaders?: (input: {
|
|
112
|
+
args: TArgs;
|
|
113
|
+
context: TContext;
|
|
114
|
+
session: TSession;
|
|
115
|
+
}) => HeadersInit | undefined;
|
|
116
|
+
buildQuery?: (input: {
|
|
117
|
+
args: TArgs;
|
|
118
|
+
context: TContext;
|
|
119
|
+
session: TSession;
|
|
120
|
+
}) => Record<string, string | number | undefined> | undefined;
|
|
121
|
+
description: string;
|
|
122
|
+
fetch?: VoiceApiRequestToolFetch;
|
|
123
|
+
formatResult?: (result: VoiceApiRequestToolResult<TResponse>) => string;
|
|
124
|
+
headers?: HeadersInit;
|
|
125
|
+
method?: VoiceApiRequestToolHttpMethod;
|
|
126
|
+
name: string;
|
|
127
|
+
parameters?: Record<string, unknown>;
|
|
128
|
+
parseResponse?: (response: Response) => Promise<TResponse> | TResponse;
|
|
129
|
+
url: string;
|
|
130
|
+
};
|
|
131
|
+
export declare const createVoiceApiRequestTool: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TArgs extends VoiceApiRequestToolArgs = VoiceApiRequestToolArgs, TResponse = unknown>(options: VoiceApiRequestToolOptions<TContext, TSession, TArgs, TResponse>) => VoiceAgentTool<TContext, TSession, TArgs, VoiceApiRequestToolResult<TResponse>>;
|
|
132
|
+
export type VoiceRouteResultLike = VoiceRouteResult<unknown>;
|
package/dist/index.d.ts
CHANGED
|
@@ -71,6 +71,8 @@ export { createVoiceSessionListRoutes, createVoiceSessionReplayHTMLHandler, crea
|
|
|
71
71
|
export { createVoiceAgent, createVoiceAgentSquad, createVoiceAgentTool, } from "./agent";
|
|
72
72
|
export { createVoiceRAGTool } from "./ragTool";
|
|
73
73
|
export type { VoiceRAGCollectionLike, VoiceRAGQueryResult, VoiceRAGSearchInput, VoiceRAGToolArgs, VoiceRAGToolOptions, VoiceRAGToolResult, } from "./ragTool";
|
|
74
|
+
export { createVoiceApiRequestTool, createVoiceDTMFTool, createVoiceEndCallTool, createVoiceTransferCallTool, createVoiceVoicemailDetectionTool, } from "./agentTools";
|
|
75
|
+
export type { VoiceApiRequestToolArgs, VoiceApiRequestToolFetch, VoiceApiRequestToolHttpMethod, VoiceApiRequestToolOptions, VoiceApiRequestToolResult, VoiceDTMFToolArgs, VoiceDTMFToolOptions, VoiceDTMFToolResult, VoiceEndCallToolArgs, VoiceEndCallToolOptions, VoiceEndCallToolResult, VoiceTransferCallToolArgs, VoiceTransferCallToolDestination, VoiceTransferCallToolOptions, VoiceTransferCallToolResult, VoiceVoicemailDetectionToolArgs, VoiceVoicemailDetectionToolOptions, VoiceVoicemailDetectionToolResult, } from "./agentTools";
|
|
74
76
|
export { assertVoiceAgentSquadContractEvidence, assertVoiceAgentSquadContract, evaluateVoiceAgentSquadContractEvidence, runVoiceAgentSquadContract, } from "./agentSquadContract";
|
|
75
77
|
export { createVoiceToolIdempotencyKey, createVoiceToolRuntime, } from "./toolRuntime";
|
|
76
78
|
export { assertVoiceToolContractEvidence, createVoiceToolContract, createVoiceToolContractHTMLHandler, createVoiceToolContractJSONHandler, createVoiceToolContractRoutes, createVoiceToolRuntimeContractDefaults, evaluateVoiceToolContractEvidence, renderVoiceToolContractHTML, runVoiceToolContractSuite, runVoiceToolContract, } from "./toolContract";
|
package/dist/index.js
CHANGED
|
@@ -34629,6 +34629,228 @@ var createVoiceRAGTool = (collection, options = {}) => {
|
|
|
34629
34629
|
resultToMessage: options.resultToMessage ?? ((result) => result.message)
|
|
34630
34630
|
});
|
|
34631
34631
|
};
|
|
34632
|
+
// src/agentTools.ts
|
|
34633
|
+
var createVoiceEndCallTool = (options = {}) => createVoiceAgentTool({
|
|
34634
|
+
description: options.description ?? "End the call gracefully. Call this only when the conversation is complete or the caller asks to hang up.",
|
|
34635
|
+
execute: async ({ api, args, context, session }) => {
|
|
34636
|
+
const farewell = typeof options.farewell === "function" ? options.farewell({ args, context, session }) : options.farewell;
|
|
34637
|
+
const result = options.resolveResult?.({ args, context, session });
|
|
34638
|
+
await api.complete(result);
|
|
34639
|
+
return {
|
|
34640
|
+
farewell,
|
|
34641
|
+
ok: true,
|
|
34642
|
+
reason: args?.reason
|
|
34643
|
+
};
|
|
34644
|
+
},
|
|
34645
|
+
name: options.name ?? "endCall",
|
|
34646
|
+
parameters: {
|
|
34647
|
+
additionalProperties: false,
|
|
34648
|
+
properties: {
|
|
34649
|
+
reason: {
|
|
34650
|
+
description: "Optional one-line note about why the call is ending.",
|
|
34651
|
+
type: "string"
|
|
34652
|
+
}
|
|
34653
|
+
},
|
|
34654
|
+
type: "object"
|
|
34655
|
+
},
|
|
34656
|
+
resultToMessage: (result) => result.farewell ?? "Call ended."
|
|
34657
|
+
});
|
|
34658
|
+
var createVoiceTransferCallTool = (options) => {
|
|
34659
|
+
if (options.destinations.length === 0) {
|
|
34660
|
+
throw new Error("createVoiceTransferCallTool requires at least one destination.");
|
|
34661
|
+
}
|
|
34662
|
+
const destinationIds = options.destinations.map((entry) => entry.id);
|
|
34663
|
+
const destinationDocs = options.destinations.map((entry) => `- ${entry.id} \u2192 ${entry.target}${entry.description ? `: ${entry.description}` : ""}`).join(`
|
|
34664
|
+
`);
|
|
34665
|
+
return createVoiceAgentTool({
|
|
34666
|
+
description: options.description ?? `Transfer the caller to a human or another route. Available destinations:
|
|
34667
|
+
${destinationDocs}`,
|
|
34668
|
+
execute: async ({ api, args, context, session }) => {
|
|
34669
|
+
const destination = options.destinations.find((entry) => entry.id === args?.destinationId);
|
|
34670
|
+
if (!destination) {
|
|
34671
|
+
throw new Error(`Unknown transfer destination "${String(args?.destinationId)}". Allowed: ${destinationIds.join(", ")}.`);
|
|
34672
|
+
}
|
|
34673
|
+
const result = options.resolveResult?.({
|
|
34674
|
+
args,
|
|
34675
|
+
context,
|
|
34676
|
+
destination,
|
|
34677
|
+
session
|
|
34678
|
+
});
|
|
34679
|
+
await api.transfer({
|
|
34680
|
+
metadata: destination.metadata,
|
|
34681
|
+
reason: args?.reason,
|
|
34682
|
+
result,
|
|
34683
|
+
target: destination.target
|
|
34684
|
+
});
|
|
34685
|
+
return {
|
|
34686
|
+
destinationId: destination.id,
|
|
34687
|
+
message: destination.message,
|
|
34688
|
+
ok: true,
|
|
34689
|
+
target: destination.target
|
|
34690
|
+
};
|
|
34691
|
+
},
|
|
34692
|
+
name: options.name ?? "transferCall",
|
|
34693
|
+
parameters: {
|
|
34694
|
+
additionalProperties: false,
|
|
34695
|
+
properties: {
|
|
34696
|
+
destinationId: {
|
|
34697
|
+
description: "Which configured destination to transfer the call to.",
|
|
34698
|
+
enum: destinationIds,
|
|
34699
|
+
type: "string"
|
|
34700
|
+
},
|
|
34701
|
+
reason: {
|
|
34702
|
+
description: "Optional one-line summary of why the transfer is happening.",
|
|
34703
|
+
type: "string"
|
|
34704
|
+
}
|
|
34705
|
+
},
|
|
34706
|
+
required: ["destinationId"],
|
|
34707
|
+
type: "object"
|
|
34708
|
+
},
|
|
34709
|
+
resultToMessage: (result) => result.message ?? `Transferring you to ${result.target}.`
|
|
34710
|
+
});
|
|
34711
|
+
};
|
|
34712
|
+
var DEFAULT_DTMF_ALLOWED = "0123456789*#";
|
|
34713
|
+
var createVoiceDTMFTool = (options) => {
|
|
34714
|
+
const allowedSet = new Set((options.allowedDigits ?? DEFAULT_DTMF_ALLOWED).split(""));
|
|
34715
|
+
const maxDigits = options.maxDigits ?? 32;
|
|
34716
|
+
return createVoiceAgentTool({
|
|
34717
|
+
description: options.description ?? "Send DTMF (touch-tone) digits to the active call. Use for IVR navigation and keypad entry.",
|
|
34718
|
+
execute: async ({ api, args, context, session }) => {
|
|
34719
|
+
const raw = typeof args?.digits === "string" ? args.digits.trim() : "";
|
|
34720
|
+
if (raw.length === 0) {
|
|
34721
|
+
throw new Error("DTMF tool requires a non-empty digits string.");
|
|
34722
|
+
}
|
|
34723
|
+
if (raw.length > maxDigits) {
|
|
34724
|
+
throw new Error(`DTMF digits exceed configured maxDigits=${String(maxDigits)}.`);
|
|
34725
|
+
}
|
|
34726
|
+
for (const character of raw) {
|
|
34727
|
+
if (!allowedSet.has(character)) {
|
|
34728
|
+
throw new Error(`DTMF digit "${character}" is not in the allowed set "${options.allowedDigits ?? DEFAULT_DTMF_ALLOWED}".`);
|
|
34729
|
+
}
|
|
34730
|
+
}
|
|
34731
|
+
await options.send({
|
|
34732
|
+
api,
|
|
34733
|
+
args: { digits: raw },
|
|
34734
|
+
context,
|
|
34735
|
+
session
|
|
34736
|
+
});
|
|
34737
|
+
return {
|
|
34738
|
+
digits: raw,
|
|
34739
|
+
ok: true
|
|
34740
|
+
};
|
|
34741
|
+
},
|
|
34742
|
+
name: options.name ?? "sendDTMF",
|
|
34743
|
+
parameters: {
|
|
34744
|
+
additionalProperties: false,
|
|
34745
|
+
properties: {
|
|
34746
|
+
digits: {
|
|
34747
|
+
description: `Digits to send. Allowed characters: ${options.allowedDigits ?? DEFAULT_DTMF_ALLOWED}. Max length ${String(maxDigits)}.`,
|
|
34748
|
+
maxLength: maxDigits,
|
|
34749
|
+
minLength: 1,
|
|
34750
|
+
type: "string"
|
|
34751
|
+
}
|
|
34752
|
+
},
|
|
34753
|
+
required: ["digits"],
|
|
34754
|
+
type: "object"
|
|
34755
|
+
},
|
|
34756
|
+
resultToMessage: (result) => `Sent DTMF: ${result.digits}`
|
|
34757
|
+
});
|
|
34758
|
+
};
|
|
34759
|
+
var createVoiceVoicemailDetectionTool = (options = {}) => {
|
|
34760
|
+
const completeAfterMarking = options.completeAfterMarking ?? true;
|
|
34761
|
+
return createVoiceAgentTool({
|
|
34762
|
+
description: options.description ?? "Mark the call as a voicemail when you hear a beep, a 'please leave a message' prompt, or other voicemail cues. Call exactly once per detection.",
|
|
34763
|
+
execute: async ({ api, args, context, session }) => {
|
|
34764
|
+
const metadata = {};
|
|
34765
|
+
if (typeof args?.confidence === "number") {
|
|
34766
|
+
metadata.confidence = args.confidence;
|
|
34767
|
+
}
|
|
34768
|
+
if (typeof args?.reason === "string" && args.reason.length > 0) {
|
|
34769
|
+
metadata.reason = args.reason;
|
|
34770
|
+
}
|
|
34771
|
+
const result = options.resolveResult?.({ args, context, session });
|
|
34772
|
+
await api.markVoicemail({ metadata, result });
|
|
34773
|
+
if (completeAfterMarking) {
|
|
34774
|
+
await api.complete(result);
|
|
34775
|
+
}
|
|
34776
|
+
return {
|
|
34777
|
+
confidence: args?.confidence,
|
|
34778
|
+
ok: true,
|
|
34779
|
+
reason: args?.reason
|
|
34780
|
+
};
|
|
34781
|
+
},
|
|
34782
|
+
name: options.name ?? "markVoicemail",
|
|
34783
|
+
parameters: {
|
|
34784
|
+
additionalProperties: false,
|
|
34785
|
+
properties: {
|
|
34786
|
+
confidence: {
|
|
34787
|
+
description: "Optional model confidence in the 0..1 range.",
|
|
34788
|
+
maximum: 1,
|
|
34789
|
+
minimum: 0,
|
|
34790
|
+
type: "number"
|
|
34791
|
+
},
|
|
34792
|
+
reason: {
|
|
34793
|
+
description: "One-line description of the cue that triggered detection.",
|
|
34794
|
+
type: "string"
|
|
34795
|
+
}
|
|
34796
|
+
},
|
|
34797
|
+
type: "object"
|
|
34798
|
+
},
|
|
34799
|
+
resultToMessage: (result) => options.message ?? `Voicemail detected${typeof result.confidence === "number" ? ` (confidence ${result.confidence.toFixed(2)})` : ""}.`
|
|
34800
|
+
});
|
|
34801
|
+
};
|
|
34802
|
+
var appendSearchParams = (url, entries) => {
|
|
34803
|
+
if (!entries)
|
|
34804
|
+
return;
|
|
34805
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
34806
|
+
if (value === undefined)
|
|
34807
|
+
continue;
|
|
34808
|
+
url.searchParams.set(key, String(value));
|
|
34809
|
+
}
|
|
34810
|
+
};
|
|
34811
|
+
var createVoiceApiRequestTool = (options) => {
|
|
34812
|
+
const method = options.method ?? "GET";
|
|
34813
|
+
const fetchImpl = options.fetch ?? ((request) => fetch(request));
|
|
34814
|
+
return createVoiceAgentTool({
|
|
34815
|
+
description: options.description,
|
|
34816
|
+
execute: async ({ args, context, session }) => {
|
|
34817
|
+
const url = new URL(options.url);
|
|
34818
|
+
appendSearchParams(url, options.buildQuery?.({ args, context, session }));
|
|
34819
|
+
const baseHeaders = new Headers(options.headers ?? {});
|
|
34820
|
+
const dynamicHeaders = options.buildHeaders?.({
|
|
34821
|
+
args,
|
|
34822
|
+
context,
|
|
34823
|
+
session
|
|
34824
|
+
});
|
|
34825
|
+
if (dynamicHeaders) {
|
|
34826
|
+
const merged = new Headers(dynamicHeaders);
|
|
34827
|
+
merged.forEach((value, key) => baseHeaders.set(key, value));
|
|
34828
|
+
}
|
|
34829
|
+
const body = method === "GET" || method === "DELETE" ? undefined : options.buildBody ? JSON.stringify(options.buildBody({ args, context, session })) : JSON.stringify(args);
|
|
34830
|
+
if (body !== undefined && !baseHeaders.has("content-type")) {
|
|
34831
|
+
baseHeaders.set("content-type", "application/json");
|
|
34832
|
+
}
|
|
34833
|
+
const request = new Request(url, {
|
|
34834
|
+
body,
|
|
34835
|
+
headers: baseHeaders,
|
|
34836
|
+
method
|
|
34837
|
+
});
|
|
34838
|
+
const response = await fetchImpl(request);
|
|
34839
|
+
const parsedBody = options.parseResponse ? await options.parseResponse(response) : await response.json().catch(() => {
|
|
34840
|
+
return;
|
|
34841
|
+
});
|
|
34842
|
+
return {
|
|
34843
|
+
body: parsedBody,
|
|
34844
|
+
ok: response.ok,
|
|
34845
|
+
status: response.status,
|
|
34846
|
+
url: url.toString()
|
|
34847
|
+
};
|
|
34848
|
+
},
|
|
34849
|
+
name: options.name,
|
|
34850
|
+
parameters: options.parameters,
|
|
34851
|
+
resultToMessage: options.formatResult ?? ((result) => result.ok ? `API request ${options.name} succeeded (${String(result.status)}).` : `API request ${options.name} failed with status ${String(result.status)}.`)
|
|
34852
|
+
});
|
|
34853
|
+
};
|
|
34632
34854
|
// src/agentSquadContract.ts
|
|
34633
34855
|
var normalizeIncludes = (value) => value.trim().toLowerCase();
|
|
34634
34856
|
var resolveOutcome4 = (result) => {
|
|
@@ -43185,6 +43407,7 @@ export {
|
|
|
43185
43407
|
createVoiceWebhookDeliveryWorkerLoop,
|
|
43186
43408
|
createVoiceWebhookDeliveryWorker,
|
|
43187
43409
|
createVoiceWebhookDeliverySink,
|
|
43410
|
+
createVoiceVoicemailDetectionTool,
|
|
43188
43411
|
createVoiceTwilioRedirectHandoffAdapter,
|
|
43189
43412
|
createVoiceTwilioCampaignDialer,
|
|
43190
43413
|
createVoiceTurnQualityRoutes,
|
|
@@ -43193,6 +43416,7 @@ export {
|
|
|
43193
43416
|
createVoiceTurnLatencyRoutes,
|
|
43194
43417
|
createVoiceTurnLatencyJSONHandler,
|
|
43195
43418
|
createVoiceTurnLatencyHTMLHandler,
|
|
43419
|
+
createVoiceTransferCallTool,
|
|
43196
43420
|
createVoiceTraceTimelineRoutes,
|
|
43197
43421
|
createVoiceTraceSinkStore,
|
|
43198
43422
|
createVoiceTraceSinkDeliveryWorkerLoop,
|
|
@@ -43431,6 +43655,7 @@ export {
|
|
|
43431
43655
|
createVoiceExperiment,
|
|
43432
43656
|
createVoiceEvidenceAssertion,
|
|
43433
43657
|
createVoiceEvalRoutes,
|
|
43658
|
+
createVoiceEndCallTool,
|
|
43434
43659
|
createVoiceDiagnosticsRoutes,
|
|
43435
43660
|
createVoiceDemoReadyRoutes,
|
|
43436
43661
|
createVoiceDeliverySinkRoutes,
|
|
@@ -43440,6 +43665,7 @@ export {
|
|
|
43440
43665
|
createVoiceDeliveryRuntimePresetConfig,
|
|
43441
43666
|
createVoiceDeliveryRuntime,
|
|
43442
43667
|
createVoiceDataControlRoutes,
|
|
43668
|
+
createVoiceDTMFTool,
|
|
43443
43669
|
createVoiceCompetitiveCoverageRoutes,
|
|
43444
43670
|
createVoiceCampaignWorkerLoop,
|
|
43445
43671
|
createVoiceCampaignWorker,
|
|
@@ -43475,6 +43701,7 @@ export {
|
|
|
43475
43701
|
createVoiceAssistantHealthJSONHandler,
|
|
43476
43702
|
createVoiceAssistantHealthHTMLHandler,
|
|
43477
43703
|
createVoiceAssistant,
|
|
43704
|
+
createVoiceApiRequestTool,
|
|
43478
43705
|
createVoiceAgentTool,
|
|
43479
43706
|
createVoiceAgentSquad,
|
|
43480
43707
|
createVoiceAgent,
|