@alexkroman1/aai 0.9.3 → 0.10.1

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 (57) hide show
  1. package/dist/_internal-types.d.ts +49 -22
  2. package/dist/_internal-types.js +43 -1
  3. package/dist/_mock-ws.d.ts +1 -2
  4. package/dist/_run-code.d.ts +31 -0
  5. package/dist/_session-ctx.d.ts +73 -0
  6. package/dist/_session-otel.d.ts +43 -0
  7. package/dist/_session-persist.d.ts +30 -0
  8. package/dist/_ssrf.d.ts +30 -0
  9. package/dist/_ssrf.js +123 -0
  10. package/dist/_utils.d.ts +25 -0
  11. package/dist/_utils.js +54 -1
  12. package/dist/builtin-tools.d.ts +5 -34
  13. package/dist/direct-executor-Ca0wt5H0.js +572 -0
  14. package/dist/direct-executor.d.ts +34 -5
  15. package/dist/index.d.ts +2 -1
  16. package/dist/index.js +2 -2
  17. package/dist/kv.d.ts +30 -38
  18. package/dist/kv.js +19 -86
  19. package/dist/matchers.d.ts +20 -0
  20. package/dist/matchers.js +41 -0
  21. package/dist/memory-tools.d.ts +39 -0
  22. package/dist/middleware-core.d.ts +47 -0
  23. package/dist/middleware-core.js +107 -0
  24. package/dist/middleware.d.ts +37 -0
  25. package/dist/protocol.d.ts +44 -24
  26. package/dist/protocol.js +34 -14
  27. package/dist/runtime.d.ts +26 -2
  28. package/dist/runtime.js +44 -7
  29. package/dist/s2s.d.ts +19 -29
  30. package/dist/s2s.js +117 -87
  31. package/dist/server.d.ts +31 -3
  32. package/dist/server.js +102 -28
  33. package/dist/session-BkN9u0ni.js +683 -0
  34. package/dist/session.d.ts +55 -28
  35. package/dist/session.js +2 -312
  36. package/dist/sqlite-kv.d.ts +34 -0
  37. package/dist/sqlite-kv.js +133 -0
  38. package/dist/sqlite-vector.d.ts +58 -0
  39. package/dist/sqlite-vector.js +149 -0
  40. package/dist/system-prompt.d.ts +21 -0
  41. package/dist/telemetry.d.ts +49 -0
  42. package/dist/telemetry.js +95 -0
  43. package/dist/testing-MRl3SXsI.js +519 -0
  44. package/dist/testing.d.ts +299 -0
  45. package/dist/testing.js +2 -0
  46. package/dist/types.d.ts +324 -39
  47. package/dist/types.js +62 -9
  48. package/dist/vector.d.ts +18 -22
  49. package/dist/vector.js +41 -48
  50. package/dist/worker-entry.d.ts +11 -3
  51. package/dist/worker-entry.js +19 -8
  52. package/dist/ws-handler.d.ts +7 -3
  53. package/dist/ws-handler.js +64 -12
  54. package/package.json +55 -8
  55. package/dist/_mock-ws.js +0 -158
  56. package/dist/builtin-tools.js +0 -270
  57. package/dist/direct-executor.js +0 -125
@@ -1,270 +0,0 @@
1
- import { tool } from "./types.js";
2
- import { EMPTY_PARAMS } from "./_internal-types.js";
3
- import { errorMessage } from "./_utils.js";
4
- import { z } from "zod";
5
- import { convert } from "html-to-text";
6
- //#region builtin-tools.ts
7
- /**
8
- * Built-in tool definitions for the AAI agent SDK.
9
- *
10
- * These tools run inside the sandboxed worker alongside custom tools.
11
- * Network requests go through the host's fetch proxy (with SSRF protection).
12
- */
13
- /** Per-fetch timeout for network tools — tighter than the overall tool timeout. */
14
- const FETCH_TIMEOUT_MS = 15e3;
15
- /** Timeout for sandboxed code execution. */
16
- const RUN_CODE_TIMEOUT = 5e3;
17
- /** Create a fetch timeout signal. */
18
- function fetchSignal() {
19
- return AbortSignal.timeout(FETCH_TIMEOUT_MS);
20
- }
21
- function htmlToText(html) {
22
- return convert(html, { wordwrap: false });
23
- }
24
- const webSearchParams = z.object({
25
- query: z.string().describe("The search query"),
26
- max_results: z.number().describe("Maximum number of results to return (default 5)").optional()
27
- });
28
- const BRAVE_SEARCH_URL = "https://api.search.brave.com/res/v1/web/search";
29
- const BraveSearchResponseSchema = z.object({ web: z.object({ results: z.array(z.object({
30
- title: z.string(),
31
- url: z.string(),
32
- description: z.string()
33
- })) }).optional() });
34
- function createWebSearch(fetchFn = globalThis.fetch) {
35
- return {
36
- description: "Search the web for current information, facts, news, or answers to questions. Returns a list of results with title, URL, and description. Use this when the user asks about something you don't know, need up-to-date information, or want to verify facts.",
37
- parameters: webSearchParams,
38
- async execute(args, ctx) {
39
- const { query, max_results: maxResults = 5 } = args;
40
- const apiKey = ctx.env.BRAVE_API_KEY ?? "";
41
- if (!apiKey) return { error: "BRAVE_API_KEY is not set — web search unavailable" };
42
- const resp = await fetchFn(`${BRAVE_SEARCH_URL}?${new URLSearchParams({
43
- q: query,
44
- count: String(maxResults),
45
- text_decorations: "false"
46
- })}`, {
47
- headers: { "X-Subscription-Token": apiKey },
48
- signal: fetchSignal()
49
- });
50
- if (!resp.ok) return [];
51
- const raw = await resp.json();
52
- const data = BraveSearchResponseSchema.safeParse(raw);
53
- if (!data.success) return [];
54
- return (data.data.web?.results ?? []).slice(0, maxResults).map((r) => ({
55
- title: r.title,
56
- url: r.url,
57
- description: r.description
58
- }));
59
- }
60
- };
61
- }
62
- const MAX_PAGE_CHARS = 1e4;
63
- const MAX_HTML_BYTES = 2e5;
64
- const visitWebpageParams = z.object({ url: z.string().describe("The full URL to fetch (e.g., 'https://example.com/page')") });
65
- function createVisitWebpage(fetchFn = globalThis.fetch) {
66
- return {
67
- description: "Fetch a webpage and return its content as clean text. Use this to read the full content of a URL found via web_search, or any link the user shares. Good for reading articles, documentation, blog posts, or product pages.",
68
- parameters: visitWebpageParams,
69
- async execute(args, _ctx) {
70
- const { url } = args;
71
- const resp = await fetchFn(url, {
72
- headers: {
73
- "User-Agent": "Mozilla/5.0 (compatible; VoiceAgent/1.0; +https://github.com/AssemblyAI/aai)",
74
- Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
75
- },
76
- redirect: "follow",
77
- signal: fetchSignal()
78
- });
79
- if (!resp.ok) return {
80
- error: `Failed to fetch: ${resp.status} ${resp.statusText}`,
81
- url
82
- };
83
- const htmlContent = await resp.text();
84
- const text = htmlToText(htmlContent.length > MAX_HTML_BYTES ? htmlContent.slice(0, MAX_HTML_BYTES) : htmlContent);
85
- const truncated = text.length > MAX_PAGE_CHARS;
86
- return {
87
- url,
88
- content: truncated ? text.slice(0, MAX_PAGE_CHARS) : text,
89
- ...truncated ? {
90
- truncated: true,
91
- totalChars: text.length
92
- } : {}
93
- };
94
- }
95
- };
96
- }
97
- const fetchJsonParams = z.object({
98
- url: z.string().describe("The URL to fetch JSON from"),
99
- headers: z.record(z.string(), z.string()).describe("Optional HTTP headers to include in the request").optional()
100
- });
101
- function createFetchJson(fetchFn = globalThis.fetch) {
102
- return {
103
- description: "Call a REST API endpoint via HTTP GET and return the JSON response. Use this to fetch structured data from APIs — for example, weather data, stock prices, exchange rates, or any public JSON API. Supports custom headers for authenticated APIs.",
104
- parameters: fetchJsonParams,
105
- async execute(args, _ctx) {
106
- const { url, headers } = args;
107
- const resp = await fetchFn(url, {
108
- ...headers && { headers },
109
- signal: fetchSignal()
110
- });
111
- if (!resp.ok) return {
112
- error: `HTTP ${resp.status} ${resp.statusText}`,
113
- url
114
- };
115
- try {
116
- return await resp.json();
117
- } catch {
118
- return {
119
- error: "Response was not valid JSON",
120
- url
121
- };
122
- }
123
- }
124
- };
125
- }
126
- const runCodeParams = z.object({ code: z.string().describe("JavaScript code to execute. Use console.log() for output.") });
127
- function createRunCode() {
128
- return {
129
- 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.",
130
- parameters: runCodeParams,
131
- async execute(args) {
132
- const { code } = args;
133
- const output = [];
134
- function capture(...captureArgs) {
135
- output.push(captureArgs.map(String).join(" "));
136
- }
137
- const fakeConsole = {
138
- log: capture,
139
- info: capture,
140
- warn: capture,
141
- error: capture,
142
- debug: capture
143
- };
144
- const AsyncFunction = Object.getPrototypeOf(async () => {}).constructor;
145
- try {
146
- const fn = new AsyncFunction("console", code);
147
- await Promise.race([fn(fakeConsole), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error("Code execution timed out")), RUN_CODE_TIMEOUT))]);
148
- return output.join("\n").trim() || "Code ran successfully (no output)";
149
- } catch (err) {
150
- return { error: errorMessage(err) };
151
- }
152
- }
153
- };
154
- }
155
- const vectorSearchParams = z.object({
156
- query: z.string().describe("Short keyword query to search the knowledge base. Use specific topic terms, not full sentences. Do NOT include the company or product name since all documents are from the same source. For example, if the user asks \"how much does Acme cost\", search for \"pricing plans rates\"."),
157
- topK: z.number().describe("Maximum results to return (default: 5)").optional()
158
- });
159
- function createVectorSearch(vectorSearchFn) {
160
- return {
161
- description: "Search the agent's knowledge base for relevant information. Use this when the user asks a question that might be answered by previously ingested documents or data. Returns the most relevant matches ranked by similarity.",
162
- parameters: vectorSearchParams,
163
- async execute(args) {
164
- const { query, topK = 5 } = args;
165
- return vectorSearchFn(query, topK);
166
- }
167
- };
168
- }
169
- /** Single-tool creators and multi-tool expanders in one registry. */
170
- const TOOL_REGISTRY = {
171
- web_search: { create: (opts) => createWebSearch(opts?.fetch) },
172
- visit_webpage: { create: (opts) => createVisitWebpage(opts?.fetch) },
173
- fetch_json: { create: (opts) => createFetchJson(opts?.fetch) },
174
- run_code: { create: createRunCode },
175
- vector_search: { create: (opts) => createVectorSearch(opts?.vectorSearch ?? (async () => "")) },
176
- memory: { multi: memoryTools }
177
- };
178
- /** Resolve a builtin name to an array of [toolName, ToolDef] pairs. */
179
- function resolveBuiltin(name, opts) {
180
- const entry = TOOL_REGISTRY[name];
181
- if (!entry) return [];
182
- if ("multi" in entry) return Object.entries(entry.multi());
183
- if (name === "vector_search" && !opts?.vectorSearch) return [];
184
- return [[name, entry.create(opts)]];
185
- }
186
- /**
187
- * Create built-in tool definitions for the given tool names.
188
- * For runtime use — vector_search requires opts.vectorSearch to be included.
189
- */
190
- function getBuiltinToolDefs(names, opts) {
191
- const defs = {};
192
- for (const name of names) for (const [k, v] of resolveBuiltin(name, opts)) defs[k] = v;
193
- return defs;
194
- }
195
- /** Returns JSON tool schemas for the specified builtin tools. */
196
- function getBuiltinToolSchemas(names) {
197
- return names.flatMap((name) => resolveBuiltin(name, { vectorSearch: async () => "" }).map(([toolName, def]) => ({
198
- name: toolName,
199
- description: def.description,
200
- parameters: z.toJSONSchema(def.parameters ?? EMPTY_PARAMS)
201
- })));
202
- }
203
- /**
204
- * Returns a standard set of KV-backed memory tools: `save_memory`,
205
- * `recall_memory`, `list_memories`, and `forget_memory`.
206
- *
207
- * Spread the result into your agent's `tools` record.
208
- *
209
- * @example
210
- * ```ts
211
- * import { defineAgent, memoryTools } from "aai";
212
- *
213
- * export default defineAgent({
214
- * name: "My Agent",
215
- * tools: { ...memoryTools() },
216
- * });
217
- * ```
218
- */
219
- function memoryTools() {
220
- return {
221
- save_memory: tool({
222
- description: "Save a piece of information to persistent memory. Use a descriptive key like 'user:name' or 'project:status'.",
223
- parameters: z.object({
224
- key: z.string().describe("A descriptive key for this memory (e.g. 'user:name', 'preference:color')"),
225
- value: z.string().describe("The information to remember")
226
- }),
227
- execute: async ({ key, value }, ctx) => {
228
- await ctx.kv.set(key, value);
229
- return { saved: key };
230
- }
231
- }),
232
- recall_memory: tool({
233
- description: "Retrieve a previously saved memory by its key.",
234
- parameters: z.object({ key: z.string().describe("The key to look up") }),
235
- execute: async ({ key }, ctx) => {
236
- const value = await ctx.kv.get(key);
237
- if (value === null) return {
238
- found: false,
239
- key
240
- };
241
- return {
242
- found: true,
243
- key,
244
- value
245
- };
246
- }
247
- }),
248
- list_memories: tool({
249
- description: "List all saved memory keys, optionally filtered by a prefix (e.g. 'user:').",
250
- parameters: z.object({ prefix: z.string().describe("Prefix to filter keys (e.g. 'user:'). Use empty string for all.").optional() }),
251
- execute: async ({ prefix }, ctx) => {
252
- const entries = await ctx.kv.list(prefix ?? "");
253
- return {
254
- count: entries.length,
255
- keys: entries.map((e) => e.key)
256
- };
257
- }
258
- }),
259
- forget_memory: tool({
260
- description: "Delete a previously saved memory by its key.",
261
- parameters: z.object({ key: z.string().describe("The key to delete") }),
262
- execute: async ({ key }, ctx) => {
263
- await ctx.kv.delete(key);
264
- return { deleted: key };
265
- }
266
- })
267
- };
268
- }
269
- //#endregion
270
- export { getBuiltinToolDefs, getBuiltinToolSchemas, memoryTools };
@@ -1,125 +0,0 @@
1
- import { createMemoryKv } from "./kv.js";
2
- import { createMemoryVectorStore } from "./vector.js";
3
- import { agentToolsToSchemas } from "./_internal-types.js";
4
- import { getBuiltinToolDefs, getBuiltinToolSchemas } from "./builtin-tools.js";
5
- import { DEFAULT_S2S_CONFIG, consoleLogger } from "./runtime.js";
6
- import { createS2sSession } from "./session.js";
7
- import { executeToolCall } from "./worker-entry.js";
8
- //#region direct-executor.ts
9
- /**
10
- * Direct tool execution for self-hosted mode.
11
- *
12
- * In self-hosted mode, agent code is trusted (you're running your own code).
13
- * Tools execute directly in-process — no sandbox, no RPC.
14
- */
15
- /** Build a serializable AgentConfig from an AgentDef. */
16
- function buildAgentConfig(agent) {
17
- const config = {
18
- name: agent.name,
19
- instructions: agent.instructions,
20
- greeting: agent.greeting
21
- };
22
- if (agent.sttPrompt !== void 0) config.sttPrompt = agent.sttPrompt;
23
- if (typeof agent.maxSteps !== "function") config.maxSteps = agent.maxSteps;
24
- if (agent.toolChoice !== void 0) config.toolChoice = agent.toolChoice;
25
- if (agent.builtinTools) config.builtinTools = [...agent.builtinTools];
26
- if (agent.activeTools) config.activeTools = [...agent.activeTools];
27
- return config;
28
- }
29
- /** Create a direct (in-process) tool executor and hook invoker for an agent. */
30
- function createDirectExecutor(opts) {
31
- const { agent, env, kv = createMemoryKv(), vector = createMemoryVectorStore(), vectorSearch, createWebSocket, logger = consoleLogger, s2sConfig = DEFAULT_S2S_CONFIG } = opts;
32
- const agentConfig = buildAgentConfig(agent);
33
- const allTools = {
34
- ...getBuiltinToolDefs(agent.builtinTools ?? [], vectorSearch ? { vectorSearch } : void 0),
35
- ...agent.tools
36
- };
37
- const customSchemas = agentToolsToSchemas(agent.tools ?? {});
38
- const builtinSchemas = getBuiltinToolSchemas(agent.builtinTools ?? []);
39
- const toolSchemas = [...customSchemas, ...builtinSchemas];
40
- const sessionState = /* @__PURE__ */ new Map();
41
- const frozenEnv = Object.freeze({ ...env });
42
- function getState(sessionId) {
43
- if (!sessionState.has(sessionId) && agent.state) sessionState.set(sessionId, agent.state());
44
- return sessionState.get(sessionId) ?? {};
45
- }
46
- function makeHookContext(sessionId) {
47
- return {
48
- env: frozenEnv,
49
- state: getState(sessionId),
50
- get kv() {
51
- return kv;
52
- },
53
- get vector() {
54
- return vector;
55
- }
56
- };
57
- }
58
- const executeTool = async (name, args, sessionId, messages) => {
59
- const tool = allTools[name];
60
- if (!tool) return JSON.stringify({ error: `Unknown tool: ${name}` });
61
- return executeToolCall(name, args, {
62
- tool,
63
- env: frozenEnv,
64
- state: getState(sessionId ?? ""),
65
- kv,
66
- vector,
67
- messages
68
- });
69
- };
70
- const hookInvoker = {
71
- async onConnect(sessionId) {
72
- await agent.onConnect?.(makeHookContext(sessionId));
73
- },
74
- async onDisconnect(sessionId) {
75
- await agent.onDisconnect?.(makeHookContext(sessionId));
76
- sessionState.delete(sessionId);
77
- },
78
- async onTurn(sessionId, text) {
79
- await agent.onTurn?.(text, makeHookContext(sessionId));
80
- },
81
- async onError(sessionId, error) {
82
- await agent.onError?.(new Error(error.message), makeHookContext(sessionId));
83
- },
84
- async onStep(sessionId, step) {
85
- await agent.onStep?.(step, makeHookContext(sessionId));
86
- },
87
- async resolveTurnConfig(sessionId) {
88
- const ctx = makeHookContext(sessionId);
89
- let maxSteps;
90
- let activeTools;
91
- if (typeof agent.maxSteps === "function") maxSteps = await agent.maxSteps(ctx) ?? void 0;
92
- if (agent.onBeforeStep) activeTools = (await agent.onBeforeStep(0, ctx))?.activeTools;
93
- if (maxSteps === void 0 && activeTools === void 0) return null;
94
- const config = {};
95
- if (maxSteps !== void 0) config.maxSteps = maxSteps;
96
- if (activeTools !== void 0) config.activeTools = activeTools;
97
- return config;
98
- }
99
- };
100
- function createSession(sessionOpts) {
101
- const apiKey = frozenEnv.ASSEMBLYAI_API_KEY ?? "";
102
- return createS2sSession({
103
- id: sessionOpts.id,
104
- agent: sessionOpts.agent,
105
- client: sessionOpts.client,
106
- agentConfig,
107
- toolSchemas,
108
- apiKey,
109
- s2sConfig,
110
- executeTool,
111
- ...createWebSocket ? { createWebSocket } : {},
112
- hookInvoker,
113
- skipGreeting: sessionOpts.skipGreeting ?? false,
114
- logger
115
- });
116
- }
117
- return {
118
- executeTool,
119
- hookInvoker,
120
- toolSchemas,
121
- createSession
122
- };
123
- }
124
- //#endregion
125
- export { buildAgentConfig, createDirectExecutor };