@alexkroman1/aai 0.7.12 → 0.8.0

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 (81) hide show
  1. package/dist/aai.js +1 -1
  2. package/dist/cli.js +656 -354
  3. package/dist/sdk/_internal_types.d.ts +0 -1
  4. package/dist/sdk/_internal_types.d.ts.map +1 -1
  5. package/dist/sdk/_internal_types.js.map +1 -1
  6. package/dist/sdk/_render_check.d.ts +7 -0
  7. package/dist/sdk/_render_check.d.ts.map +1 -0
  8. package/dist/sdk/_render_check.js +38 -0
  9. package/dist/sdk/_render_check.js.map +1 -0
  10. package/dist/sdk/builtin_tools.d.ts.map +1 -1
  11. package/dist/sdk/builtin_tools.js +21 -0
  12. package/dist/sdk/builtin_tools.js.map +1 -1
  13. package/dist/sdk/define_agent.d.ts.map +1 -1
  14. package/dist/sdk/define_agent.js +0 -1
  15. package/dist/sdk/define_agent.js.map +1 -1
  16. package/dist/sdk/direct_executor.d.ts.map +1 -1
  17. package/dist/sdk/direct_executor.js +0 -1
  18. package/dist/sdk/direct_executor.js.map +1 -1
  19. package/dist/sdk/memory_tools.d.ts +38 -0
  20. package/dist/sdk/memory_tools.d.ts.map +1 -0
  21. package/dist/sdk/memory_tools.js +77 -0
  22. package/dist/sdk/memory_tools.js.map +1 -0
  23. package/dist/sdk/mod.d.ts +3 -1
  24. package/dist/sdk/mod.d.ts.map +1 -1
  25. package/dist/sdk/mod.js +2 -0
  26. package/dist/sdk/mod.js.map +1 -1
  27. package/dist/sdk/protocol.d.ts +3 -3
  28. package/dist/sdk/protocol.js +1 -1
  29. package/dist/sdk/s2s.d.ts.map +1 -1
  30. package/dist/sdk/s2s.js +3 -1
  31. package/dist/sdk/s2s.js.map +1 -1
  32. package/dist/sdk/session.d.ts.map +1 -1
  33. package/dist/sdk/session.js +2 -0
  34. package/dist/sdk/session.js.map +1 -1
  35. package/dist/sdk/types.d.ts +23 -14
  36. package/dist/sdk/types.d.ts.map +1 -1
  37. package/dist/sdk/types.js +29 -0
  38. package/dist/sdk/types.js.map +1 -1
  39. package/dist/ui/_components/app.d.ts.map +1 -1
  40. package/dist/ui/_components/app.js +6 -7
  41. package/dist/ui/_components/app.js.map +1 -1
  42. package/dist/ui/_components/sidebar_layout.d.ts +19 -0
  43. package/dist/ui/_components/sidebar_layout.d.ts.map +1 -0
  44. package/dist/ui/_components/sidebar_layout.js +21 -0
  45. package/dist/ui/_components/sidebar_layout.js.map +1 -0
  46. package/dist/ui/_components/start_screen.d.ts +24 -0
  47. package/dist/ui/_components/start_screen.d.ts.map +1 -0
  48. package/dist/ui/_components/start_screen.js +25 -0
  49. package/dist/ui/_components/start_screen.js.map +1 -0
  50. package/dist/ui/_hooks.d.ts +21 -0
  51. package/dist/ui/_hooks.d.ts.map +1 -0
  52. package/dist/ui/_hooks.js +35 -0
  53. package/dist/ui/_hooks.js.map +1 -0
  54. package/dist/ui/components.d.ts +20 -0
  55. package/dist/ui/components.d.ts.map +1 -1
  56. package/dist/ui/components.js +12 -0
  57. package/dist/ui/components.js.map +1 -1
  58. package/dist/ui/components_mod.d.ts +2 -1
  59. package/dist/ui/components_mod.d.ts.map +1 -1
  60. package/dist/ui/components_mod.js +2 -1
  61. package/dist/ui/components_mod.js.map +1 -1
  62. package/dist/ui/mod.d.ts +2 -1
  63. package/dist/ui/mod.d.ts.map +1 -1
  64. package/dist/ui/mod.js +2 -1
  65. package/dist/ui/mod.js.map +1 -1
  66. package/dist/ui/signals.d.ts.map +1 -1
  67. package/dist/ui/signals.js +5 -2
  68. package/dist/ui/signals.js.map +1 -1
  69. package/package.json +17 -1
  70. package/templates/_shared/CLAUDE.md +241 -121
  71. package/templates/_shared/package.json +4 -1
  72. package/templates/dispatch-center/agent.ts +43 -72
  73. package/templates/embedded-assets/agent.ts +4 -5
  74. package/templates/health-assistant/agent.ts +7 -7
  75. package/templates/infocom-adventure/agent.ts +20 -20
  76. package/templates/memory-agent/agent.ts +1 -55
  77. package/templates/night-owl/agent.ts +4 -4
  78. package/templates/night-owl/client.tsx +6 -23
  79. package/templates/pizza-ordering/agent.ts +14 -15
  80. package/templates/pizza-ordering/client.tsx +41 -101
  81. package/templates/smart-research/agent.ts +10 -10
@@ -1,4 +1,4 @@
1
- import { defineAgent } from "@alexkroman1/aai";
1
+ import { defineAgent, tool } from "@alexkroman1/aai";
2
2
  import { z } from "zod";
3
3
 
4
4
  interface Pizza {
@@ -53,7 +53,6 @@ function calculateTotal(pizzas: Pizza[]): number {
53
53
 
54
54
  export default defineAgent({
55
55
  name: "Pizza Palace",
56
- voice: "e3827ec5-697a-4b7c-9704-1a23041bbc51", // Sweet Lady
57
56
  greeting:
58
57
  "Welcome to Pizza Palace. I can help you build your perfect pizza. What would you like to order?",
59
58
  instructions: `You are a friendly pizza order-taker at Pizza Palace. Keep responses short and conversational, optimized for voice.
@@ -85,7 +84,7 @@ Behavior:
85
84
  }),
86
85
 
87
86
  tools: {
88
- add_pizza: {
87
+ add_pizza: tool({
89
88
  description:
90
89
  "Add a pizza to the order. Use when the customer has decided on a pizza.",
91
90
  parameters: z.object({
@@ -96,7 +95,7 @@ Behavior:
96
95
  .describe("List of topping names, e.g. ['pepperoni', 'mushrooms']"),
97
96
  quantity: z.number().default(1),
98
97
  }),
99
- execute: (args: { size: Pizza["size"]; crust: Pizza["crust"]; toppings: string[]; quantity: number }, ctx) => {
98
+ execute: (args, ctx) => {
100
99
  const state = ctx.state as OrderState;
101
100
  const pizza: Pizza = {
102
101
  id: state.nextId++,
@@ -113,9 +112,9 @@ Behavior:
113
112
  itemCount: state.pizzas.length,
114
113
  };
115
114
  },
116
- },
115
+ }),
117
116
 
118
- remove_pizza: {
117
+ remove_pizza: tool({
119
118
  description: "Remove a pizza from the order by its ID.",
120
119
  parameters: z.object({
121
120
  pizza_id: z.number().describe("The pizza ID to remove"),
@@ -132,9 +131,9 @@ Behavior:
132
131
  itemCount: state.pizzas.length,
133
132
  };
134
133
  },
135
- },
134
+ }),
136
135
 
137
- update_pizza: {
136
+ update_pizza: tool({
138
137
  description:
139
138
  "Update an existing pizza in the order. Only provided fields are changed.",
140
139
  parameters: z.object({
@@ -144,7 +143,7 @@ Behavior:
144
143
  toppings: z.array(z.string()).optional(),
145
144
  quantity: z.number().optional(),
146
145
  }),
147
- execute: (args: { pizza_id: number; size?: Pizza["size"]; crust?: Pizza["crust"]; toppings?: string[]; quantity?: number }, ctx) => {
146
+ execute: (args, ctx) => {
148
147
  const state = ctx.state as OrderState;
149
148
  const pizza = state.pizzas.find((p) => p.id === args.pizza_id);
150
149
  if (!pizza) return { error: "Pizza not found in the order." };
@@ -158,7 +157,7 @@ Behavior:
158
157
  orderTotal: `$${total.toFixed(2)}`,
159
158
  };
160
159
  },
161
- },
160
+ }),
162
161
 
163
162
  view_order: {
164
163
  description:
@@ -182,15 +181,15 @@ Behavior:
182
181
  },
183
182
  },
184
183
 
185
- set_customer_name: {
184
+ set_customer_name: tool({
186
185
  description: "Set the customer name for the order.",
187
186
  parameters: z.object({ name: z.string() }),
188
- execute: (args: { name: string }, ctx) => {
187
+ execute: ({ name }, ctx) => {
189
188
  const state = ctx.state as OrderState;
190
- state.customerName = args.name;
191
- return { name: args.name };
189
+ state.customerName = name;
190
+ return { name };
192
191
  },
193
- },
192
+ }),
194
193
 
195
194
  place_order: {
196
195
  description:
@@ -1,6 +1,6 @@
1
1
  import "@alexkroman1/aai/ui/styles.css";
2
2
  import { useState } from "preact/hooks";
3
- import { ChatView, mount, useSession, useToolResult } from "@alexkroman1/aai/ui";
3
+ import { ChatView, SidebarLayout, StartScreen, mount, useSession, useToolResult } from "@alexkroman1/aai/ui";
4
4
 
5
5
  interface Pizza {
6
6
  id: number;
@@ -64,7 +64,7 @@ function PizzaIcon({ size }: { size: string }) {
64
64
  width={dim}
65
65
  height={dim}
66
66
  viewBox="0 0 100 100"
67
- style={{ flexShrink: 0 }}
67
+ class="shrink-0"
68
68
  >
69
69
  <circle cx="50" cy="50" r="48" fill="#F4C542" stroke="#D4A017" stroke-width="3" />
70
70
  <circle cx="50" cy="50" r="42" fill="#E8A025" />
@@ -83,7 +83,7 @@ function OrderPanel({ order }: { order: OrderInfo }) {
83
83
  if (order.orderPlaced) {
84
84
  return (
85
85
  <div class="flex flex-col items-center gap-4 p-6 text-center">
86
- <div style={{ fontSize: "48px" }}>&#10003;</div>
86
+ <div class="text-5xl">&#10003;</div>
87
87
  <h2 class="text-lg font-bold text-aai-text">Order Placed</h2>
88
88
  {order.orderNumber && (
89
89
  <p class="text-aai-text opacity-70">
@@ -119,8 +119,7 @@ function OrderPanel({ order }: { order: OrderInfo }) {
119
119
  {order.pizzas.map((p) => (
120
120
  <div
121
121
  key={p.id}
122
- class="flex items-center gap-3 p-3 rounded-lg"
123
- style={{ background: "var(--color-aai-surface)" }}
122
+ class="flex items-center gap-3 p-3 rounded-lg bg-aai-surface"
124
123
  >
125
124
  <PizzaIcon size={p.size} />
126
125
  <div class="flex-1 min-w-0">
@@ -140,10 +139,7 @@ function OrderPanel({ order }: { order: OrderInfo }) {
140
139
  </p>
141
140
  </div>
142
141
  ))}
143
- <div
144
- class="flex justify-between items-center pt-3 mt-1"
145
- style={{ borderTop: "1px solid var(--color-aai-border)" }}
146
- >
142
+ <div class="flex justify-between items-center pt-3 mt-1 border-t border-aai-border">
147
143
  <span class="text-aai-text font-bold">Total</span>
148
144
  <span class="text-aai-primary font-bold text-lg">{order.total}</span>
149
145
  </div>
@@ -152,7 +148,7 @@ function OrderPanel({ order }: { order: OrderInfo }) {
152
148
  }
153
149
 
154
150
  function PizzaAgent() {
155
- const { started, running, start, toggle, reset } = useSession();
151
+ const { running, toggle, reset } = useSession();
156
152
  const [order, setOrder] = useState<OrderInfo>({
157
153
  pizzas: [],
158
154
  total: "$0.00",
@@ -214,101 +210,45 @@ function PizzaAgent() {
214
210
  }
215
211
  });
216
212
 
217
- if (!started.value) {
218
- return (
219
- <div
220
- class="flex items-center justify-center h-screen"
221
- style={{ background: "var(--color-aai-bg)" }}
222
- >
223
- <style>
224
- {`
225
- @keyframes float {
226
- 0%, 100% { transform: translateY(0px); }
227
- 50% { transform: translateY(-10px); }
228
- }
229
- .pizza-float { animation: float 3s ease-in-out infinite; }
230
- `}
231
- </style>
232
- <div class="flex flex-col items-center gap-6">
233
- <div class="pizza-float">
234
- <svg width="120" height="120" viewBox="0 0 100 100">
235
- <circle cx="50" cy="50" r="48" fill="#F4C542" stroke="#D4A017" stroke-width="3" />
236
- <circle cx="50" cy="50" r="42" fill="#E8A025" />
237
- <circle cx="35" cy="35" r="7" fill="#C0392B" opacity="0.9" />
238
- <circle cx="60" cy="30" r="6" fill="#C0392B" opacity="0.9" />
239
- <circle cx="55" cy="55" r="7" fill="#C0392B" opacity="0.9" />
240
- <circle cx="30" cy="58" r="6" fill="#C0392B" opacity="0.9" />
241
- <circle cx="65" cy="65" r="5" fill="#C0392B" opacity="0.9" />
242
- <circle cx="45" cy="68" r="4" fill="#27AE60" opacity="0.7" />
243
- <circle cx="70" cy="42" r="4" fill="#27AE60" opacity="0.7" />
244
- </svg>
245
- </div>
246
- <h1 class="text-2xl font-bold text-aai-text">Pizza Palace</h1>
247
- <p class="text-aai-text opacity-60 text-sm">
248
- Voice-powered pizza ordering
249
- </p>
250
- <button
251
- class="px-8 py-3 rounded-full text-white border-none cursor-pointer font-medium text-base"
252
- style={{ background: "var(--color-aai-primary)" }}
253
- onClick={start}
254
- >
255
- Start Ordering
256
- </button>
257
- </div>
213
+ const sidebar = (
214
+ <>
215
+ <div class="p-4 flex items-center gap-3 border-b border-aai-border">
216
+ <PizzaIcon size="small" />
217
+ <h2 class="text-base font-bold text-aai-text">Pizza Palace</h2>
258
218
  </div>
259
- );
260
- }
261
-
262
- return (
263
- <div class="flex h-screen" style={{ background: "var(--color-aai-bg)" }}>
264
- <div
265
- class="w-80 flex-shrink-0 flex flex-col overflow-y-auto"
266
- style={{
267
- borderRight: "1px solid var(--color-aai-border)",
268
- background: "var(--color-aai-bg)",
269
- }}
270
- >
271
- <div class="p-4 flex items-center gap-3" style={{ borderBottom: "1px solid var(--color-aai-border)" }}>
272
- <PizzaIcon size="small" />
273
- <h2 class="text-base font-bold text-aai-text">Pizza Palace</h2>
274
- </div>
275
- <div class="flex-1">
276
- <OrderPanel order={order} />
277
- </div>
278
- <div
279
- class="p-3 flex gap-2"
280
- style={{ borderTop: "1px solid var(--color-aai-border)" }}
219
+ <div class="flex-1">
220
+ <OrderPanel order={order} />
221
+ </div>
222
+ <div class="p-3 flex gap-2 border-t border-aai-border">
223
+ <button
224
+ class={`flex-1 py-2 rounded-lg text-sm border-none cursor-pointer text-white ${running.value ? "bg-aai-error" : "bg-aai-primary"}`}
225
+ onClick={toggle}
281
226
  >
282
- <button
283
- class="flex-1 py-2 rounded-lg text-sm border-none cursor-pointer text-white"
284
- style={{ background: running.value ? "#C0392B" : "var(--color-aai-primary)" }}
285
- onClick={toggle}
286
- >
287
- {running.value ? "Pause" : "Resume"}
288
- </button>
289
- <button
290
- class="py-2 px-4 rounded-lg text-sm cursor-pointer text-aai-text"
291
- style={{
292
- background: "var(--color-aai-surface)",
293
- border: "1px solid var(--color-aai-border)",
294
- }}
295
- onClick={() => {
296
- reset();
297
- setOrder({
298
- pizzas: [],
299
- total: "$0.00",
300
- orderPlaced: false,
301
- });
302
- }}
303
- >
304
- New Order
305
- </button>
306
- </div>
227
+ {running.value ? "Pause" : "Resume"}
228
+ </button>
229
+ <button
230
+ class="py-2 px-4 rounded-lg text-sm cursor-pointer text-aai-text bg-aai-surface border border-aai-border"
231
+ onClick={() => {
232
+ reset();
233
+ setOrder({
234
+ pizzas: [],
235
+ total: "$0.00",
236
+ orderPlaced: false,
237
+ });
238
+ }}
239
+ >
240
+ New Order
241
+ </button>
307
242
  </div>
308
- <div class="flex-1 min-w-0">
243
+ </>
244
+ );
245
+
246
+ return (
247
+ <StartScreen icon={<PizzaIcon size="large" />} title="Pizza Palace" subtitle="Voice-powered pizza ordering" buttonText="Start Ordering">
248
+ <SidebarLayout sidebar={sidebar}>
309
249
  <ChatView />
310
- </div>
311
- </div>
250
+ </SidebarLayout>
251
+ </StartScreen>
312
252
  );
313
253
  }
314
254
 
@@ -1,6 +1,6 @@
1
- import { defineAgent } from "@alexkroman1/aai";
1
+ import { defineAgent, tool } from "@alexkroman1/aai";
2
+ import type { HookContext, StepInfo } from "@alexkroman1/aai";
2
3
  import { z } from "zod";
3
- import type { HookContext, StepInfo } from "@alexkroman1/aai/types";
4
4
 
5
5
  /**
6
6
  * Smart Research Agent — demonstrates all 5 advanced features:
@@ -88,18 +88,18 @@ Always search first, then analyze, then answer. Be thorough but concise.`,
88
88
  },
89
89
 
90
90
  tools: {
91
- save_source: {
91
+ save_source: tool({
92
92
  description: "Save a source URL found during research for later analysis",
93
93
  parameters: z.object({
94
94
  url: z.string().describe("The source URL"),
95
95
  title: z.string().describe("Brief title or description"),
96
96
  }),
97
- execute: (args: { url: string; title: string }, ctx) => {
97
+ execute: ({ url, title }, ctx) => {
98
98
  const state = ctx.state;
99
- state.sources.push(`${args.title}: ${args.url}`);
99
+ state.sources.push(`${title}: ${url}`);
100
100
  return { saved: true, totalSources: state.sources.length };
101
101
  },
102
- },
102
+ }),
103
103
 
104
104
  mark_complex: {
105
105
  description:
@@ -126,25 +126,25 @@ Always search first, then analyze, then answer. Be thorough but concise.`,
126
126
  },
127
127
 
128
128
  // Feature 2: ctx.messages — access conversation history in tools
129
- analyze: {
129
+ analyze: tool({
130
130
  description:
131
131
  "Analyze all gathered sources and conversation context to form a conclusion",
132
132
  parameters: z.object({
133
133
  focus: z.string().describe("What aspect to focus the analysis on"),
134
134
  }),
135
- execute: (args: { focus: string }, ctx) => {
135
+ execute: ({ focus }, ctx) => {
136
136
  const state = ctx.state;
137
137
  // Use ctx.messages to see what's been discussed
138
138
  const userMessages = ctx.messages.filter((m) => m.role === "user");
139
139
  return {
140
- focus: args.focus,
140
+ focus,
141
141
  sources: state.sources,
142
142
  conversationTurns: userMessages.length,
143
143
  totalMessages: ctx.messages.length,
144
144
  phase: state.phase,
145
145
  };
146
146
  },
147
- },
147
+ }),
148
148
 
149
149
  conversation_summary: {
150
150
  description: "Get a summary of the conversation so far",