@absolutejs/voice 0.0.22-beta.470 → 0.0.22-beta.471

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 CHANGED
@@ -8,6 +8,52 @@ 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.471 · Vapi parity — `fromVapiAssistantConfig` adapter
12
+
13
+ Mechanical migration from a Vapi Assistant JSON to a voice assistant. Pass the JSON dump (or a typed subset), provide a `modelFactory` that maps Vapi's `model.provider`+`model.model` to a voice `VoiceAgentModel`, and get back `{ assistant, tools, routeHints, unsupported }`.
14
+
15
+ ```ts
16
+ import {
17
+ createOpenAIVoiceAssistantModel,
18
+ fromVapiAssistantConfig,
19
+ type VapiAssistantConfig,
20
+ } from "@absolutejs/voice";
21
+
22
+ const config: VapiAssistantConfig = JSON.parse(vapiDump);
23
+
24
+ const { assistant, tools, routeHints, unsupported } = fromVapiAssistantConfig(config, {
25
+ assistantId: "support",
26
+ fetch,
27
+ knowledgeBase: { collection: ragCollection },
28
+ modelFactory: ({ provider, model, temperature }) => {
29
+ if (provider === "openai") {
30
+ return createOpenAIVoiceAssistantModel({
31
+ apiKey: process.env.OPENAI_API_KEY!,
32
+ model: model ?? "gpt-4.1-mini",
33
+ temperature,
34
+ });
35
+ }
36
+ throw new Error(`Unsupported provider: ${provider}`);
37
+ },
38
+ variableResolver: (path, { context }) => {
39
+ if (path === "customer.name") return context.customerName;
40
+ return undefined;
41
+ },
42
+ dtmfSendFactory: () => ({ args, api }) =>
43
+ api.transfer({ target: "ivr", metadata: { digits: args.digits } }),
44
+ });
45
+
46
+ console.log("Migrated", tools.length, "tools;", unsupported.length, "fields need manual review:");
47
+ for (const reason of unsupported) console.log(` - ${reason.field}: ${reason.detail}`);
48
+ ```
49
+
50
+ Mappings:
51
+ - **`model.provider` + `model.model` + `temperature`** → your `modelFactory` (you control which provider adapter to use; the adapter doesn't bake in API keys).
52
+ - **`messages[].role === "system"` (or `systemPrompt`)** → assistant `system` field; `{{var}}` bare expansions auto-compile to a function-form prompt that resolves built-ins (`{{now}}`, `{{date}}`, `{{time}}`) and your `variableResolver` for everything else. LiquidJS filters are reported in `unsupported`.
53
+ - **`tools[].type`** → named-tool factories from beta.470: `endCall` → `createVoiceEndCallTool`, `transferCall` → `createVoiceTransferCallTool` (numbers/SIP URIs auto-mapped), `voicemail` → `createVoiceVoicemailDetectionTool`, `apiRequest` / `function` (with `server.url`) → `createVoiceApiRequestTool`, `query` (or top-level `knowledgeBaseId`) → `createVoiceRAGTool` if you pass a `knowledgeBase` option. `dtmf` requires a `dtmfSendFactory` so it can reach your telephony adapter. `function` tools without `server.url` are forwarded to your optional `customToolFactory`.
54
+ - **`voice.*` (TTS) + `transcriber.*` (STT) + `firstMessage` / `firstMessageMode` / `silenceTimeoutSeconds` / `maxDurationSeconds` / `endCall*` / `recordingEnabled` / `compliancePlan.*` / `backgroundSound` / `voicemailMessage`** → `routeHints` you pass into your `voice()` plugin / carrier route at mount time.
55
+ - **`monitorPlan`, `startSpeakingPlan`, `stopSpeakingPlan`, `voicemailDetection.provider`, `model.toolIds`, `firstMessageMode`** → reported in `unsupported` with concrete migration instructions.
56
+
11
57
  ### 0.0.22-beta.470 · Vapi parity — named tool catalog
12
58
 
13
59
  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.
package/dist/index.d.ts CHANGED
@@ -72,6 +72,8 @@ export { createVoiceAgent, createVoiceAgentSquad, createVoiceAgentTool, } from "
72
72
  export { createVoiceRAGTool } from "./ragTool";
73
73
  export type { VoiceRAGCollectionLike, VoiceRAGQueryResult, VoiceRAGSearchInput, VoiceRAGToolArgs, VoiceRAGToolOptions, VoiceRAGToolResult, } from "./ragTool";
74
74
  export { createVoiceApiRequestTool, createVoiceDTMFTool, createVoiceEndCallTool, createVoiceTransferCallTool, createVoiceVoicemailDetectionTool, } from "./agentTools";
75
+ export { fromVapiAssistantConfig } from "./vapiAdapter";
76
+ export type { VapiAssistantConfig, VapiAssistantConfigModel, VapiAssistantConfigTool, VapiAssistantConfigTranscriber, VapiAssistantConfigTransferDestination, VapiAssistantConfigVoice, VapiAssistantMessage, VoiceFromVapiAssistantOptions, VoiceFromVapiAssistantResult, VoiceFromVapiCustomToolFactory, VoiceFromVapiCustomToolInput, VoiceFromVapiDTMFFactory, VoiceFromVapiKnowledgeBase, VoiceFromVapiModelFactory, VoiceFromVapiModelFactoryInput, VoiceFromVapiRouteHints, VoiceFromVapiUnsupportedReason, } from "./vapiAdapter";
75
77
  export type { VoiceApiRequestToolArgs, VoiceApiRequestToolFetch, VoiceApiRequestToolHttpMethod, VoiceApiRequestToolOptions, VoiceApiRequestToolResult, VoiceDTMFToolArgs, VoiceDTMFToolOptions, VoiceDTMFToolResult, VoiceEndCallToolArgs, VoiceEndCallToolOptions, VoiceEndCallToolResult, VoiceTransferCallToolArgs, VoiceTransferCallToolDestination, VoiceTransferCallToolOptions, VoiceTransferCallToolResult, VoiceVoicemailDetectionToolArgs, VoiceVoicemailDetectionToolOptions, VoiceVoicemailDetectionToolResult, } from "./agentTools";
76
78
  export { assertVoiceAgentSquadContractEvidence, assertVoiceAgentSquadContract, evaluateVoiceAgentSquadContractEvidence, runVoiceAgentSquadContract, } from "./agentSquadContract";
77
79
  export { createVoiceToolIdempotencyKey, createVoiceToolRuntime, } from "./toolRuntime";
package/dist/index.js CHANGED
@@ -34851,6 +34851,280 @@ var createVoiceApiRequestTool = (options) => {
34851
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
34852
  });
34853
34853
  };
34854
+ // src/vapiAdapter.ts
34855
+ var VAPI_BUILT_IN_VARIABLES = {
34856
+ date: () => new Date().toISOString().slice(0, 10),
34857
+ now: () => new Date().toISOString(),
34858
+ time: () => new Date().toISOString().slice(11, 19)
34859
+ };
34860
+ var VAPI_TEMPLATE_REGEX = /\{\{\s*([^}|]+?)\s*(?:\|[^}]*)?\}\}/g;
34861
+ var VAPI_TEMPLATE_FILTER_REGEX = /\{\{[^}]*\|[^}]*\}\}/;
34862
+ var extractSystemPrompt = (model, fallback) => {
34863
+ if (model?.systemPrompt)
34864
+ return model.systemPrompt;
34865
+ const systemMessage = model?.messages?.find((message) => message.role === "system" && typeof message.content === "string");
34866
+ if (systemMessage?.content)
34867
+ return systemMessage.content;
34868
+ return fallback;
34869
+ };
34870
+ var compileVapiSystem = (template, variableResolver) => {
34871
+ if (!template)
34872
+ return;
34873
+ if (!VAPI_TEMPLATE_REGEX.test(template)) {
34874
+ return template;
34875
+ }
34876
+ VAPI_TEMPLATE_REGEX.lastIndex = 0;
34877
+ return (input) => template.replace(VAPI_TEMPLATE_REGEX, (match, rawPath) => {
34878
+ const path = rawPath.trim();
34879
+ const builtIn = VAPI_BUILT_IN_VARIABLES[path];
34880
+ if (builtIn) {
34881
+ return builtIn({ context: input.context, session: input.session });
34882
+ }
34883
+ if (variableResolver) {
34884
+ const resolved = variableResolver(path, input);
34885
+ if (resolved !== undefined)
34886
+ return String(resolved);
34887
+ }
34888
+ return match;
34889
+ });
34890
+ };
34891
+ var httpMethodFor = (raw) => {
34892
+ const upper = (raw ?? "GET").toUpperCase();
34893
+ if (upper === "GET" || upper === "POST" || upper === "PUT" || upper === "DELETE" || upper === "PATCH") {
34894
+ return upper;
34895
+ }
34896
+ return "GET";
34897
+ };
34898
+ var buildToolFromVapi = (raw, options, unsupported) => {
34899
+ const type = raw.type ?? "function";
34900
+ if (type === "endCall") {
34901
+ return createVoiceEndCallTool({
34902
+ description: raw.function?.description ?? raw.description,
34903
+ name: raw.function?.name ?? "endCall"
34904
+ });
34905
+ }
34906
+ if (type === "transferCall") {
34907
+ const destinations = (raw.destinations ?? []).map((entry, index) => {
34908
+ const target = entry.number ?? entry.sipUri;
34909
+ if (!target)
34910
+ return;
34911
+ return {
34912
+ description: entry.description,
34913
+ id: target.replace(/[^a-zA-Z0-9_-]/g, "-") || `destination-${String(index)}`,
34914
+ message: entry.message,
34915
+ metadata: entry.metadata,
34916
+ target
34917
+ };
34918
+ }).filter((entry) => entry !== undefined);
34919
+ if (destinations.length === 0) {
34920
+ unsupported.push({
34921
+ detail: "transferCall tool has no usable destinations (need number or sipUri).",
34922
+ field: "tools[].destinations"
34923
+ });
34924
+ return;
34925
+ }
34926
+ return createVoiceTransferCallTool({
34927
+ description: raw.function?.description ?? raw.description,
34928
+ destinations,
34929
+ name: raw.function?.name ?? "transferCall"
34930
+ });
34931
+ }
34932
+ if (type === "dtmf") {
34933
+ const send = options.dtmfSendFactory?.({ raw });
34934
+ if (!send) {
34935
+ unsupported.push({
34936
+ detail: "dtmf tool requires a dtmfSendFactory to map to the telephony adapter.",
34937
+ field: "tools[].type=dtmf"
34938
+ });
34939
+ return;
34940
+ }
34941
+ return createVoiceDTMFTool({
34942
+ description: raw.function?.description ?? raw.description,
34943
+ name: raw.function?.name ?? "sendDTMF",
34944
+ send
34945
+ });
34946
+ }
34947
+ if (type === "voicemail") {
34948
+ return createVoiceVoicemailDetectionTool({
34949
+ description: raw.function?.description ?? raw.description,
34950
+ name: raw.function?.name ?? "markVoicemail"
34951
+ });
34952
+ }
34953
+ if (type === "apiRequest") {
34954
+ if (!raw.url) {
34955
+ unsupported.push({
34956
+ detail: "apiRequest tool is missing url.",
34957
+ field: "tools[].url"
34958
+ });
34959
+ return;
34960
+ }
34961
+ return createVoiceApiRequestTool({
34962
+ description: raw.function?.description ?? raw.description ?? `Call ${raw.url}`,
34963
+ fetch: options.fetch,
34964
+ headers: raw.headers,
34965
+ method: httpMethodFor(raw.method),
34966
+ name: raw.function?.name ?? raw.name ?? "apiRequest",
34967
+ parameters: raw.function?.parameters,
34968
+ url: raw.url
34969
+ });
34970
+ }
34971
+ if (type === "query") {
34972
+ if (!options.knowledgeBase) {
34973
+ unsupported.push({
34974
+ detail: "query tool requires a knowledgeBase option (a VoiceRAGCollectionLike).",
34975
+ field: "tools[].type=query"
34976
+ });
34977
+ return;
34978
+ }
34979
+ return createVoiceRAGTool(options.knowledgeBase.collection, {
34980
+ description: raw.function?.description ?? raw.description,
34981
+ name: raw.function?.name ?? "searchKnowledgeBase",
34982
+ ...options.knowledgeBase.toolOptions ?? {}
34983
+ });
34984
+ }
34985
+ if (type === "function") {
34986
+ if (raw.server?.url) {
34987
+ return createVoiceApiRequestTool({
34988
+ description: raw.function?.description ?? raw.description ?? `Custom function tool (server: ${raw.server.url}).`,
34989
+ fetch: options.fetch,
34990
+ headers: raw.server.headers,
34991
+ method: "POST",
34992
+ name: raw.function?.name ?? raw.name ?? "customFunction",
34993
+ parameters: raw.function?.parameters,
34994
+ url: raw.server.url
34995
+ });
34996
+ }
34997
+ const customTool = options.customToolFactory?.({ raw });
34998
+ if (customTool)
34999
+ return customTool;
35000
+ unsupported.push({
35001
+ detail: "function tool without server.url; provide customToolFactory to handle it.",
35002
+ field: `tools[].name=${raw.function?.name ?? raw.name ?? "<unnamed>"}`
35003
+ });
35004
+ return;
35005
+ }
35006
+ unsupported.push({
35007
+ detail: `Unrecognized Vapi tool type "${type}".`,
35008
+ field: "tools[].type"
35009
+ });
35010
+ return;
35011
+ };
35012
+ var collectRouteHints = (config) => ({
35013
+ backgroundDenoisingEnabled: config.backgroundDenoisingEnabled,
35014
+ backgroundSound: config.backgroundSound,
35015
+ endCallMessage: config.endCallMessage,
35016
+ endCallPhrases: config.endCallPhrases,
35017
+ firstMessage: config.firstMessage,
35018
+ firstMessageMode: config.firstMessageMode,
35019
+ hipaaEnabled: config.compliancePlan?.hipaaEnabled,
35020
+ maxDurationSeconds: config.maxDurationSeconds,
35021
+ pciEnabled: config.compliancePlan?.pciEnabled,
35022
+ recordingEnabled: config.recordingEnabled,
35023
+ silenceTimeoutSeconds: config.silenceTimeoutSeconds,
35024
+ stt: config.transcriber ? {
35025
+ confidenceThreshold: config.transcriber.confidenceThreshold,
35026
+ language: config.transcriber.language,
35027
+ model: config.transcriber.model,
35028
+ provider: config.transcriber.provider
35029
+ } : undefined,
35030
+ tts: config.voice ? {
35031
+ provider: config.voice.provider,
35032
+ speed: config.voice.speed,
35033
+ stability: config.voice.stability,
35034
+ style: config.voice.style,
35035
+ voiceId: config.voice.voiceId
35036
+ } : undefined,
35037
+ voicemailMessage: config.voicemailMessage
35038
+ });
35039
+ var collectAssistantLevelUnsupported = (config, unsupported, hasKnowledgeBaseOption) => {
35040
+ if (config.knowledgeBaseId && !hasKnowledgeBaseOption) {
35041
+ unsupported.push({
35042
+ detail: "knowledgeBaseId is set but no knowledgeBase option was provided; configure one to surface a query tool.",
35043
+ field: "knowledgeBaseId"
35044
+ });
35045
+ }
35046
+ if (config.voicemailDetection?.provider) {
35047
+ unsupported.push({
35048
+ detail: "voicemailDetection.provider (ML detection) has no direct voice equivalent; wire your carrier's AMD callback and call VoiceSessionHandle.markVoicemail yourself.",
35049
+ field: "voicemailDetection.provider"
35050
+ });
35051
+ }
35052
+ if (config.startSpeakingPlan) {
35053
+ unsupported.push({
35054
+ detail: "startSpeakingPlan is a route-level concern; map it to the voice() plugin / barge-in config.",
35055
+ field: "startSpeakingPlan"
35056
+ });
35057
+ }
35058
+ if (config.stopSpeakingPlan) {
35059
+ unsupported.push({
35060
+ detail: "stopSpeakingPlan is a route-level concern; map it to the voice() plugin / barge-in config.",
35061
+ field: "stopSpeakingPlan"
35062
+ });
35063
+ }
35064
+ if (config.monitorPlan) {
35065
+ unsupported.push({
35066
+ detail: "monitorPlan (listenUrl / controlUrl) has no direct voice equivalent yet; use live-ops routes for control.",
35067
+ field: "monitorPlan"
35068
+ });
35069
+ }
35070
+ if (config.firstMessageMode) {
35071
+ unsupported.push({
35072
+ detail: `firstMessageMode "${config.firstMessageMode}" is a route concern; the system/firstMessage hints are in routeHints.`,
35073
+ field: "firstMessageMode"
35074
+ });
35075
+ }
35076
+ const systemPromptText = extractSystemPrompt(config.model, undefined);
35077
+ if (systemPromptText && VAPI_TEMPLATE_FILTER_REGEX.test(systemPromptText)) {
35078
+ unsupported.push({
35079
+ detail: "system prompt uses LiquidJS filter syntax (e.g. {{ now | date: ... }}); only bare {{var}} expansion is auto-translated.",
35080
+ field: "model.messages[0].content (filters)"
35081
+ });
35082
+ }
35083
+ };
35084
+ var fromVapiAssistantConfig = (config, options) => {
35085
+ const unsupported = [];
35086
+ const model = options.modelFactory({
35087
+ model: config.model?.model,
35088
+ provider: config.model?.provider,
35089
+ raw: config.model ?? {},
35090
+ temperature: config.model?.temperature
35091
+ });
35092
+ const system = compileVapiSystem(extractSystemPrompt(config.model, options.systemFallback), options.variableResolver);
35093
+ const tools = [];
35094
+ for (const raw of config.model?.tools ?? []) {
35095
+ const tool = buildToolFromVapi(raw, options, unsupported);
35096
+ if (tool)
35097
+ tools.push(tool);
35098
+ }
35099
+ if (config.knowledgeBaseId && options.knowledgeBase) {
35100
+ const alreadyHas = tools.some((tool) => tool.name === (options.knowledgeBase.toolOptions?.name ?? "searchKnowledgeBase"));
35101
+ if (!alreadyHas) {
35102
+ tools.push(createVoiceRAGTool(options.knowledgeBase.collection, options.knowledgeBase.toolOptions));
35103
+ }
35104
+ }
35105
+ if (config.model?.toolIds && config.model.toolIds.length > 0) {
35106
+ unsupported.push({
35107
+ detail: "model.toolIds references saved Vapi tools; provide their definitions via tools[] or customToolFactory.",
35108
+ field: "model.toolIds"
35109
+ });
35110
+ }
35111
+ collectAssistantLevelUnsupported(config, unsupported, Boolean(options.knowledgeBase));
35112
+ const assistantOptions = {
35113
+ id: options.assistantId ?? "vapi-imported-assistant",
35114
+ model,
35115
+ system,
35116
+ tools
35117
+ };
35118
+ const assistant = createVoiceAssistant(assistantOptions);
35119
+ return {
35120
+ assistant,
35121
+ assistantOptions,
35122
+ modelAgent: assistant.agent,
35123
+ routeHints: collectRouteHints(config),
35124
+ tools,
35125
+ unsupported
35126
+ };
35127
+ };
34854
35128
  // src/agentSquadContract.ts
34855
35129
  var normalizeIncludes = (value) => value.trim().toLowerCase();
34856
35130
  var resolveOutcome4 = (result) => {
@@ -43341,6 +43615,7 @@ export {
43341
43615
  getLatestVoiceTelephonyMediaReport,
43342
43616
  getLatestVoiceBrowserMediaReport,
43343
43617
  getDefaultVoiceTelephonyBenchmarkScenarios,
43618
+ fromVapiAssistantConfig,
43344
43619
  formatVoiceProofTrendAge,
43345
43620
  filterVoiceTraceEvents,
43346
43621
  filterVoiceAuditEvents,
@@ -0,0 +1,160 @@
1
+ import type { VoiceAgent, VoiceAgentModel, VoiceAgentTool } from "./agent";
2
+ import { type VoiceDTMFToolOptions } from "./agentTools";
3
+ import { type VoiceAssistant, type VoiceAssistantOptions } from "./assistant";
4
+ import { type VoiceRAGCollectionLike, type VoiceRAGToolOptions } from "./ragTool";
5
+ import type { VoiceSessionRecord } from "./types";
6
+ export type VapiAssistantMessage = {
7
+ content?: string;
8
+ role?: "assistant" | "system" | "user";
9
+ };
10
+ export type VapiAssistantConfigModel = {
11
+ emotionRecognitionEnabled?: boolean;
12
+ maxTokens?: number;
13
+ messages?: readonly VapiAssistantMessage[];
14
+ model?: string;
15
+ numFastTurns?: number;
16
+ provider?: string;
17
+ systemPrompt?: string;
18
+ temperature?: number;
19
+ toolIds?: readonly string[];
20
+ tools?: readonly VapiAssistantConfigTool[];
21
+ };
22
+ export type VapiAssistantConfigVoice = {
23
+ provider?: string;
24
+ speed?: number;
25
+ stability?: number;
26
+ style?: number;
27
+ voiceId?: string;
28
+ };
29
+ export type VapiAssistantConfigTranscriber = {
30
+ confidenceThreshold?: number;
31
+ language?: string;
32
+ model?: string;
33
+ provider?: string;
34
+ };
35
+ export type VapiAssistantConfigTransferDestination = {
36
+ description?: string;
37
+ message?: string;
38
+ metadata?: Record<string, unknown>;
39
+ number?: string;
40
+ sipUri?: string;
41
+ type?: string;
42
+ };
43
+ export type VapiAssistantConfigTool = {
44
+ async?: boolean;
45
+ description?: string;
46
+ destinations?: readonly VapiAssistantConfigTransferDestination[];
47
+ function?: {
48
+ description?: string;
49
+ name?: string;
50
+ parameters?: Record<string, unknown>;
51
+ };
52
+ headers?: Record<string, string>;
53
+ knowledgeBases?: readonly string[] | readonly Record<string, unknown>[];
54
+ method?: string;
55
+ name?: string;
56
+ server?: {
57
+ headers?: Record<string, string>;
58
+ url?: string;
59
+ };
60
+ type?: string;
61
+ url?: string;
62
+ };
63
+ export type VapiAssistantConfig = {
64
+ backgroundDenoisingEnabled?: boolean;
65
+ backgroundSound?: string;
66
+ compliancePlan?: {
67
+ hipaaEnabled?: boolean;
68
+ pciEnabled?: boolean;
69
+ };
70
+ endCallMessage?: string;
71
+ endCallPhrases?: readonly string[];
72
+ firstMessage?: string;
73
+ firstMessageMode?: string;
74
+ knowledgeBaseId?: string;
75
+ maxDurationSeconds?: number;
76
+ model?: VapiAssistantConfigModel;
77
+ monitorPlan?: Record<string, unknown>;
78
+ recordingEnabled?: boolean;
79
+ silenceTimeoutSeconds?: number;
80
+ startSpeakingPlan?: Record<string, unknown>;
81
+ stopSpeakingPlan?: Record<string, unknown>;
82
+ transcriber?: VapiAssistantConfigTranscriber;
83
+ variableValues?: Record<string, unknown>;
84
+ voice?: VapiAssistantConfigVoice;
85
+ voicemailDetection?: {
86
+ provider?: string;
87
+ };
88
+ voicemailMessage?: string;
89
+ };
90
+ export type VoiceFromVapiModelFactoryInput = {
91
+ model?: string;
92
+ provider?: string;
93
+ raw: VapiAssistantConfigModel;
94
+ temperature?: number;
95
+ };
96
+ export type VoiceFromVapiModelFactory<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = (input: VoiceFromVapiModelFactoryInput) => VoiceAgentModel<TContext, TSession, TResult>;
97
+ export type VoiceFromVapiCustomToolInput = {
98
+ raw: VapiAssistantConfigTool;
99
+ };
100
+ export type VoiceFromVapiCustomToolFactory<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = (input: VoiceFromVapiCustomToolInput) => VoiceAgentTool<TContext, TSession, Record<string, unknown>, unknown, TResult> | undefined;
101
+ export type VoiceFromVapiDTMFFactory<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord> = (input: {
102
+ raw: VapiAssistantConfigTool;
103
+ }) => VoiceDTMFToolOptions<TContext, TSession>["send"] | undefined;
104
+ export type VoiceFromVapiKnowledgeBase<TContext = unknown> = {
105
+ collection: VoiceRAGCollectionLike;
106
+ toolOptions?: VoiceRAGToolOptions<TContext>;
107
+ };
108
+ export type VoiceFromVapiUnsupportedReason = {
109
+ detail: string;
110
+ field: string;
111
+ };
112
+ export type VoiceFromVapiRouteHints = {
113
+ backgroundDenoisingEnabled?: boolean;
114
+ backgroundSound?: string;
115
+ endCallMessage?: string;
116
+ endCallPhrases?: readonly string[];
117
+ firstMessage?: string;
118
+ firstMessageMode?: string;
119
+ hipaaEnabled?: boolean;
120
+ maxDurationSeconds?: number;
121
+ pciEnabled?: boolean;
122
+ recordingEnabled?: boolean;
123
+ silenceTimeoutSeconds?: number;
124
+ stt?: {
125
+ confidenceThreshold?: number;
126
+ language?: string;
127
+ model?: string;
128
+ provider?: string;
129
+ };
130
+ tts?: {
131
+ provider?: string;
132
+ speed?: number;
133
+ stability?: number;
134
+ style?: number;
135
+ voiceId?: string;
136
+ };
137
+ voicemailMessage?: string;
138
+ };
139
+ export type VoiceFromVapiAssistantOptions<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
140
+ assistantId?: string;
141
+ customToolFactory?: VoiceFromVapiCustomToolFactory<TContext, TSession, TResult>;
142
+ dtmfSendFactory?: VoiceFromVapiDTMFFactory<TContext, TSession>;
143
+ fetch?: typeof fetch;
144
+ knowledgeBase?: VoiceFromVapiKnowledgeBase<TContext>;
145
+ modelFactory: VoiceFromVapiModelFactory<TContext, TSession, TResult>;
146
+ systemFallback?: string;
147
+ variableResolver?: (path: string, input: {
148
+ context: TContext;
149
+ session: TSession;
150
+ }) => unknown;
151
+ };
152
+ export type VoiceFromVapiAssistantResult<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
153
+ assistant: VoiceAssistant<TContext, TSession, TResult>;
154
+ assistantOptions: VoiceAssistantOptions<TContext, TSession, TResult>;
155
+ modelAgent: VoiceAgent<TContext, TSession, TResult>;
156
+ routeHints: VoiceFromVapiRouteHints;
157
+ tools: ReadonlyArray<VoiceAgentTool<TContext, TSession, Record<string, unknown>, unknown, TResult>>;
158
+ unsupported: readonly VoiceFromVapiUnsupportedReason[];
159
+ };
160
+ export declare const fromVapiAssistantConfig: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown>(config: VapiAssistantConfig, options: VoiceFromVapiAssistantOptions<TContext, TSession, TResult>) => VoiceFromVapiAssistantResult<TContext, TSession, TResult>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.470",
3
+ "version": "0.0.22-beta.471",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",