@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
package/sdk/types.ts ADDED
@@ -0,0 +1,226 @@
1
+ // Copyright 2025 the AAI authors. MIT license.
2
+ /**
3
+ * Core type definitions for the AAI agent SDK.
4
+ */
5
+
6
+ import { z } from "zod";
7
+ import type { Kv } from "./kv.ts";
8
+
9
+ /**
10
+ * Identifier for a built-in server-side tool.
11
+ *
12
+ * Built-in tools run on the host process (not inside the sandboxed worker)
13
+ * and provide capabilities like web search, code execution, and API access.
14
+ *
15
+ * - `"web_search"` — Search the web for current information, facts, or news.
16
+ * - `"visit_webpage"` — Fetch a URL and return its content as clean text.
17
+ * - `"fetch_json"` — Call a REST API endpoint and return the JSON response.
18
+ * - `"run_code"` — Execute JavaScript in a sandbox for calculations and data processing.
19
+ *
20
+ * @public
21
+ */
22
+ export type BuiltinTool = "web_search" | "visit_webpage" | "fetch_json" | "run_code";
23
+
24
+ /**
25
+ * How the LLM should select tools during a turn.
26
+ *
27
+ * - `"auto"` — The model decides whether to call a tool (default).
28
+ * - `"required"` — The model must call at least one tool each step.
29
+ *
30
+ * @public
31
+ */
32
+ export type ToolChoice = "auto" | "required";
33
+
34
+ /**
35
+ * A single message in the conversation history.
36
+ *
37
+ * Messages are passed to tool `execute` functions via
38
+ * {@link ToolContext.messages} to provide conversation context.
39
+ *
40
+ * @public
41
+ */
42
+ export type Message = {
43
+ /** The role of the message sender. */
44
+ role: "user" | "assistant" | "tool";
45
+ /** The text content of the message. */
46
+ content: string;
47
+ };
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 "@alexkroman1/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
+ /** Unique identifier for the current session. Useful for correlating logs across concurrent sessions. */
85
+ sessionId: string;
86
+ };
87
+
88
+ /**
89
+ * Definition of a custom tool that the agent can invoke.
90
+ *
91
+ * Tools are the primary way to extend agent capabilities. Each tool has a
92
+ * description (shown to the LLM), optional Zod parameters schema, and an
93
+ * `execute` function that runs inside the sandboxed worker.
94
+ *
95
+ * @typeParam P - A Zod object schema describing the tool's parameters.
96
+ * Defaults to `ZodObject<ZodRawShape>` so tools without parameters don't need an explicit
97
+ * type argument.
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * import { type ToolDef } from "@alexkroman1/aai";
102
+ * import { z } from "zod";
103
+ *
104
+ * const weatherTool: ToolDef<typeof params> = {
105
+ * description: "Get current weather for a city",
106
+ * parameters: z.object({
107
+ * city: z.string().describe("City name"),
108
+ * }),
109
+ * execute: async ({ city }) => {
110
+ * const res = await fetch(`https://wttr.in/${city}?format=j1`);
111
+ * return await res.json();
112
+ * },
113
+ * };
114
+ *
115
+ * const params = z.object({ city: z.string() });
116
+ * ```
117
+ *
118
+ * @public
119
+ */
120
+ export type ToolDef<
121
+ P extends z.ZodObject<z.ZodRawShape> = z.ZodObject<z.ZodRawShape>,
122
+ S = Record<string, unknown>,
123
+ > = {
124
+ /** Human-readable description shown to the LLM. */
125
+ description: string;
126
+ /** Zod schema for the tool's parameters. */
127
+ parameters?: P;
128
+ /** Function that executes the tool and returns a result. */
129
+ execute(args: z.infer<P>, ctx: ToolContext<S>): Promise<unknown> | unknown;
130
+ };
131
+
132
+ /**
133
+ * A mapping of tool names to their result types.
134
+ *
135
+ * Define this in a shared file (e.g. `shared.ts`) that both `agent.ts` and
136
+ * `client.tsx` can import, so tool result types stay in sync without
137
+ * duplication.
138
+ *
139
+ * @example
140
+ * ```ts
141
+ * // shared.ts
142
+ * import type { ToolResultMap } from "@alexkroman1/aai-cli/types";
143
+ *
144
+ * export interface Pizza {
145
+ * id: number;
146
+ * size: "small" | "medium" | "large";
147
+ * toppings: string[];
148
+ * }
149
+ *
150
+ * export type MyToolResults = ToolResultMap<{
151
+ * add_pizza: { added: Pizza; orderTotal: string };
152
+ * place_order: { orderNumber: number; total: string };
153
+ * }>;
154
+ * ```
155
+ *
156
+ * Then use with {@link aai-ui#useToolResult | useToolResult}:
157
+ *
158
+ * ```tsx
159
+ * // client.tsx
160
+ * import type { MyToolResults } from "./shared.ts";
161
+ *
162
+ * useToolResult<MyToolResults["add_pizza"]>("add_pizza", (result) => {
163
+ * console.log(result.added); // fully typed
164
+ * });
165
+ * ```
166
+ *
167
+ * @public
168
+ */
169
+ export type ToolResultMap<T extends Record<string, unknown> = Record<string, unknown>> = T;
170
+
171
+ /**
172
+ * Default system prompt used when `systemPrompt` is not provided.
173
+ *
174
+ * Optimized for voice-first interactions: short sentences, no visual
175
+ * formatting, confident tone, and concise answers.
176
+ */
177
+ export const DEFAULT_SYSTEM_PROMPT: string = `\
178
+ You are AAI, a helpful AI assistant.
179
+
180
+ Voice-First Rules:
181
+ - Optimize for natural speech. Avoid jargon unless central to the answer. \
182
+ Use short, punchy sentences.
183
+ - Never mention "search results," "sources," or "the provided text." \
184
+ Speak as if the knowledge is your own.
185
+ - No visual formatting. Do not say "bullet point," "bold," or "bracketed one." \
186
+ If you need to list items, say "First," "Next," and "Finally."
187
+ - Start with the most important information. No introductory filler.
188
+ - Be concise. Keep answers to 1-3 sentences. For complex topics, provide a high-level summary.
189
+ - Be confident. Avoid hedging phrases like "It seems that" or "I believe."
190
+ - If you don't have enough information, say so directly rather than guessing.
191
+ - Never use exclamation points. Keep your tone calm and conversational.`;
192
+
193
+ /** Default greeting spoken when a session starts. */
194
+ export const DEFAULT_GREETING: string =
195
+ "Hey there. I'm a voice assistant. What can I help you with?";
196
+
197
+ /**
198
+ * Fully resolved agent definition.
199
+ *
200
+ * Core fields (`name`, `systemPrompt`, `greeting`, `maxSteps`, `tools`)
201
+ * are resolved to their final values with defaults applied. Optional
202
+ * behavioral fields (hooks, `sttPrompt`, etc.) remain optional —
203
+ * `undefined` means "not configured."
204
+ *
205
+ * @public
206
+ */
207
+ export type AgentDef<S = Record<string, unknown>> = {
208
+ name: string;
209
+ systemPrompt: string;
210
+ greeting: string;
211
+ sttPrompt?: string;
212
+ maxSteps: number;
213
+ toolChoice?: ToolChoice;
214
+ builtinTools?: readonly BuiltinTool[];
215
+ tools: Readonly<Record<string, ToolDef<z.ZodObject<z.ZodRawShape>, S>>>;
216
+ state?: () => S;
217
+ idleTimeoutMs?: number;
218
+ };
219
+
220
+ // ─── Zod schemas ────────────────────────────────────────────────────────────
221
+
222
+ /** @internal Zod schema for {@link BuiltinTool}. Exported for reuse in internal schemas. */
223
+ export const BuiltinToolSchema = z.enum(["web_search", "visit_webpage", "fetch_json", "run_code"]);
224
+
225
+ /** @internal Zod schema for {@link ToolChoice}. Exported for reuse in internal schemas. */
226
+ export const ToolChoiceSchema = z.enum(["auto", "required"]);
@@ -0,0 +1,52 @@
1
+ // Copyright 2025 the AAI authors. MIT license.
2
+ import { describe, expect, test } from "vitest";
3
+ import { errorDetail, errorMessage } from "./utils.ts";
4
+
5
+ describe("errorMessage", () => {
6
+ test("extracts message from Error instance", () => {
7
+ expect(errorMessage(new Error("something broke"))).toBe("something broke");
8
+ });
9
+
10
+ test("converts string to string", () => {
11
+ expect(errorMessage("plain string")).toBe("plain string");
12
+ });
13
+
14
+ test("converts number to string", () => {
15
+ expect(errorMessage(42)).toBe("42");
16
+ });
17
+
18
+ test("converts null to string", () => {
19
+ expect(errorMessage(null)).toBe("null");
20
+ });
21
+
22
+ test("converts undefined to string", () => {
23
+ expect(errorMessage(undefined)).toBe("undefined");
24
+ });
25
+ });
26
+
27
+ describe("errorDetail", () => {
28
+ test("returns stack trace when available", () => {
29
+ const err = new Error("something broke");
30
+ const result = errorDetail(err);
31
+ expect(result).toBe(err.stack);
32
+ expect(result).toContain("something broke");
33
+ });
34
+
35
+ test("returns message when stack is undefined", () => {
36
+ const err = new Error("no stack");
37
+ Object.defineProperty(err, "stack", { value: undefined });
38
+ expect(errorDetail(err)).toBe("no stack");
39
+ });
40
+
41
+ test("converts string to string", () => {
42
+ expect(errorDetail("plain string")).toBe("plain string");
43
+ });
44
+
45
+ test("converts null to string", () => {
46
+ expect(errorDetail(null)).toBe("null");
47
+ });
48
+
49
+ test("converts undefined to string", () => {
50
+ expect(errorDetail(undefined)).toBe("undefined");
51
+ });
52
+ });
package/sdk/utils.ts ADDED
@@ -0,0 +1,20 @@
1
+ // Copyright 2025 the AAI authors. MIT license.
2
+ /** Shared utility functions. */
3
+
4
+ /** Extract an error message from an unknown thrown value. */
5
+ export function errorMessage(err: unknown): string {
6
+ return err instanceof Error ? err.message : String(err);
7
+ }
8
+
9
+ /** Extract a detailed error string (message + stack) for diagnostic logging. */
10
+ export function errorDetail(err: unknown): string {
11
+ if (err instanceof Error) {
12
+ return err.stack ?? err.message;
13
+ }
14
+ return String(err);
15
+ }
16
+
17
+ /** Return a JSON error string for the LLM: `'{"error":"<message>"}'`. */
18
+ export function toolError(message: string): string {
19
+ return JSON.stringify({ error: message });
20
+ }
@@ -0,0 +1,48 @@
1
+ // Copyright 2025 the AAI authors. MIT license.
2
+
3
+ import { describe, expect, it } from "vitest";
4
+ import { parseWsUpgradeParams } from "./ws-upgrade.ts";
5
+
6
+ describe("parseWsUpgradeParams", () => {
7
+ it("returns defaults for URL with no query params", () => {
8
+ const result = parseWsUpgradeParams("/websocket");
9
+ expect(result).toEqual({ resumeFrom: undefined, skipGreeting: false });
10
+ });
11
+
12
+ it("extracts sessionId and sets skipGreeting", () => {
13
+ const result = parseWsUpgradeParams("/ws?sessionId=abc-123");
14
+ expect(result.resumeFrom).toBe("abc-123");
15
+ expect(result.skipGreeting).toBe(true);
16
+ });
17
+
18
+ it("sets skipGreeting when resume param is present", () => {
19
+ const result = parseWsUpgradeParams("/ws?resume=1");
20
+ expect(result.resumeFrom).toBeUndefined();
21
+ expect(result.skipGreeting).toBe(true);
22
+ });
23
+
24
+ it("sessionId takes precedence for resumeFrom", () => {
25
+ const result = parseWsUpgradeParams("/ws?resume=1&sessionId=sess-42");
26
+ expect(result.resumeFrom).toBe("sess-42");
27
+ expect(result.skipGreeting).toBe(true);
28
+ });
29
+
30
+ it("handles URL with no query string", () => {
31
+ const result = parseWsUpgradeParams("/websocket");
32
+ expect(result.resumeFrom).toBeUndefined();
33
+ expect(result.skipGreeting).toBe(false);
34
+ });
35
+
36
+ it("handles full URL with query params", () => {
37
+ const result = parseWsUpgradeParams("ws://localhost:3000/websocket?sessionId=s1");
38
+ expect(result.resumeFrom).toBe("s1");
39
+ expect(result.skipGreeting).toBe(true);
40
+ });
41
+
42
+ it("handles empty sessionId", () => {
43
+ const result = parseWsUpgradeParams("/ws?sessionId=");
44
+ // Empty string from URLSearchParams.get is truthy for ?? check
45
+ expect(result.resumeFrom).toBe("");
46
+ expect(result.skipGreeting).toBe(true);
47
+ });
48
+ });
@@ -0,0 +1,13 @@
1
+ // Copyright 2025 the AAI authors. MIT license.
2
+
3
+ /** Parse WebSocket upgrade query params into session start options. */
4
+ export function parseWsUpgradeParams(rawUrl: string): {
5
+ resumeFrom?: string;
6
+ skipGreeting: boolean;
7
+ } {
8
+ const search = rawUrl.includes("?") ? (rawUrl.split("?")[1] ?? "") : "";
9
+ const params = new URLSearchParams(search);
10
+ const resumeFrom = params.get("sessionId") ?? undefined;
11
+ const skipGreeting = params.has("resume") || resumeFrom !== undefined;
12
+ return resumeFrom !== undefined ? { resumeFrom, skipGreeting } : { skipGreeting };
13
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": ".",
6
+ "noEmit": false,
7
+ "declaration": true,
8
+ "emitDeclarationOnly": true,
9
+ "incremental": false,
10
+ "allowImportingTsExtensions": false,
11
+ "rewriteRelativeImportExtensions": true
12
+ },
13
+ "exclude": ["node_modules", "dist", "**/*.test.ts", "**/_test-utils.ts", "vitest*.config.ts"]
14
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "incremental": true,
5
+ "tsBuildInfoFile": "../../.tsbuildinfo/aai.tsbuildinfo",
6
+ "types": ["node"]
7
+ },
8
+ "include": ["./**/*.ts"],
9
+ "exclude": ["node_modules", "dist", "**/__snapshots__"]
10
+ }
@@ -0,0 +1,26 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { defineConfig } from "tsdown";
3
+
4
+ // Derive build entries from package.json exports so they can never drift.
5
+ const pkg = JSON.parse(readFileSync("package.json", "utf-8"));
6
+ const entry = [
7
+ ...new Set(
8
+ Object.values(pkg.exports as Record<string, Record<string, string>>)
9
+ .filter(
10
+ (v): v is { "@dev/source": string } =>
11
+ typeof v === "object" && typeof v["@dev/source"] === "string",
12
+ )
13
+ .map((v) => v["@dev/source"].replace(/^\.\//, "")),
14
+ ),
15
+ ];
16
+
17
+ export default defineConfig({
18
+ entry,
19
+ format: "esm",
20
+ platform: "node",
21
+ target: "node22",
22
+ outDir: "dist",
23
+ dts: false,
24
+ outExtensions: () => ({ js: ".js" }),
25
+ deps: { neverBundle: [/^[^./]/] },
26
+ });
@@ -0,0 +1,17 @@
1
+ import { defineConfig } from "vitest/config";
2
+ import { sharedConfig } from "../../vitest.shared.ts";
3
+
4
+ export default defineConfig({
5
+ ...sharedConfig,
6
+ test: {
7
+ restoreMocks: true,
8
+ include: ["**/*.test.ts"],
9
+ exclude: [
10
+ "**/pentest.test.ts",
11
+ "**/run-code-sandbox.test.ts",
12
+ "**/integration.test.ts",
13
+ "node_modules",
14
+ "dist",
15
+ ],
16
+ },
17
+ });
@@ -1,73 +0,0 @@
1
- import type { AgentConfig } from "../isolate/_internal-types.ts";
2
- import type { ClientSink } from "../isolate/protocol.ts";
3
- import type { AgentDef, ToolContext, ToolDef } from "../isolate/types.ts";
4
- import type { S2sEvents, S2sHandle } from "./s2s.ts";
5
- import type { Session } from "./session.ts";
6
- import { type S2sSessionOptions } from "./session.ts";
7
- /** Yield to the microtask queue so pending promises settle. */
8
- export declare function flush(): Promise<void>;
9
- export declare function createMockToolContext(overrides?: Partial<ToolContext>): ToolContext;
10
- export declare function makeTool(overrides?: Partial<ToolDef>): ToolDef;
11
- export declare function makeAgent(overrides?: Partial<AgentDef>): AgentDef;
12
- export declare function makeConfig(overrides?: Partial<AgentConfig>): AgentConfig;
13
- /** Create a stub Session with all methods as vi.fn() spies. */
14
- export declare function makeStubSession(overrides?: Partial<Session>): Session;
15
- export type MockS2sHandle = S2sHandle & {
16
- _fire: <K extends keyof S2sEvents>(type: K, ...args: Parameters<S2sEvents[K]>) => void;
17
- };
18
- /** Create a mock S2sHandle backed by nanoevents. */
19
- export declare function makeMockHandle(): MockS2sHandle;
20
- /** Minimal client that tracks events and audio. All methods are vi.fn() spies. */
21
- export declare function makeClient(): ClientSink & {
22
- events: unknown[];
23
- audioChunks: Uint8Array[];
24
- audioDoneCount: number;
25
- };
26
- export declare const silentLogger: {
27
- info: (...args: unknown[]) => void;
28
- warn: (...args: unknown[]) => void;
29
- error: (...args: unknown[]) => void;
30
- debug: (...args: unknown[]) => void;
31
- };
32
- export declare function makeSessionOpts(overrides?: Partial<S2sSessionOptions>): S2sSessionOptions;
33
- /** Load a JSON fixture from fixtures/. */
34
- export declare function loadFixture<T = Record<string, unknown>[]>(name: string): T;
35
- /**
36
- * Replay recorded S2S API messages through a MockS2sHandle.
37
- *
38
- * Converts raw wire-format JSON (from fixtures/) into typed `_fire()` calls.
39
- * This is the inverse of `dispatchS2sMessage` in s2s.ts — it translates
40
- * snake_case API fields to camelCase event payloads.
41
- *
42
- * Messages that don't map to an event (audio, `reply.content_part.*`) are skipped.
43
- */
44
- export declare function replayFixtureMessages(handle: MockS2sHandle, messages: Record<string, unknown>[]): void;
45
- /**
46
- * Create a real Runtime-backed session for fixture replay testing.
47
- *
48
- * Uses a real `Runtime` (real tool execution, real hooks) but replaces the
49
- * S2S WebSocket with a mock handle so fixture messages can be replayed
50
- * through the full orchestration layer.
51
- *
52
- * Exercises: defineAgent → toAgentConfig → tool schemas → Zod arg validation
53
- * → executeToolCall → session orchestration (reply guards, tool buffering,
54
- * turnPromise chaining).
55
- *
56
- * Call `cleanup()` when done to restore the connectS2s spy.
57
- */
58
- export declare function createFixtureSession(agent: AgentDef<any>, opts?: {
59
- env?: Record<string, string>;
60
- }): {
61
- session: Session;
62
- client: ClientSink & {
63
- events: unknown[];
64
- audioChunks: Uint8Array[];
65
- audioDoneCount: number;
66
- };
67
- mockHandle: MockS2sHandle;
68
- executor: import("./direct-executor.ts").Runtime;
69
- /** Replay a fixture file through the session's S2S handle. */
70
- replay(fixtureName: string): void;
71
- /** Restore the connectS2s spy. Call in afterEach. */
72
- cleanup(): void;
73
- };
@@ -1,130 +0,0 @@
1
- /**
2
- * Agent runtime — the execution engine for voice agents.
3
- *
4
- * {@link createRuntime} builds the single execution engine used by both
5
- * self-hosted servers and the platform sandbox. It wires up tool execution,
6
- * lifecycle hooks, and session management.
7
- */
8
- import { type ExecuteTool, type ToolSchema } from "../isolate/_internal-types.ts";
9
- import { type AgentHooks } from "../isolate/hooks.ts";
10
- import type { Kv } from "../isolate/kv.ts";
11
- import type { ClientSink } from "../isolate/protocol.ts";
12
- import { type ReadyConfig } from "../isolate/protocol.ts";
13
- import type { AgentDef, Message, ToolDef } from "../isolate/types.ts";
14
- import type { Logger, S2SConfig } from "./runtime.ts";
15
- import type { CreateS2sWebSocket } from "./s2s.ts";
16
- import { type Session } from "./session.ts";
17
- import { type SessionWebSocket } from "./ws-handler.ts";
18
- export type { ExecuteTool } from "../isolate/_internal-types.ts";
19
- export type ExecuteToolCallOptions = {
20
- tool: ToolDef;
21
- env: Readonly<Record<string, string>>;
22
- state?: Record<string, unknown>;
23
- sessionId?: string | undefined;
24
- kv?: Kv | undefined;
25
- messages?: readonly Message[] | undefined;
26
- logger?: Logger | undefined;
27
- fetch?: typeof globalThis.fetch | undefined;
28
- };
29
- export declare function executeToolCall(name: string, args: Readonly<Record<string, unknown>>, options: ExecuteToolCallOptions): Promise<string>;
30
- /** Per-session options passed to {@link AgentRuntime.startSession}. */
31
- export type SessionStartOptions = {
32
- skipGreeting?: boolean;
33
- resumeFrom?: string;
34
- logContext?: Record<string, string>;
35
- onOpen?: () => void;
36
- onClose?: () => void;
37
- };
38
- /**
39
- * Common interface for agent runtimes.
40
- *
41
- * Implemented by {@link createRuntime} and the platform sandbox.
42
- */
43
- export type AgentRuntime = {
44
- startSession(ws: SessionWebSocket, opts?: SessionStartOptions): void;
45
- shutdown(): Promise<void>;
46
- readonly readyConfig: ReadyConfig;
47
- };
48
- /**
49
- * Configuration for {@link createRuntime}.
50
- *
51
- * Configures the agent, environment, KV store, logging, and S2S connection.
52
- *
53
- * @public
54
- */
55
- export type RuntimeOptions = {
56
- agent: AgentDef<any>;
57
- env: Record<string, string>;
58
- kv?: Kv | undefined;
59
- /** Custom WebSocket factory for the S2S connection (useful for testing). */
60
- createWebSocket?: CreateS2sWebSocket | undefined;
61
- logger?: Logger | undefined;
62
- s2sConfig?: S2SConfig | undefined;
63
- /**
64
- * Timeout in ms for `session.start()` (S2S connection setup).
65
- * Defaults to 10 000 (10 s).
66
- */
67
- sessionStartTimeoutMs?: number | undefined;
68
- /**
69
- * Maximum time in milliseconds to wait for sessions to stop during
70
- * {@link AgentRuntime.shutdown | shutdown()}. Defaults to `30_000` (30 s).
71
- */
72
- shutdownTimeoutMs?: number | undefined;
73
- /**
74
- * Override tool execution. When provided, `createRuntime` skips building
75
- * in-process tool definitions and uses this function instead. Used by the
76
- * platform sandbox to RPC tool calls to the isolate.
77
- */
78
- executeTool?: ExecuteTool | undefined;
79
- /**
80
- * Override lifecycle hooks. When provided, `createRuntime` skips building
81
- * in-process hooks and uses these instead. Used by the platform sandbox
82
- * to RPC hook calls to the isolate.
83
- */
84
- hooks?: AgentHooks | undefined;
85
- /**
86
- * Override tool schemas sent to the S2S API. Required when `executeTool`
87
- * is provided (the host doesn't have the tool definitions to derive schemas).
88
- */
89
- toolSchemas?: ToolSchema[] | undefined;
90
- /** System prompt guidance for builtin tools. Passed through in sandbox mode. */
91
- toolGuidance?: string[] | undefined;
92
- };
93
- /**
94
- * The agent runtime returned by {@link createRuntime}.
95
- *
96
- * Satisfies {@link AgentRuntime} for use by transport code, and also exposes
97
- * lower-level helpers (`executeTool`, `hooks`, `toolSchemas`,
98
- * `createSession`) for testing and advanced usage.
99
- *
100
- * @public
101
- */
102
- export type Runtime = AgentRuntime & {
103
- /** Execute a named tool with the given args, returning a JSON result string. */
104
- executeTool: ExecuteTool;
105
- /** Hookable instance wired to the agent's lifecycle hooks. */
106
- hooks: AgentHooks;
107
- /** Tool schemas registered with the S2S API (custom + built-in). */
108
- toolSchemas: ToolSchema[];
109
- /** Create a new voice session for a connected client (lower-level than startSession). */
110
- createSession(opts: {
111
- id: string;
112
- agent: string;
113
- client: ClientSink;
114
- skipGreeting?: boolean;
115
- resumeFrom?: string;
116
- }): Session;
117
- };
118
- /**
119
- * Create an agent runtime — the execution engine for a voice agent.
120
- *
121
- * Merges built-in and custom tool definitions, builds tool schemas for the
122
- * S2S API, and wires up lifecycle hooks.
123
- *
124
- * @param opts - Runtime configuration. See {@link RuntimeOptions}.
125
- * @returns A {@link Runtime} with tool execution, hook invocation,
126
- * schemas, and session management.
127
- *
128
- * @public
129
- */
130
- export declare function createRuntime(opts: RuntimeOptions): Runtime;
@@ -1,19 +0,0 @@
1
- /**
2
- * Host barrel — re-exports all SDK internals for use by the platform
3
- * server (`aai-server`) and CLI. **Not a public API.**
4
- *
5
- * Includes the full isolate-safe kernel plus host-only modules that
6
- * depend on Node.js APIs (server, executor, S2S, etc.).
7
- *
8
- * Consumer packages should import from the top-level `@alexkroman1/aai`
9
- * entry, `./server`, `./types`, `./kv`, `./protocol`, or `./testing`.
10
- */
11
- export * from "../isolate/index.ts";
12
- export * from "./_runtime-conformance.ts";
13
- export * from "./builtin-tools.ts";
14
- export * from "./direct-executor.ts";
15
- export * from "./runtime.ts";
16
- export * from "./s2s.ts";
17
- export * from "./session.ts";
18
- export * from "./unstorage-kv.ts";
19
- export * from "./ws-handler.ts";