@alexkroman1/aai 0.8.1 → 0.8.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 (44) hide show
  1. package/dist/cli.js +181 -230
  2. package/dist/sdk/_render_check.d.ts.map +1 -1
  3. package/dist/sdk/_render_check.js +3 -0
  4. package/dist/sdk/_render_check.js.map +1 -1
  5. package/dist/sdk/server.d.ts.map +1 -1
  6. package/dist/sdk/server.js +30 -87
  7. package/dist/sdk/server.js.map +1 -1
  8. package/dist/sdk/winterc_server.d.ts +1 -0
  9. package/dist/sdk/winterc_server.d.ts.map +1 -1
  10. package/dist/sdk/winterc_server.js +11 -15
  11. package/dist/sdk/winterc_server.js.map +1 -1
  12. package/dist/sdk/ws_handler.d.ts +2 -0
  13. package/dist/sdk/ws_handler.d.ts.map +1 -1
  14. package/dist/sdk/ws_handler.js +3 -1
  15. package/dist/sdk/ws_handler.js.map +1 -1
  16. package/dist/ui/_components/app.d.ts.map +1 -1
  17. package/dist/ui/_components/app.js +3 -4
  18. package/dist/ui/_components/app.js.map +1 -1
  19. package/dist/ui/_components/chat_view.d.ts.map +1 -1
  20. package/dist/ui/_components/chat_view.js +1 -2
  21. package/dist/ui/_components/chat_view.js.map +1 -1
  22. package/dist/ui/_components/start_screen.js +1 -1
  23. package/dist/ui/_components/start_screen.js.map +1 -1
  24. package/dist/ui/components_mod.d.ts +2 -2
  25. package/dist/ui/components_mod.d.ts.map +1 -1
  26. package/dist/ui/components_mod.js.map +1 -1
  27. package/dist/ui/mod.d.ts +2 -2
  28. package/dist/ui/mod.d.ts.map +1 -1
  29. package/dist/ui/mount.d.ts +1 -13
  30. package/dist/ui/mount.d.ts.map +1 -1
  31. package/dist/ui/mount.js.map +1 -1
  32. package/dist/ui/mount_context.d.ts +13 -1
  33. package/dist/ui/mount_context.d.ts.map +1 -1
  34. package/dist/ui/mount_context.js.map +1 -1
  35. package/dist/ui/session.d.ts.map +1 -1
  36. package/dist/ui/session.js +12 -0
  37. package/dist/ui/session.js.map +1 -1
  38. package/package.json +4 -1
  39. package/templates/_shared/CLAUDE.md +52 -29
  40. package/templates/_shared/global.d.ts +1 -0
  41. package/templates/_shared/package.json +2 -1
  42. package/templates/night-owl/client.tsx +1 -1
  43. package/templates/solo-rpg/agent.ts +1240 -0
  44. package/templates/solo-rpg/client.tsx +698 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexkroman1/aai",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "aai": "dist/aai.js"
@@ -107,6 +107,8 @@
107
107
  },
108
108
  "dependencies": {
109
109
  "@chonkiejs/core": "^0.0.8",
110
+ "@hono/node-server": "^1.19.11",
111
+ "@hono/node-ws": "^1.3.0",
110
112
  "@inkjs/ui": "^2.0.0",
111
113
  "@preact/preset-vite": "^2.10.4",
112
114
  "@preact/signals": "^2.8.2",
@@ -115,6 +117,7 @@
115
117
  "chalk": "^5.6.2",
116
118
  "fast-glob": "^3.3.3",
117
119
  "fs-extra": "^11.3.4",
120
+ "hono": "^4.12.8",
118
121
  "html-to-text": "^9.0.5",
119
122
  "human-id": "^4.1.3",
120
123
  "ink": "^6.8.0",
@@ -10,7 +10,9 @@ You are helping a user build a voice agent using the **aai** framework.
10
10
  does what the user needs before writing custom code.
11
11
  3. **Start minimal** — Scaffold from the closest template, then layer on
12
12
  customizations. Don't over-engineer the first version.
13
- 4. **Iterate** — Make small, focused changes. Verify each change works before
13
+ 4. **Verify** — After every change, run `aai build` to validate the bundle and
14
+ catch errors. Fix all errors before presenting work to the user.
15
+ 5. **Iterate** — Make small, focused changes. Verify each change works before
14
16
  moving on.
15
17
 
16
18
  ## Key rules
@@ -19,7 +21,7 @@ You are helping a user build a voice agent using the **aai** framework.
19
21
  - Custom UI goes in `client.tsx` alongside `agent.ts`
20
22
  - Optimize `instructions` for spoken conversation — short sentences, no visual
21
23
  formatting, no exclamation points
22
- - Never hardcode secrets — use `aai env add` and access via `ctx.env`
24
+ - Never hardcode secrets — use `aai secret put` and access via `ctx.env`
23
25
  - Tool `execute` return values go into LLM context — filter and truncate large
24
26
  API responses
25
27
  - Agent code runs in a sandboxed worker — use `fetch` (proxied) for HTTP,
@@ -35,10 +37,11 @@ aai build # Bundle and validate (no server or deploy)
35
37
  aai deploy # Bundle and deploy to production
36
38
  aai deploy -y # Deploy without prompts
37
39
  aai deploy --dry-run # Validate and bundle without deploying
38
- aai env add <NAME> # Set an environment variable on the server
39
- aai env rm <NAME> # Remove an environment variable
40
- aai env ls # List environment variable names
41
- aai env pull # Pull env var names into .env for local dev
40
+ aai secret put <NAME> # Set a secret on the server (prompts for value)
41
+ aai secret delete <NAME> # Remove a secret
42
+ aai secret list # List secret names
43
+ aai secret pull # Pull secret names into .env for local dev
44
+ aai rag <url> # Ingest a site's llms-full.txt into the vector store
42
45
  ```
43
46
 
44
47
  ## Templates
@@ -61,9 +64,9 @@ with `aai init -t <template_name>`.
61
64
  | `pizza-ordering` | Pizza order-taker with dynamic cart sidebar. **Has custom UI.** |
62
65
  | `dispatch-center` | 911 dispatch with incident triage and resource assignment. **Has custom UI.** |
63
66
  | `infocom-adventure` | Zork-style text adventure with state, puzzles, inventory. **Has custom UI.** |
67
+ | `solo-rpg` | Solo dark-fantasy RPG with dice, oaths, combat, save/load. **Has custom UI.** |
64
68
  | `embedded-assets` | FAQ bot using embedded JSON knowledge (no web search) |
65
69
  | `support` | RAG-powered support agent using vector_search (AssemblyAI docs example) |
66
- | `terminal` | STT-only mode for voice-driven kubectl commands |
67
70
 
68
71
  ## Minimal agent
69
72
 
@@ -150,17 +153,17 @@ injected into agent workers at runtime and available as `ctx.env`. Secrets are
150
153
 
151
154
  ```sh
152
155
  # Set secrets on the server (prompts for value)
153
- aai env add ASSEMBLYAI_API_KEY
154
- aai env add MY_API_KEY
156
+ aai secret put ASSEMBLYAI_API_KEY
157
+ aai secret put MY_API_KEY
155
158
 
156
159
  # List what's set
157
- aai env ls
160
+ aai secret list
158
161
 
159
- # Pull env var names into .env for local dev reference
160
- aai env pull
162
+ # Pull secret names into .env for local dev reference
163
+ aai secret pull
161
164
 
162
165
  # Remove a secret
163
- aai env rm MY_API_KEY
166
+ aai secret delete MY_API_KEY
164
167
  ```
165
168
 
166
169
  Access secrets in tool code via `ctx.env`:
@@ -246,7 +249,7 @@ Enable via `builtinTools`.
246
249
  | `web_search` | Search the web (Brave Search) | `query`, `max_results?` (default 5) |
247
250
  | `visit_webpage` | Fetch URL → Markdown | `url` |
248
251
  | `fetch_json` | HTTP GET a JSON API | `url`, `headers?` |
249
- | `run_code` | Execute JS in sandbox (no net/fs, 30s timeout) | `code` |
252
+ | `run_code` | Execute JS in sandbox (no net/fs, 5s timeout) | `code` |
250
253
  | `vector_search` | Search the agent's RAG knowledge base | `query`, `topK?` (default 5) |
251
254
  | `memory` | Persistent KV memory (4 tools, see below) | — |
252
255
 
@@ -259,7 +262,7 @@ Every `execute` function and lifecycle hook receives a context object:
259
262
 
260
263
  ```ts
261
264
  ctx.sessionId; // string — unique per connection
262
- ctx.env; // Record<string, string> — secrets from `aai env add`
265
+ ctx.env; // Record<string, string> — secrets from `aai secret put`
263
266
  ctx.abortSignal; // AbortSignal — cancelled on interruption (tools only)
264
267
  ctx.state; // per-session state
265
268
  ctx.kv; // persistent KV store
@@ -267,8 +270,7 @@ ctx.vector; // VectorStore — vector store for RAG (tools only)
267
270
  ctx.messages; // readonly Message[] — conversation history (tools only)
268
271
  ```
269
272
 
270
- Hooks get `HookContext` (same but without `abortSignal`, `vector`, and
271
- `messages`).
273
+ Hooks get `HookContext` (same but without `abortSignal` and `messages`).
272
274
 
273
275
  **Timeouts:** Tool execution times out after **30 seconds** (`abortSignal`
274
276
  fires). Lifecycle hooks (`onConnect`, `onTurn`, etc.) time out after **5
@@ -318,6 +320,28 @@ export default defineAgent({
318
320
  });
319
321
  ```
320
322
 
323
+ ### Persisting state across reconnects
324
+
325
+ `ctx.sessionId` is a persistent user ID stored in the browser's
326
+ `localStorage`. It stays the same when a user closes and reopens the
327
+ browser. Use it as a KV key to auto-save and auto-load state:
328
+
329
+ ```ts
330
+ export default defineAgent({
331
+ state: () => ({ score: 0, initialized: false }),
332
+ onConnect: async (ctx) => {
333
+ const saved = await ctx.kv.get(`save:${ctx.sessionId}`);
334
+ if (saved) Object.assign(ctx.state, saved);
335
+ },
336
+ onTurn: async (_text, ctx) => {
337
+ await ctx.kv.set(`save:${ctx.sessionId}`, ctx.state);
338
+ },
339
+ });
340
+ ```
341
+
342
+ Each browser gets its own saved state. This works for games, workflows,
343
+ or any agent where users expect to resume where they left off.
344
+
321
345
  ### Persistent storage (KV)
322
346
 
323
347
  `ctx.kv` is a persistent key-value store scoped per agent. Values are
@@ -841,12 +865,12 @@ const agent = defineAgent({
841
865
  instructions: "You are a helpful assistant.",
842
866
  });
843
867
 
844
- const server = createServer(agent, {
845
- port: 3000, // default: 3000
846
- staticDir: "public", // optional: serve static files
868
+ const server = createServer({
869
+ agent,
870
+ clientDir: "public", // optional: serve static files
847
871
  });
848
872
 
849
- server.listen();
873
+ await server.listen(3000);
850
874
  ```
851
875
 
852
876
  Run with `node --experimental-strip-types server.ts` or bundle with your
@@ -1018,22 +1042,21 @@ Use directional words naturally: "To the north you see..." not "N: forest"
1018
1042
  - **Returning huge payloads from tools** — Everything a tool returns goes into
1019
1043
  the LLM context. Filter, summarize, or truncate API responses before
1020
1044
  returning. Return only what the agent needs to formulate a spoken answer.
1021
- - **Forgetting sandbox constraints** — Agent code runs in a Deno Worker with
1022
- _all permissions disabled_ (no net, no fs, no env). Use `fetch` (proxied
1023
- through the host) for HTTP. Use `ctx.env` for secrets. `Deno.readFile`,
1024
- `Deno.env.get`, and direct network access will fail silently or throw.
1045
+ - **Forgetting sandbox constraints** — Agent code runs in a sandboxed Worker
1046
+ with no direct network or filesystem access. Use `fetch` (proxied through the
1047
+ host) for HTTP. Use `ctx.env` for secrets. Direct network access will fail.
1025
1048
  - **Ignoring `ctx.abortSignal`** — When the user interrupts, in-flight tool
1026
1049
  calls are cancelled via `ctx.abortSignal`. Long-running tools (polling,
1027
1050
  multi-step fetches) should check `ctx.abortSignal.aborted` or pass the signal
1028
1051
  to `fetch`.
1029
1052
  - **Hardcoding secrets** — Never put API keys in `agent.ts`. Use
1030
- `aai env add MY_KEY` to store them on the server, then access via
1053
+ `aai secret put MY_KEY` to store them on the server, then access via
1031
1054
  `ctx.env.MY_KEY`.
1032
1055
  - **Telling the agent to be verbose** — Voice responses should be 1-3 sentences.
1033
1056
  If your `instructions` say "provide detailed explanations", the agent will
1034
1057
  monologue. Instruct it to be brief and let the user ask follow-ups.
1035
- - **Not setting env vars before deploying** — If your agent needs custom env
1036
- vars, set them with `aai env add MY_KEY` before deploying.
1058
+ - **Not setting secrets before deploying** — If your agent needs custom
1059
+ secrets, set them with `aai secret put MY_KEY` before deploying.
1037
1060
  - **Forgetting SSRF restrictions on `fetch`** — The host validates all proxied
1038
1061
  fetch URLs. Requests to private/internal IP addresses (localhost, 10.x,
1039
1062
  192.168.x, etc.) are blocked.
@@ -1043,7 +1066,7 @@ Use directional words naturally: "To the north you see..." not "N: forest"
1043
1066
  - **"no agent found"** — Ensure `agent.ts` exists in the current directory
1044
1067
  - **"bundle failed"** — TypeScript syntax error — check imports, brackets
1045
1068
  - **"No .aai/project.json found"** — Run `aai deploy` first before using
1046
- `aai env`
1069
+ `aai secret`
1047
1070
  - **Tool returns `undefined`** — Make sure `execute` returns a value. Even
1048
1071
  `return { ok: true }` is better than an implicit void return.
1049
1072
  - **Agent doesn't use a tool** — Check `description` is clear about when to use
@@ -0,0 +1 @@
1
+ declare module "*.css";
@@ -11,7 +11,8 @@
11
11
  "@alexkroman1/aai": "*",
12
12
  "@preact/signals": "^2.8.2",
13
13
  "preact": "^10.29.0",
14
- "tailwindcss": "^4.2.1"
14
+ "tailwindcss": "^4.2.1",
15
+ "zod": "^4.3.6"
15
16
  },
16
17
  "devDependencies": {
17
18
  "@biomejs/biome": "^2",
@@ -3,7 +3,7 @@ import { ChatView, StartScreen, mount } from "@alexkroman1/aai/ui";
3
3
 
4
4
  function NightOwl() {
5
5
  return (
6
- <StartScreen icon={<span>&#x1F989;</span>} title="Night Owl" subtitle="your evening companion" buttonText="Start Conversation">
6
+ <StartScreen icon={<span class="text-5xl">&#x1F989;</span>} title="Night Owl" subtitle="your evening companion" buttonText="Start Conversation">
7
7
  <ChatView />
8
8
  </StartScreen>
9
9
  );