@alexkroman1/aai 0.12.3 → 1.0.3

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.
Files changed (135) hide show
  1. package/.turbo/turbo-build.log +20 -0
  2. package/CHANGELOG.md +176 -0
  3. package/dist/constants-VTFoymJ-.js +47 -0
  4. package/dist/host/_run-code.d.ts +1 -1
  5. package/dist/host/_runtime-conformance.d.ts +4 -5
  6. package/dist/host/builtin-tools.d.ts +11 -9
  7. package/dist/host/runtime-barrel.d.ts +15 -0
  8. package/dist/{direct-executor-DRRrZUp0.js → host/runtime-barrel.js} +453 -348
  9. package/dist/host/runtime-config.d.ts +42 -0
  10. package/dist/host/runtime.d.ts +119 -35
  11. package/dist/host/s2s.d.ts +14 -38
  12. package/dist/host/server.d.ts +16 -8
  13. package/dist/host/session-ctx.d.ts +55 -0
  14. package/dist/host/session.d.ts +20 -70
  15. package/dist/host/tool-executor.d.ts +20 -0
  16. package/dist/host/unstorage-kv.d.ts +1 -1
  17. package/dist/host/ws-handler.d.ts +4 -2
  18. package/dist/index.d.ts +9 -20
  19. package/dist/index.js +63 -2
  20. package/dist/{isolate → sdk}/_internal-types.d.ts +5 -9
  21. package/dist/{isolate → sdk}/constants.d.ts +6 -4
  22. package/dist/sdk/define.d.ts +66 -0
  23. package/dist/{isolate → sdk}/kv.d.ts +1 -49
  24. package/dist/sdk/manifest-barrel.d.ts +8 -0
  25. package/dist/sdk/manifest-barrel.js +52 -0
  26. package/dist/sdk/manifest.d.ts +50 -0
  27. package/dist/{isolate → sdk}/protocol.d.ts +59 -36
  28. package/dist/sdk/protocol.js +163 -0
  29. package/dist/{isolate → sdk}/system-prompt.d.ts +2 -2
  30. package/dist/sdk/types.d.ts +201 -0
  31. package/dist/sdk/ws-upgrade.d.ts +5 -0
  32. package/dist/{system-prompt-DYAYFW99.js → system-prompt-nik_iavo.js} +10 -10
  33. package/dist/types-Cfx_4QDK.js +39 -0
  34. package/dist/ws-upgrade-BeOQ7fXL.js +30 -0
  35. package/exports-no-dev-deps.test.ts +62 -0
  36. package/host/_mock-ws.ts +185 -0
  37. package/host/_run-code.ts +217 -0
  38. package/host/_runtime-conformance.ts +143 -0
  39. package/host/_test-utils.ts +276 -0
  40. package/host/builtin-tools.test.ts +774 -0
  41. package/host/builtin-tools.ts +255 -0
  42. package/host/cleanup.test.ts +422 -0
  43. package/host/fixture-replay.test.ts +463 -0
  44. package/host/fixtures/README.md +40 -0
  45. package/host/fixtures/greeting-session-sequence.json +40 -0
  46. package/host/fixtures/reply-audio-samples.json +42 -0
  47. package/host/fixtures/reply-lifecycle.json +21 -0
  48. package/host/fixtures/session-ready.json +48 -0
  49. package/host/fixtures/session-updated.json +45 -0
  50. package/host/fixtures/simple-question-sequence.json +73 -0
  51. package/host/fixtures/tool-call-sequence.json +114 -0
  52. package/host/fixtures/tool-calls.json +11 -0
  53. package/host/fixtures/tool-config-session-sequence.json +51 -0
  54. package/host/fixtures/user-speech-recognition.json +30 -0
  55. package/host/fixtures/web-search-sequence.json +122 -0
  56. package/host/integration.test.ts +222 -0
  57. package/host/runtime-barrel.ts +25 -0
  58. package/host/runtime-config.test.ts +71 -0
  59. package/host/runtime-config.ts +99 -0
  60. package/host/runtime.test.ts +641 -0
  61. package/host/runtime.ts +308 -0
  62. package/host/s2s-fixtures.test.ts +237 -0
  63. package/host/s2s.test.ts +562 -0
  64. package/host/s2s.ts +310 -0
  65. package/host/server-shutdown.test.ts +76 -0
  66. package/host/server.test.ts +116 -0
  67. package/host/server.ts +223 -0
  68. package/host/session-ctx.ts +107 -0
  69. package/host/session-fixture-replay.test.ts +136 -0
  70. package/host/session-prompt.test.ts +77 -0
  71. package/host/session.test.ts +590 -0
  72. package/host/session.ts +370 -0
  73. package/host/tool-executor.test.ts +124 -0
  74. package/host/tool-executor.ts +80 -0
  75. package/host/unstorage-kv.test.ts +99 -0
  76. package/host/unstorage-kv.ts +69 -0
  77. package/host/ws-handler.test.ts +739 -0
  78. package/host/ws-handler.ts +255 -0
  79. package/index.ts +16 -0
  80. package/package.json +24 -72
  81. package/sdk/_internal-types.test.ts +34 -0
  82. package/sdk/_internal-types.ts +115 -0
  83. package/sdk/compat-fixtures/README.md +26 -0
  84. package/sdk/compat-fixtures/v1.json +68 -0
  85. package/sdk/constants.ts +77 -0
  86. package/sdk/define.test.ts +57 -0
  87. package/sdk/define.ts +88 -0
  88. package/sdk/kv.ts +60 -0
  89. package/sdk/manifest-barrel.ts +12 -0
  90. package/sdk/manifest.test.ts +56 -0
  91. package/sdk/manifest.ts +89 -0
  92. package/sdk/protocol-compat.test.ts +187 -0
  93. package/sdk/protocol-snapshot.test.ts +199 -0
  94. package/sdk/protocol.test.ts +170 -0
  95. package/sdk/protocol.ts +223 -0
  96. package/sdk/schema-alignment.test.ts +191 -0
  97. package/sdk/system-prompt.test.ts +111 -0
  98. package/sdk/system-prompt.ts +74 -0
  99. package/sdk/tsconfig.json +12 -0
  100. package/sdk/types-inference.test.ts +122 -0
  101. package/sdk/types.test.ts +14 -0
  102. package/sdk/types.ts +226 -0
  103. package/sdk/utils.test.ts +52 -0
  104. package/sdk/utils.ts +20 -0
  105. package/sdk/ws-upgrade.test.ts +48 -0
  106. package/sdk/ws-upgrade.ts +13 -0
  107. package/tsconfig.build.json +14 -0
  108. package/tsconfig.json +10 -0
  109. package/tsdown.config.ts +26 -0
  110. package/vitest.config.ts +17 -0
  111. package/dist/host/_test-utils.d.ts +0 -73
  112. package/dist/host/direct-executor.d.ts +0 -130
  113. package/dist/host/index.d.ts +0 -19
  114. package/dist/host/index.js +0 -165
  115. package/dist/host/matchers.d.ts +0 -20
  116. package/dist/host/matchers.js +0 -41
  117. package/dist/host/server.js +0 -164
  118. package/dist/host/testing.d.ts +0 -294
  119. package/dist/host/testing.js +0 -2
  120. package/dist/host/vite-plugin.d.ts +0 -15
  121. package/dist/host/vite-plugin.js +0 -83
  122. package/dist/isolate/_kv-utils.d.ts +0 -10
  123. package/dist/isolate/_utils.js +0 -17
  124. package/dist/isolate/hooks.d.ts +0 -44
  125. package/dist/isolate/hooks.js +0 -58
  126. package/dist/isolate/index.d.ts +0 -18
  127. package/dist/isolate/index.js +0 -6
  128. package/dist/isolate/kv.js +0 -1
  129. package/dist/isolate/protocol.js +0 -2
  130. package/dist/isolate/types.d.ts +0 -418
  131. package/dist/isolate/types.js +0 -175
  132. package/dist/protocol-rcOrz7T3.js +0 -183
  133. package/dist/testing-BreLdpq-.js +0 -513
  134. package/dist/types.test-d.d.ts +0 -7
  135. /package/dist/{isolate/_utils.d.ts → sdk/utils.d.ts} +0 -0
@@ -1,15 +0,0 @@
1
- /**
2
- * Vite plugin for AAI agent development.
3
- *
4
- * In dev mode: boots the agent backend server and configures proxy.
5
- * Handles .env loading, runtime creation, and WebSocket proxying
6
- * so `vite` alone gives you a working dev server.
7
- */
8
- import type { Plugin } from "vite";
9
- export type AaiPluginOptions = {
10
- /** Path to agent entry (default: "agent.ts") */
11
- agent?: string;
12
- /** Backend port (default: Vite port + 1) */
13
- backendPort?: number;
14
- };
15
- export declare function aai(options?: AaiPluginOptions): Plugin;
@@ -1,83 +0,0 @@
1
- import path from "node:path";
2
- import fs from "node:fs/promises";
3
- //#region host/vite-plugin.ts
4
- /**
5
- * Vite plugin for AAI agent development.
6
- *
7
- * In dev mode: boots the agent backend server and configures proxy.
8
- * Handles .env loading, runtime creation, and WebSocket proxying
9
- * so `vite` alone gives you a working dev server.
10
- */
11
- function parseEnvFile(content) {
12
- const entries = {};
13
- for (const raw of content.split("\n")) {
14
- const line = raw.trim();
15
- if (!line || line.startsWith("#")) continue;
16
- const eq = line.indexOf("=");
17
- if (eq === -1) continue;
18
- const key = line.slice(0, eq).trim();
19
- if (key) entries[key] = line.slice(eq + 1);
20
- }
21
- return entries;
22
- }
23
- async function resolveAgentEnv(root) {
24
- let fileEntries = {};
25
- try {
26
- fileEntries = parseEnvFile(await fs.readFile(path.join(root, ".env"), "utf-8"));
27
- } catch {}
28
- const env = {};
29
- for (const [key, fileVal] of Object.entries(fileEntries)) env[key] = process.env[key] ?? fileVal;
30
- if (!env.ASSEMBLYAI_API_KEY && process.env.ASSEMBLYAI_API_KEY) env.ASSEMBLYAI_API_KEY = process.env.ASSEMBLYAI_API_KEY;
31
- return env;
32
- }
33
- function aai(options) {
34
- const agentEntry = options?.agent ?? "agent.ts";
35
- let backendPort = options?.backendPort;
36
- let server = null;
37
- return {
38
- name: "aai",
39
- apply: "serve",
40
- config(config) {
41
- const vitePort = config.server?.port ?? 3e3;
42
- const envPort = Number(process.env.AAI_BACKEND_PORT);
43
- backendPort = backendPort ?? (envPort > 0 ? envPort : vitePort + 1);
44
- const target = `http://localhost:${backendPort}`;
45
- return { server: { proxy: {
46
- "/health": target,
47
- "/websocket": {
48
- target,
49
- ws: true
50
- }
51
- } } };
52
- },
53
- async configureServer(viteServer) {
54
- const root = viteServer.config.root;
55
- const agentPath = path.resolve(root, agentEntry);
56
- const { createRuntime, createServer } = await import("./server.js");
57
- const agentDef = (await viteServer.ssrLoadModule(agentPath)).default;
58
- if (!agentDef?.name) {
59
- viteServer.config.logger.error("agent.ts must export a default defineAgent() call");
60
- return;
61
- }
62
- const agentServer = createServer({
63
- runtime: createRuntime({
64
- agent: agentDef,
65
- env: await resolveAgentEnv(root)
66
- }),
67
- name: agentDef.name
68
- });
69
- if (backendPort == null) throw new Error("backendPort was not resolved during config phase");
70
- await agentServer.listen(backendPort);
71
- server = agentServer;
72
- viteServer.config.logger.info(`Agent backend on port ${backendPort}`);
73
- },
74
- async buildEnd() {
75
- if (server) {
76
- await server.close();
77
- server = null;
78
- }
79
- }
80
- };
81
- }
82
- //#endregion
83
- export { aai };
@@ -1,10 +0,0 @@
1
- /** Internal KV helpers shared by kv.ts and unstorage-kv.ts. */
2
- /** Sort entries by key and apply reverse/limit options. Mutates the array. */
3
- export declare function sortAndPaginate<T extends {
4
- key: string;
5
- }>(entries: T[], options?: {
6
- limit?: number;
7
- reverse?: boolean;
8
- }): T[];
9
- /** Simple glob matcher — supports `*` as a wildcard for any characters. */
10
- export declare function matchGlob(key: string, pattern: string): boolean;
@@ -1,17 +0,0 @@
1
- //#region isolate/_utils.ts
2
- /** Shared utility functions. */
3
- /** Extract an error message from an unknown thrown value. */
4
- function errorMessage(err) {
5
- return err instanceof Error ? err.message : String(err);
6
- }
7
- /** Extract a detailed error string (message + stack) for diagnostic logging. */
8
- function errorDetail(err) {
9
- if (err instanceof Error) return err.stack ?? err.message;
10
- return String(err);
11
- }
12
- /** Return a JSON error string for the LLM: `'{"error":"<message>"}'`. */
13
- function toolError(message) {
14
- return JSON.stringify({ error: message });
15
- }
16
- //#endregion
17
- export { errorDetail, errorMessage, toolError };
@@ -1,44 +0,0 @@
1
- /**
2
- * Hookable-based lifecycle hook system.
3
- *
4
- * Provides a unified hook registry built on {@link https://github.com/unjs/hookable | hookable}.
5
- * Lifecycle hooks (connect, disconnect, turn, error, resolveTurnConfig) are
6
- * registered on a single `Hookable<AgentHookMap>` instance.
7
- */
8
- import { type Hookable } from "hookable";
9
- import type { AgentDef, HookContext } from "./types.ts";
10
- /**
11
- * Map of all agent hook names to their function signatures.
12
- *
13
- * All hooks are typed as void-returning for hookable compatibility.
14
- * Value-returning hooks (resolveTurnConfig) are invoked via
15
- * {@link callHookWith} with a custom caller that extracts the return value.
16
- */
17
- export interface AgentHookMap {
18
- connect: (sessionId: string, timeoutMs?: number) => void | Promise<void>;
19
- disconnect: (sessionId: string, timeoutMs?: number) => void | Promise<void>;
20
- turn: (sessionId: string, text: string, timeoutMs?: number) => void | Promise<void>;
21
- error: (sessionId: string, error: {
22
- message: string;
23
- }, timeoutMs?: number) => void | Promise<void>;
24
- resolveTurnConfig: (sessionId: string, timeoutMs?: number) => void | Promise<void>;
25
- }
26
- /** A hookable instance typed to the agent hook map. */
27
- export type AgentHooks = Hookable<AgentHookMap>;
28
- /**
29
- * Call the resolveTurnConfig hook.
30
- * Returns null when no handler is registered.
31
- */
32
- export declare function callResolveTurnConfig(hooks: AgentHooks | undefined, sessionId: string, timeoutMs?: number): Promise<{
33
- maxSteps?: number;
34
- } | null>;
35
- /**
36
- * Create an {@link AgentHooks} instance from an agent definition.
37
- *
38
- * Registers lifecycle hooks from the agent's `onConnect`, `onDisconnect`,
39
- * `onTurn`, `onError` callbacks.
40
- */
41
- export declare function createAgentHooks(opts: {
42
- agent: AgentDef<any>;
43
- makeCtx: (sessionId: string) => HookContext;
44
- }): AgentHooks;
@@ -1,58 +0,0 @@
1
- import { createHooks } from "hookable";
2
- //#region isolate/hooks.ts
3
- /**
4
- * Hookable-based lifecycle hook system.
5
- *
6
- * Provides a unified hook registry built on {@link https://github.com/unjs/hookable | hookable}.
7
- * Lifecycle hooks (connect, disconnect, turn, error, resolveTurnConfig) are
8
- * registered on a single `Hookable<AgentHookMap>` instance.
9
- */
10
- /**
11
- * Caller that invokes the first registered handler and returns its result.
12
- * Returns `fallback` when no handlers are registered.
13
- */
14
- function firstResultCaller(fallback) {
15
- return async (fns, args) => {
16
- if (fns.length === 0) return fallback;
17
- return await fns[0](...args) ?? fallback;
18
- };
19
- }
20
- /**
21
- * Call the resolveTurnConfig hook.
22
- * Returns null when no handler is registered.
23
- */
24
- async function callResolveTurnConfig(hooks, sessionId, timeoutMs) {
25
- if (!hooks) return null;
26
- return hooks.callHookWith(firstResultCaller(null), "resolveTurnConfig", [sessionId, timeoutMs]);
27
- }
28
- /**
29
- * Create an {@link AgentHooks} instance from an agent definition.
30
- *
31
- * Registers lifecycle hooks from the agent's `onConnect`, `onDisconnect`,
32
- * `onTurn`, `onError` callbacks.
33
- */
34
- function createAgentHooks(opts) {
35
- const { agent, makeCtx } = opts;
36
- const hooks = createHooks();
37
- hooks.hook("connect", async (sessionId) => {
38
- await agent.onConnect?.(makeCtx(sessionId));
39
- });
40
- hooks.hook("disconnect", async (sessionId) => {
41
- await agent.onDisconnect?.(makeCtx(sessionId));
42
- });
43
- hooks.hook("turn", async (sessionId, text) => {
44
- await agent.onTurn?.(text, makeCtx(sessionId));
45
- });
46
- hooks.hook("error", async (sessionId, error) => {
47
- await agent.onError?.(new Error(error.message), makeCtx(sessionId));
48
- });
49
- hooks.hook("resolveTurnConfig", (async (sessionId) => {
50
- const ctx = makeCtx(sessionId);
51
- const maxSteps = typeof agent.maxSteps === "function" ? await agent.maxSteps(ctx) ?? void 0 : void 0;
52
- if (maxSteps === void 0) return null;
53
- return { maxSteps };
54
- }));
55
- return hooks;
56
- }
57
- //#endregion
58
- export { callResolveTurnConfig, createAgentHooks };
@@ -1,18 +0,0 @@
1
- /**
2
- * Isolate-safe barrel — re-exports all SDK modules that are guaranteed to
3
- * run inside secure-exec V8 isolates (no `node:*` dependencies).
4
- *
5
- * This directory is compiled under a restricted `tsconfig.json` that excludes
6
- * `@types/node`. Any accidental `node:*` import becomes a type error.
7
- *
8
- * Host-only code (server, executor, S2S, etc.) lives at the package root
9
- * and is re-exported via `./host`.
10
- */
11
- export * from "./_internal-types.ts";
12
- export * from "./_utils.ts";
13
- export * from "./constants.ts";
14
- export * from "./hooks.ts";
15
- export * from "./kv.ts";
16
- export * from "./protocol.ts";
17
- export * from "./system-prompt.ts";
18
- export * from "./types.ts";
@@ -1,6 +0,0 @@
1
- import { BuiltinToolSchema, DEFAULT_GREETING, DEFAULT_INSTRUCTIONS, ToolChoiceSchema, defineAgent, defineTool, defineToolFactory } from "./types.js";
2
- import { a as agentToolsToSchemas, i as ToolSchemaSchema, n as AgentConfigSchema, o as toAgentConfig, r as EMPTY_PARAMS, t as buildSystemPrompt } from "../system-prompt-DYAYFW99.js";
3
- import { errorDetail, errorMessage, toolError } from "./_utils.js";
4
- import { C as MAX_VALUE_SIZE, S as MAX_TOOL_RESULT_CHARS, T as TOOL_EXECUTION_TIMEOUT_MS, _ as FETCH_TIMEOUT_MS, a as ReadyConfigSchema, b as MAX_HTML_BYTES, c as TurnConfigSchema, d as DEFAULT_IDLE_TIMEOUT_MS, f as DEFAULT_MAX_HISTORY, g as DEFAULT_TTS_SAMPLE_RATE, h as DEFAULT_STT_SAMPLE_RATE, i as KvRequestSchema, l as buildReadyConfig, m as DEFAULT_SHUTDOWN_TIMEOUT_MS, n as ClientEventSchema, o as ServerMessageSchema, p as DEFAULT_SESSION_START_TIMEOUT_MS, r as ClientMessageSchema, s as SessionErrorCodeSchema, t as AUDIO_FORMAT, u as AGENT_CSP, v as HOOK_TIMEOUT_MS, w as RUN_CODE_TIMEOUT_MS, x as MAX_PAGE_CHARS, y as MAX_GLOB_PATTERN_LENGTH } from "../protocol-rcOrz7T3.js";
5
- import { callResolveTurnConfig, createAgentHooks } from "./hooks.js";
6
- export { AGENT_CSP, AUDIO_FORMAT, AgentConfigSchema, BuiltinToolSchema, ClientEventSchema, ClientMessageSchema, DEFAULT_GREETING, DEFAULT_IDLE_TIMEOUT_MS, DEFAULT_INSTRUCTIONS, DEFAULT_MAX_HISTORY, DEFAULT_SESSION_START_TIMEOUT_MS, DEFAULT_SHUTDOWN_TIMEOUT_MS, DEFAULT_STT_SAMPLE_RATE, DEFAULT_TTS_SAMPLE_RATE, EMPTY_PARAMS, FETCH_TIMEOUT_MS, HOOK_TIMEOUT_MS, KvRequestSchema, MAX_GLOB_PATTERN_LENGTH, MAX_HTML_BYTES, MAX_PAGE_CHARS, MAX_TOOL_RESULT_CHARS, MAX_VALUE_SIZE, RUN_CODE_TIMEOUT_MS, ReadyConfigSchema, ServerMessageSchema, SessionErrorCodeSchema, TOOL_EXECUTION_TIMEOUT_MS, ToolChoiceSchema, ToolSchemaSchema, TurnConfigSchema, agentToolsToSchemas, buildReadyConfig, buildSystemPrompt, callResolveTurnConfig, createAgentHooks, defineAgent, defineTool, defineTool as tool, defineToolFactory, errorDetail, errorMessage, toAgentConfig, toolError };
@@ -1 +0,0 @@
1
- export {};
@@ -1,2 +0,0 @@
1
- import { a as ReadyConfigSchema, c as TurnConfigSchema, i as KvRequestSchema, l as buildReadyConfig, n as ClientEventSchema, o as ServerMessageSchema, r as ClientMessageSchema, s as SessionErrorCodeSchema, t as AUDIO_FORMAT } from "../protocol-rcOrz7T3.js";
2
- export { AUDIO_FORMAT, ClientEventSchema, ClientMessageSchema, KvRequestSchema, ReadyConfigSchema, ServerMessageSchema, SessionErrorCodeSchema, TurnConfigSchema, buildReadyConfig };
@@ -1,418 +0,0 @@
1
- /**
2
- * Core type definitions for the AAI agent SDK.
3
- */
4
- import { z } from "zod";
5
- import type { Kv } from "./kv.ts";
6
- /**
7
- * Identifier for a built-in server-side tool.
8
- *
9
- * Built-in tools run on the host process (not inside the sandboxed worker)
10
- * and provide capabilities like web search, code execution, and API access.
11
- *
12
- * - `"web_search"` — Search the web for current information, facts, or news.
13
- * - `"visit_webpage"` — Fetch a URL and return its content as clean text.
14
- * - `"fetch_json"` — Call a REST API endpoint and return the JSON response.
15
- * - `"run_code"` — Execute JavaScript in a sandbox for calculations and data processing.
16
- * - `"memory"` — Persistent KV memory: save_memory, recall_memory, list_memories, forget_memory.
17
- *
18
- * @public
19
- */
20
- export type BuiltinTool = "web_search" | "visit_webpage" | "fetch_json" | "run_code";
21
- /**
22
- * How the LLM should select tools during a turn.
23
- *
24
- * - `"auto"` — The model decides whether to call a tool.
25
- * - `"required"` — The model must call at least one tool.
26
- * - `"none"` — Tool calling is disabled.
27
- * - `{ type: "tool"; toolName: string }` — Force a specific tool.
28
- *
29
- * @public
30
- */
31
- export type ToolChoice = "auto" | "required" | "none" | {
32
- type: "tool";
33
- toolName: string;
34
- };
35
- /**
36
- * A single message in the conversation history.
37
- *
38
- * Messages are passed to tool `execute` functions via
39
- * {@link ToolContext.messages} to provide conversation context.
40
- *
41
- * @public
42
- */
43
- export type Message = {
44
- /** The role of the message sender. */
45
- role: "user" | "assistant" | "tool";
46
- /** The text content of the message. */
47
- content: string;
48
- };
49
- /**
50
- * Context passed to tool `execute` functions.
51
- *
52
- * Provides access to the session environment, state, KV store, and
53
- * conversation history from within a tool's execute handler.
54
- *
55
- * @typeParam S - The shape of per-session state created by the agent's
56
- * `state` factory. Defaults to `Record<string, unknown>`.
57
- *
58
- * @example
59
- * ```ts
60
- * import { type ToolDef } from "aai";
61
- * import { z } from "zod";
62
- *
63
- * const myTool: ToolDef = {
64
- * description: "Look up a value from the KV store",
65
- * parameters: z.object({ key: z.string() }),
66
- * execute: async ({ key }, ctx) => {
67
- * const value = await ctx.kv.get(key);
68
- * return { key, value };
69
- * },
70
- * };
71
- * ```
72
- *
73
- * @public
74
- */
75
- export type ToolContext<S = Record<string, unknown>> = {
76
- /** Environment variables declared in the agent config. */
77
- env: Readonly<Record<string, string>>;
78
- /** Mutable per-session state created by the agent's `state` factory. */
79
- state: S;
80
- /** Key-value store scoped to this agent deployment. */
81
- kv: Kv;
82
- /** Read-only snapshot of conversation messages so far. */
83
- messages: readonly Message[];
84
- /**
85
- * SSRF-safe fetch function.
86
- *
87
- * In self-hosted mode this calls the network directly (with SSRF protection).
88
- * In platform mode this is proxied through the sidecar so it works inside
89
- * the sandbox. Always use `ctx.fetch` instead of the global `fetch` in tool
90
- * code to ensure portability across both deployment modes.
91
- */
92
- fetch: typeof globalThis.fetch;
93
- /** Unique identifier for the current session. Useful for correlating logs across concurrent sessions. */
94
- sessionId: string;
95
- };
96
- /**
97
- * Context passed to lifecycle hooks.
98
- *
99
- * @typeParam S - The shape of per-session state created by the agent's
100
- * `state` factory. Defaults to `Record<string, unknown>`.
101
- *
102
- * @public
103
- */
104
- export type HookContext<S = Record<string, unknown>> = {
105
- /** Environment variables declared in the agent config. */
106
- env: Readonly<Record<string, string>>;
107
- /** Mutable per-session state created by the agent's `state` factory. */
108
- state: S;
109
- /** Key-value store scoped to this agent deployment. */
110
- kv: Kv;
111
- /**
112
- * SSRF-safe fetch function.
113
- * In self-hosted mode this calls the network directly (with SSRF protection).
114
- * In platform mode this is proxied through the sidecar.
115
- */
116
- fetch: typeof globalThis.fetch;
117
- /** Unique identifier for the current session. */
118
- sessionId: string;
119
- };
120
- /**
121
- * Definition of a custom tool that the agent can invoke.
122
- *
123
- * Tools are the primary way to extend agent capabilities. Each tool has a
124
- * description (shown to the LLM), optional Zod parameters schema, and an
125
- * `execute` function that runs inside the sandboxed worker.
126
- *
127
- * @typeParam P - A Zod object schema describing the tool's parameters.
128
- * Defaults to `ZodObject<ZodRawShape>` so tools without parameters don't need an explicit
129
- * type argument.
130
- *
131
- * @example
132
- * ```ts
133
- * import { type ToolDef } from "aai";
134
- * import { z } from "zod";
135
- *
136
- * const weatherTool: ToolDef<typeof params> = {
137
- * description: "Get current weather for a city",
138
- * parameters: z.object({
139
- * city: z.string().describe("City name"),
140
- * }),
141
- * execute: async ({ city }) => {
142
- * const res = await fetch(`https://wttr.in/${city}?format=j1`);
143
- * return await res.json();
144
- * },
145
- * };
146
- *
147
- * const params = z.object({ city: z.string() });
148
- * ```
149
- *
150
- * @public
151
- */
152
- export type ToolDef<P extends z.ZodObject<z.ZodRawShape> = z.ZodObject<z.ZodRawShape>, S = Record<string, unknown>> = {
153
- /** Human-readable description shown to the LLM. */
154
- description: string;
155
- /** Zod schema for the tool's parameters. */
156
- parameters?: P;
157
- /** Function that executes the tool and returns a result. */
158
- execute(args: z.infer<P>, ctx: ToolContext<S>): Promise<unknown> | unknown;
159
- };
160
- /**
161
- * Identity helper that preserves the Zod schema generic for type inference.
162
- *
163
- * When tools are defined inline in `defineAgent({ tools: { ... } })`, the
164
- * generic `P` gets widened to the base `ZodObject` type, so `args` in
165
- * `execute` loses its specific shape. Wrapping a tool definition in
166
- * `defineTool()` lets TypeScript infer `P` from `parameters` and type
167
- * `args` correctly.
168
- *
169
- * @example
170
- * ```ts
171
- * import { defineAgent, defineTool } from "aai";
172
- * import { z } from "zod";
173
- *
174
- * export default defineAgent({
175
- * name: "my-agent",
176
- * tools: {
177
- * greet: defineTool({
178
- * description: "Greet the user",
179
- * parameters: z.object({ name: z.string() }),
180
- * execute: ({ name }) => `Hello, ${name}!`, // name is string
181
- * }),
182
- * },
183
- * });
184
- * ```
185
- *
186
- * @public
187
- */
188
- export declare function defineTool<P extends z.ZodObject<z.ZodRawShape>, S = Record<string, unknown>>(def: ToolDef<P, S>): ToolDef<P, S>;
189
- /** Alias for {@link defineTool}. Prefer `defineTool` for clarity. */
190
- export { defineTool as tool };
191
- /**
192
- * Create a typed `defineTool` helper with the session state type baked in.
193
- *
194
- * When tools need access to typed session state, you'd normally have to write
195
- * verbose generics on every `defineTool` call. `defineToolFactory` eliminates
196
- * that boilerplate by returning a `defineTool` variant that already knows `S`.
197
- *
198
- * @example
199
- * ```ts
200
- * import { defineToolFactory, defineAgent } from "aai";
201
- * import { z } from "zod";
202
- *
203
- * interface PortfolioState { holdings: Map<string, number> }
204
- *
205
- * const tool = defineToolFactory<PortfolioState>();
206
- *
207
- * export default defineAgent<PortfolioState>({
208
- * name: "portfolio",
209
- * state: () => ({ holdings: new Map() }),
210
- * tools: {
211
- * buy: tool({
212
- * description: "Buy shares",
213
- * parameters: z.object({ symbol: z.string(), qty: z.number() }),
214
- * execute: (args, ctx) => {
215
- * // args.symbol is string, ctx.state is PortfolioState
216
- * ctx.state.holdings.set(args.symbol, args.qty);
217
- * },
218
- * }),
219
- * },
220
- * });
221
- * ```
222
- *
223
- * @public
224
- */
225
- export declare function defineToolFactory<S = Record<string, unknown>>(): <P extends z.ZodObject<z.ZodRawShape>>(def: ToolDef<P, S>) => ToolDef<P, S>;
226
- /**
227
- * A mapping of tool names to their result types.
228
- *
229
- * Define this in a shared file (e.g. `shared.ts`) that both `agent.ts` and
230
- * `client.tsx` can import, so tool result types stay in sync without
231
- * duplication.
232
- *
233
- * @example
234
- * ```ts
235
- * // shared.ts
236
- * import type { ToolResultMap } from "@alexkroman1/aai";
237
- *
238
- * export interface Pizza {
239
- * id: number;
240
- * size: "small" | "medium" | "large";
241
- * toppings: string[];
242
- * }
243
- *
244
- * export type MyToolResults = ToolResultMap<{
245
- * add_pizza: { added: Pizza; orderTotal: string };
246
- * place_order: { orderNumber: number; total: string };
247
- * }>;
248
- * ```
249
- *
250
- * Then use with {@link @alexkroman1/aai-ui#useToolResult | useToolResult}:
251
- *
252
- * ```tsx
253
- * // client.tsx
254
- * import type { MyToolResults } from "./shared.ts";
255
- *
256
- * useToolResult<MyToolResults["add_pizza"]>("add_pizza", (result) => {
257
- * console.log(result.added); // fully typed
258
- * });
259
- * ```
260
- *
261
- * @public
262
- */
263
- export type ToolResultMap<T extends Record<string, unknown> = Record<string, unknown>> = T;
264
- /**
265
- * Options passed to {@link defineAgent} to configure an agent.
266
- *
267
- * Only `name` is required; all other fields have sensible defaults.
268
- *
269
- * @typeParam S - The shape of per-session state returned by the `state`
270
- * factory. Defaults to `Record<string, unknown>`.
271
- *
272
- * @example
273
- * ```ts
274
- * import { defineAgent } from "aai";
275
- * import { z } from "zod";
276
- *
277
- * export default defineAgent({
278
- * name: "research-bot",
279
- * instructions: "You help users research topics.",
280
- * builtinTools: ["web_search"],
281
- * tools: {
282
- * summarize: {
283
- * description: "Summarize text",
284
- * parameters: z.object({ text: z.string() }),
285
- * execute: ({ text }) => text.slice(0, 200) + "...",
286
- * },
287
- * },
288
- * });
289
- * ```
290
- *
291
- * @public
292
- */
293
- export type AgentOptions<S = Record<string, unknown>> = {
294
- /** Display name for the agent. */
295
- name: string;
296
- /** System prompt for the LLM. Defaults to a built-in voice-optimized prompt. */
297
- instructions?: string;
298
- /** Initial spoken greeting when a session starts. */
299
- greeting?: string;
300
- /** Prompt hint for the STT model to improve transcription accuracy. */
301
- sttPrompt?: string;
302
- /**
303
- * Maximum agentic loop iterations per turn. Can be a static number or
304
- * a function that receives the hook context and returns a number.
305
- *
306
- * @defaultValue 5
307
- */
308
- maxSteps?: number | ((ctx: HookContext<S>) => number);
309
- /** How the LLM should choose tools. */
310
- toolChoice?: ToolChoice;
311
- /** Built-in tools to enable (e.g. `"web_search"`, `"run_code"`). */
312
- builtinTools?: readonly BuiltinTool[];
313
- /** Custom tools the agent can invoke. */
314
- tools?: Readonly<Record<string, ToolDef<z.ZodObject<z.ZodRawShape>, NoInfer<S>>>>;
315
- /** Factory that creates fresh per-session state. Called once per connection. */
316
- state?: () => S;
317
- /** Called when a new session connects. */
318
- onConnect?: (ctx: HookContext<S>) => void | Promise<void>;
319
- /** Called when a session disconnects. */
320
- onDisconnect?: (ctx: HookContext<S>) => void | Promise<void>;
321
- /** Called when an unhandled error occurs. */
322
- onError?: (error: Error, ctx?: HookContext<S>) => void;
323
- /** Called after a complete turn (all steps finished). */
324
- onTurn?: (text: string, ctx: HookContext<S>) => void | Promise<void>;
325
- /**
326
- * Close the S2S connection after this many milliseconds of inactivity.
327
- * Inactivity means no audio, transcripts, or tool calls in either direction.
328
- * When the timeout fires the session is stopped and the client receives an
329
- * `idle_timeout` event.
330
- *
331
- * Set to `0` or `Infinity` to disable.
332
- *
333
- * @defaultValue 300_000 (5 minutes)
334
- */
335
- idleTimeoutMs?: number;
336
- };
337
- /**
338
- * Default system prompt used when `instructions` is not provided.
339
- *
340
- * Optimized for voice-first interactions: short sentences, no visual
341
- * formatting, confident tone, and concise answers.
342
- */
343
- export declare const DEFAULT_INSTRUCTIONS: string;
344
- /** Default greeting spoken when a session starts. */
345
- export declare const DEFAULT_GREETING: string;
346
- /**
347
- * Agent definition returned by {@link defineAgent}.
348
- *
349
- * Core fields (`name`, `instructions`, `greeting`, `maxSteps`, `tools`)
350
- * are resolved to their final values with defaults applied. Optional
351
- * behavioral fields (hooks, `sttPrompt`, etc.) remain optional —
352
- * `undefined` means "not configured."
353
- *
354
- * @public
355
- */
356
- export type AgentDef<S = Record<string, unknown>> = {
357
- name: string;
358
- instructions: string;
359
- greeting: string;
360
- sttPrompt?: string;
361
- maxSteps: number | ((ctx: HookContext<S>) => number);
362
- toolChoice?: ToolChoice;
363
- builtinTools?: readonly BuiltinTool[];
364
- tools: Readonly<Record<string, ToolDef<z.ZodObject<z.ZodRawShape>, S>>>;
365
- state?: () => S;
366
- onConnect?: (ctx: HookContext<S>) => void | Promise<void>;
367
- onDisconnect?: (ctx: HookContext<S>) => void | Promise<void>;
368
- onError?: (error: Error, ctx?: HookContext<S>) => void;
369
- onTurn?: (text: string, ctx: HookContext<S>) => void | Promise<void>;
370
- idleTimeoutMs?: number;
371
- };
372
- /** @internal Zod schema for {@link BuiltinTool}. Exported for reuse in internal schemas. */
373
- export declare const BuiltinToolSchema: z.ZodEnum<{
374
- web_search: "web_search";
375
- visit_webpage: "visit_webpage";
376
- fetch_json: "fetch_json";
377
- run_code: "run_code";
378
- }>;
379
- /** @internal Zod schema for {@link ToolChoice}. Exported for reuse in internal schemas. */
380
- export declare const ToolChoiceSchema: z.ZodUnion<readonly [z.ZodEnum<{
381
- auto: "auto";
382
- required: "required";
383
- none: "none";
384
- }>, z.ZodObject<{
385
- type: z.ZodLiteral<"tool">;
386
- toolName: z.ZodString;
387
- }, z.core.$strip>]>;
388
- /**
389
- * Create an agent definition from the given options, applying sensible defaults.
390
- *
391
- * This is the main entry point for defining a voice agent. The returned
392
- * `AgentDef` is consumed by the AAI server at deploy time.
393
- *
394
- * @param options - Configuration for the agent including name, instructions,
395
- * tools, hooks, and other settings.
396
- * @returns A fully resolved agent definition with all defaults applied.
397
- *
398
- * @public
399
- *
400
- * @example Basic agent with a custom tool
401
- * ```ts
402
- * import { defineAgent } from "aai";
403
- * import { z } from "zod";
404
- *
405
- * export default defineAgent({
406
- * name: "greeter",
407
- * instructions: "You greet people warmly.",
408
- * tools: {
409
- * greet: {
410
- * description: "Greet a user by name",
411
- * parameters: z.object({ name: z.string() }),
412
- * execute: ({ name }) => `Hello, ${name}!`,
413
- * },
414
- * },
415
- * });
416
- * ```
417
- */
418
- export declare function defineAgent<S = Record<string, unknown>>(options: AgentOptions<S>): AgentDef<S>;