@alexkroman1/aai 0.8.2 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/dist/cli/tsconfig.tsbuildinfo +1 -0
  2. package/dist/cli.js +1368 -1904
  3. package/dist/sdk/_mock_ws.js +2 -2
  4. package/dist/sdk/_mock_ws.js.map +1 -1
  5. package/dist/sdk/_render_check.d.ts.map +1 -1
  6. package/dist/sdk/_render_check.js +30 -0
  7. package/dist/sdk/_render_check.js.map +1 -1
  8. package/dist/sdk/_utils.d.ts +4 -0
  9. package/dist/sdk/_utils.d.ts.map +1 -0
  10. package/dist/sdk/_utils.js +7 -0
  11. package/dist/sdk/_utils.js.map +1 -0
  12. package/dist/sdk/builtin_tools.d.ts +35 -11
  13. package/dist/sdk/builtin_tools.d.ts.map +1 -1
  14. package/dist/sdk/builtin_tools.js +118 -76
  15. package/dist/sdk/builtin_tools.js.map +1 -1
  16. package/dist/sdk/capnweb.d.ts +76 -47
  17. package/dist/sdk/capnweb.d.ts.map +1 -1
  18. package/dist/sdk/capnweb.js +99 -242
  19. package/dist/sdk/capnweb.js.map +1 -1
  20. package/dist/sdk/direct_executor.d.ts.map +1 -1
  21. package/dist/sdk/direct_executor.js +0 -2
  22. package/dist/sdk/direct_executor.js.map +1 -1
  23. package/dist/sdk/host.d.ts +59 -0
  24. package/dist/sdk/host.d.ts.map +1 -0
  25. package/dist/sdk/host.js +131 -0
  26. package/dist/sdk/host.js.map +1 -0
  27. package/dist/sdk/mod.d.ts +2 -4
  28. package/dist/sdk/mod.d.ts.map +1 -1
  29. package/dist/sdk/mod.js +2 -3
  30. package/dist/sdk/mod.js.map +1 -1
  31. package/dist/sdk/protocol.d.ts +33 -135
  32. package/dist/sdk/protocol.d.ts.map +1 -1
  33. package/dist/sdk/protocol.js +49 -51
  34. package/dist/sdk/protocol.js.map +1 -1
  35. package/dist/sdk/runtime.d.ts +0 -1
  36. package/dist/sdk/runtime.d.ts.map +1 -1
  37. package/dist/sdk/runtime.js +5 -24
  38. package/dist/sdk/runtime.js.map +1 -1
  39. package/dist/sdk/s2s.d.ts +14 -3
  40. package/dist/sdk/s2s.d.ts.map +1 -1
  41. package/dist/sdk/s2s.js +72 -113
  42. package/dist/sdk/s2s.js.map +1 -1
  43. package/dist/sdk/server.d.ts +1 -1
  44. package/dist/sdk/server.d.ts.map +1 -1
  45. package/dist/sdk/server.js +51 -92
  46. package/dist/sdk/server.js.map +1 -1
  47. package/dist/sdk/session.d.ts +5 -1
  48. package/dist/sdk/session.d.ts.map +1 -1
  49. package/dist/sdk/session.js +131 -137
  50. package/dist/sdk/session.js.map +1 -1
  51. package/dist/sdk/tsconfig.tsbuildinfo +1 -0
  52. package/dist/sdk/types.d.ts +30 -3
  53. package/dist/sdk/types.d.ts.map +1 -1
  54. package/dist/sdk/types.js +37 -0
  55. package/dist/sdk/types.js.map +1 -1
  56. package/dist/sdk/winterc_server.d.ts.map +1 -1
  57. package/dist/sdk/winterc_server.js +10 -15
  58. package/dist/sdk/winterc_server.js.map +1 -1
  59. package/dist/sdk/worker_entry.d.ts +3 -11
  60. package/dist/sdk/worker_entry.d.ts.map +1 -1
  61. package/dist/sdk/worker_entry.js +8 -18
  62. package/dist/sdk/worker_entry.js.map +1 -1
  63. package/dist/sdk/worker_shim.d.ts +5 -6
  64. package/dist/sdk/worker_shim.d.ts.map +1 -1
  65. package/dist/sdk/worker_shim.js +93 -136
  66. package/dist/sdk/worker_shim.js.map +1 -1
  67. package/dist/sdk/ws_handler.d.ts +1 -1
  68. package/dist/sdk/ws_handler.d.ts.map +1 -1
  69. package/dist/sdk/ws_handler.js +13 -22
  70. package/dist/sdk/ws_handler.js.map +1 -1
  71. package/dist/ui/_cn.d.ts +5 -0
  72. package/dist/ui/_cn.d.ts.map +1 -0
  73. package/dist/ui/_cn.js +22 -0
  74. package/dist/ui/_cn.js.map +1 -0
  75. package/dist/ui/_components/app.d.ts +3 -1
  76. package/dist/ui/_components/app.d.ts.map +1 -1
  77. package/dist/ui/_components/app.js +2 -2
  78. package/dist/ui/_components/app.js.map +1 -1
  79. package/dist/ui/_components/button.d.ts +11 -0
  80. package/dist/ui/_components/button.d.ts.map +1 -0
  81. package/dist/ui/_components/button.js +17 -0
  82. package/dist/ui/_components/button.js.map +1 -0
  83. package/dist/ui/_components/chat_view.d.ts +3 -1
  84. package/dist/ui/_components/chat_view.d.ts.map +1 -1
  85. package/dist/ui/_components/chat_view.js +4 -2
  86. package/dist/ui/_components/chat_view.js.map +1 -1
  87. package/dist/ui/_components/controls.d.ts +3 -1
  88. package/dist/ui/_components/controls.d.ts.map +1 -1
  89. package/dist/ui/_components/controls.js +4 -5
  90. package/dist/ui/_components/controls.js.map +1 -1
  91. package/dist/ui/_components/error_banner.d.ts +2 -1
  92. package/dist/ui/_components/error_banner.d.ts.map +1 -1
  93. package/dist/ui/_components/error_banner.js +3 -2
  94. package/dist/ui/_components/error_banner.js.map +1 -1
  95. package/dist/ui/_components/message_bubble.d.ts +2 -1
  96. package/dist/ui/_components/message_bubble.d.ts.map +1 -1
  97. package/dist/ui/_components/message_bubble.js +5 -3
  98. package/dist/ui/_components/message_bubble.js.map +1 -1
  99. package/dist/ui/_components/message_list.d.ts +3 -1
  100. package/dist/ui/_components/message_list.d.ts.map +1 -1
  101. package/dist/ui/_components/message_list.js +7 -15
  102. package/dist/ui/_components/message_list.js.map +1 -1
  103. package/dist/ui/_components/sidebar_layout.d.ts +2 -1
  104. package/dist/ui/_components/sidebar_layout.d.ts.map +1 -1
  105. package/dist/ui/_components/sidebar_layout.js +5 -7
  106. package/dist/ui/_components/sidebar_layout.js.map +1 -1
  107. package/dist/ui/_components/start_screen.d.ts +2 -1
  108. package/dist/ui/_components/start_screen.d.ts.map +1 -1
  109. package/dist/ui/_components/start_screen.js +5 -2
  110. package/dist/ui/_components/start_screen.js.map +1 -1
  111. package/dist/ui/_components/state_indicator.d.ts +2 -1
  112. package/dist/ui/_components/state_indicator.d.ts.map +1 -1
  113. package/dist/ui/_components/state_indicator.js +3 -2
  114. package/dist/ui/_components/state_indicator.js.map +1 -1
  115. package/dist/ui/_components/thinking_indicator.d.ts +3 -1
  116. package/dist/ui/_components/thinking_indicator.d.ts.map +1 -1
  117. package/dist/ui/_components/thinking_indicator.js +4 -2
  118. package/dist/ui/_components/thinking_indicator.js.map +1 -1
  119. package/dist/ui/_components/tool_call_block.d.ts +2 -1
  120. package/dist/ui/_components/tool_call_block.d.ts.map +1 -1
  121. package/dist/ui/_components/tool_call_block.js +13 -25
  122. package/dist/ui/_components/tool_call_block.js.map +1 -1
  123. package/dist/ui/_components/transcript.d.ts +2 -1
  124. package/dist/ui/_components/transcript.d.ts.map +1 -1
  125. package/dist/ui/_components/transcript.js +3 -2
  126. package/dist/ui/_components/transcript.js.map +1 -1
  127. package/dist/ui/_jsdom_setup.d.ts +1 -0
  128. package/dist/ui/_jsdom_setup.d.ts.map +1 -0
  129. package/dist/ui/_jsdom_setup.js +6 -0
  130. package/dist/ui/_jsdom_setup.js.map +1 -0
  131. package/dist/ui/audio.d.ts.map +1 -1
  132. package/dist/ui/audio.js +4 -4
  133. package/dist/ui/audio.js.map +1 -1
  134. package/dist/ui/components.d.ts +13 -55
  135. package/dist/ui/components.d.ts.map +1 -1
  136. package/dist/ui/components.js +13 -42
  137. package/dist/ui/components.js.map +1 -1
  138. package/dist/ui/components_mod.d.ts +14 -3
  139. package/dist/ui/components_mod.d.ts.map +1 -1
  140. package/dist/ui/components_mod.js +14 -3
  141. package/dist/ui/components_mod.js.map +1 -1
  142. package/dist/ui/mod.d.ts +1 -8
  143. package/dist/ui/mod.d.ts.map +1 -1
  144. package/dist/ui/mod.js +1 -5
  145. package/dist/ui/mod.js.map +1 -1
  146. package/dist/ui/mount.d.ts +1 -1
  147. package/dist/ui/mount.d.ts.map +1 -1
  148. package/dist/ui/mount.js +1 -0
  149. package/dist/ui/mount.js.map +1 -1
  150. package/dist/ui/session.d.ts +0 -2
  151. package/dist/ui/session.d.ts.map +1 -1
  152. package/dist/ui/session.js +9 -6
  153. package/dist/ui/session.js.map +1 -1
  154. package/dist/ui/signals.d.ts +8 -3
  155. package/dist/ui/signals.d.ts.map +1 -1
  156. package/dist/ui/signals.js +22 -11
  157. package/dist/ui/signals.js.map +1 -1
  158. package/dist/ui/tsconfig.tsbuildinfo +1 -0
  159. package/dist/ui/worklets/playback-processor.js +3 -3
  160. package/package.json +39 -16
  161. package/templates/_shared/CLAUDE.md +50 -30
  162. package/templates/_shared/global.d.ts +1 -0
  163. package/templates/_shared/package.json +2 -1
  164. package/templates/dispatch-center/agent.ts +85 -397
  165. package/templates/solo-rpg/agent.ts +1240 -0
  166. 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.2",
3
+ "version": "0.8.4",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "aai": "dist/aai.js"
@@ -12,133 +12,154 @@
12
12
  ],
13
13
  "exports": {
14
14
  ".": {
15
+ "source": "./sdk/mod.ts",
15
16
  "types": "./dist/sdk/mod.d.ts",
16
17
  "default": "./dist/sdk/mod.js"
17
18
  },
18
19
  "./types": {
20
+ "source": "./sdk/types.ts",
19
21
  "types": "./dist/sdk/types.d.ts",
20
22
  "default": "./dist/sdk/types.js"
21
23
  },
22
- "./define-agent": {
23
- "types": "./dist/sdk/define_agent.d.ts",
24
- "default": "./dist/sdk/define_agent.js"
25
- },
26
24
  "./kv": {
25
+ "source": "./sdk/kv.ts",
27
26
  "types": "./dist/sdk/kv.d.ts",
28
27
  "default": "./dist/sdk/kv.js"
29
28
  },
30
29
  "./vector": {
30
+ "source": "./sdk/vector.ts",
31
31
  "types": "./dist/sdk/vector.d.ts",
32
32
  "default": "./dist/sdk/vector.js"
33
33
  },
34
34
  "./testing": {
35
+ "source": "./sdk/_mock_ws.ts",
35
36
  "types": "./dist/sdk/_mock_ws.d.ts",
36
37
  "default": "./dist/sdk/_mock_ws.js"
37
38
  },
38
39
  "./server": {
40
+ "source": "./sdk/server.ts",
39
41
  "types": "./dist/sdk/server.d.ts",
40
42
  "default": "./dist/sdk/server.js"
41
43
  },
42
44
  "./runtime": {
45
+ "source": "./sdk/runtime.ts",
43
46
  "types": "./dist/sdk/runtime.d.ts",
44
47
  "default": "./dist/sdk/runtime.js"
45
48
  },
46
49
  "./ui": {
50
+ "source": "./ui/mod.ts",
47
51
  "types": "./dist/ui/mod.d.ts",
48
52
  "default": "./dist/ui/mod.js"
49
53
  },
50
54
  "./ui/styles.css": "./ui/styles.css",
51
55
  "./ui/session": {
56
+ "source": "./ui/session_mod.ts",
52
57
  "types": "./dist/ui/session_mod.d.ts",
53
58
  "default": "./dist/ui/session_mod.js"
54
59
  },
55
60
  "./ui/components": {
61
+ "source": "./ui/components_mod.ts",
56
62
  "types": "./dist/ui/components_mod.d.ts",
57
63
  "default": "./dist/ui/components_mod.js"
58
64
  },
59
65
  "./internal-types": {
66
+ "source": "./sdk/_internal_types.ts",
60
67
  "types": "./dist/sdk/_internal_types.d.ts",
61
68
  "default": "./dist/sdk/_internal_types.js"
62
69
  },
63
70
  "./protocol": {
71
+ "source": "./sdk/protocol.ts",
64
72
  "types": "./dist/sdk/protocol.d.ts",
65
73
  "default": "./dist/sdk/protocol.js"
66
74
  },
67
75
  "./worker-entry": {
76
+ "source": "./sdk/worker_entry.ts",
68
77
  "types": "./dist/sdk/worker_entry.d.ts",
69
78
  "default": "./dist/sdk/worker_entry.js"
70
79
  },
71
80
  "./builtin-tools": {
81
+ "source": "./sdk/builtin_tools.ts",
72
82
  "types": "./dist/sdk/builtin_tools.d.ts",
73
83
  "default": "./dist/sdk/builtin_tools.js"
74
84
  },
75
85
  "./s2s": {
86
+ "source": "./sdk/s2s.ts",
76
87
  "types": "./dist/sdk/s2s.d.ts",
77
88
  "default": "./dist/sdk/s2s.js"
78
89
  },
79
90
  "./session": {
91
+ "source": "./sdk/session.ts",
80
92
  "types": "./dist/sdk/session.d.ts",
81
93
  "default": "./dist/sdk/session.js"
82
94
  },
83
- "./system-prompt": {
84
- "types": "./dist/sdk/system_prompt.d.ts",
85
- "default": "./dist/sdk/system_prompt.js"
86
- },
87
95
  "./ws-handler": {
96
+ "source": "./sdk/ws_handler.ts",
88
97
  "types": "./dist/sdk/ws_handler.d.ts",
89
98
  "default": "./dist/sdk/ws_handler.js"
90
99
  },
91
100
  "./direct-executor": {
101
+ "source": "./sdk/direct_executor.ts",
92
102
  "types": "./dist/sdk/direct_executor.d.ts",
93
103
  "default": "./dist/sdk/direct_executor.js"
94
104
  },
95
105
  "./capnweb": {
106
+ "source": "./sdk/capnweb.ts",
96
107
  "types": "./dist/sdk/capnweb.d.ts",
97
108
  "default": "./dist/sdk/capnweb.js"
98
109
  },
110
+ "./host": {
111
+ "source": "./sdk/host.ts",
112
+ "types": "./dist/sdk/host.d.ts",
113
+ "default": "./dist/sdk/host.js"
114
+ },
99
115
  "./winterc-server": {
116
+ "source": "./sdk/winterc_server.ts",
100
117
  "types": "./dist/sdk/winterc_server.d.ts",
101
118
  "default": "./dist/sdk/winterc_server.js"
102
119
  },
103
120
  "./worker-shim": {
121
+ "source": "./sdk/worker_shim.ts",
104
122
  "types": "./dist/sdk/worker_shim.d.ts",
105
123
  "default": "./dist/sdk/worker_shim.js"
106
124
  }
107
125
  },
108
126
  "dependencies": {
109
127
  "@chonkiejs/core": "^0.0.8",
128
+ "@hono/node-server": "^1.19.11",
110
129
  "@inkjs/ui": "^2.0.0",
111
130
  "@preact/preset-vite": "^2.10.4",
112
131
  "@preact/signals": "^2.8.2",
113
132
  "@tailwindcss/vite": "^4.2.1",
114
133
  "@types/json-schema": "^7.0.15",
134
+ "capnweb": "^0.6.1",
115
135
  "chalk": "^5.6.2",
116
- "fast-glob": "^3.3.3",
117
- "fs-extra": "^11.3.4",
136
+ "clsx": "^2.1.1",
137
+ "commander": "^14.0.3",
138
+ "hono": "^4.12.8",
118
139
  "html-to-text": "^9.0.5",
119
140
  "human-id": "^4.1.3",
120
141
  "ink": "^6.8.0",
121
- "minimist": "^1.2.8",
122
142
  "p-limit": "^7.3.0",
123
143
  "preact": "^10.29.0",
124
144
  "react": "^19.2.4",
145
+ "tsx": "^4.21.0",
125
146
  "vite": "^7.3.1",
126
147
  "ws": "^8.18.0",
127
148
  "zod": "^4.3.6"
128
149
  },
129
150
  "devDependencies": {
130
151
  "@biomejs/biome": "^2.4.7",
131
- "@types/fs-extra": "^11.0.4",
152
+ "@testing-library/preact": "^3.2.4",
132
153
  "@types/html-to-text": "^9.0.4",
133
- "@types/minimist": "^1.2.5",
134
154
  "@types/node": "^25.5.0",
135
155
  "@types/react": "^19.2.14",
136
156
  "@types/ws": "^8.18.1",
137
157
  "@vitest/coverage-v8": "^4.1.0",
158
+ "concurrently": "^9.2.1",
138
159
  "ink-testing-library": "^4.0.0",
160
+ "jsdom": "^29.0.1",
139
161
  "linkedom": "^0.18.12",
140
162
  "markdownlint-cli2": "^0.21.0",
141
- "tsx": "^4.21.0",
142
163
  "typescript": "^5.9.3",
143
164
  "vitest": "^4.1.0"
144
165
  },
@@ -166,6 +187,8 @@
166
187
  "test": "vitest run",
167
188
  "lint": "biome check sdk/ ui/ cli/",
168
189
  "lint:fix": "biome check --write sdk/ ui/ cli/",
169
- "check": "tsc --noEmit && tsc -p cli/tsconfig.json --noEmit && tsc -p tsconfig.build.json --noEmit && tsc -p tsconfig.templates.json && biome check sdk/ ui/ cli/ && markdownlint-cli2 '**/*.md' '#node_modules' '#.aai' && vitest run"
190
+ "exports": "node scripts/gen-exports.mjs --write",
191
+ "exports:check": "node scripts/gen-exports.mjs",
192
+ "check": "concurrently -g -n tsc,tsc:cli,tsc:build,tsc:tpl,biome,mdlint,exports,test \"tsc --noEmit\" \"tsc -p cli/tsconfig.json --noEmit\" \"tsc -p tsconfig.build.json --noEmit\" \"tsc -p tsconfig.templates.json\" \"biome check sdk/ ui/ cli/\" \"markdownlint-cli2 '**/*.md' '#node_modules' '#.aai'\" \"node scripts/gen-exports.mjs\" \"vitest run\""
170
193
  }
171
194
  }
@@ -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
 
@@ -258,8 +261,7 @@ LLM produces a text response.
258
261
  Every `execute` function and lifecycle hook receives a context object:
259
262
 
260
263
  ```ts
261
- ctx.sessionId; // string — unique per connection
262
- ctx.env; // Record<string, string> — secrets from `aai env add`
264
+ ctx.env; // Record<string, string> secrets from `aai secret put`
263
265
  ctx.abortSignal; // AbortSignal — cancelled on interruption (tools only)
264
266
  ctx.state; // per-session state
265
267
  ctx.kv; // persistent KV store
@@ -267,8 +269,7 @@ ctx.vector; // VectorStore — vector store for RAG (tools only)
267
269
  ctx.messages; // readonly Message[] — conversation history (tools only)
268
270
  ```
269
271
 
270
- Hooks get `HookContext` (same but without `abortSignal`, `vector`, and
271
- `messages`).
272
+ Hooks get `HookContext` (same but without `abortSignal` and `messages`).
272
273
 
273
274
  **Timeouts:** Tool execution times out after **30 seconds** (`abortSignal`
274
275
  fires). Lifecycle hooks (`onConnect`, `onTurn`, etc.) time out after **5
@@ -318,6 +319,26 @@ export default defineAgent({
318
319
  });
319
320
  ```
320
321
 
322
+ ### Persisting state across reconnects
323
+
324
+ Use the KV store to auto-save and auto-load state:
325
+
326
+ ```ts
327
+ export default defineAgent({
328
+ state: () => ({ score: 0, initialized: false }),
329
+ onConnect: async (ctx) => {
330
+ const saved = await ctx.kv.get("save:game");
331
+ if (saved) Object.assign(ctx.state, saved);
332
+ },
333
+ onTurn: async (_text, ctx) => {
334
+ await ctx.kv.set("save:game", ctx.state);
335
+ },
336
+ });
337
+ ```
338
+
339
+ This works for games, workflows,
340
+ or any agent where users expect to resume where they left off.
341
+
321
342
  ### Persistent storage (KV)
322
343
 
323
344
  `ctx.kv` is a persistent key-value store scoped per agent. Values are
@@ -841,12 +862,12 @@ const agent = defineAgent({
841
862
  instructions: "You are a helpful assistant.",
842
863
  });
843
864
 
844
- const server = createServer(agent, {
845
- port: 3000, // default: 3000
846
- staticDir: "public", // optional: serve static files
865
+ const server = createServer({
866
+ agent,
867
+ clientDir: "public", // optional: serve static files
847
868
  });
848
869
 
849
- server.listen();
870
+ await server.listen(3000);
850
871
  ```
851
872
 
852
873
  Run with `node --experimental-strip-types server.ts` or bundle with your
@@ -1018,22 +1039,21 @@ Use directional words naturally: "To the north you see..." not "N: forest"
1018
1039
  - **Returning huge payloads from tools** — Everything a tool returns goes into
1019
1040
  the LLM context. Filter, summarize, or truncate API responses before
1020
1041
  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.
1042
+ - **Forgetting sandbox constraints** — Agent code runs in a sandboxed Worker
1043
+ with no direct network or filesystem access. Use `fetch` (proxied through the
1044
+ host) for HTTP. Use `ctx.env` for secrets. Direct network access will fail.
1025
1045
  - **Ignoring `ctx.abortSignal`** — When the user interrupts, in-flight tool
1026
1046
  calls are cancelled via `ctx.abortSignal`. Long-running tools (polling,
1027
1047
  multi-step fetches) should check `ctx.abortSignal.aborted` or pass the signal
1028
1048
  to `fetch`.
1029
1049
  - **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
1050
+ `aai secret put MY_KEY` to store them on the server, then access via
1031
1051
  `ctx.env.MY_KEY`.
1032
1052
  - **Telling the agent to be verbose** — Voice responses should be 1-3 sentences.
1033
1053
  If your `instructions` say "provide detailed explanations", the agent will
1034
1054
  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.
1055
+ - **Not setting secrets before deploying** — If your agent needs custom
1056
+ secrets, set them with `aai secret put MY_KEY` before deploying.
1037
1057
  - **Forgetting SSRF restrictions on `fetch`** — The host validates all proxied
1038
1058
  fetch URLs. Requests to private/internal IP addresses (localhost, 10.x,
1039
1059
  192.168.x, etc.) are blocked.
@@ -1043,7 +1063,7 @@ Use directional words naturally: "To the north you see..." not "N: forest"
1043
1063
  - **"no agent found"** — Ensure `agent.ts` exists in the current directory
1044
1064
  - **"bundle failed"** — TypeScript syntax error — check imports, brackets
1045
1065
  - **"No .aai/project.json found"** — Run `aai deploy` first before using
1046
- `aai env`
1066
+ `aai secret`
1047
1067
  - **Tool returns `undefined`** — Make sure `execute` returns a value. Even
1048
1068
  `return { ok: true }` is better than an implicit void return.
1049
1069
  - **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",