@alexkroman1/aai 0.10.2 → 0.10.3

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 (46) hide show
  1. package/dist/_embeddings.d.ts +31 -0
  2. package/dist/_internal-types-IfPcaJd5.js +61 -0
  3. package/dist/_internal-types.js +1 -60
  4. package/dist/_ssrf-DCp_27V4.js +123 -0
  5. package/dist/_ssrf.js +1 -122
  6. package/dist/_utils-DgzpOMSV.js +61 -0
  7. package/dist/_utils.js +1 -60
  8. package/dist/{direct-executor-Ca0wt5H0.js → direct-executor-B-5mq3cu.js} +15 -17
  9. package/dist/index.js +1 -1
  10. package/dist/kv-iXtikQmR.js +32 -0
  11. package/dist/kv.js +1 -31
  12. package/dist/matchers.js +1 -1
  13. package/dist/middleware-core-BwyBIPed.js +107 -0
  14. package/dist/middleware-core.js +1 -106
  15. package/dist/protocol-B-H2Q4ox.js +162 -0
  16. package/dist/protocol.js +1 -161
  17. package/dist/runtime-CxcwaK68.js +58 -0
  18. package/dist/runtime.js +1 -52
  19. package/dist/s2s-M7JqtgFw.js +272 -0
  20. package/dist/s2s.js +1 -271
  21. package/dist/server.d.ts +6 -6
  22. package/dist/server.js +47 -43
  23. package/dist/{session-BkN9u0ni.js → session-BYlwcrya.js} +6 -6
  24. package/dist/session.js +1 -1
  25. package/dist/telemetry-CJlaDFNc.js +95 -0
  26. package/dist/telemetry.js +1 -94
  27. package/dist/{testing-MRl3SXsI.js → testing-BbitshLb.js} +7 -9
  28. package/dist/testing.js +1 -1
  29. package/dist/types-D8ZBxTL_.js +192 -0
  30. package/dist/types.js +1 -191
  31. package/dist/unstorage-kv-CDgP-frt.js +64 -0
  32. package/dist/unstorage-kv.d.ts +33 -0
  33. package/dist/unstorage-kv.js +2 -0
  34. package/dist/unstorage-vector-Cj5llNhg.js +172 -0
  35. package/dist/unstorage-vector.d.ts +47 -0
  36. package/dist/unstorage-vector.js +2 -0
  37. package/dist/vector.d.ts +3 -2
  38. package/dist/worker-entry-2jaiqIj0.js +70 -0
  39. package/dist/worker-entry.js +1 -69
  40. package/dist/ws-handler-C0Q6eSay.js +207 -0
  41. package/dist/ws-handler.js +1 -206
  42. package/package.json +14 -9
  43. package/dist/sqlite-kv.d.ts +0 -34
  44. package/dist/sqlite-kv.js +0 -133
  45. package/dist/sqlite-vector.d.ts +0 -58
  46. package/dist/sqlite-vector.js +0 -149
package/dist/types.js CHANGED
@@ -1,192 +1,2 @@
1
- import { z } from "zod";
2
- //#region types.ts
3
- /**
4
- * Core type definitions for the AAI agent SDK.
5
- */
6
- /**
7
- * Identity helper that preserves the Zod schema generic for type inference.
8
- *
9
- * When tools are defined inline in `defineAgent({ tools: { ... } })`, the
10
- * generic `P` gets widened to the base `ZodObject` type, so `args` in
11
- * `execute` loses its specific shape. Wrapping a tool definition in
12
- * `defineTool()` lets TypeScript infer `P` from `parameters` and type
13
- * `args` correctly.
14
- *
15
- * @example
16
- * ```ts
17
- * import { defineAgent, defineTool } from "aai";
18
- * import { z } from "zod";
19
- *
20
- * export default defineAgent({
21
- * name: "my-agent",
22
- * tools: {
23
- * greet: defineTool({
24
- * description: "Greet the user",
25
- * parameters: z.object({ name: z.string() }),
26
- * execute: ({ name }) => `Hello, ${name}!`, // name is string
27
- * }),
28
- * },
29
- * });
30
- * ```
31
- *
32
- * @public
33
- */
34
- function defineTool(def) {
35
- return def;
36
- }
37
- /**
38
- * Create a typed `defineTool` helper with the session state type baked in.
39
- *
40
- * When tools need access to typed session state, you'd normally have to write
41
- * verbose generics on every `defineTool` call. `createToolFactory` eliminates
42
- * that boilerplate by returning a `defineTool` variant that already knows `S`.
43
- *
44
- * @example
45
- * ```ts
46
- * import { createToolFactory, defineAgent } from "aai";
47
- * import { z } from "zod";
48
- *
49
- * interface PortfolioState { holdings: Map<string, number> }
50
- *
51
- * const tool = createToolFactory<PortfolioState>();
52
- *
53
- * export default defineAgent<PortfolioState>({
54
- * name: "portfolio",
55
- * state: () => ({ holdings: new Map() }),
56
- * tools: {
57
- * buy: tool({
58
- * description: "Buy shares",
59
- * parameters: z.object({ symbol: z.string(), qty: z.number() }),
60
- * execute: (args, ctx) => {
61
- * // args.symbol is string, ctx.state is PortfolioState
62
- * ctx.state.holdings.set(args.symbol, args.qty);
63
- * },
64
- * }),
65
- * },
66
- * });
67
- * ```
68
- *
69
- * @public
70
- */
71
- function createToolFactory() {
72
- return (def) => def;
73
- }
74
- /**
75
- * Default system prompt used when `instructions` is not provided.
76
- *
77
- * Optimized for voice-first interactions: short sentences, no visual
78
- * formatting, confident tone, and concise answers.
79
- */
80
- const DEFAULT_INSTRUCTIONS = `\
81
- You are AAI, a helpful AI assistant.
82
-
83
- Voice-First Rules:
84
- - Optimize for natural speech. Avoid jargon unless central to the answer. \
85
- Use short, punchy sentences.
86
- - Never mention "search results," "sources," or "the provided text." \
87
- Speak as if the knowledge is your own.
88
- - No visual formatting. Do not say "bullet point," "bold," or "bracketed one." \
89
- If you need to list items, say "First," "Next," and "Finally."
90
- - Start with the most important information. No introductory filler.
91
- - Be concise. Keep answers to 1-3 sentences. For complex topics, provide a high-level summary.
92
- - Be confident. Avoid hedging phrases like "It seems that" or "I believe."
93
- - If you don't have enough information, say so directly rather than guessing.
94
- - Never use exclamation points. Keep your tone calm and conversational.`;
95
- /** Default greeting spoken when a session starts. */
96
- const DEFAULT_GREETING = "Hey there. I'm a voice assistant. What can I help you with?";
97
- /** @internal Zod schema for {@link BuiltinTool}. Exported for reuse in internal schemas. */
98
- const BuiltinToolSchema = z.enum([
99
- "web_search",
100
- "visit_webpage",
101
- "fetch_json",
102
- "run_code",
103
- "vector_search",
104
- "memory"
105
- ]);
106
- /** @internal Zod schema for {@link ToolChoice}. Exported for reuse in internal schemas. */
107
- const ToolChoiceSchema = z.union([z.enum([
108
- "auto",
109
- "required",
110
- "none"
111
- ]), z.object({
112
- type: z.literal("tool"),
113
- toolName: z.string().min(1)
114
- })]);
115
- const ToolDefSchema = z.object({
116
- description: z.string().min(1, "Tool description must be non-empty"),
117
- parameters: z.custom((val) => val === void 0 || val instanceof z.ZodType, "Expected a Zod schema").optional(),
118
- execute: z.function()
119
- });
120
- /** Default TTL for persisted session data: 1 hour. */
121
- const DEFAULT_PERSIST_TTL = 36e5;
122
- const AgentOptionsSchema = z.object({
123
- name: z.string().min(1, "Agent name must be non-empty"),
124
- instructions: z.string().optional(),
125
- greeting: z.string().optional(),
126
- sttPrompt: z.string().optional(),
127
- maxSteps: z.union([z.number().int().positive(), z.function()]).optional(),
128
- toolChoice: ToolChoiceSchema.optional(),
129
- builtinTools: z.array(BuiltinToolSchema).optional(),
130
- tools: z.record(z.string(), ToolDefSchema).optional(),
131
- state: z.function().optional(),
132
- persistence: z.union([z.literal(true), z.object({ ttl: z.number().int().positive().optional() })]).optional(),
133
- onConnect: z.function().optional(),
134
- onDisconnect: z.function().optional(),
135
- onError: z.function().optional(),
136
- 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
- idleTimeoutMs: z.number().nonnegative().optional()
148
- });
149
- /**
150
- * Create an agent definition from the given options, applying sensible defaults.
151
- *
152
- * This is the main entry point for defining a voice agent. The returned
153
- * `AgentDef` is consumed by the AAI server at deploy time.
154
- *
155
- * @param options - Configuration for the agent including name, instructions,
156
- * tools, hooks, and other settings.
157
- * @returns A fully resolved agent definition with all defaults applied.
158
- *
159
- * @public
160
- *
161
- * @example Basic agent with a custom tool
162
- * ```ts
163
- * import { defineAgent } from "aai";
164
- * import { z } from "zod";
165
- *
166
- * export default defineAgent({
167
- * name: "greeter",
168
- * instructions: "You greet people warmly.",
169
- * tools: {
170
- * greet: {
171
- * description: "Greet a user by name",
172
- * parameters: z.object({ name: z.string() }),
173
- * execute: ({ name }) => `Hello, ${name}!`,
174
- * },
175
- * },
176
- * });
177
- * ```
178
- */
179
- function defineAgent(options) {
180
- 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
- return {
183
- ...options,
184
- instructions: options.instructions ?? DEFAULT_INSTRUCTIONS,
185
- greeting: options.greeting ?? "Hey there. I'm a voice assistant. What can I help you with?",
186
- maxSteps: options.maxSteps ?? 5,
187
- tools: options.tools ?? {},
188
- persistence
189
- };
190
- }
191
- //#endregion
1
+ import { a as createToolFactory, i as ToolChoiceSchema, n as DEFAULT_GREETING, o as defineAgent, r as DEFAULT_INSTRUCTIONS, s as defineTool, t as BuiltinToolSchema } from "./types-D8ZBxTL_.js";
192
2
  export { BuiltinToolSchema, DEFAULT_GREETING, DEFAULT_INSTRUCTIONS, ToolChoiceSchema, createToolFactory, defineAgent, defineTool, defineTool as tool };
@@ -0,0 +1,64 @@
1
+ import { n as matchGlob, r as sortAndPaginate, t as MAX_VALUE_SIZE } from "./kv-iXtikQmR.js";
2
+ import { prefixStorage } from "unstorage";
3
+ //#region unstorage-kv.ts
4
+ /**
5
+ * Key-value store backed by unstorage.
6
+ *
7
+ * Works with any unstorage driver (memory, fs, S3/R2, etc.).
8
+ */
9
+ /**
10
+ * Create a KV store backed by any unstorage driver.
11
+ *
12
+ * @param options - See {@link UnstorageKvOptions}.
13
+ * @returns A {@link Kv} instance.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { createStorage } from "unstorage";
18
+ * import { createUnstorageKv } from "@alexkroman1/aai/unstorage-kv";
19
+ *
20
+ * const kv = createUnstorageKv({ storage: createStorage() });
21
+ * await kv.set("greeting", "hello");
22
+ * const value = await kv.get<string>("greeting"); // "hello"
23
+ * ```
24
+ */
25
+ function createUnstorageKv(options) {
26
+ const store = options.prefix ? prefixStorage(options.storage, options.prefix) : options.storage;
27
+ return {
28
+ async get(key) {
29
+ return await store.getItem(key) ?? null;
30
+ },
31
+ async set(key, value, setOptions) {
32
+ if (JSON.stringify(value).length > 65536) throw new Error(`Value exceeds max size of ${MAX_VALUE_SIZE} bytes`);
33
+ const storable = value;
34
+ if (setOptions?.expireIn && setOptions.expireIn > 0) await store.setItem(key, storable, { ttl: Math.ceil(setOptions.expireIn / 1e3) });
35
+ else await store.setItem(key, storable);
36
+ },
37
+ async delete(keys) {
38
+ const keyArray = Array.isArray(keys) ? keys : [keys];
39
+ await Promise.all(keyArray.map((k) => store.removeItem(k)));
40
+ },
41
+ async list(listPrefix, listOptions) {
42
+ const allKeys = await store.getKeys(listPrefix);
43
+ const entries = [];
44
+ for (const key of allKeys) {
45
+ const value = await store.getItem(key);
46
+ if (value != null) entries.push({
47
+ key,
48
+ value
49
+ });
50
+ }
51
+ return sortAndPaginate(entries, listOptions);
52
+ },
53
+ async keys(pattern) {
54
+ const allKeys = await store.getKeys();
55
+ if (!pattern) return allKeys.sort((a, b) => a.localeCompare(b));
56
+ return allKeys.filter((key) => matchGlob(key, pattern)).sort((a, b) => a.localeCompare(b));
57
+ },
58
+ close() {
59
+ store.dispose();
60
+ }
61
+ };
62
+ }
63
+ //#endregion
64
+ export { createUnstorageKv as t };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Key-value store backed by unstorage.
3
+ *
4
+ * Works with any unstorage driver (memory, fs, S3/R2, etc.).
5
+ */
6
+ import { type Storage } from "unstorage";
7
+ import type { Kv } from "./kv.ts";
8
+ /**
9
+ * Options for creating an unstorage-backed KV store.
10
+ */
11
+ export type UnstorageKvOptions = {
12
+ /** Configured unstorage Storage instance. */
13
+ storage: Storage;
14
+ /** Key prefix prepended to all operations (e.g. `"agents/my-agent/kv"`). */
15
+ prefix?: string;
16
+ };
17
+ /**
18
+ * Create a KV store backed by any unstorage driver.
19
+ *
20
+ * @param options - See {@link UnstorageKvOptions}.
21
+ * @returns A {@link Kv} instance.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * import { createStorage } from "unstorage";
26
+ * import { createUnstorageKv } from "@alexkroman1/aai/unstorage-kv";
27
+ *
28
+ * const kv = createUnstorageKv({ storage: createStorage() });
29
+ * await kv.set("greeting", "hello");
30
+ * const value = await kv.get<string>("greeting"); // "hello"
31
+ * ```
32
+ */
33
+ export declare function createUnstorageKv(options: UnstorageKvOptions): Kv;
@@ -0,0 +1,2 @@
1
+ import { t as createUnstorageKv } from "./unstorage-kv-CDgP-frt.js";
2
+ export { createUnstorageKv };
@@ -0,0 +1,172 @@
1
+ const DEFAULT_MODEL = "Xenova/all-MiniLM-L6-v2";
2
+ /**
3
+ * Create a local embedding function using `all-MiniLM-L6-v2`.
4
+ *
5
+ * The model is downloaded on first use (~86 MB) and cached locally.
6
+ * Subsequent calls load from cache in ~90ms. Each embedding takes <2ms.
7
+ */
8
+ function createLocalEmbedFn(cacheDir) {
9
+ let pipelinePromise = null;
10
+ async function getPipeline() {
11
+ if (!pipelinePromise) pipelinePromise = (async () => {
12
+ const { pipeline, env } = await import("@huggingface/transformers");
13
+ env.cacheDir = cacheDir;
14
+ return pipeline("feature-extraction", DEFAULT_MODEL);
15
+ })();
16
+ return pipelinePromise;
17
+ }
18
+ return async (text) => {
19
+ const output = await (await getPipeline())(text, {
20
+ pooling: "mean",
21
+ normalize: true
22
+ });
23
+ return Array.from(output.data);
24
+ };
25
+ }
26
+ /**
27
+ * Create a deterministic hash-based embedding function for testing.
28
+ *
29
+ * Produces repeatable vectors where similar text yields similar embeddings.
30
+ * Not suitable for production — use the default local model instead.
31
+ *
32
+ * @param dimensions - Vector dimensions (default: 384).
33
+ */
34
+ function createTestEmbedFn(dimensions = 384) {
35
+ return async (text) => {
36
+ const vec = new Float32Array(dimensions);
37
+ const words = text.toLowerCase().split(/\s+/).filter(Boolean);
38
+ for (const word of words) {
39
+ let hash = 0;
40
+ for (let i = 0; i < word.length; i++) hash = (hash << 5) - hash + word.charCodeAt(i) | 0;
41
+ for (let i = 0; i < 8; i++) {
42
+ const idx = Math.abs((hash + i * 31337) % dimensions);
43
+ vec[idx] = (vec[idx] ?? 0) + 1;
44
+ }
45
+ }
46
+ let norm = 0;
47
+ for (let i = 0; i < dimensions; i++) norm += (vec[i] ?? 0) * (vec[i] ?? 0);
48
+ norm = Math.sqrt(norm) || 1;
49
+ return Array.from(vec, (v) => v / norm);
50
+ };
51
+ }
52
+ /** Cosine similarity between two Float32Array vectors. */
53
+ function cosineSimilarity(a, b) {
54
+ let dot = 0;
55
+ let normA = 0;
56
+ let normB = 0;
57
+ for (let i = 0; i < a.length; i++) {
58
+ const ai = a[i] ?? 0;
59
+ const bi = b[i] ?? 0;
60
+ dot += ai * bi;
61
+ normA += ai * ai;
62
+ normB += bi * bi;
63
+ }
64
+ const denom = Math.sqrt(normA) * Math.sqrt(normB);
65
+ return denom === 0 ? 0 : dot / denom;
66
+ }
67
+ /** Encode an embedding as a base64 string. */
68
+ function encodeEmbedding(vec) {
69
+ const f32 = vec instanceof Float32Array ? vec : new Float32Array(vec);
70
+ return Buffer.from(f32.buffer, f32.byteOffset, f32.byteLength).toString("base64");
71
+ }
72
+ /** Decode a base64 string back to a Float32Array embedding. */
73
+ function decodeEmbedding(b64) {
74
+ const buf = Buffer.from(b64, "base64");
75
+ return new Float32Array(buf.buffer, buf.byteOffset, buf.byteLength / 4);
76
+ }
77
+ //#endregion
78
+ //#region unstorage-vector.ts
79
+ /**
80
+ * Create a vector store backed by any unstorage driver.
81
+ *
82
+ * All vectors for the scope are stored in a single blob. The blob is loaded
83
+ * lazily on first operation and cached in memory. Mutations are written
84
+ * through immediately.
85
+ *
86
+ * @param options - See {@link UnstorageVectorOptions}.
87
+ * @returns A {@link VectorStore} instance.
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * import { createStorage } from "unstorage";
92
+ * import { createUnstorageVectorStore } from "@alexkroman1/aai/unstorage-vector";
93
+ *
94
+ * const vector = createUnstorageVectorStore({ storage: createStorage() });
95
+ * await vector.upsert("doc-1", "The capital of France is Paris.");
96
+ * const results = await vector.query("France capital");
97
+ * ```
98
+ */
99
+ function createUnstorageVectorStore(options) {
100
+ const { storage, blobKey = "vectors.json", dimensions = 384, modelCacheDir = ".aai/models" } = options;
101
+ const embedFn = options.embedFn ?? createLocalEmbedFn(modelCacheDir);
102
+ let cache = null;
103
+ async function loadCache() {
104
+ if (cache) return cache;
105
+ cache = /* @__PURE__ */ new Map();
106
+ const raw = await storage.getItem(blobKey);
107
+ if (raw != null) {
108
+ const blob = raw;
109
+ for (const [id, entry] of Object.entries(blob.entries)) {
110
+ const cached = {
111
+ data: entry.data,
112
+ embedding: decodeEmbedding(entry.emb)
113
+ };
114
+ if (entry.meta) cached.metadata = entry.meta;
115
+ cache.set(id, cached);
116
+ }
117
+ }
118
+ return cache;
119
+ }
120
+ async function flushCache() {
121
+ if (!cache) return;
122
+ const entries = {};
123
+ for (const [id, entry] of cache) entries[id] = {
124
+ data: entry.data,
125
+ ...entry.metadata ? { meta: entry.metadata } : {},
126
+ emb: encodeEmbedding(entry.embedding)
127
+ };
128
+ const blob = {
129
+ v: 1,
130
+ d: dimensions,
131
+ entries
132
+ };
133
+ await storage.setItem(blobKey, blob);
134
+ }
135
+ return {
136
+ async upsert(id, data, metadata) {
137
+ const c = await loadCache();
138
+ const vector = await embedFn(data);
139
+ const entry = {
140
+ data,
141
+ embedding: new Float32Array(vector)
142
+ };
143
+ if (metadata) entry.metadata = metadata;
144
+ c.set(id, entry);
145
+ await flushCache();
146
+ },
147
+ async query(text, queryOptions) {
148
+ const topK = queryOptions?.topK ?? 10;
149
+ if (queryOptions?.filter) throw new Error("Metadata filter is not supported by the unstorage vector store");
150
+ if (!text.trim()) return [];
151
+ const c = await loadCache();
152
+ const queryVec = new Float32Array(await embedFn(text));
153
+ const scored = [];
154
+ for (const [id, entry] of c) scored.push({
155
+ id,
156
+ score: cosineSimilarity(queryVec, entry.embedding),
157
+ data: entry.data,
158
+ metadata: entry.metadata
159
+ });
160
+ scored.sort((a, b) => b.score - a.score);
161
+ return scored.slice(0, topK);
162
+ },
163
+ async delete(ids) {
164
+ const c = await loadCache();
165
+ const idArray = Array.isArray(ids) ? ids : [ids];
166
+ for (const id of idArray) c.delete(id);
167
+ await flushCache();
168
+ }
169
+ };
170
+ }
171
+ //#endregion
172
+ export { createTestEmbedFn as n, createUnstorageVectorStore as t };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Vector store backed by unstorage.
3
+ *
4
+ * Stores all vectors for a scope in a single blob (JSON with base64-encoded
5
+ * embeddings). Works with any unstorage driver. Brute-force cosine similarity
6
+ * — fast for <10k vectors.
7
+ */
8
+ import type { Storage } from "unstorage";
9
+ import { type EmbedFn } from "./_embeddings.ts";
10
+ import type { VectorStore } from "./vector.ts";
11
+ export { createTestEmbedFn, type EmbedFn } from "./_embeddings.ts";
12
+ /**
13
+ * Options for creating an unstorage-backed vector store.
14
+ */
15
+ export type UnstorageVectorOptions = {
16
+ /** Configured unstorage Storage instance. */
17
+ storage: Storage;
18
+ /** Key for the vector blob in storage. Defaults to `"vectors.json"`. */
19
+ blobKey?: string;
20
+ /** Custom embedding function. Defaults to local `all-MiniLM-L6-v2` model. */
21
+ embedFn?: EmbedFn;
22
+ /** Embedding dimensions. Must match the embedFn output. Defaults to 384. */
23
+ dimensions?: number;
24
+ /** Directory for caching downloaded models. Defaults to `.aai/models`. */
25
+ modelCacheDir?: string;
26
+ };
27
+ /**
28
+ * Create a vector store backed by any unstorage driver.
29
+ *
30
+ * All vectors for the scope are stored in a single blob. The blob is loaded
31
+ * lazily on first operation and cached in memory. Mutations are written
32
+ * through immediately.
33
+ *
34
+ * @param options - See {@link UnstorageVectorOptions}.
35
+ * @returns A {@link VectorStore} instance.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * import { createStorage } from "unstorage";
40
+ * import { createUnstorageVectorStore } from "@alexkroman1/aai/unstorage-vector";
41
+ *
42
+ * const vector = createUnstorageVectorStore({ storage: createStorage() });
43
+ * await vector.upsert("doc-1", "The capital of France is Paris.");
44
+ * const results = await vector.query("France capital");
45
+ * ```
46
+ */
47
+ export declare function createUnstorageVectorStore(options: UnstorageVectorOptions): VectorStore;
@@ -0,0 +1,2 @@
1
+ import { n as createTestEmbedFn, t as createUnstorageVectorStore } from "./unstorage-vector-Cj5llNhg.js";
2
+ export { createTestEmbedFn, createUnstorageVectorStore };
package/dist/vector.d.ts CHANGED
@@ -34,8 +34,9 @@ export type VectorEntry = {
34
34
  * Async vector store interface used by agents.
35
35
  *
36
36
  * Agents access the vector store via `ToolContext.vector` or
37
- * `HookContext.vector`. Backed by Upstash Vector with built-in
38
- * embeddings raw text is sent and vectorized server-side.
37
+ * `HookContext.vector`. Backed by unstorage with local embeddings
38
+ * via `all-MiniLM-L6-v2` by default. Pluggable storage driver and
39
+ * embedding function.
39
40
  *
40
41
  * @example
41
42
  * ```ts
@@ -0,0 +1,70 @@
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,70 +1,2 @@
1
- import { EMPTY_PARAMS } from "./_internal-types.js";
2
- import { errorDetail, errorMessage, toolError } from "./_utils.js";
3
- import { TOOL_EXECUTION_TIMEOUT_MS } from "./protocol.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
1
+ import { t as executeToolCall } from "./worker-entry-2jaiqIj0.js";
70
2
  export { executeToolCall };