@alexkroman1/aai 0.6.0 → 0.7.2

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 (2) hide show
  1. package/dist/cli.js +90 -457
  2. package/package.json +23 -29
package/dist/cli.js CHANGED
@@ -65,13 +65,13 @@ __export(new_exports, {
65
65
  listTemplates: () => listTemplates,
66
66
  runNew: () => runNew
67
67
  });
68
- import fs5 from "node:fs/promises";
68
+ import fs4 from "node:fs/promises";
69
69
  import path4 from "node:path";
70
70
  import glob from "fast-glob";
71
71
  import fsExtra from "fs-extra";
72
72
  async function listTemplates(dir) {
73
73
  const templates = [];
74
- const entries = await fs5.readdir(dir, { withFileTypes: true });
74
+ const entries = await fs4.readdir(dir, { withFileTypes: true });
75
75
  for (const entry of entries) {
76
76
  if (entry.isDirectory() && !entry.name.startsWith("_")) {
77
77
  templates.push(entry.name);
@@ -84,10 +84,10 @@ async function copyDirNoOverwrite(src, dest) {
84
84
  for (const file of files) {
85
85
  const destPath = path4.join(dest, file);
86
86
  try {
87
- await fs5.access(destPath);
87
+ await fs4.access(destPath);
88
88
  } catch {
89
- await fs5.mkdir(path4.dirname(destPath), { recursive: true });
90
- await fs5.copyFile(path4.join(src, file), destPath);
89
+ await fs4.mkdir(path4.dirname(destPath), { recursive: true });
90
+ await fs4.copyFile(path4.join(src, file), destPath);
91
91
  }
92
92
  }
93
93
  }
@@ -101,12 +101,12 @@ async function runNew(opts) {
101
101
  await fsExtra.copy(path4.join(templatesDir, template), targetDir, { overwrite: true });
102
102
  await copyDirNoOverwrite(path4.join(templatesDir, "_shared"), targetDir);
103
103
  try {
104
- await fs5.copyFile(path4.join(targetDir, ".env.example"), path4.join(targetDir, ".env"));
104
+ await fs4.copyFile(path4.join(targetDir, ".env.example"), path4.join(targetDir, ".env"));
105
105
  } catch {
106
106
  }
107
107
  const readmePath = path4.join(targetDir, "README.md");
108
108
  try {
109
- await fs5.access(readmePath);
109
+ await fs4.access(readmePath);
110
110
  } catch {
111
111
  const slug = path4.basename(path4.resolve(targetDir));
112
112
  const readme = `# ${slug}
@@ -138,7 +138,7 @@ Access secrets in your agent via \`ctx.env.MY_KEY\`.
138
138
 
139
139
  See \`CLAUDE.md\` for the full agent API reference.
140
140
  `;
141
- await fs5.writeFile(readmePath, readme);
141
+ await fs4.writeFile(readmePath, readme);
142
142
  }
143
143
  _internals2.step("Done", targetDir);
144
144
  return targetDir;
@@ -766,11 +766,11 @@ var init_s2s = __esm({
766
766
  });
767
767
 
768
768
  // dist/sdk/types.js
769
- var DEFAULT_INSTRUCTIONS2;
769
+ var DEFAULT_INSTRUCTIONS;
770
770
  var init_types = __esm({
771
771
  "dist/sdk/types.js"() {
772
772
  "use strict";
773
- DEFAULT_INSTRUCTIONS2 = `You are AAI, a helpful AI assistant.
773
+ DEFAULT_INSTRUCTIONS = `You are AAI, a helpful AI assistant.
774
774
 
775
775
  Voice-First Rules:
776
776
  - Optimize for natural speech. Avoid jargon unless central to the answer. Use short, punchy sentences.
@@ -798,7 +798,7 @@ ${config.instructions}` : "";
798
798
  month: "long",
799
799
  day: "numeric"
800
800
  });
801
- return DEFAULT_INSTRUCTIONS2 + `
801
+ return DEFAULT_INSTRUCTIONS + `
802
802
 
803
803
  Today's date is ${today}.` + agentInstructions + toolPreamble + (opts?.voice ? VOICE_RULES : "");
804
804
  }
@@ -1844,9 +1844,7 @@ async function loadAgent(dir) {
1844
1844
  slug,
1845
1845
  dir,
1846
1846
  entryPoint: path.join(dir, "agent.ts"),
1847
- env: {},
1848
- clientEntry,
1849
- transport: ["websocket"]
1847
+ clientEntry
1850
1848
  };
1851
1849
  }
1852
1850
  async function ensureClaudeMd(targetDir) {
@@ -1880,7 +1878,7 @@ init_output();
1880
1878
  var _internals = {
1881
1879
  fetch: globalThis.fetch.bind(globalThis)
1882
1880
  };
1883
- async function attemptDeploy(url, slug, apiKey, env, transport, worker, html, config, toolSchemas) {
1881
+ async function attemptDeploy(url, slug, apiKey, env, worker, html) {
1884
1882
  return await _internals.fetch(`${url}/${slug}/deploy`, {
1885
1883
  method: "POST",
1886
1884
  headers: {
@@ -1890,21 +1888,14 @@ async function attemptDeploy(url, slug, apiKey, env, transport, worker, html, co
1890
1888
  body: JSON.stringify({
1891
1889
  env,
1892
1890
  worker,
1893
- html,
1894
- transport,
1895
- config,
1896
- toolSchemas
1891
+ html
1897
1892
  })
1898
1893
  });
1899
1894
  }
1900
1895
  var MAX_RETRIES = 20;
1901
1896
  async function runDeploy(opts) {
1902
- const manifest = JSON.parse(opts.bundle.manifest);
1903
1897
  const worker = opts.bundle.worker;
1904
1898
  const html = opts.bundle.html;
1905
- const transport = manifest.transport ?? ["websocket"];
1906
- const config = manifest.config;
1907
- const toolSchemas = manifest.toolSchemas;
1908
1899
  let slug = opts.slug;
1909
1900
  if (opts.dryRun) {
1910
1901
  stepInfo("Dry run", "would deploy:");
@@ -1912,17 +1903,7 @@ async function runDeploy(opts) {
1912
1903
  return { slug };
1913
1904
  }
1914
1905
  for (let i = 0; i < MAX_RETRIES; i++) {
1915
- const resp = await attemptDeploy(
1916
- opts.url,
1917
- slug,
1918
- opts.apiKey,
1919
- opts.env,
1920
- transport,
1921
- worker,
1922
- html,
1923
- config,
1924
- toolSchemas
1925
- );
1906
+ const resp = await attemptDeploy(opts.url, slug, opts.apiKey, opts.env, worker, html);
1926
1907
  if (resp.ok) {
1927
1908
  step("Deploy", `${slug} -> ${opts.url}/${slug}`);
1928
1909
  try {
@@ -2078,365 +2059,16 @@ async function runWithInk(label, fn) {
2078
2059
  }
2079
2060
 
2080
2061
  // cli/build.ts
2081
- import fs4 from "node:fs/promises";
2062
+ import fs3 from "node:fs/promises";
2082
2063
  import path3 from "node:path";
2083
2064
 
2084
2065
  // cli/_bundler.ts
2085
- import fs3 from "node:fs/promises";
2066
+ import fs2 from "node:fs/promises";
2086
2067
  import path2 from "node:path";
2087
2068
  import preact from "@preact/preset-vite";
2088
2069
  import tailwindcss from "@tailwindcss/vite";
2089
2070
  import { build } from "vite";
2090
2071
  import { viteSingleFile } from "vite-plugin-singlefile";
2091
-
2092
- // cli/_static_config.ts
2093
- import fs2 from "node:fs/promises";
2094
- import {
2095
- Project,
2096
- SyntaxKind
2097
- } from "ts-morph";
2098
-
2099
- // sdk/types.ts
2100
- var DEFAULT_INSTRUCTIONS = `You are AAI, a helpful AI assistant.
2101
-
2102
- Voice-First Rules:
2103
- - Optimize for natural speech. Avoid jargon unless central to the answer. Use short, punchy sentences.
2104
- - Never mention "search results," "sources," or "the provided text." Speak as if the knowledge is your own.
2105
- - No visual formatting. Do not say "bullet point," "bold," or "bracketed one." If you need to list items, say "First," "Next," and "Finally."
2106
- - Start with the most important information. No introductory filler.
2107
- - Be concise. Keep answers to 1-3 sentences. For complex topics, provide a high-level summary.
2108
- - Be confident. Avoid hedging phrases like "It seems that" or "I believe."
2109
- - If you don't have enough information, say so directly rather than guessing.
2110
- - Never use exclamation points. Keep your tone calm and conversational.`;
2111
- var DEFAULT_GREETING = "Hey there. I'm a voice assistant. What can I help you with?";
2112
-
2113
- // cli/_static_config.ts
2114
- var project = new Project({ useInMemoryFileSystem: true });
2115
- async function extractStaticConfig(agentPath) {
2116
- const source = await fs2.readFile(agentPath, "utf-8");
2117
- return extractStaticConfigFromSource(source, agentPath);
2118
- }
2119
- function extractStaticConfigFromSource(source, fileName = "agent.ts") {
2120
- const sf = project.createSourceFile(fileName, source, { overwrite: true });
2121
- const call = findDefineAgentCall(sf);
2122
- if (!call) {
2123
- throw new BundleError(
2124
- `Could not find a defineAgent({...}) call in ${fileName}. Make sure your agent.ts has \`export default defineAgent({...})\`.`
2125
- );
2126
- }
2127
- const args = call.getArguments();
2128
- const arg = args[0];
2129
- if (!arg || !arg.isKind(SyntaxKind.ObjectLiteralExpression)) {
2130
- throw new BundleError("The argument to defineAgent() must be an inline object literal");
2131
- }
2132
- const obj = arg.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
2133
- const config = extractConfig(obj, fileName);
2134
- const toolSchemas = extractToolSchemas(obj, fileName);
2135
- return { config, toolSchemas };
2136
- }
2137
- function findDefineAgentCall(sf) {
2138
- return sf.getFirstDescendant((node) => {
2139
- if (!node.isKind(SyntaxKind.CallExpression)) return false;
2140
- const expr = node.getExpression();
2141
- return expr.isKind(SyntaxKind.Identifier) && expr.getText() === "defineAgent";
2142
- });
2143
- }
2144
- function extractConfig(obj, fileName) {
2145
- const name = requireString(obj, "name", fileName);
2146
- const config = {
2147
- name,
2148
- instructions: optionalString(obj, "instructions", fileName) ?? DEFAULT_INSTRUCTIONS,
2149
- greeting: optionalString(obj, "greeting", fileName) ?? DEFAULT_GREETING,
2150
- voice: optionalString(obj, "voice", fileName) ?? ""
2151
- };
2152
- const mode = optionalString(obj, "mode", fileName);
2153
- config.mode = mode ?? "s2s";
2154
- const sttPrompt = optionalString(obj, "sttPrompt", fileName);
2155
- if (sttPrompt !== void 0) config.sttPrompt = sttPrompt;
2156
- const maxStepsProp = getProperty(obj, "maxSteps");
2157
- if (maxStepsProp) {
2158
- const init = maxStepsProp.getInitializer();
2159
- if (init.isKind(SyntaxKind.NumericLiteral)) {
2160
- config.maxSteps = Number(init.getLiteralValue());
2161
- }
2162
- }
2163
- const toolChoiceProp = getProperty(obj, "toolChoice");
2164
- if (toolChoiceProp) {
2165
- config.toolChoice = evalLiteral(
2166
- toolChoiceProp.getInitializer(),
2167
- "toolChoice",
2168
- fileName
2169
- );
2170
- }
2171
- const builtinToolsProp = getProperty(obj, "builtinTools");
2172
- if (builtinToolsProp) {
2173
- config.builtinTools = evalStringArray(
2174
- builtinToolsProp.getInitializer(),
2175
- "builtinTools",
2176
- fileName
2177
- );
2178
- }
2179
- const activeToolsProp = getProperty(obj, "activeTools");
2180
- if (activeToolsProp) {
2181
- config.activeTools = evalStringArray(
2182
- activeToolsProp.getInitializer(),
2183
- "activeTools",
2184
- fileName
2185
- );
2186
- }
2187
- const transportProp = getProperty(obj, "transport");
2188
- if (transportProp) {
2189
- const init = transportProp.getInitializer();
2190
- if (init.isKind(SyntaxKind.StringLiteral)) {
2191
- config.transport = [init.getLiteralValue()];
2192
- } else if (init.isKind(SyntaxKind.ArrayLiteralExpression)) {
2193
- config.transport = evalStringArray(init, "transport", fileName);
2194
- } else {
2195
- throw new BundleError(
2196
- `${fileName}: \`transport\` must be a string literal or array of strings.`
2197
- );
2198
- }
2199
- }
2200
- return config;
2201
- }
2202
- function extractToolSchemas(obj, fileName) {
2203
- const toolsProp = getProperty(obj, "tools");
2204
- if (!toolsProp) return [];
2205
- const init = toolsProp.getInitializer();
2206
- if (!init.isKind(SyntaxKind.ObjectLiteralExpression)) {
2207
- throw new BundleError(`${fileName}: \`tools\` must be an inline object literal.`);
2208
- }
2209
- const toolsObj = init.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
2210
- const schemas = [];
2211
- for (const member of toolsObj.getProperties()) {
2212
- if (member.isKind(SyntaxKind.SpreadAssignment)) {
2213
- const text = member.getExpression().getText();
2214
- throw new BundleError(
2215
- `${fileName}: Spread expressions like \`...${text}\` in tools cannot be statically analyzed. Define each tool directly in the \`tools\` object.`
2216
- );
2217
- }
2218
- if (!member.isKind(SyntaxKind.PropertyAssignment)) continue;
2219
- const prop = member;
2220
- const toolName = prop.getName();
2221
- const toolInit = prop.getInitializer();
2222
- if (!toolInit.isKind(SyntaxKind.ObjectLiteralExpression)) {
2223
- throw new BundleError(`${fileName}: Tool \`${toolName}\` must be an inline object literal.`);
2224
- }
2225
- const toolObj = toolInit.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
2226
- const descProp = getProperty(toolObj, "description");
2227
- if (!descProp) {
2228
- throw new BundleError(`${fileName}: Tool \`${toolName}\` is missing a \`description\`.`);
2229
- }
2230
- const description = evalStringLiteral(descProp.getInitializer(), toolName, fileName);
2231
- const paramsProp = getProperty(toolObj, "parameters");
2232
- const parameters = paramsProp ? zodAstToJsonSchema(paramsProp.getInitializer(), toolName, fileName) : { type: "object", properties: {}, additionalProperties: false };
2233
- schemas.push({ name: toolName, description, parameters });
2234
- }
2235
- return schemas;
2236
- }
2237
- function zodAstToJsonSchema(node, toolName, fileName) {
2238
- return parseZodExpr(node, toolName, fileName).schema;
2239
- }
2240
- function parseZodExpr(node, toolName, fileName) {
2241
- if (!node.isKind(SyntaxKind.CallExpression)) {
2242
- throw zodError(node, toolName, fileName);
2243
- }
2244
- const call = node.asKindOrThrow(SyntaxKind.CallExpression);
2245
- const expr = call.getExpression();
2246
- if (expr.isKind(SyntaxKind.PropertyAccessExpression)) {
2247
- const propAccess = expr.asKindOrThrow(SyntaxKind.PropertyAccessExpression);
2248
- const obj = propAccess.getExpression();
2249
- const method = propAccess.getName();
2250
- if (obj.isKind(SyntaxKind.Identifier) && obj.getText() === "z") {
2251
- return parseZodBase(method, call, toolName, fileName);
2252
- }
2253
- if (method === "describe") {
2254
- const result = parseZodExpr(obj, toolName, fileName);
2255
- const args = call.getArguments();
2256
- if (args[0]) {
2257
- result.schema.description = evalStringLiteral(args[0], toolName, fileName);
2258
- }
2259
- return result;
2260
- }
2261
- if (method === "optional") {
2262
- const result = parseZodExpr(obj, toolName, fileName);
2263
- result.optional = true;
2264
- return result;
2265
- }
2266
- if (method === "default" || method === "nullable") {
2267
- return parseZodExpr(obj, toolName, fileName);
2268
- }
2269
- return parseZodExpr(obj, toolName, fileName);
2270
- }
2271
- throw zodError(node, toolName, fileName);
2272
- }
2273
- function parseZodBase(method, call, toolName, fileName) {
2274
- switch (method) {
2275
- case "string":
2276
- return { schema: { type: "string" }, optional: false };
2277
- case "number":
2278
- return { schema: { type: "number" }, optional: false };
2279
- case "boolean":
2280
- return { schema: { type: "boolean" }, optional: false };
2281
- case "enum": {
2282
- const args = call.getArguments();
2283
- const arg = args[0];
2284
- if (!arg || !arg.isKind(SyntaxKind.ArrayLiteralExpression)) {
2285
- throw new BundleError(
2286
- `${fileName}: Tool \`${toolName}\`: z.enum() requires an array literal argument.`
2287
- );
2288
- }
2289
- const arr = arg.asKindOrThrow(SyntaxKind.ArrayLiteralExpression);
2290
- const values = arr.getElements().map((el) => {
2291
- if (!el.isKind(SyntaxKind.StringLiteral)) {
2292
- throw new BundleError(
2293
- `${fileName}: Tool \`${toolName}\`: z.enum() values must be string literals.`
2294
- );
2295
- }
2296
- return el.asKindOrThrow(SyntaxKind.StringLiteral).getLiteralValue();
2297
- });
2298
- return {
2299
- schema: { type: "string", enum: values },
2300
- optional: false
2301
- };
2302
- }
2303
- case "array": {
2304
- const args = call.getArguments();
2305
- const arg = args[0];
2306
- if (!arg) {
2307
- return { schema: { type: "array" }, optional: false };
2308
- }
2309
- const items = parseZodExpr(arg, toolName, fileName);
2310
- return {
2311
- schema: { type: "array", items: items.schema },
2312
- optional: false
2313
- };
2314
- }
2315
- case "object": {
2316
- const args = call.getArguments();
2317
- const arg = args[0];
2318
- if (!arg || !arg.isKind(SyntaxKind.ObjectLiteralExpression)) {
2319
- return {
2320
- schema: {
2321
- type: "object",
2322
- properties: {},
2323
- additionalProperties: false
2324
- },
2325
- optional: false
2326
- };
2327
- }
2328
- const objLit = arg.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
2329
- const properties = {};
2330
- const required = [];
2331
- for (const member of objLit.getProperties()) {
2332
- if (!member.isKind(SyntaxKind.PropertyAssignment)) continue;
2333
- const prop = member;
2334
- const propName = prop.getName();
2335
- const result = parseZodExpr(prop.getInitializer(), toolName, fileName);
2336
- properties[propName] = result.schema;
2337
- if (!result.optional) {
2338
- required.push(propName);
2339
- }
2340
- }
2341
- const schema = {
2342
- type: "object",
2343
- properties,
2344
- additionalProperties: false
2345
- };
2346
- if (required.length > 0) {
2347
- schema.required = required;
2348
- }
2349
- return { schema, optional: false };
2350
- }
2351
- default:
2352
- throw new BundleError(
2353
- `${fileName}: Tool \`${toolName}\`: unsupported Zod type \`z.${method}()\`. Supported: z.string(), z.number(), z.boolean(), z.enum([...]), z.array(...), z.object({...}).`
2354
- );
2355
- }
2356
- }
2357
- function zodError(node, toolName, fileName) {
2358
- const text = node.getText().slice(0, 60);
2359
- return new BundleError(
2360
- `${fileName}: Tool \`${toolName}\`: unsupported Zod pattern \`${text}\`. Supported: z.string(), z.number(), z.boolean(), z.enum([...]), z.array(...), z.object({...}), .describe(), .optional().`
2361
- );
2362
- }
2363
- function getProperty(obj, name) {
2364
- const prop = obj.getProperty(name);
2365
- if (!prop) return void 0;
2366
- if (!prop.isKind(SyntaxKind.PropertyAssignment)) return void 0;
2367
- return prop;
2368
- }
2369
- function requireString(obj, field, fileName) {
2370
- const prop = getProperty(obj, field);
2371
- if (!prop) {
2372
- throw new BundleError(`${fileName}: The \`${field}\` field is required in defineAgent({...}).`);
2373
- }
2374
- return evalStringLiteral(prop.getInitializer(), field, fileName);
2375
- }
2376
- function optionalString(obj, field, fileName) {
2377
- const prop = getProperty(obj, field);
2378
- if (!prop) return void 0;
2379
- return evalStringLiteral(prop.getInitializer(), field, fileName);
2380
- }
2381
- function evalStringLiteral(node, context, fileName) {
2382
- if (node.isKind(SyntaxKind.StringLiteral)) {
2383
- return node.asKindOrThrow(SyntaxKind.StringLiteral).getLiteralValue();
2384
- }
2385
- if (node.isKind(SyntaxKind.NoSubstitutionTemplateLiteral)) {
2386
- return node.asKindOrThrow(SyntaxKind.NoSubstitutionTemplateLiteral).getLiteralValue();
2387
- }
2388
- if (node.isKind(SyntaxKind.TemplateExpression)) {
2389
- throw new BundleError(
2390
- `${fileName}: \`${context}\` uses template expressions with substitutions, which cannot be statically analyzed. Use a plain string literal.`
2391
- );
2392
- }
2393
- throw new BundleError(
2394
- `${fileName}: \`${context}\` must be a static string literal. Dynamic expressions cannot be analyzed at build time.`
2395
- );
2396
- }
2397
- function evalStringArray(node, context, fileName) {
2398
- if (!node.isKind(SyntaxKind.ArrayLiteralExpression)) {
2399
- throw new BundleError(`${fileName}: \`${context}\` must be an array literal.`);
2400
- }
2401
- const arr = node.asKindOrThrow(SyntaxKind.ArrayLiteralExpression);
2402
- return arr.getElements().map((el) => evalStringLiteral(el, context, fileName));
2403
- }
2404
- function evalLiteral(node, context, fileName) {
2405
- if (node.isKind(SyntaxKind.StringLiteral)) {
2406
- return node.asKindOrThrow(SyntaxKind.StringLiteral).getLiteralValue();
2407
- }
2408
- if (node.isKind(SyntaxKind.NoSubstitutionTemplateLiteral)) {
2409
- return node.asKindOrThrow(SyntaxKind.NoSubstitutionTemplateLiteral).getLiteralValue();
2410
- }
2411
- if (node.isKind(SyntaxKind.NumericLiteral)) {
2412
- return Number(node.asKindOrThrow(SyntaxKind.NumericLiteral).getLiteralValue());
2413
- }
2414
- if (node.isKind(SyntaxKind.TrueKeyword)) return true;
2415
- if (node.isKind(SyntaxKind.FalseKeyword)) return false;
2416
- if (node.isKind(SyntaxKind.ArrayLiteralExpression)) {
2417
- return node.asKindOrThrow(SyntaxKind.ArrayLiteralExpression).getElements().map((el) => evalLiteral(el, context, fileName));
2418
- }
2419
- if (node.isKind(SyntaxKind.ObjectLiteralExpression)) {
2420
- const obj = node.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
2421
- const result = {};
2422
- for (const member of obj.getProperties()) {
2423
- if (member.isKind(SyntaxKind.PropertyAssignment)) {
2424
- const prop = member;
2425
- result[prop.getName()] = evalLiteral(
2426
- prop.getInitializer(),
2427
- context,
2428
- fileName
2429
- );
2430
- }
2431
- }
2432
- return result;
2433
- }
2434
- throw new BundleError(
2435
- `${fileName}: \`${context}\` must be a static literal value. Dynamic expressions cannot be analyzed at build time.`
2436
- );
2437
- }
2438
-
2439
- // cli/_bundler.ts
2440
2072
  var BundleError = class extends Error {
2441
2073
  constructor(message) {
2442
2074
  super(message);
@@ -2558,14 +2190,13 @@ var INDEX_HTML = `<!DOCTYPE html>
2558
2190
  async function bundleAgent(agent, opts) {
2559
2191
  const aaiDir = path2.join(agent.dir, ".aai");
2560
2192
  const buildDir = path2.join(aaiDir, "build");
2561
- await fs3.mkdir(aaiDir, { recursive: true });
2562
- const { config: agentConfig, toolSchemas } = await extractStaticConfig(agent.entryPoint);
2563
- await fs3.writeFile(path2.join(aaiDir, "index.html"), INDEX_HTML);
2193
+ await fs2.mkdir(aaiDir, { recursive: true });
2194
+ await fs2.writeFile(path2.join(aaiDir, "index.html"), INDEX_HTML);
2564
2195
  const stylesPath = path2.join(agent.dir, "styles.css");
2565
2196
  try {
2566
- await fs3.access(stylesPath);
2197
+ await fs2.access(stylesPath);
2567
2198
  } catch {
2568
- await fs3.writeFile(stylesPath, DEFAULT_STYLES_CSS);
2199
+ await fs2.writeFile(stylesPath, DEFAULT_STYLES_CSS);
2569
2200
  }
2570
2201
  try {
2571
2202
  await build({
@@ -2610,22 +2241,12 @@ async function bundleAgent(agent, opts) {
2610
2241
  throw new BundleError(err instanceof Error ? err.message : String(err));
2611
2242
  }
2612
2243
  }
2613
- const worker = await fs3.readFile(path2.join(buildDir, "worker.js"), "utf-8");
2244
+ const worker = await fs2.readFile(path2.join(buildDir, "worker.js"), "utf-8");
2614
2245
  const htmlPath = skipClient ? path2.join(aaiDir, "index.html") : path2.join(buildDir, "index.html");
2615
- const html = await fs3.readFile(htmlPath, "utf-8");
2616
- const manifest = JSON.stringify(
2617
- {
2618
- transport: agentConfig.transport ?? agent.transport,
2619
- config: agentConfig,
2620
- toolSchemas
2621
- },
2622
- null,
2623
- 2
2624
- );
2246
+ const html = await fs2.readFile(htmlPath, "utf-8");
2625
2247
  return {
2626
2248
  worker,
2627
2249
  html,
2628
- manifest,
2629
2250
  workerBytes: Buffer.byteLength(worker)
2630
2251
  };
2631
2252
  }
@@ -2634,18 +2255,17 @@ async function bundleAgent(agent, opts) {
2634
2255
  init_output();
2635
2256
  async function writeBuildOutput(agentDir, bundle) {
2636
2257
  const buildDir = path3.join(agentDir, ".aai", "build");
2637
- await fs4.mkdir(buildDir, { recursive: true });
2258
+ await fs3.mkdir(buildDir, { recursive: true });
2638
2259
  await Promise.all([
2639
- fs4.writeFile(path3.join(buildDir, "worker.js"), bundle.worker),
2640
- fs4.writeFile(path3.join(buildDir, "manifest.json"), bundle.manifest),
2641
- fs4.writeFile(path3.join(buildDir, "index.html"), bundle.html)
2260
+ fs3.writeFile(path3.join(buildDir, "worker.js"), bundle.worker),
2261
+ fs3.writeFile(path3.join(buildDir, "index.html"), bundle.html)
2642
2262
  ]);
2643
2263
  }
2644
2264
  async function checkAgent(agentDir) {
2645
2265
  const userFiles = ["agent.ts"];
2646
2266
  for (const f of ["client.tsx", "components.tsx"]) {
2647
2267
  try {
2648
- await fs4.stat(path3.join(agentDir, f));
2268
+ await fs3.stat(path3.join(agentDir, f));
2649
2269
  userFiles.push(f);
2650
2270
  } catch {
2651
2271
  }
@@ -2655,12 +2275,12 @@ async function checkAgent(agentDir) {
2655
2275
  checks.map(({ args }) => execFileAsync("npx", ["tsc", ...args], { cwd: agentDir }))
2656
2276
  );
2657
2277
  const errors = [];
2658
- for (let i = 0; i < results.length; i++) {
2659
- const r = results[i];
2278
+ for (const [i, r] of results.entries()) {
2660
2279
  if (r.status === "rejected") {
2280
+ const label = checks[i]?.label ?? "unknown";
2661
2281
  const msg = r.reason.stderr?.trim() ?? String(r.reason);
2662
- error2(`${checks[i].label}: ${msg}`);
2663
- errors.push(checks[i].label);
2282
+ error2(`${label}: ${msg}`);
2283
+ errors.push(label);
2664
2284
  }
2665
2285
  }
2666
2286
  if (errors.length > 0) {
@@ -2691,7 +2311,7 @@ async function runBuild(opts) {
2691
2311
 
2692
2312
  // cli/new.tsx
2693
2313
  init_colors();
2694
- import fs6 from "node:fs/promises";
2314
+ import fs5 from "node:fs/promises";
2695
2315
  import path5 from "node:path";
2696
2316
  import { fileURLToPath as fileURLToPath2 } from "node:url";
2697
2317
  import minimist from "minimist";
@@ -2767,14 +2387,14 @@ async function runNewCommand(args, version) {
2767
2387
  if (isDevMode()) {
2768
2388
  const monorepoRoot = path5.join(cliDir2, "..");
2769
2389
  const pkgJsonPath2 = path5.join(cwd, "package.json");
2770
- const pkgJson2 = JSON.parse(await fs6.readFile(pkgJsonPath2, "utf-8"));
2390
+ const pkgJson2 = JSON.parse(await fs5.readFile(pkgJsonPath2, "utf-8"));
2771
2391
  for (const pkg of ["sdk", "ui"]) {
2772
2392
  const localPkgPath = path5.join(monorepoRoot, pkg, "package.json");
2773
- const localPkg = JSON.parse(await fs6.readFile(localPkgPath, "utf-8"));
2393
+ const localPkg = JSON.parse(await fs5.readFile(localPkgPath, "utf-8"));
2774
2394
  const pkgName = localPkg.name;
2775
2395
  pkgJson2.dependencies[pkgName] = `file:${path5.join(monorepoRoot, pkg)}`;
2776
2396
  }
2777
- await fs6.writeFile(pkgJsonPath2, `${JSON.stringify(pkgJson2, null, 2)}
2397
+ await fs5.writeFile(pkgJsonPath2, `${JSON.stringify(pkgJson2, null, 2)}
2778
2398
  `);
2779
2399
  }
2780
2400
  await ensureClaudeMd(cwd);
@@ -2868,7 +2488,9 @@ async function loadAgentDef(cwd) {
2868
2488
  }
2869
2489
  }
2870
2490
  async function resolveServerEnv() {
2871
- const env = { ...process.env };
2491
+ const env = Object.fromEntries(
2492
+ Object.entries(process.env).filter((e) => e[1] !== void 0)
2493
+ );
2872
2494
  if (!env.ASSEMBLYAI_API_KEY) {
2873
2495
  try {
2874
2496
  env.ASSEMBLYAI_API_KEY = await getApiKey();
@@ -3042,14 +2664,26 @@ async function runRag(opts) {
3042
2664
  log(/* @__PURE__ */ jsx4(Step, { action: "Parsed", msg: `${pages.length} pages` }));
3043
2665
  const { RecursiveChunker } = await import("@chonkiejs/core");
3044
2666
  const chunker = await RecursiveChunker.create({ chunkSize });
3045
- const allChunks = [];
3046
2667
  const siteSlug = slugify(origin);
2668
+ const allChunks = await chunkPages(pages, chunker, origin, siteSlug);
2669
+ log(/* @__PURE__ */ jsx4(Step, { action: "Chunked", msg: `${allChunks.length} chunks` }));
2670
+ const vectorUrl = `${serverUrl}/${slug}/vector`;
2671
+ log(/* @__PURE__ */ jsx4(Info, { msg: `target: ${vectorUrl}` }));
2672
+ const result = await upsertChunks(allChunks, vectorUrl, apiKey, setProgress);
2673
+ log(/* @__PURE__ */ jsx4(Step, { action: "Done", msg: `${result.upserted} chunks upserted` }));
2674
+ if (result.errors > 0) {
2675
+ log(/* @__PURE__ */ jsx4(Warn, { msg: `${result.errors} failed` }));
2676
+ if (result.lastError) log(/* @__PURE__ */ jsx4(Info, { msg: `last error: ${result.lastError}` }));
2677
+ }
2678
+ log(/* @__PURE__ */ jsx4(Detail, { msg: `Agent: ${slug}` }));
2679
+ }
2680
+ async function chunkPages(pages, chunker, origin, siteSlug) {
2681
+ const allChunks = [];
3047
2682
  for (const page of pages) {
3048
2683
  page.body = stripNoise(page.body);
3049
2684
  if (!page.body) continue;
3050
2685
  const raw = await chunker.chunk(page.body);
3051
- for (let i = 0; i < raw.length; i++) {
3052
- const c = raw[i];
2686
+ for (const [i, c] of raw.entries()) {
3053
2687
  const data = page.title ? `${page.title}
3054
2688
 
3055
2689
  ${c.text}` : c.text;
@@ -3065,10 +2699,10 @@ ${c.text}` : c.text;
3065
2699
  });
3066
2700
  }
3067
2701
  }
3068
- log(/* @__PURE__ */ jsx4(Step, { action: "Chunked", msg: `${allChunks.length} chunks` }));
3069
- const vectorUrl = `${serverUrl}/${slug}/vector`;
3070
- log(/* @__PURE__ */ jsx4(Info, { msg: `target: ${vectorUrl}` }));
3071
- const total = allChunks.length;
2702
+ return allChunks;
2703
+ }
2704
+ async function upsertChunks(chunks, vectorUrl, apiKey, setProgress) {
2705
+ const total = chunks.length;
3072
2706
  let completed = 0;
3073
2707
  let upserted = 0;
3074
2708
  let errors = 0;
@@ -3076,7 +2710,7 @@ ${c.text}` : c.text;
3076
2710
  setProgress({ completed: 0, total });
3077
2711
  const limit = pLimit(5);
3078
2712
  await Promise.all(
3079
- allChunks.map(
2713
+ chunks.map(
3080
2714
  (chunk) => limit(async () => {
3081
2715
  try {
3082
2716
  const r = await fetch(vectorUrl, {
@@ -3107,12 +2741,7 @@ ${c.text}` : c.text;
3107
2741
  })
3108
2742
  )
3109
2743
  );
3110
- log(/* @__PURE__ */ jsx4(Step, { action: "Done", msg: `${upserted} chunks upserted` }));
3111
- if (errors > 0) {
3112
- log(/* @__PURE__ */ jsx4(Warn, { msg: `${errors} failed` }));
3113
- if (lastError) log(/* @__PURE__ */ jsx4(Info, { msg: `last error: ${lastError}` }));
3114
- }
3115
- log(/* @__PURE__ */ jsx4(Detail, { msg: `Agent: ${slug}` }));
2744
+ return { upserted, errors, lastError };
3116
2745
  }
3117
2746
  async function runRagCommand(args, version) {
3118
2747
  const parsed = minimist4(args, {
@@ -3170,34 +2799,38 @@ function splitPages(content) {
3170
2799
  for (const section of raw) {
3171
2800
  const trimmed = section.trim();
3172
2801
  if (!trimmed) continue;
3173
- let title = "";
3174
- let body = trimmed;
3175
- const dashIndex = trimmed.search(/^-{3,}$/m);
3176
- if (dashIndex !== -1) {
3177
- const frontmatter = trimmed.slice(0, dashIndex);
3178
- body = trimmed.slice(dashIndex).replace(/^-+$/m, "").trim();
3179
- const titleMatch = frontmatter.match(/^title:\s*(.+)$/m);
3180
- if (titleMatch) {
3181
- title = titleMatch[1].trim();
3182
- }
2802
+ const page = parsePage(trimmed);
2803
+ if (page.body.length > 0) {
2804
+ pages.push(page);
3183
2805
  }
3184
- if (!title) {
3185
- const titleLineMatch = body.match(/^#{1,2}\s+title:\s*(.+)$/m);
3186
- if (titleLineMatch) {
3187
- title = titleLineMatch[1].trim();
3188
- body = body.replace(/^#{1,2}\s+title:\s*.+\n?/m, "").trim();
3189
- } else {
3190
- const headingMatch = body.match(/^(#{1,3})\s+(.+)$/m);
3191
- if (headingMatch) {
3192
- title = headingMatch[2].trim();
3193
- }
2806
+ }
2807
+ return pages;
2808
+ }
2809
+ function parsePage(trimmed) {
2810
+ let title = "";
2811
+ let body = trimmed;
2812
+ const dashIndex = trimmed.search(/^-{3,}$/m);
2813
+ if (dashIndex !== -1) {
2814
+ const frontmatter = trimmed.slice(0, dashIndex);
2815
+ body = trimmed.slice(dashIndex).replace(/^-+$/m, "").trim();
2816
+ const titleMatch = frontmatter.match(/^title:\s*(.+)$/m);
2817
+ if (titleMatch) {
2818
+ title = titleMatch[1]?.trim() ?? "";
2819
+ }
2820
+ }
2821
+ if (!title) {
2822
+ const titleLineMatch = body.match(/^#{1,2}\s+title:\s*(.+)$/m);
2823
+ if (titleLineMatch) {
2824
+ title = titleLineMatch[1]?.trim() ?? "";
2825
+ body = body.replace(/^#{1,2}\s+title:\s*.+\n?/m, "").trim();
2826
+ } else {
2827
+ const headingMatch = body.match(/^(#{1,3})\s+(.+)$/m);
2828
+ if (headingMatch) {
2829
+ title = headingMatch[2]?.trim() ?? "";
3194
2830
  }
3195
2831
  }
3196
- if (body.length > 0) {
3197
- pages.push({ title, body });
3198
- }
3199
2832
  }
3200
- return pages;
2833
+ return { title, body };
3201
2834
  }
3202
2835
  function stripNoise(text) {
3203
2836
  return text.replace(/^(`{3,}|~{3,}).*[\s\S]*?^\1/gm, "").replace(/^(?:[ ]{4,}|\t).+$/gm, "").replace(/`[^`]+`/g, "").replace(/\{\/\*[\s\S]*?\*\/\}/g, "").replace(/<[^>]+>/g, "").replace(/^\s*\}[^}\n]*$/gm, "").replace(/^\s+$/gm, "").replace(/\n{3,}/g, "\n\n").trim();
@@ -3247,7 +2880,7 @@ async function runSecretCommand(args, version) {
3247
2880
  }
3248
2881
  switch (sub) {
3249
2882
  case "put":
3250
- await secretPut(cwd, String(parsed._[1] ?? ""), secretValue);
2883
+ await secretPut(cwd, String(parsed._[1] ?? ""), secretValue ?? "");
3251
2884
  break;
3252
2885
  case "delete":
3253
2886
  await secretDelete(cwd, String(parsed._[1] ?? ""));
@@ -3326,11 +2959,11 @@ import minimist6 from "minimist";
3326
2959
 
3327
2960
  // cli/_start.ts
3328
2961
  init_output();
3329
- import fs7 from "node:fs/promises";
2962
+ import fs6 from "node:fs/promises";
3330
2963
  import path9 from "node:path";
3331
2964
  async function _startProductionServer(cwd, port) {
3332
2965
  const buildDir = path9.join(cwd, ".aai", "build");
3333
- const html = await fs7.readFile(path9.join(buildDir, "index.html"), "utf-8");
2966
+ const html = await fs6.readFile(path9.join(buildDir, "index.html"), "utf-8");
3334
2967
  step("Load", "agent");
3335
2968
  const agentDef = await loadAgentDef(cwd);
3336
2969
  const env = await resolveServerEnv();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexkroman1/aai",
3
- "version": "0.6.0",
3
+ "version": "0.7.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "aai": "dist/aai.js"
@@ -65,10 +65,6 @@
65
65
  "types": "./dist/sdk/worker_entry.d.ts",
66
66
  "default": "./dist/sdk/worker_entry.js"
67
67
  },
68
- "./timeout": {
69
- "types": "./dist/sdk/_timeout.d.ts",
70
- "default": "./dist/sdk/_timeout.js"
71
- },
72
68
  "./builtin-tools": {
73
69
  "types": "./dist/sdk/builtin_tools.d.ts",
74
70
  "default": "./dist/sdk/builtin_tools.js"
@@ -107,38 +103,36 @@
107
103
  }
108
104
  },
109
105
  "dependencies": {
110
- "@chonkiejs/core": "^0",
111
- "@inkjs/ui": "^2",
112
- "@preact/preset-vite": "~2.9",
106
+ "@chonkiejs/core": "^0.0.8",
107
+ "@inkjs/ui": "^2.0.0",
108
+ "@preact/preset-vite": "^2.10.4",
113
109
  "@preact/signals": "^2.8.2",
114
- "@tailwindcss/vite": "^4",
110
+ "@tailwindcss/vite": "^4.2.1",
115
111
  "@types/json-schema": "^7.0.15",
116
- "chalk": "^5.4",
117
- "fast-glob": "^3.3",
118
- "fs-extra": "^11.3",
119
- "human-id": "^4.1",
120
- "ink": "^5",
121
- "minimist": "^1.2",
112
+ "chalk": "^5.6.2",
113
+ "fast-glob": "^3.3.3",
114
+ "fs-extra": "^11.3.4",
115
+ "human-id": "^4.1.3",
116
+ "ink": "^6.8.0",
117
+ "minimist": "^1.2.8",
122
118
  "p-limit": "^7.3.0",
123
- "p-timeout": "^7.0.1",
124
119
  "preact": "^10.29.0",
125
- "react": "^18",
126
- "ts-morph": "^25",
127
- "vite": "^6",
128
- "vite-plugin-singlefile": "^2",
120
+ "react": "^19.2.4",
121
+ "vite": "^7.3.1",
122
+ "vite-plugin-singlefile": "^2.3.2",
129
123
  "zod": "^4.3.6"
130
124
  },
131
125
  "devDependencies": {
132
126
  "@biomejs/biome": "^2.4.7",
133
- "@types/fs-extra": "^11",
134
- "@types/minimist": "^1.2",
135
- "@types/node": "^22",
136
- "@types/react": "^18",
127
+ "@types/fs-extra": "^11.0.4",
128
+ "@types/minimist": "^1.2.5",
129
+ "@types/node": "^25.5.0",
130
+ "@types/react": "^19.2.14",
137
131
  "@types/ws": "^8.18.1",
138
- "ink-testing-library": "^4",
139
- "linkedom": "^0.18.10",
140
- "typescript": "^5.7",
141
- "vitest": "^3.1"
132
+ "ink-testing-library": "^4.0.0",
133
+ "linkedom": "^0.18.12",
134
+ "typescript": "^5.9.3",
135
+ "vitest": "^4.1.0"
142
136
  },
143
137
  "engines": {
144
138
  "node": ">=20"
@@ -148,6 +142,6 @@
148
142
  "test": "vitest run",
149
143
  "lint": "biome check sdk/ ui/ cli/",
150
144
  "lint:fix": "biome check --write sdk/ ui/ cli/",
151
- "check": "tsc -p tsconfig.build.json --noEmit && biome check sdk/ ui/ cli/ && vitest run"
145
+ "check": "tsc -p tsconfig.build.json --noEmit && tsc -p tsconfig.templates.json && biome check sdk/ ui/ cli/ && vitest run"
152
146
  }
153
147
  }