@alexkroman1/aai 0.10.4 → 0.11.0

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.
@@ -1,6 +1,6 @@
1
1
  /**
2
- * run_code built-in tool — executes user JavaScript in a fresh secure-exec
3
- * V8 isolate with no network, filesystem writes, or env access.
2
+ * run_code built-in tool — executes user JavaScript in a fresh `node:vm`
3
+ * context with no network, filesystem, or process access.
4
4
  */
5
5
  import { z } from "zod";
6
6
  import type { ToolDef } from "./types.ts";
@@ -8,22 +8,26 @@ declare const runCodeParams: z.ZodObject<{
8
8
  code: z.ZodString;
9
9
  }, z.core.$strip>;
10
10
  /**
11
- * Execute JavaScript code inside a fresh secure-exec V8 isolate.
11
+ * Execute JavaScript code inside a fresh `node:vm` context.
12
12
  *
13
- * Each invocation spins up a disposable isolate with:
14
- * - No filesystem writes
15
- * - No network access
13
+ * Each invocation creates a disposable VM context with:
14
+ * - No filesystem access (`node:fs` and other built-ins unavailable)
15
+ * - No network access (`fetch`, `http` unavailable)
16
16
  * - No child process spawning
17
- * - No environment variable access
18
- * - 32 MB memory limit
19
- * - 5 second execution timeout
17
+ * - No environment variable access (`process` unavailable)
18
+ * - Execution timeout (default 5 s)
20
19
  *
21
- * The isolate is disposed immediately after execution, so no state
22
- * leaks between invocations or across sessions.
20
+ * The context is discarded after execution, so no state leaks between
21
+ * invocations or across sessions.
23
22
  */
24
23
  export declare function createRunCode(): ToolDef<typeof runCodeParams>;
25
24
  /**
26
- * Exported for testing — execute user code in a fresh secure-exec V8 isolate.
25
+ * Execute user code in a fresh `node:vm` context.
26
+ *
27
+ * @remarks
28
+ * The VM context only exposes standard ECMAScript globals and a console
29
+ * object that captures output. Node.js APIs (`process`, `require`,
30
+ * `import()`) are not available inside the sandbox.
27
31
  */
28
32
  export declare function executeInIsolate(code: string): Promise<string | {
29
33
  error: string;
@@ -17,12 +17,12 @@
17
17
  * });
18
18
  * ```
19
19
  *
20
- * @example Sandbox (integration test)
20
+ * @example Sandbox (integration test in aai-server)
21
21
  * ```ts
22
- * import { testRuntime, CONFORMANCE_AGENT_BUNDLE } from "@alexkroman1/aai/runtime-conformance";
22
+ * import { testRuntime } from "@alexkroman1/aai/internal";
23
23
  *
24
24
  * testRuntime("sandbox", async () => {
25
- * // ... start isolate with CONFORMANCE_AGENT_BUNDLE
25
+ * // ... start isolate with a bundled agent
26
26
  * return { executeTool: buildExecuteTool(...), hooks: buildHookInvoker(...) };
27
27
  * });
28
28
  * ```
@@ -40,17 +40,8 @@ export type RuntimeTestContext = {
40
40
  executeTool: ExecuteTool;
41
41
  hooks: AgentHooks;
42
42
  };
43
- /**
44
- * Agent definition used by the conformance suite (direct executor path).
45
- *
46
- * Must be kept in sync with {@link CONFORMANCE_AGENT_BUNDLE}.
47
- */
43
+ /** Agent definition used by the conformance suite (direct executor path). */
48
44
  export declare const CONFORMANCE_AGENT: AgentDef;
49
- /**
50
- * JavaScript bundle equivalent of {@link CONFORMANCE_AGENT} for the sandbox
51
- * isolate path. Must be kept in sync with the AgentDef above.
52
- */
53
- export declare const CONFORMANCE_AGENT_BUNDLE = "\nexport default {\n name: \"conformance-test\",\n instructions: \"Conformance test agent.\",\n greeting: \"Hello!\",\n maxSteps: 5,\n state: () => ({ count: 0, lastTurn: \"\" }),\n tools: {\n echo: {\n description: \"Echo input\",\n execute(args) { return \"echo:\" + args.text; },\n },\n get_env: {\n description: \"Get MY_VAR from env\",\n execute(_args, ctx) { return ctx.env.MY_VAR ?? \"missing\"; },\n },\n get_state: {\n description: \"Get session state\",\n execute(_args, ctx) { return JSON.stringify(ctx.state); },\n },\n echo_messages: {\n description: \"Return messages as JSON\",\n execute(_args, ctx) { return JSON.stringify(ctx.messages); },\n },\n kv_roundtrip: {\n description: \"KV set then get\",\n async execute(args, ctx) {\n await ctx.kv.set(\"test-key\", args.value);\n const result = await ctx.kv.get(\"test-key\");\n return \"stored:\" + JSON.stringify(result);\n },\n },\n },\n onConnect: (ctx) => { ctx.state.count = 1; },\n onTurn: (text, ctx) => { ctx.state.lastTurn = text; },\n};\n";
54
45
  /**
55
46
  * Run the runtime conformance test suite against a given runtime context.
56
47
  *
@@ -1,6 +1,7 @@
1
1
  import type { AgentConfig } from "./_internal-types.ts";
2
2
  import type { ClientSink } from "./protocol.ts";
3
3
  import type { S2sEvents, S2sHandle } from "./s2s.ts";
4
+ import type { Session } from "./session.ts";
4
5
  import { type S2sSessionOptions } from "./session.ts";
5
6
  import type { AgentDef, ToolContext, ToolDef } from "./types.ts";
6
7
  /** Yield to the microtask queue so pending promises settle. */
@@ -9,6 +10,8 @@ export declare function createMockToolContext(overrides?: Partial<ToolContext>):
9
10
  export declare function makeTool(overrides?: Partial<ToolDef>): ToolDef;
10
11
  export declare function makeAgent(overrides?: Partial<AgentDef>): AgentDef;
11
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;
12
15
  export type MockS2sHandle = S2sHandle & {
13
16
  _fire: <K extends keyof S2sEvents>(type: K, ...args: Parameters<S2sEvents[K]>) => void;
14
17
  };
@@ -55,7 +58,7 @@ export declare function replayFixtureMessages(handle: MockS2sHandle, messages: R
55
58
  export declare function createFixtureSession(agent: AgentDef<any>, opts?: {
56
59
  env?: Record<string, string>;
57
60
  }): {
58
- session: import("./session.ts").Session;
61
+ session: Session;
59
62
  client: ClientSink & {
60
63
  events: unknown[];
61
64
  audioChunks: Uint8Array[];
package/dist/_utils.d.ts CHANGED
@@ -5,17 +5,5 @@ export declare function errorMessage(err: unknown): string;
5
5
  export declare function errorDetail(err: unknown): string;
6
6
  /** Check whether a filesystem operation is a read-only operation. */
7
7
  export declare function isReadOnlyFsOp(op: string): boolean;
8
- /**
9
- * Lazily initialized per-session state manager.
10
- *
11
- * On first access for a given session, calls `initState()` (if provided) to
12
- * create the initial state. Returns `{}` if no initializer and no prior state.
13
- */
14
- export declare function createSessionStateMap(initState?: () => Record<string, unknown>): {
15
- get(sessionId: string): Record<string, unknown>;
16
- /** Explicitly set the state for a session. */
17
- set(sessionId: string, state: Record<string, unknown>): void;
18
- delete(sessionId: string): boolean;
19
- };
20
8
  /** Return a JSON error string for the LLM: `'{"error":"<message>"}'`. */
21
9
  export declare function toolError(message: string): string;
package/dist/_utils.js CHANGED
@@ -20,30 +20,9 @@ const READ_ONLY_FS_OPS = new Set([
20
20
  function isReadOnlyFsOp(op) {
21
21
  return READ_ONLY_FS_OPS.has(op);
22
22
  }
23
- /**
24
- * Lazily initialized per-session state manager.
25
- *
26
- * On first access for a given session, calls `initState()` (if provided) to
27
- * create the initial state. Returns `{}` if no initializer and no prior state.
28
- */
29
- function createSessionStateMap(initState) {
30
- const map = /* @__PURE__ */ new Map();
31
- return {
32
- get(sessionId) {
33
- if (!map.has(sessionId) && initState) map.set(sessionId, initState());
34
- return map.get(sessionId) ?? {};
35
- },
36
- set(sessionId, state) {
37
- map.set(sessionId, state);
38
- },
39
- delete(sessionId) {
40
- return map.delete(sessionId);
41
- }
42
- };
43
- }
44
23
  /** Return a JSON error string for the LLM: `'{"error":"<message>"}'`. */
45
24
  function toolError(message) {
46
25
  return JSON.stringify({ error: message });
47
26
  }
48
27
  //#endregion
49
- export { createSessionStateMap, errorDetail, errorMessage, isReadOnlyFsOp, toolError };
28
+ export { errorDetail, errorMessage, isReadOnlyFsOp, toolError };
@@ -35,8 +35,6 @@ const MAX_VALUE_SIZE = 65536;
35
35
  const MAX_GLOB_PATTERN_LENGTH = 1024;
36
36
  /** Maximum conversation messages to retain (sliding window). */
37
37
  const DEFAULT_MAX_HISTORY = 200;
38
- /** Memory limit for run_code isolates (MB). */
39
- const RUN_CODE_MEMORY_MB = 32;
40
38
  /**
41
39
  * Content-Security-Policy applied to agent UI pages (both self-hosted and
42
40
  * platform). Single source of truth — used by `secureHeaders` middleware
@@ -44,4 +42,4 @@ const RUN_CODE_MEMORY_MB = 32;
44
42
  */
45
43
  const AGENT_CSP = "default-src 'self'; script-src 'self' 'unsafe-eval' blob:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; connect-src 'self' wss: ws:; img-src 'self' data:; font-src 'self' https://fonts.gstatic.com; object-src 'none'; base-uri 'self'";
46
44
  //#endregion
47
- export { TOOL_EXECUTION_TIMEOUT_MS as _, DEFAULT_SHUTDOWN_TIMEOUT_MS as a, FETCH_TIMEOUT_MS as c, MAX_HTML_BYTES as d, MAX_PAGE_CHARS as f, RUN_CODE_TIMEOUT_MS as g, RUN_CODE_MEMORY_MB as h, DEFAULT_SESSION_START_TIMEOUT_MS as i, HOOK_TIMEOUT_MS as l, MAX_VALUE_SIZE as m, DEFAULT_IDLE_TIMEOUT_MS as n, DEFAULT_STT_SAMPLE_RATE as o, MAX_TOOL_RESULT_CHARS as p, DEFAULT_MAX_HISTORY as r, DEFAULT_TTS_SAMPLE_RATE as s, AGENT_CSP as t, MAX_GLOB_PATTERN_LENGTH as u };
45
+ export { DEFAULT_SHUTDOWN_TIMEOUT_MS as a, FETCH_TIMEOUT_MS as c, MAX_HTML_BYTES as d, MAX_PAGE_CHARS as f, TOOL_EXECUTION_TIMEOUT_MS as g, RUN_CODE_TIMEOUT_MS as h, DEFAULT_SESSION_START_TIMEOUT_MS as i, HOOK_TIMEOUT_MS as l, MAX_VALUE_SIZE as m, DEFAULT_IDLE_TIMEOUT_MS as n, DEFAULT_STT_SAMPLE_RATE as o, MAX_TOOL_RESULT_CHARS as p, DEFAULT_MAX_HISTORY as r, DEFAULT_TTS_SAMPLE_RATE as s, AGENT_CSP as t, MAX_GLOB_PATTERN_LENGTH as u };
@@ -34,8 +34,6 @@ export declare const MAX_VALUE_SIZE = 65536;
34
34
  export declare const MAX_GLOB_PATTERN_LENGTH = 1024;
35
35
  /** Maximum conversation messages to retain (sliding window). */
36
36
  export declare const DEFAULT_MAX_HISTORY = 200;
37
- /** Memory limit for run_code isolates (MB). */
38
- export declare const RUN_CODE_MEMORY_MB = 32;
39
37
  /**
40
38
  * Content-Security-Policy applied to agent UI pages (both self-hosted and
41
39
  * platform). Single source of truth — used by `secureHeaders` middleware
@@ -1,6 +1,6 @@
1
1
  import { BuiltinToolSchema, DEFAULT_INSTRUCTIONS, ToolChoiceSchema, defineTool } from "./types.js";
2
- import { _ as TOOL_EXECUTION_TIMEOUT_MS, a as DEFAULT_SHUTDOWN_TIMEOUT_MS, c as FETCH_TIMEOUT_MS, d as MAX_HTML_BYTES, f as MAX_PAGE_CHARS, g as RUN_CODE_TIMEOUT_MS, l as HOOK_TIMEOUT_MS, m as MAX_VALUE_SIZE, o as DEFAULT_STT_SAMPLE_RATE, p as MAX_TOOL_RESULT_CHARS, s as DEFAULT_TTS_SAMPLE_RATE } from "./constants-BbAOvKl_.js";
3
- import { errorDetail, errorMessage, isReadOnlyFsOp, toolError } from "./_utils.js";
2
+ import { a as DEFAULT_SHUTDOWN_TIMEOUT_MS, c as FETCH_TIMEOUT_MS, d as MAX_HTML_BYTES, f as MAX_PAGE_CHARS, g as TOOL_EXECUTION_TIMEOUT_MS, h as RUN_CODE_TIMEOUT_MS, l as HOOK_TIMEOUT_MS, m as MAX_VALUE_SIZE, o as DEFAULT_STT_SAMPLE_RATE, p as MAX_TOOL_RESULT_CHARS, s as DEFAULT_TTS_SAMPLE_RATE } from "./constants-CwotjpJR.js";
3
+ import { errorDetail, errorMessage, toolError } from "./_utils.js";
4
4
  import { callResolveTurnConfig, createAgentHooks } from "./hooks.js";
5
5
  import { ClientMessageSchema, buildReadyConfig } from "./protocol.js";
6
6
  import { matchGlob, sortAndPaginate } from "./kv.js";
@@ -8,6 +8,7 @@ import { z } from "zod";
8
8
  import WsWebSocket from "ws";
9
9
  import pTimeout from "p-timeout";
10
10
  import { createStorage, prefixStorage } from "unstorage";
11
+ import vm from "node:vm";
11
12
  import { createNanoEvents } from "nanoevents";
12
13
  //#region runtime.ts
13
14
  /**
@@ -112,131 +113,71 @@ function agentToolsToSchemas(tools) {
112
113
  //#endregion
113
114
  //#region _run-code.ts
114
115
  /**
115
- * run_code built-in tool — executes user JavaScript in a fresh secure-exec
116
- * V8 isolate with no network, filesystem writes, or env access.
116
+ * run_code built-in tool — executes user JavaScript in a fresh `node:vm`
117
+ * context with no network, filesystem, or process access.
117
118
  */
118
119
  const runCodeParams = z.object({ code: z.string().describe("JavaScript code to execute. Use console.log() for output.") });
119
120
  /**
120
- * Execute JavaScript code inside a fresh secure-exec V8 isolate.
121
+ * Execute JavaScript code inside a fresh `node:vm` context.
121
122
  *
122
- * Each invocation spins up a disposable isolate with:
123
- * - No filesystem writes
124
- * - No network access
123
+ * Each invocation creates a disposable VM context with:
124
+ * - No filesystem access (`node:fs` and other built-ins unavailable)
125
+ * - No network access (`fetch`, `http` unavailable)
125
126
  * - No child process spawning
126
- * - No environment variable access
127
- * - 32 MB memory limit
128
- * - 5 second execution timeout
127
+ * - No environment variable access (`process` unavailable)
128
+ * - Execution timeout (default 5 s)
129
129
  *
130
- * The isolate is disposed immediately after execution, so no state
131
- * leaks between invocations or across sessions.
130
+ * The context is discarded after execution, so no state leaks between
131
+ * invocations or across sessions.
132
132
  */
133
133
  function createRunCode() {
134
134
  return {
135
- description: "Execute JavaScript code in a secure sandbox and return the output. Use this for calculations, data transformations, string manipulation, or any task that benefits from running code. Output is captured from console.log(). No network or filesystem access.",
135
+ description: "Execute JavaScript code in a sandbox and return the output. Use this for calculations, data transformations, string manipulation, or any task that benefits from running code. Output is captured from console.log(). No network or filesystem access.",
136
136
  parameters: runCodeParams,
137
137
  async execute(args) {
138
138
  return executeInIsolate(args.code);
139
139
  }
140
140
  };
141
141
  }
142
- /** Lazily import secure-exec to avoid top-level side effects. */
143
- let _secureExecPromise;
144
- function getSecureExec() {
145
- _secureExecPromise ??= import("secure-exec");
146
- return _secureExecPromise;
147
- }
148
- const RUN_CODE_HARNESS = `
149
- import { readFileSync } from "node:fs";
150
-
151
- const __output = [];
152
- const __capture = (...args) => __output.push(args.map(String).join(" "));
153
- const __console = {
154
- log: __capture, info: __capture, warn: __capture,
155
- error: __capture, debug: __capture,
156
- };
157
- try {
158
- const __userCode = readFileSync("/app/user-code.js", "utf8");
159
- const __AsyncFn = Object.getPrototypeOf(async function(){}).constructor;
160
- const __fn = new __AsyncFn("console", __userCode);
161
- await __fn(__console);
162
- const result = __output.join("\\n").trim();
163
- process.stdout.write(JSON.stringify({ ok: true, result: result || "Code ran successfully (no output)" }));
164
- } catch (err) {
165
- process.stdout.write(JSON.stringify({ ok: false, error: String(err?.message ?? err) }));
166
- }
167
- `;
168
- const IsolateOutputSchema = z.object({
169
- ok: z.boolean(),
170
- result: z.string().optional(),
171
- error: z.string().optional()
172
- });
173
- /** Parse stdout from the run_code harness into a result or error. */
174
- function parseIsolateOutput(stdout, stderr) {
175
- if (!stdout) {
176
- if (stderr) return { error: stderr.trim() };
177
- return { error: "Code execution timed out" };
178
- }
179
- try {
180
- const parsed = IsolateOutputSchema.parse(JSON.parse(stdout));
181
- if (parsed.ok) return parsed.result ?? "Code ran successfully (no output)";
182
- return { error: parsed.error ?? "Unknown error" };
183
- } catch {
184
- return stdout.trim() || "Code ran successfully (no output)";
185
- }
186
- }
187
142
  /**
188
- * Exported for testing — execute user code in a fresh secure-exec V8 isolate.
143
+ * Execute user code in a fresh `node:vm` context.
144
+ *
145
+ * @remarks
146
+ * The VM context only exposes standard ECMAScript globals and a console
147
+ * object that captures output. Node.js APIs (`process`, `require`,
148
+ * `import()`) are not available inside the sandbox.
189
149
  */
190
150
  async function executeInIsolate(code) {
191
- const { createInMemoryFileSystem, createNodeDriver, createNodeRuntimeDriverFactory, NodeRuntime } = await getSecureExec();
192
- const fs = createInMemoryFileSystem();
193
- await fs.writeFile("/app/harness.js", RUN_CODE_HARNESS);
194
- await fs.writeFile("/app/user-code.js", code);
195
- const stdoutChunks = [];
196
- const stderrChunks = [];
197
- let resolveOutput = null;
198
- const outputReady = new Promise((r) => {
199
- resolveOutput = r;
200
- });
201
- const runtime = new NodeRuntime({
202
- systemDriver: createNodeDriver({
203
- filesystem: fs,
204
- permissions: {
205
- fs: (req) => isReadOnlyFsOp(req.op) ? { allow: true } : {
206
- allow: false,
207
- reason: "Filesystem is read-only"
208
- },
209
- network: () => ({
210
- allow: false,
211
- reason: "Network access is disabled in run_code"
212
- }),
213
- childProcess: () => ({
214
- allow: false,
215
- reason: "Subprocess spawning is disabled"
216
- }),
217
- env: () => ({
218
- allow: false,
219
- reason: "Env access is disabled in run_code"
220
- })
221
- }
222
- }),
223
- runtimeDriverFactory: createNodeRuntimeDriverFactory(),
224
- memoryLimit: 32,
225
- onStdio(event) {
226
- if (event.channel === "stdout") stdoutChunks.push(event.message);
227
- if (event.channel === "stderr") stderrChunks.push(event.message);
228
- resolveOutput?.();
229
- }
151
+ const output = [];
152
+ const capture = (...args) => output.push(args.map(String).join(" "));
153
+ const context = vm.createContext({
154
+ console: {
155
+ log: capture,
156
+ info: capture,
157
+ warn: capture,
158
+ error: capture,
159
+ debug: capture
160
+ },
161
+ setTimeout,
162
+ clearTimeout,
163
+ setInterval,
164
+ clearInterval,
165
+ URL,
166
+ URLSearchParams,
167
+ TextEncoder,
168
+ TextDecoder,
169
+ atob,
170
+ btoa,
171
+ structuredClone,
172
+ queueMicrotask
230
173
  });
231
- const execPromise = runtime.exec("import \"/app/harness.js\";", { cwd: "/app" });
232
174
  try {
233
- await Promise.race([outputReady, new Promise((r) => setTimeout(r, RUN_CODE_TIMEOUT_MS))]);
234
- await Promise.race([execPromise.catch(() => {}), new Promise((r) => setTimeout(r, 200))]);
235
- return parseIsolateOutput(stdoutChunks.join(""), stderrChunks.join(""));
175
+ const wrapped = `(async () => {\n${code}\n})()`;
176
+ const promise = new vm.Script(wrapped, { filename: "run_code.js" }).runInContext(context, { timeout: RUN_CODE_TIMEOUT_MS });
177
+ await Promise.race([promise, new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error("Code execution timed out")), RUN_CODE_TIMEOUT_MS))]);
178
+ return output.join("\n").trim() || "Code ran successfully (no output)";
236
179
  } catch (err) {
237
180
  return { error: errorMessage(err) };
238
- } finally {
239
- runtime.dispose();
240
181
  }
241
182
  }
242
183
  //#endregion
package/dist/internal.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { defineTool } from "./types.js";
2
- import { _ as TOOL_EXECUTION_TIMEOUT_MS, a as DEFAULT_SHUTDOWN_TIMEOUT_MS, c as FETCH_TIMEOUT_MS, d as MAX_HTML_BYTES, f as MAX_PAGE_CHARS, g as RUN_CODE_TIMEOUT_MS, h as RUN_CODE_MEMORY_MB, i as DEFAULT_SESSION_START_TIMEOUT_MS, l as HOOK_TIMEOUT_MS, m as MAX_VALUE_SIZE, n as DEFAULT_IDLE_TIMEOUT_MS, o as DEFAULT_STT_SAMPLE_RATE, p as MAX_TOOL_RESULT_CHARS, r as DEFAULT_MAX_HISTORY, s as DEFAULT_TTS_SAMPLE_RATE, t as AGENT_CSP, u as MAX_GLOB_PATTERN_LENGTH } from "./constants-BbAOvKl_.js";
3
- import { _ as consoleLogger, a as _internals, c as buildSystemPrompt, d as AgentConfigSchema, f as EMPTY_PARAMS, g as DEFAULT_S2S_CONFIG, h as toAgentConfig, i as createUnstorageKv, l as connectS2s, m as agentToolsToSchemas, n as executeToolCall, o as buildCtx, p as ToolSchemaSchema, r as wireSessionSocket, s as createS2sSession, t as createRuntime, u as defaultCreateS2sWebSocket, v as jsonLogger } from "./direct-executor-BfHrDdPL.js";
4
- import { createSessionStateMap, errorDetail, errorMessage, isReadOnlyFsOp, toolError } from "./_utils.js";
2
+ import { a as DEFAULT_SHUTDOWN_TIMEOUT_MS, c as FETCH_TIMEOUT_MS, d as MAX_HTML_BYTES, f as MAX_PAGE_CHARS, g as TOOL_EXECUTION_TIMEOUT_MS, h as RUN_CODE_TIMEOUT_MS, i as DEFAULT_SESSION_START_TIMEOUT_MS, l as HOOK_TIMEOUT_MS, m as MAX_VALUE_SIZE, n as DEFAULT_IDLE_TIMEOUT_MS, o as DEFAULT_STT_SAMPLE_RATE, p as MAX_TOOL_RESULT_CHARS, r as DEFAULT_MAX_HISTORY, s as DEFAULT_TTS_SAMPLE_RATE, t as AGENT_CSP, u as MAX_GLOB_PATTERN_LENGTH } from "./constants-CwotjpJR.js";
3
+ import { _ as consoleLogger, a as _internals, c as buildSystemPrompt, d as AgentConfigSchema, f as EMPTY_PARAMS, g as DEFAULT_S2S_CONFIG, h as toAgentConfig, i as createUnstorageKv, l as connectS2s, m as agentToolsToSchemas, n as executeToolCall, o as buildCtx, p as ToolSchemaSchema, r as wireSessionSocket, s as createS2sSession, t as createRuntime, u as defaultCreateS2sWebSocket, v as jsonLogger } from "./direct-executor-DAGCZOAN.js";
4
+ import { errorDetail, errorMessage, isReadOnlyFsOp, toolError } from "./_utils.js";
5
5
  import { callResolveTurnConfig, createAgentHooks } from "./hooks.js";
6
6
  import { AUDIO_FORMAT, ClientEventSchema, ClientMessageSchema, KvRequestSchema, ReadyConfigSchema, ServerMessageSchema, SessionErrorCodeSchema, TurnConfigSchema, buildReadyConfig } from "./protocol.js";
7
7
  import { z } from "zod";
@@ -26,21 +26,17 @@ import { describe, expect, test } from "vitest";
26
26
  * });
27
27
  * ```
28
28
  *
29
- * @example Sandbox (integration test)
29
+ * @example Sandbox (integration test in aai-server)
30
30
  * ```ts
31
- * import { testRuntime, CONFORMANCE_AGENT_BUNDLE } from "@alexkroman1/aai/runtime-conformance";
31
+ * import { testRuntime } from "@alexkroman1/aai/internal";
32
32
  *
33
33
  * testRuntime("sandbox", async () => {
34
- * // ... start isolate with CONFORMANCE_AGENT_BUNDLE
34
+ * // ... start isolate with a bundled agent
35
35
  * return { executeTool: buildExecuteTool(...), hooks: buildHookInvoker(...) };
36
36
  * });
37
37
  * ```
38
38
  */
39
- /**
40
- * Agent definition used by the conformance suite (direct executor path).
41
- *
42
- * Must be kept in sync with {@link CONFORMANCE_AGENT_BUNDLE}.
43
- */
39
+ /** Agent definition used by the conformance suite (direct executor path). */
44
40
  const CONFORMANCE_AGENT = {
45
41
  name: "conformance-test",
46
42
  instructions: "Conformance test agent.",
@@ -86,47 +82,6 @@ const CONFORMANCE_AGENT = {
86
82
  }
87
83
  };
88
84
  /**
89
- * JavaScript bundle equivalent of {@link CONFORMANCE_AGENT} for the sandbox
90
- * isolate path. Must be kept in sync with the AgentDef above.
91
- */
92
- const CONFORMANCE_AGENT_BUNDLE = `
93
- export default {
94
- name: "conformance-test",
95
- instructions: "Conformance test agent.",
96
- greeting: "Hello!",
97
- maxSteps: 5,
98
- state: () => ({ count: 0, lastTurn: "" }),
99
- tools: {
100
- echo: {
101
- description: "Echo input",
102
- execute(args) { return "echo:" + args.text; },
103
- },
104
- get_env: {
105
- description: "Get MY_VAR from env",
106
- execute(_args, ctx) { return ctx.env.MY_VAR ?? "missing"; },
107
- },
108
- get_state: {
109
- description: "Get session state",
110
- execute(_args, ctx) { return JSON.stringify(ctx.state); },
111
- },
112
- echo_messages: {
113
- description: "Return messages as JSON",
114
- execute(_args, ctx) { return JSON.stringify(ctx.messages); },
115
- },
116
- kv_roundtrip: {
117
- description: "KV set then get",
118
- async execute(args, ctx) {
119
- await ctx.kv.set("test-key", args.value);
120
- const result = await ctx.kv.get("test-key");
121
- return "stored:" + JSON.stringify(result);
122
- },
123
- },
124
- },
125
- onConnect: (ctx) => { ctx.state.count = 1; },
126
- onTurn: (text, ctx) => { ctx.state.lastTurn = text; },
127
- };
128
- `;
129
- /**
130
85
  * Run the runtime conformance test suite against a given runtime context.
131
86
  *
132
87
  * The `getContext` callback is invoked once per test to retrieve the
@@ -206,4 +161,4 @@ function testRuntime(label, getContext) {
206
161
  });
207
162
  }
208
163
  //#endregion
209
- export { AGENT_CSP, AUDIO_FORMAT, AgentConfigSchema, CONFORMANCE_AGENT, CONFORMANCE_AGENT_BUNDLE, ClientEventSchema, ClientMessageSchema, DEFAULT_IDLE_TIMEOUT_MS, DEFAULT_MAX_HISTORY, DEFAULT_S2S_CONFIG, 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_MEMORY_MB, RUN_CODE_TIMEOUT_MS, ReadyConfigSchema, ServerMessageSchema, SessionErrorCodeSchema, TOOL_EXECUTION_TIMEOUT_MS, ToolSchemaSchema, TurnConfigSchema, _internals, agentToolsToSchemas, buildCtx, buildReadyConfig, buildSystemPrompt, callResolveTurnConfig, connectS2s, consoleLogger, createAgentHooks, createRuntime, createS2sSession, createSessionStateMap, createUnstorageKv, defaultCreateS2sWebSocket, errorDetail, errorMessage, executeToolCall, isReadOnlyFsOp, jsonLogger, testRuntime, toAgentConfig, toolError, wireSessionSocket };
164
+ export { AGENT_CSP, AUDIO_FORMAT, AgentConfigSchema, CONFORMANCE_AGENT, ClientEventSchema, ClientMessageSchema, DEFAULT_IDLE_TIMEOUT_MS, DEFAULT_MAX_HISTORY, DEFAULT_S2S_CONFIG, 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, ToolSchemaSchema, TurnConfigSchema, _internals, agentToolsToSchemas, buildCtx, buildReadyConfig, buildSystemPrompt, callResolveTurnConfig, connectS2s, consoleLogger, createAgentHooks, createRuntime, createS2sSession, createUnstorageKv, defaultCreateS2sWebSocket, errorDetail, errorMessage, executeToolCall, isReadOnlyFsOp, jsonLogger, testRuntime, toAgentConfig, toolError, wireSessionSocket };
package/dist/kv.js CHANGED
@@ -1,4 +1,4 @@
1
- import { m as MAX_VALUE_SIZE, u as MAX_GLOB_PATTERN_LENGTH } from "./constants-BbAOvKl_.js";
1
+ import { m as MAX_VALUE_SIZE, u as MAX_GLOB_PATTERN_LENGTH } from "./constants-CwotjpJR.js";
2
2
  //#region kv.ts
3
3
  /**
4
4
  * Key-value storage interface and shared utilities.
package/dist/matchers.js CHANGED
@@ -1,4 +1,4 @@
1
- import { n as TurnResult } from "./testing-BonJtfHJ.js";
1
+ import { n as TurnResult } from "./testing-Dmx-dudh.js";
2
2
  import { expect } from "vitest";
3
3
  //#region matchers.ts
4
4
  /**
package/dist/protocol.js CHANGED
@@ -1,4 +1,4 @@
1
- import { p as MAX_TOOL_RESULT_CHARS } from "./constants-BbAOvKl_.js";
1
+ import { p as MAX_TOOL_RESULT_CHARS } from "./constants-CwotjpJR.js";
2
2
  import { z } from "zod";
3
3
  //#region protocol.ts
4
4
  /**
package/dist/server.js CHANGED
@@ -1,5 +1,5 @@
1
- import { t as AGENT_CSP } from "./constants-BbAOvKl_.js";
2
- import { _ as consoleLogger, t as createRuntime } from "./direct-executor-BfHrDdPL.js";
1
+ import { t as AGENT_CSP } from "./constants-CwotjpJR.js";
2
+ import { _ as consoleLogger, t as createRuntime } from "./direct-executor-DAGCZOAN.js";
3
3
  import fs from "node:fs";
4
4
  import http from "node:http";
5
5
  import path from "node:path";
@@ -1,5 +1,5 @@
1
1
  import "./types.js";
2
- import { i as createUnstorageKv, t as createRuntime } from "./direct-executor-BfHrDdPL.js";
2
+ import { i as createUnstorageKv, t as createRuntime } from "./direct-executor-DAGCZOAN.js";
3
3
  import { resolve } from "node:path";
4
4
  import { createStorage } from "unstorage";
5
5
  import "nanoevents";
@@ -162,6 +162,20 @@ function installMockWebSocket() {
162
162
  function flush() {
163
163
  return new Promise((r) => queueMicrotask(r));
164
164
  }
165
+ /** Create a stub Session with all methods as vi.fn() spies. */
166
+ function makeStubSession(overrides) {
167
+ return {
168
+ start: vi.fn(() => Promise.resolve()),
169
+ stop: vi.fn(() => Promise.resolve()),
170
+ onAudio: vi.fn(),
171
+ onAudioReady: vi.fn(),
172
+ onCancel: vi.fn(),
173
+ onReset: vi.fn(),
174
+ onHistory: vi.fn(),
175
+ waitForTurn: vi.fn(() => Promise.resolve()),
176
+ ...overrides
177
+ };
178
+ }
165
179
  vi.fn(), vi.fn(), vi.fn(), vi.fn();
166
180
  resolve(import.meta.dirname, "__fixtures__");
167
181
  //#endregion
@@ -496,4 +510,4 @@ function createTestHarness(agent, options = {}) {
496
510
  }), `test-${Date.now()}`);
497
511
  }
498
512
  //#endregion
499
- export { MockWebSocket as a, flush as i, TurnResult as n, installMockWebSocket as o, createTestHarness as r, TestHarness as t };
513
+ export { makeStubSession as a, flush as i, TurnResult as n, MockWebSocket as o, createTestHarness as r, installMockWebSocket as s, TestHarness as t };
package/dist/testing.d.ts CHANGED
@@ -39,7 +39,7 @@ import { type Runtime } from "./direct-executor.ts";
39
39
  import type { Kv } from "./kv.ts";
40
40
  import type { AgentDef, Message } from "./types.ts";
41
41
  export { installMockWebSocket, MockWebSocket } from "./_mock-ws.ts";
42
- export { flush } from "./_test-utils.ts";
42
+ export { flush, makeStubSession } from "./_test-utils.ts";
43
43
  /**
44
44
  * A single tool call recorded during a turn.
45
45
  *
package/dist/testing.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as MockWebSocket, i as flush, n as TurnResult, o as installMockWebSocket, r as createTestHarness, t as TestHarness } from "./testing-BonJtfHJ.js";
2
- export { MockWebSocket, TestHarness, TurnResult, createTestHarness, flush, installMockWebSocket };
1
+ import { a as makeStubSession, i as flush, n as TurnResult, o as MockWebSocket, r as createTestHarness, s as installMockWebSocket, t as TestHarness } from "./testing-Dmx-dudh.js";
2
+ export { MockWebSocket, TestHarness, TurnResult, createTestHarness, flush, installMockWebSocket, makeStubSession };
package/package.json CHANGED
@@ -1,63 +1,63 @@
1
1
  {
2
2
  "name": "@alexkroman1/aai",
3
- "version": "0.10.4",
3
+ "version": "0.11.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
7
7
  ],
8
8
  "exports": {
9
9
  ".": {
10
- "source": "./index.ts",
10
+ "@dev/source": "./index.ts",
11
11
  "types": "./dist/index.d.ts",
12
12
  "import": "./dist/index.js"
13
13
  },
14
14
  "./server": {
15
- "source": "./server.ts",
15
+ "@dev/source": "./server.ts",
16
16
  "types": "./dist/server.d.ts",
17
17
  "import": "./dist/server.js"
18
18
  },
19
19
  "./types": {
20
- "source": "./types.ts",
20
+ "@dev/source": "./types.ts",
21
21
  "types": "./dist/types.d.ts",
22
22
  "import": "./dist/types.js"
23
23
  },
24
24
  "./kv": {
25
- "source": "./kv.ts",
25
+ "@dev/source": "./kv.ts",
26
26
  "types": "./dist/kv.d.ts",
27
27
  "import": "./dist/kv.js"
28
28
  },
29
29
  "./protocol": {
30
- "source": "./protocol.ts",
30
+ "@dev/source": "./protocol.ts",
31
31
  "types": "./dist/protocol.d.ts",
32
32
  "import": "./dist/protocol.js"
33
33
  },
34
34
  "./testing": {
35
- "source": "./testing.ts",
35
+ "@dev/source": "./testing.ts",
36
36
  "types": "./dist/testing.d.ts",
37
37
  "import": "./dist/testing.js"
38
38
  },
39
39
  "./testing/matchers": {
40
- "source": "./matchers.ts",
40
+ "@dev/source": "./matchers.ts",
41
41
  "types": "./dist/matchers.d.ts",
42
42
  "import": "./dist/matchers.js"
43
43
  },
44
44
  "./internal": {
45
- "source": "./internal.ts",
45
+ "@dev/source": "./internal.ts",
46
46
  "types": "./dist/internal.d.ts",
47
47
  "import": "./dist/internal.js"
48
48
  },
49
49
  "./hooks": {
50
- "source": "./hooks.ts",
50
+ "@dev/source": "./hooks.ts",
51
51
  "types": "./dist/hooks.d.ts",
52
52
  "import": "./dist/hooks.js"
53
53
  },
54
54
  "./utils": {
55
- "source": "./_utils.ts",
55
+ "@dev/source": "./_utils.ts",
56
56
  "types": "./dist/_utils.d.ts",
57
57
  "import": "./dist/_utils.js"
58
58
  },
59
59
  "./vite-plugin": {
60
- "source": "./vite-plugin.ts",
60
+ "@dev/source": "./vite-plugin.ts",
61
61
  "types": "./dist/vite-plugin.d.ts",
62
62
  "import": "./dist/vite-plugin.js"
63
63
  }
@@ -66,7 +66,6 @@
66
66
  "hookable": "^6.1.0",
67
67
  "nanoevents": "^9.1.0",
68
68
  "p-timeout": "^7.0.1",
69
- "secure-exec": "^0.1.0",
70
69
  "unstorage": "^1.17.5",
71
70
  "ws": "^8.20.0",
72
71
  "zod": "^4.3.6"