@alexkroman1/aai 0.10.3 → 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 +49 -2
- 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 +32 -1
- package/dist/matchers.js +1 -1
- package/dist/protocol.d.ts +3 -29
- package/dist/protocol.js +140 -2
- package/dist/server.d.ts +27 -40
- package/dist/server.js +117 -145
- package/dist/session.d.ts +65 -44
- package/dist/{testing-BbitshLb.js → testing-BonJtfHJ.js} +25 -43
- package/dist/testing.d.ts +9 -14
- package/dist/testing.js +2 -2
- package/dist/types.d.ts +24 -226
- package/dist/types.js +176 -2
- package/dist/types.test-d.d.ts +7 -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 +28 -88
- package/dist/_embeddings.d.ts +0 -31
- package/dist/_internal-types-IfPcaJd5.js +0 -61
- package/dist/_internal-types.js +0 -2
- 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-DCp_27V4.js +0 -123
- package/dist/_ssrf.d.ts +0 -30
- package/dist/_ssrf.js +0 -2
- package/dist/_utils-DgzpOMSV.js +0 -61
- package/dist/direct-executor-B-5mq3cu.js +0 -570
- package/dist/kv-iXtikQmR.js +0 -32
- package/dist/middleware-core-BwyBIPed.js +0 -107
- package/dist/middleware-core.d.ts +0 -47
- package/dist/middleware-core.js +0 -2
- package/dist/middleware.d.ts +0 -37
- package/dist/protocol-B-H2Q4ox.js +0 -162
- package/dist/runtime-CxcwaK68.js +0 -58
- package/dist/runtime.js +0 -2
- package/dist/s2s-M7JqtgFw.js +0 -272
- package/dist/s2s.js +0 -2
- package/dist/session-BYlwcrya.js +0 -683
- package/dist/session.js +0 -2
- package/dist/telemetry-CJlaDFNc.js +0 -95
- package/dist/telemetry.d.ts +0 -49
- package/dist/telemetry.js +0 -2
- package/dist/types-D8ZBxTL_.js +0 -192
- package/dist/unstorage-kv-CDgP-frt.js +0 -64
- package/dist/unstorage-kv.js +0 -2
- package/dist/unstorage-vector-Cj5llNhg.js +0 -172
- package/dist/unstorage-vector.d.ts +0 -47
- package/dist/unstorage-vector.js +0 -2
- package/dist/vector.d.ts +0 -86
- package/dist/vector.js +0 -49
- package/dist/worker-entry-2jaiqIj0.js +0 -70
- package/dist/worker-entry.d.ts +0 -47
- package/dist/worker-entry.js +0 -2
- package/dist/ws-handler-C0Q6eSay.js +0 -207
- package/dist/ws-handler.js +0 -2
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { t as
|
|
3
|
-
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
4
|
import { createStorage } from "unstorage";
|
|
5
|
+
import "nanoevents";
|
|
6
|
+
import { vi } from "vitest";
|
|
5
7
|
//#region _mock-ws.ts
|
|
6
8
|
/**
|
|
7
9
|
* A mock WebSocket implementation for testing.
|
|
@@ -155,6 +157,14 @@ function installMockWebSocket() {
|
|
|
155
157
|
};
|
|
156
158
|
}
|
|
157
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
|
|
158
168
|
//#region testing.ts
|
|
159
169
|
/**
|
|
160
170
|
* Testing utilities for AAI agents.
|
|
@@ -315,7 +325,6 @@ var TestHarness = class {
|
|
|
315
325
|
/** @internal */
|
|
316
326
|
_sessionId;
|
|
317
327
|
_messages = [];
|
|
318
|
-
_onStepCalls = [];
|
|
319
328
|
_onTurnCalls = [];
|
|
320
329
|
_connected = false;
|
|
321
330
|
/** @internal */
|
|
@@ -327,10 +336,6 @@ var TestHarness = class {
|
|
|
327
336
|
get messages() {
|
|
328
337
|
return this._messages;
|
|
329
338
|
}
|
|
330
|
-
/** All `onStep` hook invocations recorded so far. */
|
|
331
|
-
get steps() {
|
|
332
|
-
return this._onStepCalls;
|
|
333
|
-
}
|
|
334
339
|
/** All `onTurn` hook invocations (the text argument) recorded so far. */
|
|
335
340
|
get turns() {
|
|
336
341
|
return this._onTurnCalls;
|
|
@@ -343,7 +348,7 @@ var TestHarness = class {
|
|
|
343
348
|
async connect() {
|
|
344
349
|
if (this._connected) return;
|
|
345
350
|
this._connected = true;
|
|
346
|
-
await this._executor.
|
|
351
|
+
await this._executor.hooks.callHook("connect", this._sessionId);
|
|
347
352
|
}
|
|
348
353
|
/**
|
|
349
354
|
* Fire the `onDisconnect` lifecycle hook and clean up session state.
|
|
@@ -351,12 +356,12 @@ var TestHarness = class {
|
|
|
351
356
|
async disconnect() {
|
|
352
357
|
if (!this._connected) return;
|
|
353
358
|
this._connected = false;
|
|
354
|
-
await this._executor.
|
|
359
|
+
await this._executor.hooks.callHook("disconnect", this._sessionId);
|
|
355
360
|
}
|
|
356
361
|
/**
|
|
357
362
|
* Execute a single tool by name with the given arguments.
|
|
358
363
|
*
|
|
359
|
-
* The tool runs with full agent context (env, state, kv,
|
|
364
|
+
* The tool runs with full agent context (env, state, kv, messages).
|
|
360
365
|
* The call is **not** recorded in conversation history — use {@link turn}
|
|
361
366
|
* for that.
|
|
362
367
|
*
|
|
@@ -382,7 +387,7 @@ var TestHarness = class {
|
|
|
382
387
|
* 1. Fires `onConnect` if this is the first turn
|
|
383
388
|
* 2. Adds the user message to conversation history
|
|
384
389
|
* 3. Fires the `onTurn` hook
|
|
385
|
-
* 4. Executes each tool call in order
|
|
390
|
+
* 4. Executes each tool call in order
|
|
386
391
|
* 5. Returns a {@link TurnResult} with assertion helpers
|
|
387
392
|
*
|
|
388
393
|
* @param text - The user's spoken/typed input.
|
|
@@ -405,10 +410,9 @@ var TestHarness = class {
|
|
|
405
410
|
content: text
|
|
406
411
|
});
|
|
407
412
|
this._onTurnCalls.push(text);
|
|
408
|
-
await this._executor.
|
|
413
|
+
await this._executor.hooks.callHook("turn", this._sessionId, text);
|
|
409
414
|
const recorded = [];
|
|
410
|
-
for (
|
|
411
|
-
const tc = toolCalls[i];
|
|
415
|
+
for (const tc of toolCalls) {
|
|
412
416
|
const result = await this._executor.executeTool(tc.tool, tc.args, this._sessionId, this._messages);
|
|
413
417
|
recorded.push({
|
|
414
418
|
toolName: tc.tool,
|
|
@@ -419,16 +423,6 @@ var TestHarness = class {
|
|
|
419
423
|
role: "tool",
|
|
420
424
|
content: result
|
|
421
425
|
});
|
|
422
|
-
const step = {
|
|
423
|
-
stepNumber: i + 1,
|
|
424
|
-
toolCalls: [{
|
|
425
|
-
toolName: tc.tool,
|
|
426
|
-
args: tc.args
|
|
427
|
-
}],
|
|
428
|
-
text: ""
|
|
429
|
-
};
|
|
430
|
-
this._onStepCalls.push(step);
|
|
431
|
-
await this._executor.hookInvoker.onStep(this._sessionId, step);
|
|
432
426
|
}
|
|
433
427
|
return new TurnResult(text, recorded);
|
|
434
428
|
}
|
|
@@ -457,25 +451,14 @@ var TestHarness = class {
|
|
|
457
451
|
/**
|
|
458
452
|
* Reset conversation state: clears messages, step/turn history.
|
|
459
453
|
*
|
|
460
|
-
* Does **not** reset KV
|
|
454
|
+
* Does **not** reset KV store — create a new harness for that.
|
|
461
455
|
*/
|
|
462
456
|
reset() {
|
|
463
457
|
this._messages = [];
|
|
464
|
-
this._onStepCalls = [];
|
|
465
458
|
this._onTurnCalls = [];
|
|
466
459
|
}
|
|
467
460
|
};
|
|
468
461
|
/**
|
|
469
|
-
* Create a SQLite-vec backed vector store with deterministic test embeddings.
|
|
470
|
-
* Uses a temp directory that is unique per call for test isolation.
|
|
471
|
-
*/
|
|
472
|
-
function createTestVectorStore() {
|
|
473
|
-
return createUnstorageVectorStore({
|
|
474
|
-
storage: createStorage(),
|
|
475
|
-
embedFn: createTestEmbedFn()
|
|
476
|
-
});
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
462
|
* Create a test harness for unit-testing an agent.
|
|
480
463
|
*
|
|
481
464
|
* The harness wraps the agent's tool definitions and lifecycle hooks,
|
|
@@ -483,7 +466,7 @@ function createTestVectorStore() {
|
|
|
483
466
|
* conversations — all without audio, network, or an LLM.
|
|
484
467
|
*
|
|
485
468
|
* @param agent - The agent definition returned by `defineAgent()`.
|
|
486
|
-
* @param options - Optional environment
|
|
469
|
+
* @param options - Optional environment and KV store overrides.
|
|
487
470
|
* @returns A {@link TestHarness} instance.
|
|
488
471
|
*
|
|
489
472
|
* @example
|
|
@@ -505,13 +488,12 @@ function createTestVectorStore() {
|
|
|
505
488
|
* @public
|
|
506
489
|
*/
|
|
507
490
|
function createTestHarness(agent, options = {}) {
|
|
508
|
-
const { env = {}, kv = createUnstorageKv({ storage: createStorage() })
|
|
509
|
-
return new TestHarness(
|
|
491
|
+
const { env = {}, kv = createUnstorageKv({ storage: createStorage() }) } = options;
|
|
492
|
+
return new TestHarness(createRuntime({
|
|
510
493
|
agent,
|
|
511
494
|
env,
|
|
512
|
-
kv
|
|
513
|
-
vector
|
|
495
|
+
kv
|
|
514
496
|
}), `test-${Date.now()}`);
|
|
515
497
|
}
|
|
516
498
|
//#endregion
|
|
517
|
-
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. */
|