@alexkroman1/aai 0.10.2 → 0.10.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal-types.d.ts +8 -1
- package/dist/_runtime-conformance.d.ts +64 -0
- package/dist/_test-utils.d.ts +70 -0
- package/dist/_utils.d.ts +1 -8
- package/dist/_utils.js +1 -13
- package/dist/builtin-tools.d.ts +1 -5
- package/dist/constants-BbAOvKl_.js +47 -0
- package/dist/constants.d.ts +44 -0
- package/dist/direct-executor-BfHrDdPL.js +1589 -0
- package/dist/direct-executor.d.ts +90 -31
- package/dist/hooks.d.ts +44 -0
- package/dist/hooks.js +58 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +2 -2
- package/dist/internal.d.ts +19 -0
- package/dist/internal.js +209 -0
- package/dist/kv.d.ts +1 -1
- package/dist/kv.js +5 -4
- package/dist/matchers.js +1 -1
- package/dist/protocol.d.ts +3 -29
- package/dist/protocol.js +2 -24
- package/dist/server.d.ts +25 -38
- package/dist/server.js +114 -138
- package/dist/session.d.ts +65 -44
- package/dist/{testing-MRl3SXsI.js → testing-BonJtfHJ.js} +26 -46
- package/dist/testing.d.ts +9 -14
- package/dist/testing.js +2 -2
- package/dist/types.d.ts +24 -226
- package/dist/types.js +6 -22
- package/dist/types.test-d.d.ts +7 -0
- package/dist/unstorage-kv.d.ts +33 -0
- package/dist/vite-plugin.d.ts +15 -0
- package/dist/vite-plugin.js +82 -0
- package/dist/ws-handler.d.ts +1 -2
- package/package.json +29 -84
- package/dist/_internal-types.js +0 -61
- package/dist/_session-ctx.d.ts +0 -73
- package/dist/_session-otel.d.ts +0 -43
- package/dist/_session-persist.d.ts +0 -30
- package/dist/_ssrf.d.ts +0 -30
- package/dist/_ssrf.js +0 -123
- package/dist/direct-executor-Ca0wt5H0.js +0 -572
- package/dist/middleware-core.d.ts +0 -47
- package/dist/middleware-core.js +0 -107
- package/dist/middleware.d.ts +0 -37
- package/dist/runtime.js +0 -53
- package/dist/s2s.js +0 -272
- package/dist/session-BkN9u0ni.js +0 -683
- package/dist/session.js +0 -2
- package/dist/sqlite-kv.d.ts +0 -34
- package/dist/sqlite-kv.js +0 -133
- package/dist/sqlite-vector.d.ts +0 -58
- package/dist/sqlite-vector.js +0 -149
- package/dist/telemetry.d.ts +0 -49
- package/dist/telemetry.js +0 -95
- package/dist/vector.d.ts +0 -85
- package/dist/vector.js +0 -49
- package/dist/worker-entry.d.ts +0 -47
- package/dist/worker-entry.js +0 -70
- package/dist/ws-handler.js +0 -207
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
1
|
+
import "./types.js";
|
|
2
|
+
import { i as createUnstorageKv, t as createRuntime } from "./direct-executor-BfHrDdPL.js";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { createStorage } from "unstorage";
|
|
5
|
+
import "nanoevents";
|
|
6
|
+
import { vi } from "vitest";
|
|
7
7
|
//#region _mock-ws.ts
|
|
8
8
|
/**
|
|
9
9
|
* A mock WebSocket implementation for testing.
|
|
@@ -157,6 +157,14 @@ function installMockWebSocket() {
|
|
|
157
157
|
};
|
|
158
158
|
}
|
|
159
159
|
//#endregion
|
|
160
|
+
//#region _test-utils.ts
|
|
161
|
+
/** Yield to the microtask queue so pending promises settle. */
|
|
162
|
+
function flush() {
|
|
163
|
+
return new Promise((r) => queueMicrotask(r));
|
|
164
|
+
}
|
|
165
|
+
vi.fn(), vi.fn(), vi.fn(), vi.fn();
|
|
166
|
+
resolve(import.meta.dirname, "__fixtures__");
|
|
167
|
+
//#endregion
|
|
160
168
|
//#region testing.ts
|
|
161
169
|
/**
|
|
162
170
|
* Testing utilities for AAI agents.
|
|
@@ -317,7 +325,6 @@ var TestHarness = class {
|
|
|
317
325
|
/** @internal */
|
|
318
326
|
_sessionId;
|
|
319
327
|
_messages = [];
|
|
320
|
-
_onStepCalls = [];
|
|
321
328
|
_onTurnCalls = [];
|
|
322
329
|
_connected = false;
|
|
323
330
|
/** @internal */
|
|
@@ -329,10 +336,6 @@ var TestHarness = class {
|
|
|
329
336
|
get messages() {
|
|
330
337
|
return this._messages;
|
|
331
338
|
}
|
|
332
|
-
/** All `onStep` hook invocations recorded so far. */
|
|
333
|
-
get steps() {
|
|
334
|
-
return this._onStepCalls;
|
|
335
|
-
}
|
|
336
339
|
/** All `onTurn` hook invocations (the text argument) recorded so far. */
|
|
337
340
|
get turns() {
|
|
338
341
|
return this._onTurnCalls;
|
|
@@ -345,7 +348,7 @@ var TestHarness = class {
|
|
|
345
348
|
async connect() {
|
|
346
349
|
if (this._connected) return;
|
|
347
350
|
this._connected = true;
|
|
348
|
-
await this._executor.
|
|
351
|
+
await this._executor.hooks.callHook("connect", this._sessionId);
|
|
349
352
|
}
|
|
350
353
|
/**
|
|
351
354
|
* Fire the `onDisconnect` lifecycle hook and clean up session state.
|
|
@@ -353,12 +356,12 @@ var TestHarness = class {
|
|
|
353
356
|
async disconnect() {
|
|
354
357
|
if (!this._connected) return;
|
|
355
358
|
this._connected = false;
|
|
356
|
-
await this._executor.
|
|
359
|
+
await this._executor.hooks.callHook("disconnect", this._sessionId);
|
|
357
360
|
}
|
|
358
361
|
/**
|
|
359
362
|
* Execute a single tool by name with the given arguments.
|
|
360
363
|
*
|
|
361
|
-
* The tool runs with full agent context (env, state, kv,
|
|
364
|
+
* The tool runs with full agent context (env, state, kv, messages).
|
|
362
365
|
* The call is **not** recorded in conversation history — use {@link turn}
|
|
363
366
|
* for that.
|
|
364
367
|
*
|
|
@@ -384,7 +387,7 @@ var TestHarness = class {
|
|
|
384
387
|
* 1. Fires `onConnect` if this is the first turn
|
|
385
388
|
* 2. Adds the user message to conversation history
|
|
386
389
|
* 3. Fires the `onTurn` hook
|
|
387
|
-
* 4. Executes each tool call in order
|
|
390
|
+
* 4. Executes each tool call in order
|
|
388
391
|
* 5. Returns a {@link TurnResult} with assertion helpers
|
|
389
392
|
*
|
|
390
393
|
* @param text - The user's spoken/typed input.
|
|
@@ -407,10 +410,9 @@ var TestHarness = class {
|
|
|
407
410
|
content: text
|
|
408
411
|
});
|
|
409
412
|
this._onTurnCalls.push(text);
|
|
410
|
-
await this._executor.
|
|
413
|
+
await this._executor.hooks.callHook("turn", this._sessionId, text);
|
|
411
414
|
const recorded = [];
|
|
412
|
-
for (
|
|
413
|
-
const tc = toolCalls[i];
|
|
415
|
+
for (const tc of toolCalls) {
|
|
414
416
|
const result = await this._executor.executeTool(tc.tool, tc.args, this._sessionId, this._messages);
|
|
415
417
|
recorded.push({
|
|
416
418
|
toolName: tc.tool,
|
|
@@ -421,16 +423,6 @@ var TestHarness = class {
|
|
|
421
423
|
role: "tool",
|
|
422
424
|
content: result
|
|
423
425
|
});
|
|
424
|
-
const step = {
|
|
425
|
-
stepNumber: i + 1,
|
|
426
|
-
toolCalls: [{
|
|
427
|
-
toolName: tc.tool,
|
|
428
|
-
args: tc.args
|
|
429
|
-
}],
|
|
430
|
-
text: ""
|
|
431
|
-
};
|
|
432
|
-
this._onStepCalls.push(step);
|
|
433
|
-
await this._executor.hookInvoker.onStep(this._sessionId, step);
|
|
434
426
|
}
|
|
435
427
|
return new TurnResult(text, recorded);
|
|
436
428
|
}
|
|
@@ -459,25 +451,14 @@ var TestHarness = class {
|
|
|
459
451
|
/**
|
|
460
452
|
* Reset conversation state: clears messages, step/turn history.
|
|
461
453
|
*
|
|
462
|
-
* Does **not** reset KV
|
|
454
|
+
* Does **not** reset KV store — create a new harness for that.
|
|
463
455
|
*/
|
|
464
456
|
reset() {
|
|
465
457
|
this._messages = [];
|
|
466
|
-
this._onStepCalls = [];
|
|
467
458
|
this._onTurnCalls = [];
|
|
468
459
|
}
|
|
469
460
|
};
|
|
470
461
|
/**
|
|
471
|
-
* Create a SQLite-vec backed vector store with deterministic test embeddings.
|
|
472
|
-
* Uses a temp directory that is unique per call for test isolation.
|
|
473
|
-
*/
|
|
474
|
-
function createTestVectorStore() {
|
|
475
|
-
return createSqliteVectorStore({
|
|
476
|
-
path: join(mkdtempSync(join(tmpdir(), "aai-test-vec-")), "vectors.db"),
|
|
477
|
-
embedFn: createTestEmbedFn()
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
/**
|
|
481
462
|
* Create a test harness for unit-testing an agent.
|
|
482
463
|
*
|
|
483
464
|
* The harness wraps the agent's tool definitions and lifecycle hooks,
|
|
@@ -485,7 +466,7 @@ function createTestVectorStore() {
|
|
|
485
466
|
* conversations — all without audio, network, or an LLM.
|
|
486
467
|
*
|
|
487
468
|
* @param agent - The agent definition returned by `defineAgent()`.
|
|
488
|
-
* @param options - Optional environment
|
|
469
|
+
* @param options - Optional environment and KV store overrides.
|
|
489
470
|
* @returns A {@link TestHarness} instance.
|
|
490
471
|
*
|
|
491
472
|
* @example
|
|
@@ -507,13 +488,12 @@ function createTestVectorStore() {
|
|
|
507
488
|
* @public
|
|
508
489
|
*/
|
|
509
490
|
function createTestHarness(agent, options = {}) {
|
|
510
|
-
const { env = {}, kv =
|
|
511
|
-
return new TestHarness(
|
|
491
|
+
const { env = {}, kv = createUnstorageKv({ storage: createStorage() }) } = options;
|
|
492
|
+
return new TestHarness(createRuntime({
|
|
512
493
|
agent,
|
|
513
494
|
env,
|
|
514
|
-
kv
|
|
515
|
-
vector
|
|
495
|
+
kv
|
|
516
496
|
}), `test-${Date.now()}`);
|
|
517
497
|
}
|
|
518
498
|
//#endregion
|
|
519
|
-
export {
|
|
499
|
+
export { MockWebSocket as a, flush as i, TurnResult as n, installMockWebSocket as o, createTestHarness as r, TestHarness as t };
|
package/dist/testing.d.ts
CHANGED
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
*
|
|
36
36
|
* @packageDocumentation
|
|
37
37
|
*/
|
|
38
|
-
import { type
|
|
38
|
+
import { type Runtime } from "./direct-executor.ts";
|
|
39
39
|
import type { Kv } from "./kv.ts";
|
|
40
|
-
import type { AgentDef, Message
|
|
41
|
-
import type { VectorStore } from "./vector.ts";
|
|
40
|
+
import type { AgentDef, Message } from "./types.ts";
|
|
42
41
|
export { installMockWebSocket, MockWebSocket } from "./_mock-ws.ts";
|
|
42
|
+
export { flush } from "./_test-utils.ts";
|
|
43
43
|
/**
|
|
44
44
|
* A single tool call recorded during a turn.
|
|
45
45
|
*
|
|
@@ -137,8 +137,6 @@ export type TestHarnessOptions = {
|
|
|
137
137
|
env?: Record<string, string>;
|
|
138
138
|
/** KV store instance. Defaults to an in-memory SQLite store. */
|
|
139
139
|
kv?: Kv;
|
|
140
|
-
/** Vector store instance. Defaults to an in-memory SQLite store. */
|
|
141
|
-
vector?: VectorStore;
|
|
142
140
|
};
|
|
143
141
|
/**
|
|
144
142
|
* A tool call to execute during a simulated turn.
|
|
@@ -179,19 +177,16 @@ export type TurnToolCall = {
|
|
|
179
177
|
*/
|
|
180
178
|
export declare class TestHarness {
|
|
181
179
|
/** @internal */
|
|
182
|
-
readonly _executor:
|
|
180
|
+
readonly _executor: Runtime;
|
|
183
181
|
/** @internal */
|
|
184
182
|
readonly _sessionId: string;
|
|
185
183
|
private _messages;
|
|
186
|
-
private _onStepCalls;
|
|
187
184
|
private _onTurnCalls;
|
|
188
185
|
private _connected;
|
|
189
186
|
/** @internal */
|
|
190
|
-
constructor(executor:
|
|
187
|
+
constructor(executor: Runtime, sessionId: string);
|
|
191
188
|
/** Conversation messages accumulated across turns. */
|
|
192
189
|
get messages(): readonly Message[];
|
|
193
|
-
/** All `onStep` hook invocations recorded so far. */
|
|
194
|
-
get steps(): readonly StepInfo[];
|
|
195
190
|
/** All `onTurn` hook invocations (the text argument) recorded so far. */
|
|
196
191
|
get turns(): readonly string[];
|
|
197
192
|
/**
|
|
@@ -207,7 +202,7 @@ export declare class TestHarness {
|
|
|
207
202
|
/**
|
|
208
203
|
* Execute a single tool by name with the given arguments.
|
|
209
204
|
*
|
|
210
|
-
* The tool runs with full agent context (env, state, kv,
|
|
205
|
+
* The tool runs with full agent context (env, state, kv, messages).
|
|
211
206
|
* The call is **not** recorded in conversation history — use {@link turn}
|
|
212
207
|
* for that.
|
|
213
208
|
*
|
|
@@ -231,7 +226,7 @@ export declare class TestHarness {
|
|
|
231
226
|
* 1. Fires `onConnect` if this is the first turn
|
|
232
227
|
* 2. Adds the user message to conversation history
|
|
233
228
|
* 3. Fires the `onTurn` hook
|
|
234
|
-
* 4. Executes each tool call in order
|
|
229
|
+
* 4. Executes each tool call in order
|
|
235
230
|
* 5. Returns a {@link TurnResult} with assertion helpers
|
|
236
231
|
*
|
|
237
232
|
* @param text - The user's spoken/typed input.
|
|
@@ -263,7 +258,7 @@ export declare class TestHarness {
|
|
|
263
258
|
/**
|
|
264
259
|
* Reset conversation state: clears messages, step/turn history.
|
|
265
260
|
*
|
|
266
|
-
* Does **not** reset KV
|
|
261
|
+
* Does **not** reset KV store — create a new harness for that.
|
|
267
262
|
*/
|
|
268
263
|
reset(): void;
|
|
269
264
|
}
|
|
@@ -275,7 +270,7 @@ export declare class TestHarness {
|
|
|
275
270
|
* conversations — all without audio, network, or an LLM.
|
|
276
271
|
*
|
|
277
272
|
* @param agent - The agent definition returned by `defineAgent()`.
|
|
278
|
-
* @param options - Optional environment
|
|
273
|
+
* @param options - Optional environment and KV store overrides.
|
|
279
274
|
* @returns A {@link TestHarness} instance.
|
|
280
275
|
*
|
|
281
276
|
* @example
|
package/dist/testing.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { MockWebSocket, TestHarness, TurnResult, createTestHarness, installMockWebSocket };
|
|
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 };
|
package/dist/types.d.ts
CHANGED
|
@@ -3,154 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import type { Kv } from "./kv.ts";
|
|
6
|
-
import type { VectorStore } from "./vector.ts";
|
|
7
|
-
/**
|
|
8
|
-
* Result returned by a `beforeTurn` middleware to block a turn.
|
|
9
|
-
* @public
|
|
10
|
-
*/
|
|
11
|
-
export type MiddlewareBlockResult = {
|
|
12
|
-
block: true;
|
|
13
|
-
reason: string;
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
* Result returned by a `beforeToolCall` middleware hook to short-circuit tool execution.
|
|
17
|
-
*
|
|
18
|
-
* Return `{ result: string }` to skip execution and use a cached/synthetic result.
|
|
19
|
-
* Return `{ block: true; reason: string }` to deny the tool call.
|
|
20
|
-
* Return `{ args: Record<string, unknown> }` to transform the arguments.
|
|
21
|
-
* Return `undefined` to proceed normally.
|
|
22
|
-
*
|
|
23
|
-
* @public
|
|
24
|
-
*/
|
|
25
|
-
export type ToolCallInterceptResult = {
|
|
26
|
-
result: string;
|
|
27
|
-
} | {
|
|
28
|
-
block: true;
|
|
29
|
-
reason: string;
|
|
30
|
-
} | {
|
|
31
|
-
args: Record<string, unknown>;
|
|
32
|
-
} | undefined;
|
|
33
|
-
/**
|
|
34
|
-
* Composable middleware for the agent lifecycle.
|
|
35
|
-
*
|
|
36
|
-
* Middleware can intercept turns, tool calls, and output at well-defined
|
|
37
|
-
* points. Multiple middleware compose in array order: the first middleware
|
|
38
|
-
* in the array runs first for "before" hooks and last for "after" hooks.
|
|
39
|
-
*
|
|
40
|
-
* ## Middleware Composition Order
|
|
41
|
-
*
|
|
42
|
-
* **"Before" hooks** run in array order (first middleware → last):
|
|
43
|
-
* `beforeInput` → `beforeTurn` → `beforeToolCall` → `beforeOutput`
|
|
44
|
-
*
|
|
45
|
-
* **"After" hooks** run in reverse array order (last middleware → first):
|
|
46
|
-
* `afterToolCall` → `afterTurn`
|
|
47
|
-
*
|
|
48
|
-
* ### Execution flow for a user turn
|
|
49
|
-
*
|
|
50
|
-
* ```
|
|
51
|
-
* User text arrives
|
|
52
|
-
* │
|
|
53
|
-
* ▼
|
|
54
|
-
* beforeInput — transform/redact input text (piped through each middleware)
|
|
55
|
-
* │
|
|
56
|
-
* ▼
|
|
57
|
-
* beforeTurn — block or allow the turn (short-circuits on first block)
|
|
58
|
-
* │
|
|
59
|
-
* ▼ (if not blocked)
|
|
60
|
-
* LLM reasoning + tool calls
|
|
61
|
-
* │ ┌─ beforeToolCall (per call, short-circuits on block/result)
|
|
62
|
-
* │ └─ afterToolCall (per call, reverse order)
|
|
63
|
-
* │
|
|
64
|
-
* ▼
|
|
65
|
-
* beforeOutput — transform/redact LLM output text (piped through each middleware)
|
|
66
|
-
* │
|
|
67
|
-
* ▼
|
|
68
|
-
* afterTurn — cleanup/logging (reverse order)
|
|
69
|
-
* ```
|
|
70
|
-
*
|
|
71
|
-
* ### Short-circuit behavior
|
|
72
|
-
*
|
|
73
|
-
* - **`beforeTurn`**: If *any* middleware returns `{ block: true, reason }`,
|
|
74
|
-
* the turn is blocked and subsequent `beforeTurn` hooks do **not** run.
|
|
75
|
-
* When a turn is blocked, `afterTurn` hooks do **not** fire (the turn
|
|
76
|
-
* never started).
|
|
77
|
-
* - **`beforeToolCall`**: If *any* middleware blocks or returns a cached
|
|
78
|
-
* result, subsequent `beforeToolCall` hooks do **not** run. Arg transforms
|
|
79
|
-
* accumulate across middleware.
|
|
80
|
-
* - **`beforeInput`** / **`beforeOutput`**: These *always* run all middleware
|
|
81
|
-
* in sequence (no short-circuit). Each receives the output of the previous.
|
|
82
|
-
*
|
|
83
|
-
* ### Ordering example
|
|
84
|
-
*
|
|
85
|
-
* ```ts
|
|
86
|
-
* middleware: [auditTrail, hipaaGuardrails]
|
|
87
|
-
* ```
|
|
88
|
-
* - `beforeInput`: auditTrail runs first, then hipaaGuardrails
|
|
89
|
-
* - `beforeTurn`: auditTrail runs first; if it blocks, hipaaGuardrails is skipped
|
|
90
|
-
* - `afterTurn`: hipaaGuardrails runs first (reverse), then auditTrail
|
|
91
|
-
*
|
|
92
|
-
* If you want the guardrail to run *before* the audit trail logs, place it
|
|
93
|
-
* first in the array: `[hipaaGuardrails, auditTrail]`.
|
|
94
|
-
*
|
|
95
|
-
* @typeParam S - The shape of per-session state. Defaults to `any` so that
|
|
96
|
-
* reusable, state-agnostic middleware (e.g. loggers, rate-limiters) can be
|
|
97
|
-
* authored without threading a state generic. Use an explicit generic
|
|
98
|
-
* (`Middleware<MyState>`) when the middleware reads or writes session state.
|
|
99
|
-
*
|
|
100
|
-
* @public
|
|
101
|
-
*/
|
|
102
|
-
export type Middleware<S = any> = {
|
|
103
|
-
/** Human-readable name for logging and debugging. */
|
|
104
|
-
name: string;
|
|
105
|
-
/**
|
|
106
|
-
* Filters user input text before it reaches the LLM. Return the
|
|
107
|
-
* (possibly modified) text. Runs on every user transcript, before
|
|
108
|
-
* `beforeTurn`.
|
|
109
|
-
*
|
|
110
|
-
* Use this to redact PII (SSNs, emails, patient IDs) from speech
|
|
111
|
-
* transcripts so the LLM never sees sensitive data.
|
|
112
|
-
*
|
|
113
|
-
* Middleware is piped in array order: the output of one filter becomes
|
|
114
|
-
* the input of the next.
|
|
115
|
-
*
|
|
116
|
-
* @example
|
|
117
|
-
* ```ts
|
|
118
|
-
* beforeInput: (text) =>
|
|
119
|
-
* text.replace(/\b\d{3}[-.]?\d{2}[-.]?\d{4}\b/g, "[SSN REDACTED]")
|
|
120
|
-
* ```
|
|
121
|
-
*/
|
|
122
|
-
beforeInput?: (text: string, ctx: HookContext<S>) => string | Promise<string>;
|
|
123
|
-
/**
|
|
124
|
-
* Runs before each user turn. Can block the turn by returning
|
|
125
|
-
* `{ block: true, reason: "..." }`. Return `undefined` to proceed.
|
|
126
|
-
*
|
|
127
|
-
* Receives the text *after* `beforeInput` filtering has been applied.
|
|
128
|
-
*
|
|
129
|
-
* When a turn is blocked, subsequent `beforeTurn` middleware is skipped,
|
|
130
|
-
* and `afterTurn` hooks do **not** fire.
|
|
131
|
-
*/
|
|
132
|
-
beforeTurn?: (text: string, ctx: HookContext<S>) => MiddlewareBlockResult | void | undefined | Promise<MiddlewareBlockResult | void | undefined>;
|
|
133
|
-
/**
|
|
134
|
-
* Runs after each user turn completes (after all steps finish).
|
|
135
|
-
* Runs in reverse array order.
|
|
136
|
-
*/
|
|
137
|
-
afterTurn?: (text: string, ctx: HookContext<S>) => void | Promise<void>;
|
|
138
|
-
/**
|
|
139
|
-
* Runs before each tool call. Can approve, deny, transform args, or
|
|
140
|
-
* return a cached result.
|
|
141
|
-
*/
|
|
142
|
-
beforeToolCall?: (toolName: string, args: Readonly<Record<string, unknown>>, ctx: HookContext<S>) => ToolCallInterceptResult | undefined | Promise<ToolCallInterceptResult | undefined>;
|
|
143
|
-
/**
|
|
144
|
-
* Runs after each tool call completes. Useful for caching results,
|
|
145
|
-
* logging, or analytics. Runs in reverse array order.
|
|
146
|
-
*/
|
|
147
|
-
afterToolCall?: (toolName: string, args: Readonly<Record<string, unknown>>, result: string, ctx: HookContext<S>) => void | Promise<void>;
|
|
148
|
-
/**
|
|
149
|
-
* Filters agent text output before it is sent to TTS. Return the
|
|
150
|
-
* (possibly modified) text. Runs on every agent transcript chunk.
|
|
151
|
-
*/
|
|
152
|
-
beforeOutput?: (text: string, ctx: HookContext<S>) => string | Promise<string>;
|
|
153
|
-
};
|
|
154
6
|
/**
|
|
155
7
|
* Identifier for a built-in server-side tool.
|
|
156
8
|
*
|
|
@@ -161,12 +13,11 @@ export type Middleware<S = any> = {
|
|
|
161
13
|
* - `"visit_webpage"` — Fetch a URL and return its content as clean text.
|
|
162
14
|
* - `"fetch_json"` — Call a REST API endpoint and return the JSON response.
|
|
163
15
|
* - `"run_code"` — Execute JavaScript in a sandbox for calculations and data processing.
|
|
164
|
-
* - `"vector_search"` — Search the agent's RAG knowledge base for relevant documents.
|
|
165
16
|
* - `"memory"` — Persistent KV memory: save_memory, recall_memory, list_memories, forget_memory.
|
|
166
17
|
*
|
|
167
18
|
* @public
|
|
168
19
|
*/
|
|
169
|
-
export type BuiltinTool = "web_search" | "visit_webpage" | "fetch_json" | "run_code" | "
|
|
20
|
+
export type BuiltinTool = "web_search" | "visit_webpage" | "fetch_json" | "run_code" | "memory";
|
|
170
21
|
/**
|
|
171
22
|
* How the LLM should select tools during a turn.
|
|
172
23
|
*
|
|
@@ -228,23 +79,8 @@ export type ToolContext<S = Record<string, unknown>> = {
|
|
|
228
79
|
state: S;
|
|
229
80
|
/** Key-value store scoped to this agent deployment. */
|
|
230
81
|
kv: Kv;
|
|
231
|
-
/** Vector store scoped to this agent deployment. */
|
|
232
|
-
vector: VectorStore;
|
|
233
82
|
/** Read-only snapshot of conversation messages so far. */
|
|
234
83
|
messages: readonly Message[];
|
|
235
|
-
/**
|
|
236
|
-
* Push an intermediate update to the client UI before the tool finishes.
|
|
237
|
-
*
|
|
238
|
-
* Use this to send progressive data so the UI can render partial results
|
|
239
|
-
* immediately (e.g. a loading card, preview, or streaming data) instead
|
|
240
|
-
* of waiting for the full tool result.
|
|
241
|
-
*
|
|
242
|
-
* The data is serialized to JSON and delivered as a `tool_call_update`
|
|
243
|
-
* event on the client. Use `useToolCallUpdate` in the UI to consume it.
|
|
244
|
-
*
|
|
245
|
-
* No-op in sandbox (platform) mode.
|
|
246
|
-
*/
|
|
247
|
-
sendUpdate(data: unknown): void;
|
|
248
84
|
/**
|
|
249
85
|
* SSRF-safe fetch function.
|
|
250
86
|
*
|
|
@@ -258,17 +94,29 @@ export type ToolContext<S = Record<string, unknown>> = {
|
|
|
258
94
|
sessionId: string;
|
|
259
95
|
};
|
|
260
96
|
/**
|
|
261
|
-
* Context passed to lifecycle hooks
|
|
262
|
-
*
|
|
263
|
-
* Same as {@link ToolContext} but without `messages`, since hooks
|
|
264
|
-
* run outside the tool execution flow.
|
|
97
|
+
* Context passed to lifecycle hooks.
|
|
265
98
|
*
|
|
266
99
|
* @typeParam S - The shape of per-session state created by the agent's
|
|
267
100
|
* `state` factory. Defaults to `Record<string, unknown>`.
|
|
268
101
|
*
|
|
269
102
|
* @public
|
|
270
103
|
*/
|
|
271
|
-
export type HookContext<S = Record<string, unknown>> =
|
|
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
|
+
};
|
|
272
120
|
/**
|
|
273
121
|
* Definition of a custom tool that the agent can invoke.
|
|
274
122
|
*
|
|
@@ -344,17 +192,17 @@ export { defineTool as tool };
|
|
|
344
192
|
* Create a typed `defineTool` helper with the session state type baked in.
|
|
345
193
|
*
|
|
346
194
|
* When tools need access to typed session state, you'd normally have to write
|
|
347
|
-
* verbose generics on every `defineTool` call. `
|
|
195
|
+
* verbose generics on every `defineTool` call. `defineToolFactory` eliminates
|
|
348
196
|
* that boilerplate by returning a `defineTool` variant that already knows `S`.
|
|
349
197
|
*
|
|
350
198
|
* @example
|
|
351
199
|
* ```ts
|
|
352
|
-
* import {
|
|
200
|
+
* import { defineToolFactory, defineAgent } from "aai";
|
|
353
201
|
* import { z } from "zod";
|
|
354
202
|
*
|
|
355
203
|
* interface PortfolioState { holdings: Map<string, number> }
|
|
356
204
|
*
|
|
357
|
-
* const tool =
|
|
205
|
+
* const tool = defineToolFactory<PortfolioState>();
|
|
358
206
|
*
|
|
359
207
|
* export default defineAgent<PortfolioState>({
|
|
360
208
|
* name: "portfolio",
|
|
@@ -374,7 +222,7 @@ export { defineTool as tool };
|
|
|
374
222
|
*
|
|
375
223
|
* @public
|
|
376
224
|
*/
|
|
377
|
-
export declare function
|
|
225
|
+
export declare function defineToolFactory<S = Record<string, unknown>>(): <P extends z.ZodObject<z.ZodRawShape>>(def: ToolDef<P, S>) => ToolDef<P, S>;
|
|
378
226
|
/**
|
|
379
227
|
* A mapping of tool names to their result types.
|
|
380
228
|
*
|
|
@@ -413,25 +261,6 @@ export declare function createToolFactory<S = Record<string, unknown>>(): <P ext
|
|
|
413
261
|
* @public
|
|
414
262
|
*/
|
|
415
263
|
export type ToolResultMap<T extends Record<string, unknown> = Record<string, unknown>> = T;
|
|
416
|
-
/**
|
|
417
|
-
* Information about a completed agentic step, passed to the `onStep` hook.
|
|
418
|
-
*
|
|
419
|
-
* Each turn may consist of multiple steps (up to `maxSteps`). A step
|
|
420
|
-
* represents one LLM invocation that may include tool calls and text output.
|
|
421
|
-
*
|
|
422
|
-
* @public
|
|
423
|
-
*/
|
|
424
|
-
export type StepInfo = {
|
|
425
|
-
/** 1-based step index within the current turn. */
|
|
426
|
-
stepNumber: number;
|
|
427
|
-
/** Tool calls made during this step. */
|
|
428
|
-
toolCalls: readonly {
|
|
429
|
-
toolName: string;
|
|
430
|
-
args: Readonly<Record<string, unknown>>;
|
|
431
|
-
}[];
|
|
432
|
-
/** LLM text output for this step. */
|
|
433
|
-
text: string;
|
|
434
|
-
};
|
|
435
264
|
/**
|
|
436
265
|
* Options passed to {@link defineAgent} to configure an agent.
|
|
437
266
|
*
|
|
@@ -485,21 +314,6 @@ export type AgentOptions<S = Record<string, unknown>> = {
|
|
|
485
314
|
tools?: Readonly<Record<string, ToolDef<z.ZodObject<z.ZodRawShape>, NoInfer<S>>>>;
|
|
486
315
|
/** Factory that creates fresh per-session state. Called once per connection. */
|
|
487
316
|
state?: () => S;
|
|
488
|
-
/**
|
|
489
|
-
* Enable automatic session state persistence across reconnects.
|
|
490
|
-
*
|
|
491
|
-
* When enabled, session state, conversation history, and the S2S session ID
|
|
492
|
-
* are saved to KV on disconnect and restored when the client reconnects with
|
|
493
|
-
* `?sessionId=<old-session-id>` in the WebSocket URL.
|
|
494
|
-
*
|
|
495
|
-
* - `true` — enable with default TTL (1 hour)
|
|
496
|
-
* - `{ ttl: number }` — enable with custom TTL in milliseconds
|
|
497
|
-
*
|
|
498
|
-
* Requires the agent's `state` return value to be JSON-serializable.
|
|
499
|
-
*/
|
|
500
|
-
persistence?: boolean | {
|
|
501
|
-
ttl?: number;
|
|
502
|
-
};
|
|
503
317
|
/** Called when a new session connects. */
|
|
504
318
|
onConnect?: (ctx: HookContext<S>) => void | Promise<void>;
|
|
505
319
|
/** Called when a session disconnects. */
|
|
@@ -508,15 +322,6 @@ export type AgentOptions<S = Record<string, unknown>> = {
|
|
|
508
322
|
onError?: (error: Error, ctx?: HookContext<S>) => void;
|
|
509
323
|
/** Called after a complete turn (all steps finished). */
|
|
510
324
|
onTurn?: (text: string, ctx: HookContext<S>) => void | Promise<void>;
|
|
511
|
-
/** Called after each agentic step completes. */
|
|
512
|
-
onStep?: (step: StepInfo, ctx: HookContext<S>) => void | Promise<void>;
|
|
513
|
-
/**
|
|
514
|
-
* Composable middleware that intercepts turns, tool calls, and output.
|
|
515
|
-
*
|
|
516
|
-
* Middleware runs in array order for "before" hooks (first to last)
|
|
517
|
-
* and reverse order for "after" hooks (last to first).
|
|
518
|
-
*/
|
|
519
|
-
middleware?: readonly Middleware<S>[];
|
|
520
325
|
/**
|
|
521
326
|
* Close the S2S connection after this many milliseconds of inactivity.
|
|
522
327
|
* Inactivity means no audio, transcripts, or tool calls in either direction.
|
|
@@ -543,8 +348,8 @@ export declare const DEFAULT_GREETING: string;
|
|
|
543
348
|
*
|
|
544
349
|
* Core fields (`name`, `instructions`, `greeting`, `maxSteps`, `tools`)
|
|
545
350
|
* are resolved to their final values with defaults applied. Optional
|
|
546
|
-
* behavioral fields (hooks,
|
|
547
|
-
*
|
|
351
|
+
* behavioral fields (hooks, `sttPrompt`, etc.) remain optional —
|
|
352
|
+
* `undefined` means "not configured."
|
|
548
353
|
*
|
|
549
354
|
* @public
|
|
550
355
|
*/
|
|
@@ -558,16 +363,10 @@ export type AgentDef<S = Record<string, unknown>> = {
|
|
|
558
363
|
builtinTools?: readonly BuiltinTool[];
|
|
559
364
|
tools: Readonly<Record<string, ToolDef<z.ZodObject<z.ZodRawShape>, S>>>;
|
|
560
365
|
state?: () => S;
|
|
561
|
-
/** Resolved persistence config, or `undefined` if disabled. */
|
|
562
|
-
persistence?: {
|
|
563
|
-
ttl: number;
|
|
564
|
-
};
|
|
565
366
|
onConnect?: (ctx: HookContext<S>) => void | Promise<void>;
|
|
566
367
|
onDisconnect?: (ctx: HookContext<S>) => void | Promise<void>;
|
|
567
368
|
onError?: (error: Error, ctx?: HookContext<S>) => void;
|
|
568
369
|
onTurn?: (text: string, ctx: HookContext<S>) => void | Promise<void>;
|
|
569
|
-
onStep?: (step: StepInfo, ctx: HookContext<S>) => void | Promise<void>;
|
|
570
|
-
middleware?: readonly Middleware<S>[];
|
|
571
370
|
idleTimeoutMs?: number;
|
|
572
371
|
};
|
|
573
372
|
/** @internal Zod schema for {@link BuiltinTool}. Exported for reuse in internal schemas. */
|
|
@@ -576,7 +375,6 @@ export declare const BuiltinToolSchema: z.ZodEnum<{
|
|
|
576
375
|
visit_webpage: "visit_webpage";
|
|
577
376
|
fetch_json: "fetch_json";
|
|
578
377
|
run_code: "run_code";
|
|
579
|
-
vector_search: "vector_search";
|
|
580
378
|
memory: "memory";
|
|
581
379
|
}>;
|
|
582
380
|
/** @internal Zod schema for {@link ToolChoice}. Exported for reuse in internal schemas. */
|
package/dist/types.js
CHANGED
|
@@ -38,17 +38,17 @@ function defineTool(def) {
|
|
|
38
38
|
* Create a typed `defineTool` helper with the session state type baked in.
|
|
39
39
|
*
|
|
40
40
|
* When tools need access to typed session state, you'd normally have to write
|
|
41
|
-
* verbose generics on every `defineTool` call. `
|
|
41
|
+
* verbose generics on every `defineTool` call. `defineToolFactory` eliminates
|
|
42
42
|
* that boilerplate by returning a `defineTool` variant that already knows `S`.
|
|
43
43
|
*
|
|
44
44
|
* @example
|
|
45
45
|
* ```ts
|
|
46
|
-
* import {
|
|
46
|
+
* import { defineToolFactory, defineAgent } from "aai";
|
|
47
47
|
* import { z } from "zod";
|
|
48
48
|
*
|
|
49
49
|
* interface PortfolioState { holdings: Map<string, number> }
|
|
50
50
|
*
|
|
51
|
-
* const tool =
|
|
51
|
+
* const tool = defineToolFactory<PortfolioState>();
|
|
52
52
|
*
|
|
53
53
|
* export default defineAgent<PortfolioState>({
|
|
54
54
|
* name: "portfolio",
|
|
@@ -68,7 +68,7 @@ function defineTool(def) {
|
|
|
68
68
|
*
|
|
69
69
|
* @public
|
|
70
70
|
*/
|
|
71
|
-
function
|
|
71
|
+
function defineToolFactory() {
|
|
72
72
|
return (def) => def;
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
@@ -100,7 +100,6 @@ const BuiltinToolSchema = z.enum([
|
|
|
100
100
|
"visit_webpage",
|
|
101
101
|
"fetch_json",
|
|
102
102
|
"run_code",
|
|
103
|
-
"vector_search",
|
|
104
103
|
"memory"
|
|
105
104
|
]);
|
|
106
105
|
/** @internal Zod schema for {@link ToolChoice}. Exported for reuse in internal schemas. */
|
|
@@ -117,8 +116,6 @@ const ToolDefSchema = z.object({
|
|
|
117
116
|
parameters: z.custom((val) => val === void 0 || val instanceof z.ZodType, "Expected a Zod schema").optional(),
|
|
118
117
|
execute: z.function()
|
|
119
118
|
});
|
|
120
|
-
/** Default TTL for persisted session data: 1 hour. */
|
|
121
|
-
const DEFAULT_PERSIST_TTL = 36e5;
|
|
122
119
|
const AgentOptionsSchema = z.object({
|
|
123
120
|
name: z.string().min(1, "Agent name must be non-empty"),
|
|
124
121
|
instructions: z.string().optional(),
|
|
@@ -129,21 +126,10 @@ const AgentOptionsSchema = z.object({
|
|
|
129
126
|
builtinTools: z.array(BuiltinToolSchema).optional(),
|
|
130
127
|
tools: z.record(z.string(), ToolDefSchema).optional(),
|
|
131
128
|
state: z.function().optional(),
|
|
132
|
-
persistence: z.union([z.literal(true), z.object({ ttl: z.number().int().positive().optional() })]).optional(),
|
|
133
129
|
onConnect: z.function().optional(),
|
|
134
130
|
onDisconnect: z.function().optional(),
|
|
135
131
|
onError: z.function().optional(),
|
|
136
132
|
onTurn: z.function().optional(),
|
|
137
|
-
onStep: z.function().optional(),
|
|
138
|
-
middleware: z.array(z.object({
|
|
139
|
-
name: z.string().min(1, "Middleware name must be non-empty"),
|
|
140
|
-
beforeInput: z.function().optional(),
|
|
141
|
-
beforeTurn: z.function().optional(),
|
|
142
|
-
afterTurn: z.function().optional(),
|
|
143
|
-
beforeToolCall: z.function().optional(),
|
|
144
|
-
afterToolCall: z.function().optional(),
|
|
145
|
-
beforeOutput: z.function().optional()
|
|
146
|
-
})).optional(),
|
|
147
133
|
idleTimeoutMs: z.number().nonnegative().optional()
|
|
148
134
|
});
|
|
149
135
|
/**
|
|
@@ -178,15 +164,13 @@ const AgentOptionsSchema = z.object({
|
|
|
178
164
|
*/
|
|
179
165
|
function defineAgent(options) {
|
|
180
166
|
AgentOptionsSchema.parse(options);
|
|
181
|
-
const persistence = options.persistence ? { ttl: typeof options.persistence === "object" ? options.persistence.ttl ?? DEFAULT_PERSIST_TTL : DEFAULT_PERSIST_TTL } : void 0;
|
|
182
167
|
return {
|
|
183
168
|
...options,
|
|
184
169
|
instructions: options.instructions ?? DEFAULT_INSTRUCTIONS,
|
|
185
170
|
greeting: options.greeting ?? "Hey there. I'm a voice assistant. What can I help you with?",
|
|
186
171
|
maxSteps: options.maxSteps ?? 5,
|
|
187
|
-
tools: options.tools ?? {}
|
|
188
|
-
persistence
|
|
172
|
+
tools: options.tools ?? {}
|
|
189
173
|
};
|
|
190
174
|
}
|
|
191
175
|
//#endregion
|
|
192
|
-
export { BuiltinToolSchema, DEFAULT_GREETING, DEFAULT_INSTRUCTIONS, ToolChoiceSchema,
|
|
176
|
+
export { BuiltinToolSchema, DEFAULT_GREETING, DEFAULT_INSTRUCTIONS, ToolChoiceSchema, defineAgent, defineTool, defineTool as tool, defineToolFactory };
|