@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.
Files changed (73) hide show
  1. package/dist/_internal-types.d.ts +8 -1
  2. package/dist/_runtime-conformance.d.ts +64 -0
  3. package/dist/_test-utils.d.ts +70 -0
  4. package/dist/_utils.d.ts +1 -8
  5. package/dist/_utils.js +49 -2
  6. package/dist/builtin-tools.d.ts +1 -5
  7. package/dist/constants-BbAOvKl_.js +47 -0
  8. package/dist/constants.d.ts +44 -0
  9. package/dist/direct-executor-BfHrDdPL.js +1589 -0
  10. package/dist/direct-executor.d.ts +90 -31
  11. package/dist/hooks.d.ts +44 -0
  12. package/dist/hooks.js +58 -0
  13. package/dist/index.d.ts +1 -2
  14. package/dist/index.js +2 -2
  15. package/dist/internal.d.ts +19 -0
  16. package/dist/internal.js +209 -0
  17. package/dist/kv.d.ts +1 -1
  18. package/dist/kv.js +32 -1
  19. package/dist/matchers.js +1 -1
  20. package/dist/protocol.d.ts +3 -29
  21. package/dist/protocol.js +140 -2
  22. package/dist/server.d.ts +27 -40
  23. package/dist/server.js +117 -145
  24. package/dist/session.d.ts +65 -44
  25. package/dist/{testing-BbitshLb.js → testing-BonJtfHJ.js} +25 -43
  26. package/dist/testing.d.ts +9 -14
  27. package/dist/testing.js +2 -2
  28. package/dist/types.d.ts +24 -226
  29. package/dist/types.js +176 -2
  30. package/dist/types.test-d.d.ts +7 -0
  31. package/dist/vite-plugin.d.ts +15 -0
  32. package/dist/vite-plugin.js +82 -0
  33. package/dist/ws-handler.d.ts +1 -2
  34. package/package.json +28 -88
  35. package/dist/_embeddings.d.ts +0 -31
  36. package/dist/_internal-types-IfPcaJd5.js +0 -61
  37. package/dist/_internal-types.js +0 -2
  38. package/dist/_session-ctx.d.ts +0 -73
  39. package/dist/_session-otel.d.ts +0 -43
  40. package/dist/_session-persist.d.ts +0 -30
  41. package/dist/_ssrf-DCp_27V4.js +0 -123
  42. package/dist/_ssrf.d.ts +0 -30
  43. package/dist/_ssrf.js +0 -2
  44. package/dist/_utils-DgzpOMSV.js +0 -61
  45. package/dist/direct-executor-B-5mq3cu.js +0 -570
  46. package/dist/kv-iXtikQmR.js +0 -32
  47. package/dist/middleware-core-BwyBIPed.js +0 -107
  48. package/dist/middleware-core.d.ts +0 -47
  49. package/dist/middleware-core.js +0 -2
  50. package/dist/middleware.d.ts +0 -37
  51. package/dist/protocol-B-H2Q4ox.js +0 -162
  52. package/dist/runtime-CxcwaK68.js +0 -58
  53. package/dist/runtime.js +0 -2
  54. package/dist/s2s-M7JqtgFw.js +0 -272
  55. package/dist/s2s.js +0 -2
  56. package/dist/session-BYlwcrya.js +0 -683
  57. package/dist/session.js +0 -2
  58. package/dist/telemetry-CJlaDFNc.js +0 -95
  59. package/dist/telemetry.d.ts +0 -49
  60. package/dist/telemetry.js +0 -2
  61. package/dist/types-D8ZBxTL_.js +0 -192
  62. package/dist/unstorage-kv-CDgP-frt.js +0 -64
  63. package/dist/unstorage-kv.js +0 -2
  64. package/dist/unstorage-vector-Cj5llNhg.js +0 -172
  65. package/dist/unstorage-vector.d.ts +0 -47
  66. package/dist/unstorage-vector.js +0 -2
  67. package/dist/vector.d.ts +0 -86
  68. package/dist/vector.js +0 -49
  69. package/dist/worker-entry-2jaiqIj0.js +0 -70
  70. package/dist/worker-entry.d.ts +0 -47
  71. package/dist/worker-entry.js +0 -2
  72. package/dist/ws-handler-C0Q6eSay.js +0 -207
  73. package/dist/ws-handler.js +0 -2
package/dist/vector.d.ts DELETED
@@ -1,86 +0,0 @@
1
- /**
2
- * Vector store interface.
3
- */
4
- /**
5
- * Validate a vector filter expression to prevent injection attacks.
6
- *
7
- * Rejects filters containing SQL keywords (SELECT, DROP, etc.),
8
- * statement terminators, comments, and null bytes. Enforces a
9
- * maximum length of 1000 characters.
10
- *
11
- * @param filter - The raw filter string from user input.
12
- * @returns The validated filter string (trimmed).
13
- * @throws Error if the filter contains dangerous patterns.
14
- *
15
- * @public
16
- */
17
- export declare function validateVectorFilter(filter: string): string;
18
- /**
19
- * A single vector search result entry.
20
- *
21
- * @public
22
- */
23
- export type VectorEntry = {
24
- /** The unique identifier for this entry. */
25
- id: string;
26
- /** Similarity score (higher = more similar). */
27
- score: number;
28
- /** The original text data stored with this entry. */
29
- data?: string | undefined;
30
- /** Arbitrary metadata stored with this entry. */
31
- metadata?: Record<string, unknown> | undefined;
32
- };
33
- /**
34
- * Async vector store interface used by agents.
35
- *
36
- * Agents access the vector store via `ToolContext.vector` or
37
- * `HookContext.vector`. Backed by unstorage with local embeddings
38
- * via `all-MiniLM-L6-v2` by default. Pluggable storage driver and
39
- * embedding function.
40
- *
41
- * @example
42
- * ```ts
43
- * // Inside a tool execute function:
44
- * const myTool = {
45
- * description: "Search knowledge base",
46
- * execute: async (_args: unknown, ctx: { vector: VectorStore }) => {
47
- * await ctx.vector.upsert("doc-1", "The capital of France is Paris.");
48
- * const results = await ctx.vector.query("What is the capital of France?");
49
- * return results;
50
- * },
51
- * };
52
- * ```
53
- *
54
- * @public
55
- */
56
- export type VectorStore = {
57
- /**
58
- * Upsert a text entry into the vector store.
59
- *
60
- * The text is automatically embedded by the server's vector database.
61
- *
62
- * @param id - Unique identifier for this entry.
63
- * @param data - The text content to store and embed.
64
- * @param metadata - Optional metadata to store alongside the vector.
65
- */
66
- upsert(id: string, data: string, metadata?: Record<string, unknown>): Promise<void>;
67
- /**
68
- * Query the vector store with a text string.
69
- *
70
- * Returns the most similar entries ranked by score.
71
- *
72
- * @param text - The query text to search for.
73
- * @param options - Optional query parameters. `topK` sets the maximum number of results (default: 10). `filter` is a metadata filter expression.
74
- * @returns An array of matching {@link VectorEntry} objects.
75
- */
76
- query(text: string, options?: {
77
- topK?: number;
78
- filter?: string;
79
- }): Promise<VectorEntry[]>;
80
- /**
81
- * Delete entries by ID.
82
- *
83
- * @param ids - A single ID or array of IDs to delete.
84
- */
85
- delete(ids: string | string[]): Promise<void>;
86
- };
package/dist/vector.js DELETED
@@ -1,49 +0,0 @@
1
- //#region vector.ts
2
- /**
3
- * Vector store interface.
4
- */
5
- /**
6
- * Maximum allowed length for a vector filter expression.
7
- * @internal
8
- */
9
- const MAX_FILTER_LENGTH = 1e3;
10
- /**
11
- * SQL/query keywords that must not appear in filter expressions.
12
- * Checked case-insensitively as whole words (word-boundary match).
13
- * @internal
14
- */
15
- const DANGEROUS_KEYWORDS = /\b(SELECT|INSERT|UPDATE|DELETE|DROP|ALTER|CREATE|EXEC|EXECUTE|UNION|INTO|TRUNCATE|GRANT|REVOKE|CALL)\b/i;
16
- /**
17
- * Patterns that indicate injection attempts in filter strings.
18
- * @internal
19
- */
20
- const DANGEROUS_PATTERNS = [
21
- /;/,
22
- /--/,
23
- /\/\*/,
24
- /\*\//,
25
- /\0/
26
- ];
27
- /**
28
- * Validate a vector filter expression to prevent injection attacks.
29
- *
30
- * Rejects filters containing SQL keywords (SELECT, DROP, etc.),
31
- * statement terminators, comments, and null bytes. Enforces a
32
- * maximum length of 1000 characters.
33
- *
34
- * @param filter - The raw filter string from user input.
35
- * @returns The validated filter string (trimmed).
36
- * @throws Error if the filter contains dangerous patterns.
37
- *
38
- * @public
39
- */
40
- function validateVectorFilter(filter) {
41
- const trimmed = filter.trim();
42
- if (trimmed.length === 0) throw new Error("Vector filter must not be empty");
43
- if (trimmed.length > MAX_FILTER_LENGTH) throw new Error(`Vector filter exceeds maximum length of ${MAX_FILTER_LENGTH} characters`);
44
- if (DANGEROUS_KEYWORDS.test(trimmed)) throw new Error("Vector filter contains disallowed SQL keyword");
45
- for (const pattern of DANGEROUS_PATTERNS) if (pattern.test(trimmed)) throw new Error("Vector filter contains disallowed characters");
46
- return trimmed;
47
- }
48
- //#endregion
49
- export { validateVectorFilter };
@@ -1,70 +0,0 @@
1
- import { n as EMPTY_PARAMS } from "./_internal-types-IfPcaJd5.js";
2
- import { n as errorDetail, r as errorMessage, s as toolError } from "./_utils-DgzpOMSV.js";
3
- import { f as TOOL_EXECUTION_TIMEOUT_MS } from "./protocol-B-H2Q4ox.js";
4
- //#region worker-entry.ts
5
- /** Yield to the event loop so pending I/O (e.g. WebSocket frames) can be processed. */
6
- const yieldTick = () => new Promise((r) => setTimeout(r, 0));
7
- function buildToolContext(opts) {
8
- const { env, state, kv, vector, messages, onUpdate, fetch: fetchFn, sessionId } = opts;
9
- return {
10
- env: { ...env },
11
- state: state ?? {},
12
- get kv() {
13
- if (!kv) throw new Error("KV not available");
14
- return kv;
15
- },
16
- get vector() {
17
- if (!vector) throw new Error("Vector store not available");
18
- return vector;
19
- },
20
- messages: messages ?? [],
21
- sendUpdate(data) {
22
- onUpdate?.(data);
23
- },
24
- fetch: fetchFn ?? globalThis.fetch,
25
- sessionId: sessionId ?? ""
26
- };
27
- }
28
- /**
29
- * Execute a tool call with argument validation and error handling.
30
- *
31
- * Validates the provided arguments against the tool's Zod parameter schema,
32
- * constructs a {@link ToolContext}, invokes the tool's `execute` function,
33
- * and serializes the result to a string. Errors (validation failures,
34
- * execution throws, timeouts) are caught and returned as JSON strings
35
- * via {@link toolError} (`'{"error":"<message>"}'`) rather than thrown.
36
- *
37
- * @param name - The name of the tool being invoked.
38
- * @param args - Raw arguments from the LLM to validate and pass to the tool.
39
- * @param options - Tool definition, environment, and optional context.
40
- * @returns The tool's result serialized as a string, or an error message.
41
- */
42
- async function executeToolCall(name, args, options) {
43
- const { tool } = options;
44
- const parsed = (tool.parameters ?? EMPTY_PARAMS).safeParse(args);
45
- if (!parsed.success) return toolError(`Invalid arguments for tool "${name}": ${(parsed.error?.issues ?? []).map((i) => `${i.path.map(String).join(".")}: ${i.message}`).join(", ")}`);
46
- let timer;
47
- try {
48
- const ctx = buildToolContext(options);
49
- await yieldTick();
50
- const timeout = new Promise((_, reject) => {
51
- timer = setTimeout(() => reject(/* @__PURE__ */ new Error(`Tool "${name}" timed out after ${TOOL_EXECUTION_TIMEOUT_MS}ms`)), TOOL_EXECUTION_TIMEOUT_MS);
52
- });
53
- const result = await Promise.race([Promise.resolve(tool.execute(parsed.data, ctx)), timeout]);
54
- await yieldTick();
55
- if (result == null) return "null";
56
- return typeof result === "string" ? result : JSON.stringify(result);
57
- } catch (err) {
58
- const log = options.logger;
59
- if (log) log.warn("Tool execution failed", {
60
- tool: name,
61
- error: errorDetail(err)
62
- });
63
- else console.warn(`[tool-executor] Tool execution failed: ${name}`, err);
64
- return toolError(errorMessage(err));
65
- } finally {
66
- clearTimeout(timer);
67
- }
68
- }
69
- //#endregion
70
- export { executeToolCall as t };
@@ -1,47 +0,0 @@
1
- /**
2
- * Worker entry point — shared tool execution logic.
3
- */
4
- import type { Kv } from "./kv.ts";
5
- import type { Logger } from "./runtime.ts";
6
- import type { Message, ToolDef } from "./types.ts";
7
- import type { VectorStore } from "./vector.ts";
8
- /**
9
- * Function signature for executing a tool by name.
10
- *
11
- * @param name - The tool name to execute.
12
- * @param args - Key-value arguments to pass to the tool handler.
13
- * @param sessionId - Optional session identifier for stateful tools.
14
- * @param messages - Optional conversation history for context-aware tools.
15
- * @returns The tool's string result, or an error message string.
16
- */
17
- export type ExecuteTool = (name: string, args: Readonly<Record<string, unknown>>, sessionId?: string, messages?: readonly Message[], onUpdate?: (data: unknown) => void) => Promise<string>;
18
- /** Options for {@link executeToolCall}. */
19
- export type ExecuteToolCallOptions = {
20
- tool: ToolDef;
21
- env: Readonly<Record<string, string>>;
22
- state?: Record<string, unknown>;
23
- sessionId?: string | undefined;
24
- kv?: Kv | undefined;
25
- vector?: VectorStore | undefined;
26
- messages?: readonly Message[] | undefined;
27
- logger?: Logger | undefined;
28
- /** Callback for intermediate UI updates from `ctx.sendUpdate()`. */
29
- onUpdate?: ((data: unknown) => void) | undefined;
30
- /** Override fetch implementation for the tool context. */
31
- fetch?: typeof globalThis.fetch | undefined;
32
- };
33
- /**
34
- * Execute a tool call with argument validation and error handling.
35
- *
36
- * Validates the provided arguments against the tool's Zod parameter schema,
37
- * constructs a {@link ToolContext}, invokes the tool's `execute` function,
38
- * and serializes the result to a string. Errors (validation failures,
39
- * execution throws, timeouts) are caught and returned as JSON strings
40
- * via {@link toolError} (`'{"error":"<message>"}'`) rather than thrown.
41
- *
42
- * @param name - The name of the tool being invoked.
43
- * @param args - Raw arguments from the LLM to validate and pass to the tool.
44
- * @param options - Tool definition, environment, and optional context.
45
- * @returns The tool's result serialized as a string, or an error message.
46
- */
47
- export declare function executeToolCall(name: string, args: Readonly<Record<string, unknown>>, options: ExecuteToolCallOptions): Promise<string>;
@@ -1,2 +0,0 @@
1
- import { t as executeToolCall } from "./worker-entry-2jaiqIj0.js";
2
- export { executeToolCall };
@@ -1,207 +0,0 @@
1
- import { n as errorDetail, r as errorMessage } from "./_utils-DgzpOMSV.js";
2
- import { r as ClientMessageSchema } from "./protocol-B-H2Q4ox.js";
3
- import { n as consoleLogger } from "./runtime-CxcwaK68.js";
4
- import { h as tracer, y as wsSendDroppedCounter } from "./telemetry-CJlaDFNc.js";
5
- //#region ws-handler.ts
6
- /**
7
- * WebSocket session lifecycle handler.
8
- *
9
- * Audio validation is handled at the host transport layer (see server.ts).
10
- */
11
- /** Default timeout for session.start() in milliseconds. */
12
- const DEFAULT_SESSION_START_TIMEOUT_MS = 1e4;
13
- /**
14
- * Creates a {@link ClientSink} backed by a plain WebSocket.
15
- *
16
- * Text events are sent as JSON text frames; audio chunks are sent as
17
- * binary frames (zero-copy).
18
- */
19
- function createClientSink(ws, log) {
20
- /** Send data over ws, silently dropping if the socket is not open. */
21
- function safeSend(data) {
22
- try {
23
- if (ws.readyState !== 1) return;
24
- ws.send(data);
25
- } catch (err) {
26
- log.debug?.("safeSend: socket closed between readyState check and send", { error: err instanceof Error ? err.message : String(err) });
27
- wsSendDroppedCounter.add(1);
28
- }
29
- }
30
- return {
31
- get open() {
32
- return ws.readyState === 1;
33
- },
34
- event(e) {
35
- safeSend(JSON.stringify(e));
36
- },
37
- playAudioChunk(chunk) {
38
- safeSend(chunk);
39
- },
40
- playAudioDone() {
41
- safeSend(JSON.stringify({ type: "audio_done" }));
42
- }
43
- };
44
- }
45
- function handleBinaryAudio(data, session) {
46
- if (data instanceof Uint8Array) {
47
- session.onAudio(data);
48
- return true;
49
- }
50
- if (data instanceof ArrayBuffer) {
51
- session.onAudio(new Uint8Array(data));
52
- return true;
53
- }
54
- return false;
55
- }
56
- function handleTextMessage(data, session, log, ctx, sid) {
57
- if (typeof data !== "string") return;
58
- let json;
59
- try {
60
- json = JSON.parse(data);
61
- } catch {
62
- log.warn("Invalid JSON from client", {
63
- ...ctx,
64
- sid
65
- });
66
- return;
67
- }
68
- const parsed = ClientMessageSchema.safeParse(json);
69
- if (!parsed.success) {
70
- log.warn("Invalid client message", {
71
- ...ctx,
72
- sid,
73
- error: parsed.error.message
74
- });
75
- return;
76
- }
77
- const msg = parsed.data;
78
- switch (msg.type) {
79
- case "audio_ready":
80
- session.onAudioReady();
81
- break;
82
- case "cancel":
83
- session.onCancel();
84
- break;
85
- case "reset":
86
- session.onReset();
87
- break;
88
- case "history":
89
- session.onHistory(msg.messages);
90
- break;
91
- default: break;
92
- }
93
- }
94
- /**
95
- * Attaches session lifecycle handlers to a native WebSocket using
96
- * plain JSON text frames and binary audio frames.
97
- *
98
- * Connection flow:
99
- * 1. WebSocket opens → server sends `{ type: "config", ...ReadyConfig }`
100
- * 2. Client sets up audio → sends `{ type: "audio_ready" }`
101
- * 3. If reconnecting → client sends `{ type: "history", messages: [...] }`
102
- */
103
- function wireSessionSocket(ws, opts) {
104
- const { sessions, logger: log = consoleLogger } = opts;
105
- const sessionId = opts.resumeFrom ?? crypto.randomUUID();
106
- const sid = sessionId.slice(0, 8);
107
- const ctx = opts.logContext ?? {};
108
- let session = null;
109
- /** Set to true once session.start() resolves. Messages arriving before
110
- * this flag is set are buffered and replayed once the session is ready,
111
- * preventing audio/text from being dispatched to a half-initialized session. */
112
- let sessionReady = false;
113
- let messageBuffer = [];
114
- const sessionSpan = tracer.startSpan("ws.session", { attributes: { "aai.session.id": sessionId } });
115
- function drainBuffer() {
116
- if (!(session && messageBuffer)) return;
117
- const buf = messageBuffer;
118
- messageBuffer = null;
119
- for (const event of buf) {
120
- const { data } = event;
121
- if (handleBinaryAudio(data, session)) continue;
122
- handleTextMessage(data, session, log, ctx, sid);
123
- }
124
- }
125
- function onOpen() {
126
- opts.onOpen?.();
127
- log.info("Session connected", {
128
- ...ctx,
129
- sid
130
- });
131
- sessionSpan.addEvent("ws.open");
132
- const client = createClientSink(ws, log);
133
- session = opts.createSession(sessionId, client);
134
- sessions.set(sessionId, session);
135
- ws.send(JSON.stringify({
136
- type: "config",
137
- ...opts.readyConfig,
138
- sessionId
139
- }));
140
- const timeoutMs = opts.sessionStartTimeoutMs ?? DEFAULT_SESSION_START_TIMEOUT_MS;
141
- Promise.race([session.start(), new Promise((_resolve, reject) => {
142
- setTimeout(() => reject(/* @__PURE__ */ new Error(`session.start() timed out after ${timeoutMs}ms`)), timeoutMs);
143
- })]).then(() => {
144
- log.info("Session ready", {
145
- ...ctx,
146
- sid
147
- });
148
- sessionSpan.addEvent("session.ready");
149
- sessionReady = true;
150
- drainBuffer();
151
- }).catch((err) => {
152
- log.error("Session start failed", {
153
- ...ctx,
154
- sid,
155
- error: errorDetail(err)
156
- });
157
- sessionSpan.setStatus({
158
- code: 2,
159
- message: errorMessage(err)
160
- });
161
- sessions.delete(sessionId);
162
- session = null;
163
- messageBuffer = null;
164
- });
165
- }
166
- if (ws.readyState === 1) onOpen();
167
- else ws.addEventListener("open", onOpen);
168
- ws.addEventListener("message", (event) => {
169
- if (!session) return;
170
- if (!sessionReady) {
171
- messageBuffer?.push(event);
172
- return;
173
- }
174
- const { data } = event;
175
- if (handleBinaryAudio(data, session)) return;
176
- handleTextMessage(data, session, log, ctx, sid);
177
- });
178
- ws.addEventListener("close", () => {
179
- log.info("Session disconnected", {
180
- ...ctx,
181
- sid
182
- });
183
- sessionSpan.addEvent("ws.close");
184
- sessionSpan.end();
185
- if (session) session.stop().catch((err) => {
186
- log.error("Session stop failed", {
187
- ...ctx,
188
- sid,
189
- error: errorDetail(err)
190
- });
191
- }).finally(() => {
192
- sessions.delete(sessionId);
193
- });
194
- opts.onClose?.();
195
- });
196
- ws.addEventListener("error", (ev) => {
197
- const msg = typeof ev.message === "string" ? ev.message : "WebSocket error";
198
- log.error("WebSocket error", {
199
- ...ctx,
200
- sid,
201
- error: msg
202
- });
203
- sessionSpan.recordException(new Error(msg));
204
- });
205
- }
206
- //#endregion
207
- export { wireSessionSocket as t };
@@ -1,2 +0,0 @@
1
- import { t as wireSessionSocket } from "./ws-handler-C0Q6eSay.js";
2
- export { wireSessionSocket };