@navai/voice-frontend 0.1.0 → 0.1.2

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.cjs CHANGED
@@ -25,7 +25,8 @@ __export(index_exports, {
25
25
  getNavaiRoutePromptLines: () => getNavaiRoutePromptLines,
26
26
  loadNavaiFunctions: () => loadNavaiFunctions,
27
27
  resolveNavaiFrontendRuntimeConfig: () => resolveNavaiFrontendRuntimeConfig,
28
- resolveNavaiRoute: () => resolveNavaiRoute
28
+ resolveNavaiRoute: () => resolveNavaiRoute,
29
+ useWebVoiceAgent: () => useWebVoiceAgent
29
30
  });
30
31
  module.exports = __toCommonJS(index_exports);
31
32
 
@@ -271,6 +272,8 @@ function getNavaiRoutePromptLines(routes = []) {
271
272
  }
272
273
 
273
274
  // src/agent.ts
275
+ var RESERVED_TOOL_NAMES = /* @__PURE__ */ new Set(["navigate_to", "execute_app_function"]);
276
+ var TOOL_NAME_REGEXP = /^[a-zA-Z0-9_-]{1,64}$/;
274
277
  function toErrorMessage2(error) {
275
278
  return error instanceof Error ? error.message : String(error);
276
279
  }
@@ -305,6 +308,76 @@ async function buildNavaiAgent(options) {
305
308
  ...functionsRegistry.ordered.map((item) => item.name),
306
309
  ...backendFunctionsOrdered.map((item) => item.name)
307
310
  ];
311
+ const aliasWarnings = [];
312
+ const directFunctionToolNames = [...new Set(availableFunctionNames)].map((name) => name.trim().toLowerCase()).filter((name) => {
313
+ if (!name) {
314
+ return false;
315
+ }
316
+ if (RESERVED_TOOL_NAMES.has(name)) {
317
+ aliasWarnings.push(
318
+ `[navai] Function "${name}" is available only via execute_app_function because its name conflicts with a built-in tool.`
319
+ );
320
+ return false;
321
+ }
322
+ if (!TOOL_NAME_REGEXP.test(name)) {
323
+ aliasWarnings.push(
324
+ `[navai] Function "${name}" is available only via execute_app_function because its name is not a valid tool id.`
325
+ );
326
+ return false;
327
+ }
328
+ return true;
329
+ });
330
+ const executeAppFunction = async (requestedName, payload) => {
331
+ const requested = requestedName.trim().toLowerCase();
332
+ const frontendDefinition = functionsRegistry.byName.get(requested);
333
+ if (frontendDefinition) {
334
+ try {
335
+ const result = await frontendDefinition.run(payload ?? {}, options);
336
+ return { ok: true, function_name: frontendDefinition.name, source: frontendDefinition.source, result };
337
+ } catch (error) {
338
+ return {
339
+ ok: false,
340
+ function_name: frontendDefinition.name,
341
+ error: "Function execution failed.",
342
+ details: toErrorMessage2(error)
343
+ };
344
+ }
345
+ }
346
+ const backendDefinition = backendFunctionsByName.get(requested);
347
+ if (!backendDefinition) {
348
+ return {
349
+ ok: false,
350
+ error: "Unknown or disallowed function.",
351
+ available_functions: availableFunctionNames
352
+ };
353
+ }
354
+ if (!options.executeBackendFunction) {
355
+ return {
356
+ ok: false,
357
+ function_name: backendDefinition.name,
358
+ error: "Backend function execution is not configured."
359
+ };
360
+ }
361
+ try {
362
+ const result = await options.executeBackendFunction({
363
+ functionName: backendDefinition.name,
364
+ payload: payload ?? null
365
+ });
366
+ return {
367
+ ok: true,
368
+ function_name: backendDefinition.name,
369
+ source: backendDefinition.source ?? "backend",
370
+ result
371
+ };
372
+ } catch (error) {
373
+ return {
374
+ ok: false,
375
+ function_name: backendDefinition.name,
376
+ error: "Function execution failed.",
377
+ details: toErrorMessage2(error)
378
+ };
379
+ }
380
+ };
308
381
  const navigateTool = (0, import_realtime.tool)({
309
382
  name: "navigate_to",
310
383
  description: "Navigate to an allowed route in the current app.",
@@ -329,58 +402,20 @@ async function buildNavaiAgent(options) {
329
402
  "Payload object. Use null when no arguments are needed. Use payload.args as array for function args, payload.constructorArgs for class constructors, payload.methodArgs for class methods."
330
403
  )
331
404
  }),
332
- execute: async ({ function_name, payload }) => {
333
- const requested = function_name.trim().toLowerCase();
334
- const frontendDefinition = functionsRegistry.byName.get(requested);
335
- if (frontendDefinition) {
336
- try {
337
- const result = await frontendDefinition.run(payload ?? {}, options);
338
- return { ok: true, function_name: frontendDefinition.name, source: frontendDefinition.source, result };
339
- } catch (error) {
340
- return {
341
- ok: false,
342
- function_name: frontendDefinition.name,
343
- error: "Function execution failed.",
344
- details: toErrorMessage2(error)
345
- };
346
- }
347
- }
348
- const backendDefinition = backendFunctionsByName.get(requested);
349
- if (!backendDefinition) {
350
- return {
351
- ok: false,
352
- error: "Unknown or disallowed function.",
353
- available_functions: availableFunctionNames
354
- };
355
- }
356
- if (!options.executeBackendFunction) {
357
- return {
358
- ok: false,
359
- function_name: backendDefinition.name,
360
- error: "Backend function execution is not configured."
361
- };
362
- }
363
- try {
364
- const result = await options.executeBackendFunction({
365
- functionName: backendDefinition.name,
366
- payload: payload ?? null
367
- });
368
- return {
369
- ok: true,
370
- function_name: backendDefinition.name,
371
- source: backendDefinition.source ?? "backend",
372
- result
373
- };
374
- } catch (error) {
375
- return {
376
- ok: false,
377
- function_name: backendDefinition.name,
378
- error: "Function execution failed.",
379
- details: toErrorMessage2(error)
380
- };
381
- }
382
- }
405
+ execute: async ({ function_name, payload }) => await executeAppFunction(function_name, payload)
383
406
  });
407
+ const directFunctionTools = directFunctionToolNames.map(
408
+ (functionName) => (0, import_realtime.tool)({
409
+ name: functionName,
410
+ description: `Direct alias for execute_app_function("${functionName}").`,
411
+ parameters: import_zod.z.object({
412
+ payload: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).nullable().optional().describe(
413
+ "Payload object. Optional. Use payload.args as array for function args, payload.constructorArgs for class constructors, payload.methodArgs for class methods."
414
+ )
415
+ }),
416
+ execute: async ({ payload }) => await executeAppFunction(functionName, payload ?? null)
417
+ })
418
+ );
384
419
  const routeLines = getNavaiRoutePromptLines(options.routes);
385
420
  const functionLines = functionsRegistry.ordered.length + backendFunctionsOrdered.length > 0 ? [
386
421
  ...functionsRegistry.ordered.map((item) => `- ${item.name}: ${item.description}`),
@@ -396,7 +431,7 @@ async function buildNavaiAgent(options) {
396
431
  ...functionLines,
397
432
  "Rules:",
398
433
  "- If user asks to go/open a section, always call navigate_to.",
399
- "- If user asks to run an internal action, always call execute_app_function.",
434
+ "- If user asks to run an internal action, call execute_app_function or the matching direct function tool.",
400
435
  "- Always include payload in execute_app_function. Use null when no arguments are needed.",
401
436
  "- For execute_app_function, pass arguments using payload.args (array).",
402
437
  "- For class methods, pass payload.constructorArgs and payload.methodArgs.",
@@ -406,9 +441,9 @@ async function buildNavaiAgent(options) {
406
441
  const agent = new import_realtime.RealtimeAgent({
407
442
  name: options.agentName ?? "Navai Voice Agent",
408
443
  instructions,
409
- tools: [navigateTool, executeFunctionTool]
444
+ tools: [navigateTool, executeFunctionTool, ...directFunctionTools]
410
445
  });
411
- return { agent, warnings: [...functionsRegistry.warnings, ...backendWarnings] };
446
+ return { agent, warnings: [...functionsRegistry.warnings, ...backendWarnings, ...aliasWarnings] };
412
447
  }
413
448
 
414
449
  // src/backend.ts
@@ -706,6 +741,177 @@ function readOptional2(value) {
706
741
  function toErrorMessage3(error) {
707
742
  return error instanceof Error ? error.message : String(error);
708
743
  }
744
+
745
+ // src/useWebVoiceAgent.ts
746
+ var import_realtime2 = require("@openai/agents/realtime");
747
+ var import_react = require("react");
748
+ function formatError(error) {
749
+ if (error instanceof Error) {
750
+ return error.message;
751
+ }
752
+ return String(error);
753
+ }
754
+ function emitWarnings(warnings) {
755
+ for (const warning of warnings) {
756
+ if (warning.trim().length > 0) {
757
+ console.warn(warning);
758
+ }
759
+ }
760
+ }
761
+ function useWebVoiceAgent(options) {
762
+ const sessionRef = (0, import_react.useRef)(null);
763
+ const attachedRealtimeSessionRef = (0, import_react.useRef)(null);
764
+ const runtimeConfigPromise = (0, import_react.useMemo)(
765
+ () => resolveNavaiFrontendRuntimeConfig({
766
+ moduleLoaders: options.moduleLoaders,
767
+ defaultRoutes: options.defaultRoutes,
768
+ env: options.env,
769
+ routesFile: options.routesFile,
770
+ functionsFolders: options.functionsFolders,
771
+ modelOverride: options.modelOverride,
772
+ defaultRoutesFile: options.defaultRoutesFile,
773
+ defaultFunctionsFolder: options.defaultFunctionsFolder
774
+ }),
775
+ [
776
+ options.defaultFunctionsFolder,
777
+ options.defaultRoutes,
778
+ options.defaultRoutesFile,
779
+ options.env,
780
+ options.functionsFolders,
781
+ options.modelOverride,
782
+ options.moduleLoaders,
783
+ options.routesFile
784
+ ]
785
+ );
786
+ const backendClient = (0, import_react.useMemo)(
787
+ () => createNavaiBackendClient({
788
+ ...options.apiBaseUrl ? { apiBaseUrl: options.apiBaseUrl } : {},
789
+ env: options.env
790
+ }),
791
+ [options.apiBaseUrl, options.env]
792
+ );
793
+ const [status, setStatus] = (0, import_react.useState)("idle");
794
+ const [agentVoiceState, setAgentVoiceState] = (0, import_react.useState)("idle");
795
+ const [error, setError] = (0, import_react.useState)(null);
796
+ const setAgentVoiceStateIfChanged = (0, import_react.useCallback)((next) => {
797
+ setAgentVoiceState((current) => current === next ? current : next);
798
+ }, []);
799
+ const handleSessionAudioStart = (0, import_react.useCallback)(() => {
800
+ setAgentVoiceStateIfChanged("speaking");
801
+ }, [setAgentVoiceStateIfChanged]);
802
+ const handleSessionAudioStopped = (0, import_react.useCallback)(() => {
803
+ setAgentVoiceStateIfChanged("idle");
804
+ }, [setAgentVoiceStateIfChanged]);
805
+ const handleSessionAudioInterrupted = (0, import_react.useCallback)(() => {
806
+ setAgentVoiceStateIfChanged("idle");
807
+ }, [setAgentVoiceStateIfChanged]);
808
+ const handleSessionError = (0, import_react.useCallback)(() => {
809
+ setAgentVoiceStateIfChanged("idle");
810
+ }, [setAgentVoiceStateIfChanged]);
811
+ const detachSessionAudioListeners = (0, import_react.useCallback)(() => {
812
+ const attachedSession = attachedRealtimeSessionRef.current;
813
+ if (!attachedSession) {
814
+ return;
815
+ }
816
+ attachedSession.off("audio_start", handleSessionAudioStart);
817
+ attachedSession.off("audio_stopped", handleSessionAudioStopped);
818
+ attachedSession.off("audio_interrupted", handleSessionAudioInterrupted);
819
+ attachedSession.off("error", handleSessionError);
820
+ attachedRealtimeSessionRef.current = null;
821
+ }, [handleSessionAudioInterrupted, handleSessionAudioStart, handleSessionAudioStopped, handleSessionError]);
822
+ const attachSessionAudioListeners = (0, import_react.useCallback)(
823
+ (session) => {
824
+ detachSessionAudioListeners();
825
+ session.on("audio_start", handleSessionAudioStart);
826
+ session.on("audio_stopped", handleSessionAudioStopped);
827
+ session.on("audio_interrupted", handleSessionAudioInterrupted);
828
+ session.on("error", handleSessionError);
829
+ attachedRealtimeSessionRef.current = session;
830
+ },
831
+ [
832
+ detachSessionAudioListeners,
833
+ handleSessionAudioInterrupted,
834
+ handleSessionAudioStart,
835
+ handleSessionAudioStopped,
836
+ handleSessionError
837
+ ]
838
+ );
839
+ const stop = (0, import_react.useCallback)(() => {
840
+ detachSessionAudioListeners();
841
+ try {
842
+ sessionRef.current?.close();
843
+ } finally {
844
+ sessionRef.current = null;
845
+ setStatus("idle");
846
+ setAgentVoiceStateIfChanged("idle");
847
+ }
848
+ }, [detachSessionAudioListeners, setAgentVoiceStateIfChanged]);
849
+ (0, import_react.useEffect)(() => {
850
+ return () => {
851
+ stop();
852
+ };
853
+ }, [stop]);
854
+ const start = (0, import_react.useCallback)(async () => {
855
+ if (status === "connecting" || status === "connected") {
856
+ return;
857
+ }
858
+ setError(null);
859
+ setStatus("connecting");
860
+ setAgentVoiceStateIfChanged("idle");
861
+ try {
862
+ const runtimeConfig = await runtimeConfigPromise;
863
+ const requestPayload = runtimeConfig.modelOverride ? { model: runtimeConfig.modelOverride } : {};
864
+ const secretPayload = await backendClient.createClientSecret(requestPayload);
865
+ const backendFunctionsResult = await backendClient.listFunctions();
866
+ const { agent, warnings } = await buildNavaiAgent({
867
+ navigate: options.navigate,
868
+ routes: runtimeConfig.routes,
869
+ functionModuleLoaders: runtimeConfig.functionModuleLoaders,
870
+ backendFunctions: backendFunctionsResult.functions,
871
+ executeBackendFunction: backendClient.executeFunction
872
+ });
873
+ emitWarnings([...runtimeConfig.warnings, ...backendFunctionsResult.warnings, ...warnings]);
874
+ const session = new import_realtime2.RealtimeSession(agent);
875
+ attachSessionAudioListeners(session);
876
+ if (runtimeConfig.modelOverride) {
877
+ await session.connect({ apiKey: secretPayload.value, model: runtimeConfig.modelOverride });
878
+ } else {
879
+ await session.connect({ apiKey: secretPayload.value });
880
+ }
881
+ sessionRef.current = session;
882
+ setStatus("connected");
883
+ } catch (startError) {
884
+ const message = formatError(startError);
885
+ setError(message);
886
+ setStatus("error");
887
+ setAgentVoiceStateIfChanged("idle");
888
+ detachSessionAudioListeners();
889
+ try {
890
+ sessionRef.current?.close();
891
+ } catch {
892
+ }
893
+ sessionRef.current = null;
894
+ }
895
+ }, [
896
+ attachSessionAudioListeners,
897
+ backendClient,
898
+ detachSessionAudioListeners,
899
+ options.navigate,
900
+ runtimeConfigPromise,
901
+ setAgentVoiceStateIfChanged,
902
+ status
903
+ ]);
904
+ return {
905
+ status,
906
+ agentVoiceState,
907
+ error,
908
+ isConnecting: status === "connecting",
909
+ isConnected: status === "connected",
910
+ isAgentSpeaking: agentVoiceState === "speaking",
911
+ start,
912
+ stop
913
+ };
914
+ }
709
915
  // Annotate the CommonJS export names for ESM import in node:
710
916
  0 && (module.exports = {
711
917
  buildNavaiAgent,
@@ -713,5 +919,6 @@ function toErrorMessage3(error) {
713
919
  getNavaiRoutePromptLines,
714
920
  loadNavaiFunctions,
715
921
  resolveNavaiFrontendRuntimeConfig,
716
- resolveNavaiRoute
922
+ resolveNavaiRoute,
923
+ useWebVoiceAgent
717
924
  });
package/dist/index.d.cts CHANGED
@@ -51,7 +51,7 @@ type BuildNavaiAgentResult = {
51
51
  };
52
52
  declare function buildNavaiAgent(options: BuildNavaiAgentOptions): Promise<BuildNavaiAgentResult>;
53
53
 
54
- type NavaiFrontendEnv$1 = Record<string, string | undefined>;
54
+ type NavaiFrontendEnv$2 = Record<string, string | undefined>;
55
55
  type CreateClientSecretInput = {
56
56
  model?: string;
57
57
  voice?: string;
@@ -71,7 +71,7 @@ type BackendFunctionsResult = {
71
71
  };
72
72
  type CreateNavaiBackendClientOptions = {
73
73
  apiBaseUrl?: string;
74
- env?: NavaiFrontendEnv$1;
74
+ env?: NavaiFrontendEnv$2;
75
75
  fetchImpl?: typeof fetch;
76
76
  clientSecretPath?: string;
77
77
  functionsListPath?: string;
@@ -84,11 +84,11 @@ type NavaiBackendClient = {
84
84
  };
85
85
  declare function createNavaiBackendClient(options?: CreateNavaiBackendClientOptions): NavaiBackendClient;
86
86
 
87
- type NavaiFrontendEnv = Record<string, unknown>;
87
+ type NavaiFrontendEnv$1 = Record<string, unknown>;
88
88
  type ResolveNavaiFrontendRuntimeConfigOptions = {
89
89
  moduleLoaders: NavaiFunctionModuleLoaders;
90
90
  defaultRoutes: NavaiRoute[];
91
- env?: NavaiFrontendEnv;
91
+ env?: NavaiFrontendEnv$1;
92
92
  routesFile?: string;
93
93
  functionsFolders?: string;
94
94
  modelOverride?: string;
@@ -103,4 +103,31 @@ type ResolveNavaiFrontendRuntimeConfigResult = {
103
103
  };
104
104
  declare function resolveNavaiFrontendRuntimeConfig(options: ResolveNavaiFrontendRuntimeConfigOptions): Promise<ResolveNavaiFrontendRuntimeConfigResult>;
105
105
 
106
- export { type BuildNavaiAgentOptions, type BuildNavaiAgentResult, type CreateNavaiBackendClientOptions, type ExecuteNavaiBackendFunction, type ExecuteNavaiBackendFunctionInput, type NavaiBackendClient, type NavaiBackendFunctionDefinition, type NavaiFunctionContext, type NavaiFunctionDefinition, type NavaiFunctionModuleLoaders, type NavaiFunctionPayload, type NavaiFunctionsRegistry, type NavaiRoute, type ResolveNavaiFrontendRuntimeConfigOptions, type ResolveNavaiFrontendRuntimeConfigResult, buildNavaiAgent, createNavaiBackendClient, getNavaiRoutePromptLines, loadNavaiFunctions, resolveNavaiFrontendRuntimeConfig, resolveNavaiRoute };
106
+ type VoiceStatus = "idle" | "connecting" | "connected" | "error";
107
+ type AgentVoiceState = "idle" | "speaking";
108
+ type NavaiFrontendEnv = Record<string, string | undefined>;
109
+ type UseWebVoiceAgentOptions = {
110
+ navigate: (path: string) => void;
111
+ moduleLoaders: NavaiFunctionModuleLoaders;
112
+ defaultRoutes: NavaiRoute[];
113
+ env?: NavaiFrontendEnv;
114
+ apiBaseUrl?: string;
115
+ routesFile?: string;
116
+ functionsFolders?: string;
117
+ modelOverride?: string;
118
+ defaultRoutesFile?: string;
119
+ defaultFunctionsFolder?: string;
120
+ };
121
+ type UseWebVoiceAgentResult = {
122
+ status: VoiceStatus;
123
+ agentVoiceState: AgentVoiceState;
124
+ error: string | null;
125
+ isConnecting: boolean;
126
+ isConnected: boolean;
127
+ isAgentSpeaking: boolean;
128
+ start: () => Promise<void>;
129
+ stop: () => void;
130
+ };
131
+ declare function useWebVoiceAgent(options: UseWebVoiceAgentOptions): UseWebVoiceAgentResult;
132
+
133
+ export { type BuildNavaiAgentOptions, type BuildNavaiAgentResult, type CreateNavaiBackendClientOptions, type ExecuteNavaiBackendFunction, type ExecuteNavaiBackendFunctionInput, type NavaiBackendClient, type NavaiBackendFunctionDefinition, type NavaiFunctionContext, type NavaiFunctionDefinition, type NavaiFunctionModuleLoaders, type NavaiFunctionPayload, type NavaiFunctionsRegistry, type NavaiRoute, type ResolveNavaiFrontendRuntimeConfigOptions, type ResolveNavaiFrontendRuntimeConfigResult, type UseWebVoiceAgentOptions, type UseWebVoiceAgentResult, buildNavaiAgent, createNavaiBackendClient, getNavaiRoutePromptLines, loadNavaiFunctions, resolveNavaiFrontendRuntimeConfig, resolveNavaiRoute, useWebVoiceAgent };
package/dist/index.d.ts CHANGED
@@ -51,7 +51,7 @@ type BuildNavaiAgentResult = {
51
51
  };
52
52
  declare function buildNavaiAgent(options: BuildNavaiAgentOptions): Promise<BuildNavaiAgentResult>;
53
53
 
54
- type NavaiFrontendEnv$1 = Record<string, string | undefined>;
54
+ type NavaiFrontendEnv$2 = Record<string, string | undefined>;
55
55
  type CreateClientSecretInput = {
56
56
  model?: string;
57
57
  voice?: string;
@@ -71,7 +71,7 @@ type BackendFunctionsResult = {
71
71
  };
72
72
  type CreateNavaiBackendClientOptions = {
73
73
  apiBaseUrl?: string;
74
- env?: NavaiFrontendEnv$1;
74
+ env?: NavaiFrontendEnv$2;
75
75
  fetchImpl?: typeof fetch;
76
76
  clientSecretPath?: string;
77
77
  functionsListPath?: string;
@@ -84,11 +84,11 @@ type NavaiBackendClient = {
84
84
  };
85
85
  declare function createNavaiBackendClient(options?: CreateNavaiBackendClientOptions): NavaiBackendClient;
86
86
 
87
- type NavaiFrontendEnv = Record<string, unknown>;
87
+ type NavaiFrontendEnv$1 = Record<string, unknown>;
88
88
  type ResolveNavaiFrontendRuntimeConfigOptions = {
89
89
  moduleLoaders: NavaiFunctionModuleLoaders;
90
90
  defaultRoutes: NavaiRoute[];
91
- env?: NavaiFrontendEnv;
91
+ env?: NavaiFrontendEnv$1;
92
92
  routesFile?: string;
93
93
  functionsFolders?: string;
94
94
  modelOverride?: string;
@@ -103,4 +103,31 @@ type ResolveNavaiFrontendRuntimeConfigResult = {
103
103
  };
104
104
  declare function resolveNavaiFrontendRuntimeConfig(options: ResolveNavaiFrontendRuntimeConfigOptions): Promise<ResolveNavaiFrontendRuntimeConfigResult>;
105
105
 
106
- export { type BuildNavaiAgentOptions, type BuildNavaiAgentResult, type CreateNavaiBackendClientOptions, type ExecuteNavaiBackendFunction, type ExecuteNavaiBackendFunctionInput, type NavaiBackendClient, type NavaiBackendFunctionDefinition, type NavaiFunctionContext, type NavaiFunctionDefinition, type NavaiFunctionModuleLoaders, type NavaiFunctionPayload, type NavaiFunctionsRegistry, type NavaiRoute, type ResolveNavaiFrontendRuntimeConfigOptions, type ResolveNavaiFrontendRuntimeConfigResult, buildNavaiAgent, createNavaiBackendClient, getNavaiRoutePromptLines, loadNavaiFunctions, resolveNavaiFrontendRuntimeConfig, resolveNavaiRoute };
106
+ type VoiceStatus = "idle" | "connecting" | "connected" | "error";
107
+ type AgentVoiceState = "idle" | "speaking";
108
+ type NavaiFrontendEnv = Record<string, string | undefined>;
109
+ type UseWebVoiceAgentOptions = {
110
+ navigate: (path: string) => void;
111
+ moduleLoaders: NavaiFunctionModuleLoaders;
112
+ defaultRoutes: NavaiRoute[];
113
+ env?: NavaiFrontendEnv;
114
+ apiBaseUrl?: string;
115
+ routesFile?: string;
116
+ functionsFolders?: string;
117
+ modelOverride?: string;
118
+ defaultRoutesFile?: string;
119
+ defaultFunctionsFolder?: string;
120
+ };
121
+ type UseWebVoiceAgentResult = {
122
+ status: VoiceStatus;
123
+ agentVoiceState: AgentVoiceState;
124
+ error: string | null;
125
+ isConnecting: boolean;
126
+ isConnected: boolean;
127
+ isAgentSpeaking: boolean;
128
+ start: () => Promise<void>;
129
+ stop: () => void;
130
+ };
131
+ declare function useWebVoiceAgent(options: UseWebVoiceAgentOptions): UseWebVoiceAgentResult;
132
+
133
+ export { type BuildNavaiAgentOptions, type BuildNavaiAgentResult, type CreateNavaiBackendClientOptions, type ExecuteNavaiBackendFunction, type ExecuteNavaiBackendFunctionInput, type NavaiBackendClient, type NavaiBackendFunctionDefinition, type NavaiFunctionContext, type NavaiFunctionDefinition, type NavaiFunctionModuleLoaders, type NavaiFunctionPayload, type NavaiFunctionsRegistry, type NavaiRoute, type ResolveNavaiFrontendRuntimeConfigOptions, type ResolveNavaiFrontendRuntimeConfigResult, type UseWebVoiceAgentOptions, type UseWebVoiceAgentResult, buildNavaiAgent, createNavaiBackendClient, getNavaiRoutePromptLines, loadNavaiFunctions, resolveNavaiFrontendRuntimeConfig, resolveNavaiRoute, useWebVoiceAgent };