@alexkroman1/aai 0.7.10 → 0.7.12

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.
@@ -1 +1 @@
1
- {"version":3,"file":"mod.js","sourceRoot":"","sources":["../../ui/mod.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EACL,GAAG,EACH,QAAQ,EACR,WAAW,EACX,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,UAAU,GACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,KAAK,EAAE,MAAM,YAAa,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,UAAU,GACX,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"mod.js","sourceRoot":"","sources":["../../ui/mod.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EACL,GAAG,EACH,QAAQ,EACR,WAAW,EACX,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,UAAU,GACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,KAAK,EAAE,MAAM,YAAa,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,aAAa,GACd,MAAM,cAAc,CAAC"}
@@ -24,6 +24,12 @@ export type VoiceSession = {
24
24
  * non-empty string = partial/final transcript text.
25
25
  */
26
26
  readonly userUtterance: Signal<string | null>;
27
+ /**
28
+ * Streaming agent response text.
29
+ * `null` = not speaking, non-empty string = accumulated delta text.
30
+ * Cleared when the final `chat` message arrives.
31
+ */
32
+ readonly agentUtterance: Signal<string | null>;
27
33
  /** Current session error, or `null` if no error. */
28
34
  readonly error: Signal<SessionError | null>;
29
35
  /** Disconnection info, or `null` if connected. */
@@ -62,6 +68,7 @@ export declare class ClientHandler {
62
68
  messages: Signal<Message[]>;
63
69
  toolCalls: Signal<ToolCallInfo[]>;
64
70
  userUtterance: Signal<string | null>;
71
+ agentUtterance: Signal<string | null>;
65
72
  error: Signal<SessionError | null>;
66
73
  voiceIO: () => VoiceIO | null;
67
74
  });
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../ui/session.ts"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,MAAM,EAAU,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAiB,WAAW,EAAiB,MAAM,oBAAoB,CAAC;AACjG,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAElG;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IACnC,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACrC,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9C,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC5C,kDAAkD;IAClD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;QAAE,WAAW,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC/D;;;;;OAKG;IACH,OAAO,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,IAAI,CAAC;IAClD,qEAAqE;IACrE,MAAM,IAAI,IAAI,CAAC;IACf,yEAAyE;IACzE,UAAU,IAAI,IAAI,CAAC;IACnB,oDAAoD;IACpD,KAAK,IAAI,IAAI,CAAC;IACd,2DAA2D;IAC3D,UAAU,IAAI,IAAI,CAAC;IACnB,6DAA6D;IAC7D,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;CAC1B,CAAC;AAEF;;;GAGG;AACH,2CAA2C;AAC3C,qBAAa,aAAa;;gBASZ,IAAI,EAAE;QAChB,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QAC1B,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5B,SAAS,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;QAClC,aAAa,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QACrC,KAAK,EAAE,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;QACnC,OAAO,EAAE,MAAM,OAAO,GAAG,IAAI,CAAC;KAC/B;IASD,+DAA+D;IAC/D,uEAAuE;IACvE,MAAM,CAAC,QAAQ,CAAC,YAAY,QAAU;IAEtC,KAAK,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI;IAiF3B,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAQvC,aAAa,IAAI,IAAI;IAarB;;;;;OAKG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,IAAI;CA6B9D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,YAAY,CAiNxE"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../ui/session.ts"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,MAAM,EAAU,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAiB,WAAW,EAAiB,MAAM,oBAAoB,CAAC;AACjG,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAElG;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IACnC,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACrC,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC/C,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC5C,kDAAkD;IAClD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;QAAE,WAAW,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC/D;;;;;OAKG;IACH,OAAO,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,IAAI,CAAC;IAClD,qEAAqE;IACrE,MAAM,IAAI,IAAI,CAAC;IACf,yEAAyE;IACzE,UAAU,IAAI,IAAI,CAAC;IACnB,oDAAoD;IACpD,KAAK,IAAI,IAAI,CAAC;IACd,2DAA2D;IAC3D,UAAU,IAAI,IAAI,CAAC;IACnB,6DAA6D;IAC7D,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;CAC1B,CAAC;AAEF;;;GAGG;AACH,2CAA2C;AAC3C,qBAAa,aAAa;;gBAUZ,IAAI,EAAE;QAChB,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QAC1B,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5B,SAAS,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;QAClC,aAAa,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QACrC,cAAc,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QACtC,KAAK,EAAE,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;QACnC,OAAO,EAAE,MAAM,OAAO,GAAG,IAAI,CAAC;KAC/B;IAUD,+DAA+D;IAC/D,uEAAuE;IACvE,MAAM,CAAC,QAAQ,CAAC,YAAY,QAAU;IAEtC,KAAK,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI;IA6F3B,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAQvC,aAAa,IAAI,IAAI;IAarB;;;;;OAKG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,IAAI;CA6B9D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,YAAY,CAqNxE"}
@@ -10,6 +10,7 @@ export class ClientHandler {
10
10
  #messages;
11
11
  #toolCalls;
12
12
  #userUtterance;
13
+ #agentUtterance;
13
14
  #error;
14
15
  #voiceIO;
15
16
  /** Incremented on each turn boundary — stale async callbacks compare against this. */
@@ -19,6 +20,7 @@ export class ClientHandler {
19
20
  this.#messages = opts.messages;
20
21
  this.#toolCalls = opts.toolCalls;
21
22
  this.#userUtterance = opts.userUtterance;
23
+ this.#agentUtterance = opts.agentUtterance;
22
24
  this.#error = opts.error;
23
25
  this.#voiceIO = opts.voiceIO;
24
26
  }
@@ -44,8 +46,16 @@ export class ClientHandler {
44
46
  this.#state.value = "thinking";
45
47
  });
46
48
  break;
49
+ case "chat_delta":
50
+ this.#agentUtterance.value = this.#agentUtterance.value
51
+ ? `${this.#agentUtterance.value} ${e.text}`
52
+ : e.text;
53
+ break;
47
54
  case "chat":
48
- this.#messages.value = [...this.#messages.value, { role: "assistant", text: e.text }];
55
+ batch(() => {
56
+ this.#agentUtterance.value = null;
57
+ this.#messages.value = [...this.#messages.value, { role: "assistant", text: e.text }];
58
+ });
49
59
  break;
50
60
  case "tool_call_start":
51
61
  this.#toolCalls.value = [
@@ -79,8 +89,11 @@ export class ClientHandler {
79
89
  case "cancelled":
80
90
  this.#generation++;
81
91
  this.#voiceIO()?.flush();
82
- this.#userUtterance.value = null;
83
- this.#state.value = "listening";
92
+ batch(() => {
93
+ this.#userUtterance.value = null;
94
+ this.#agentUtterance.value = null;
95
+ this.#state.value = "listening";
96
+ });
84
97
  break;
85
98
  case "reset": {
86
99
  this.#generation++;
@@ -89,6 +102,7 @@ export class ClientHandler {
89
102
  this.#messages.value = [];
90
103
  this.#toolCalls.value = [];
91
104
  this.#userUtterance.value = null;
105
+ this.#agentUtterance.value = null;
92
106
  this.#error.value = null;
93
107
  this.#state.value = "listening";
94
108
  });
@@ -174,6 +188,7 @@ export function createVoiceSession(options) {
174
188
  const messages = signal([]);
175
189
  const toolCalls = signal([]);
176
190
  const userUtterance = signal(null);
191
+ const agentUtterance = signal(null);
177
192
  const error = signal(null);
178
193
  const disconnected = signal(null);
179
194
  let ws = null;
@@ -191,6 +206,7 @@ export function createVoiceSession(options) {
191
206
  messages.value = [];
192
207
  toolCalls.value = [];
193
208
  userUtterance.value = null;
209
+ agentUtterance.value = null;
194
210
  error.value = null;
195
211
  });
196
212
  }
@@ -280,6 +296,7 @@ export function createVoiceSession(options) {
280
296
  messages,
281
297
  toolCalls,
282
298
  userUtterance,
299
+ agentUtterance,
283
300
  error,
284
301
  voiceIO: () => voiceIO,
285
302
  });
@@ -343,6 +360,7 @@ export function createVoiceSession(options) {
343
360
  messages,
344
361
  toolCalls,
345
362
  userUtterance,
363
+ agentUtterance,
346
364
  error,
347
365
  disconnected,
348
366
  connect,
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../ui/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../ui/session.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import { type Signal } from "@preact/signals";
2
2
  import type * as preact from "preact";
3
3
  import type { ComponentChildren } from "preact";
4
4
  import type { VoiceSession } from "./session.ts";
5
+ import type { ToolCallInfo } from "./types.ts";
5
6
  /**
6
7
  * Reactive session controls wrapping a {@linkcode VoiceSession} with Preact signals.
7
8
  *
@@ -58,4 +59,17 @@ export declare function SessionProvider({ value, children, }: {
58
59
  * @throws {Error} If called outside of a `SessionProvider`.
59
60
  */
60
61
  export declare function useSession(): SessionSignals;
62
+ /**
63
+ * Hook that fires a callback exactly once for each newly completed tool call.
64
+ *
65
+ * Handles deduplication internally — safe to use with `useState` setters
66
+ * without worrying about duplicates. The `result` argument is the parsed
67
+ * JSON result from the tool (or the raw string if parsing fails).
68
+ *
69
+ * Automatically resets tracking when the session is reset (toolCalls cleared).
70
+ *
71
+ * @param callback - Called once per completed tool call with the tool name,
72
+ * parsed result, and full {@linkcode ToolCallInfo}.
73
+ */
74
+ export declare function useToolResult(callback: (toolName: string, result: unknown, toolCall: ToolCallInfo) => void): void;
61
75
  //# sourceMappingURL=signals.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../ui/signals.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,MAAM,EAAU,MAAM,iBAAiB,CAAC;AACrE,OAAO,KAAK,KAAK,MAAM,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAGhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,mEAAmE;IACnE,OAAO,EAAE,YAAY,CAAC;IACtB,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACzB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACzB,2DAA2D;IAC3D,OAAO,IAAI,IAAI,CAAC;IAChB,2EAA2E;IAC3E,KAAK,IAAI,IAAI,CAAC;IACd,wDAAwD;IACxD,MAAM,IAAI,IAAI,CAAC;IACf,oDAAoD;IACpD,KAAK,IAAI,IAAI,CAAC;IACd,0DAA0D;IAC1D,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,GAAG,cAAc,CAgC3E;AAID;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,cAAc,CAAC;IACtB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAErB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,cAAc,CAI3C"}
1
+ {"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../ui/signals.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,MAAM,EAAU,MAAM,iBAAiB,CAAC;AACrE,OAAO,KAAK,KAAK,MAAM,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAGhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,mEAAmE;IACnE,OAAO,EAAE,YAAY,CAAC;IACtB,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACzB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACzB,2DAA2D;IAC3D,OAAO,IAAI,IAAI,CAAC;IAChB,2EAA2E;IAC3E,KAAK,IAAI,IAAI,CAAC;IACd,wDAAwD;IACxD,MAAM,IAAI,IAAI,CAAC;IACf,oDAAoD;IACpD,KAAK,IAAI,IAAI,CAAC;IACd,0DAA0D;IAC1D,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,GAAG,cAAc,CAgC3E;AAID;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,cAAc,CAAC;IACtB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAErB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,cAAc,CAI3C;AAUD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,KAAK,IAAI,GAC5E,IAAI,CA+BN"}
@@ -1,7 +1,7 @@
1
1
  // Copyright 2025 the AAI authors. MIT license.
2
2
  import { batch, effect, signal } from "@preact/signals";
3
3
  import { createContext, h } from "preact";
4
- import { useContext } from "preact/hooks";
4
+ import { useContext, useEffect, useRef } from "preact/hooks";
5
5
  /**
6
6
  * Wrap a {@linkcode VoiceSession} in Preact signals for reactive UI binding.
7
7
  *
@@ -71,4 +71,53 @@ export function useSession() {
71
71
  throw new Error("Hook useSession() requires a SessionProvider");
72
72
  return ctx;
73
73
  }
74
+ function tryParseJSON(str) {
75
+ try {
76
+ return JSON.parse(str);
77
+ }
78
+ catch {
79
+ return str;
80
+ }
81
+ }
82
+ /**
83
+ * Hook that fires a callback exactly once for each newly completed tool call.
84
+ *
85
+ * Handles deduplication internally — safe to use with `useState` setters
86
+ * without worrying about duplicates. The `result` argument is the parsed
87
+ * JSON result from the tool (or the raw string if parsing fails).
88
+ *
89
+ * Automatically resets tracking when the session is reset (toolCalls cleared).
90
+ *
91
+ * @param callback - Called once per completed tool call with the tool name,
92
+ * parsed result, and full {@linkcode ToolCallInfo}.
93
+ */
94
+ export function useToolResult(callback) {
95
+ const { session } = useSession();
96
+ const seenRef = useRef(new Set());
97
+ const cbRef = useRef(callback);
98
+ cbRef.current = callback;
99
+ const disposeRef = useRef(null);
100
+ if (!disposeRef.current) {
101
+ disposeRef.current = effect(() => {
102
+ const toolCalls = session.toolCalls.value;
103
+ if (toolCalls.length === 0) {
104
+ seenRef.current.clear();
105
+ return;
106
+ }
107
+ for (const tc of toolCalls) {
108
+ if (tc.status !== "done" || !tc.result)
109
+ continue;
110
+ if (seenRef.current.has(tc.toolCallId))
111
+ continue;
112
+ seenRef.current.add(tc.toolCallId);
113
+ const parsed = tryParseJSON(tc.result);
114
+ cbRef.current(tc.toolName, parsed, tc);
115
+ }
116
+ });
117
+ }
118
+ useEffect(() => () => {
119
+ disposeRef.current?.();
120
+ disposeRef.current = null;
121
+ }, []);
122
+ }
74
123
  //# sourceMappingURL=signals.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.js","sourceRoot":"","sources":["../../ui/signals.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAe,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA6B1C;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAqB;IACzD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAE7B,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,EAAE;QAC1B,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,OAAO;YAAE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,OAAO;QACP,OAAO;QACP,OAAO;QACP,OAAO;QACP,KAAK;YACH,KAAK,CAAC,GAAG,EAAE;gBACT,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;gBACrB,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;YACvB,CAAC,CAAC,CAAC;YACH,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;QACD,MAAM;YACJ,IAAI,OAAO,CAAC,KAAK;gBAAE,OAAO,CAAC,UAAU,EAAE,CAAC;;gBACnC,OAAO,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC;QACjC,CAAC;QACD,KAAK;YACH,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;QACD,CAAC,MAAM,CAAC,OAAO,CAAC;YACd,OAAO,EAAE,CAAC;QACZ,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,GAAG,GAAG,aAAa,CAAwB,IAAI,CAAC,CAAC;AAEvD;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,GAIT;IACC,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAC1E,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"signals.js","sourceRoot":"","sources":["../../ui/signals.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexkroman1/aai",
3
- "version": "0.7.10",
3
+ "version": "0.7.12",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "aai": "dist/aai.js"
@@ -137,6 +137,7 @@
137
137
  "@vitest/coverage-v8": "^4.1.0",
138
138
  "ink-testing-library": "^4.0.0",
139
139
  "linkedom": "^0.18.12",
140
+ "markdownlint-cli2": "^0.21.0",
140
141
  "tsx": "^4.21.0",
141
142
  "typescript": "^5.9.3",
142
143
  "vitest": "^4.1.0"
@@ -149,6 +150,6 @@
149
150
  "test": "vitest run",
150
151
  "lint": "biome check sdk/ ui/ cli/",
151
152
  "lint:fix": "biome check --write sdk/ ui/ cli/",
152
- "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/ && vitest run"
153
+ "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"
153
154
  }
154
155
  }
@@ -57,6 +57,7 @@ with `aai init -t <template_name>`.
57
57
  | `personal-finance` | Currency conversion, crypto prices, loan calculations, savings projections |
58
58
  | `travel-concierge` | Trip planning, weather, flights, hotels, currency conversion |
59
59
  | `night-owl` | Movie/music/book recs by mood, sleep calculator. **Has custom UI.** |
60
+ | `pizza-ordering` | Pizza order-taker with dynamic cart sidebar. **Has custom UI.** |
60
61
  | `dispatch-center` | 911 dispatch with incident triage and resource assignment. **Has custom UI.** |
61
62
  | `infocom-adventure` | Zork-style text adventure with state, puzzles, inventory. **Has custom UI.** |
62
63
  | `embedded-assets` | FAQ bot using embedded JSON knowledge (no web search) |
@@ -583,6 +584,12 @@ data lives on `session` (a `VoiceSession`); UI-only controls are top-level.
583
584
 
584
585
  **Methods:** `start()`, `toggle()`, `reset()`, `dispose()`
585
586
 
587
+ **Hooks:**
588
+
589
+ | Hook | Description |
590
+ | --------------------------------------------- | -------------------------------------------------------------------------------------------- |
591
+ | `useToolResult((toolName, result, tc) => {})` | Fires once per completed tool call with parsed JSON result. Use for carts, scoreboards, etc. |
592
+
586
593
  ### Showing tool calls in custom UI
587
594
 
588
595
  ```tsx
@@ -613,6 +620,58 @@ function App() {
613
620
  mount(App);
614
621
  ```
615
622
 
623
+ ### Building dynamic UI from tool results
624
+
625
+ Use `useToolResult` to update local state (carts, scoreboards, dashboards)
626
+ whenever a tool completes. It fires exactly once per completed tool call with
627
+ the parsed JSON result, handling deduplication internally.
628
+
629
+ ```tsx
630
+ import "aai/ui/styles.css";
631
+ import { useState } from "preact/hooks";
632
+ import { ChatView, mount, useSession, useToolResult } from "aai/ui";
633
+
634
+ interface CartItem { id: number; name: string; price: number }
635
+
636
+ function ShopAgent() {
637
+ const { started, start } = useSession();
638
+ const [cart, setCart] = useState<CartItem[]>([]);
639
+
640
+ useToolResult((toolName, result: any) => {
641
+ switch (toolName) {
642
+ case "add_item":
643
+ setCart((prev) => [...prev, result.item]);
644
+ break;
645
+ case "remove_item":
646
+ setCart((prev) => prev.filter((i) => i.id !== result.removedId));
647
+ break;
648
+ case "clear_cart":
649
+ setCart([]);
650
+ break;
651
+ }
652
+ });
653
+
654
+ if (!started.value) return <button onClick={start}>Start</button>;
655
+
656
+ return (
657
+ <div class="flex h-screen">
658
+ <div class="w-64 p-4 border-r border-aai-border">
659
+ <h3>Cart ({cart.length})</h3>
660
+ {cart.map((i) => <p key={i.id}>{i.name} — ${i.price}</p>)}
661
+ </div>
662
+ <div class="flex-1"><ChatView /></div>
663
+ </div>
664
+ );
665
+ }
666
+
667
+ mount(ShopAgent);
668
+ ```
669
+
670
+ **Do NOT use `useEffect` + `session.toolCalls.value` to build derived state.**
671
+ That pattern re-processes every tool call on every signal change, causing
672
+ duplicates (e.g. items added to the cart multiple times). `useToolResult`
673
+ handles this correctly.
674
+
616
675
  ### Reacting to agent state
617
676
 
618
677
  ```tsx
@@ -786,28 +845,32 @@ Good instructions tell the LLM what it is, how to behave, and when to use each
786
845
  tool. Study these patterns:
787
846
 
788
847
  **Code execution agent** — force tool use for anything computational:
789
- ```
848
+
849
+ ```text
790
850
  You MUST use the run_code tool for ANY question involving math, counting,
791
851
  string manipulation, or data processing. NEVER do mental math or estimate.
792
852
  Use console.log() to output intermediate steps.
793
853
  ```
794
854
 
795
855
  **Research agent** — search before answering:
796
- ```
856
+
857
+ ```text
797
858
  Search first. Never guess or rely on memory for factual questions.
798
859
  Use visit_webpage when search snippets aren't detailed enough.
799
860
  For complex questions, search multiple times with different queries.
800
861
  ```
801
862
 
802
863
  **FAQ/support agent** — stay grounded in knowledge:
803
- ```
864
+
865
+ ```text
804
866
  Always use vector_search to find relevant documentation before answering.
805
867
  Base your answers strictly on the retrieved documentation — don't guess.
806
868
  If search results aren't relevant, say the docs don't cover that topic.
807
869
  ```
808
870
 
809
871
  **API-calling agent** — tell the LLM which endpoints to use:
810
- ```
872
+
873
+ ```text
811
874
  API endpoints (use fetch_json):
812
875
  - Currency rates: https://open.er-api.com/v6/latest/{CODE}
813
876
  Returns { rates: { USD: 1.0, EUR: 0.85, ... } }
@@ -815,7 +878,8 @@ API endpoints (use fetch_json):
815
878
  ```
816
879
 
817
880
  **Game/interactive agent** — establish world rules and voice style:
818
- ```
881
+
882
+ ```text
819
883
  You ARE the game. Maintain world state, describe rooms, handle puzzles.
820
884
  Keep descriptions to two to four sentences. No visual formatting.
821
885
  Use directional words naturally: "To the north you see..." not "N: forest"
@@ -823,6 +887,11 @@ Use directional words naturally: "To the north you see..." not "N: forest"
823
887
 
824
888
  ## Common pitfalls
825
889
 
890
+ - **Using `useEffect` to build state from tool calls** — Iterating
891
+ `session.toolCalls.value` in a `useEffect` re-processes every tool call on
892
+ every signal change, causing duplicates (e.g. cart items added multiple
893
+ times). Use the `useToolResult` hook instead — it fires exactly once per
894
+ completed tool call with proper deduplication.
826
895
  - **Writing `instructions` with visual formatting** — Bullets, bold, numbered
827
896
  lists sound terrible when spoken. Use natural transitions: "First", "Next",
828
897
  "Finally". Write instructions as if you're coaching a human phone operator.
@@ -0,0 +1,215 @@
1
+ import { defineAgent } from "@alexkroman1/aai";
2
+ import { z } from "zod";
3
+
4
+ interface Pizza {
5
+ id: number;
6
+ size: "small" | "medium" | "large";
7
+ crust: "thin" | "regular" | "thick" | "stuffed";
8
+ toppings: string[];
9
+ quantity: number;
10
+ }
11
+
12
+ interface OrderState {
13
+ pizzas: Pizza[];
14
+ nextId: number;
15
+ customerName: string;
16
+ orderPlaced: boolean;
17
+ }
18
+
19
+ const MENU = {
20
+ sizes: { small: 8.99, medium: 11.99, large: 14.99 },
21
+ crusts: { thin: 0, regular: 0, thick: 1.0, stuffed: 2.0 },
22
+ toppings: {
23
+ pepperoni: 1.5,
24
+ sausage: 1.5,
25
+ mushrooms: 1.0,
26
+ onions: 1.0,
27
+ green_peppers: 1.0,
28
+ black_olives: 1.0,
29
+ bacon: 2.0,
30
+ ham: 1.5,
31
+ pineapple: 1.0,
32
+ jalapenos: 1.0,
33
+ extra_cheese: 1.5,
34
+ spinach: 1.0,
35
+ tomatoes: 1.0,
36
+ anchovies: 1.5,
37
+ chicken: 2.0,
38
+ },
39
+ } as const;
40
+
41
+ function calculateTotal(pizzas: Pizza[]): number {
42
+ return pizzas.reduce((total, pizza) => {
43
+ const base = MENU.sizes[pizza.size];
44
+ const crust = MENU.crusts[pizza.crust];
45
+ const toppingsPrice = pizza.toppings.reduce(
46
+ (sum, t) =>
47
+ sum + (MENU.toppings[t as keyof typeof MENU.toppings] ?? 1.0),
48
+ 0,
49
+ );
50
+ return total + (base + crust + toppingsPrice) * pizza.quantity;
51
+ }, 0);
52
+ }
53
+
54
+ export default defineAgent({
55
+ name: "Pizza Palace",
56
+ voice: "e3827ec5-697a-4b7c-9704-1a23041bbc51", // Sweet Lady
57
+ greeting:
58
+ "Welcome to Pizza Palace. I can help you build your perfect pizza. What would you like to order?",
59
+ instructions: `You are a friendly pizza order-taker at Pizza Palace. Keep responses short and conversational, optimized for voice.
60
+
61
+ Your job is to help customers build their pizza order step by step. Guide them through size, crust, and toppings.
62
+
63
+ Menu info:
64
+ - Sizes: small ($8.99), medium ($11.99), large ($14.99)
65
+ - Crusts: thin (free), regular (free), thick (+$1), stuffed (+$2)
66
+ - Toppings: pepperoni ($1.50), sausage ($1.50), mushrooms ($1), onions ($1), green peppers ($1), black olives ($1), bacon ($2), ham ($1.50), pineapple ($1), jalapenos ($1), extra cheese ($1.50), spinach ($1), tomatoes ($1), anchovies ($1.50), chicken ($2)
67
+
68
+ Behavior:
69
+ - When a customer wants a pizza, collect size, crust, and toppings, then use add_pizza to add it.
70
+ - If they just say something like "pepperoni pizza", assume medium, regular crust, and confirm before adding.
71
+ - Always confirm what you added after using add_pizza.
72
+ - Use view_order when the customer asks to review their order.
73
+ - Use update_pizza if they want to change an existing pizza.
74
+ - Use remove_pizza if they want to remove one.
75
+ - When they say they are done ordering, use place_order.
76
+ - Suggest popular combos if they seem unsure. For example, "Our most popular is a large pepperoni with extra cheese."
77
+ - Always mention the running total after changes.
78
+ - Be warm but efficient. No long monologues.`,
79
+
80
+ state: (): OrderState => ({
81
+ pizzas: [],
82
+ nextId: 1,
83
+ customerName: "",
84
+ orderPlaced: false,
85
+ }),
86
+
87
+ tools: {
88
+ add_pizza: {
89
+ description:
90
+ "Add a pizza to the order. Use when the customer has decided on a pizza.",
91
+ parameters: z.object({
92
+ size: z.enum(["small", "medium", "large"]),
93
+ crust: z.enum(["thin", "regular", "thick", "stuffed"]),
94
+ toppings: z
95
+ .array(z.string())
96
+ .describe("List of topping names, e.g. ['pepperoni', 'mushrooms']"),
97
+ quantity: z.number().default(1),
98
+ }),
99
+ execute: (args: { size: Pizza["size"]; crust: Pizza["crust"]; toppings: string[]; quantity: number }, ctx) => {
100
+ const state = ctx.state as OrderState;
101
+ const pizza: Pizza = {
102
+ id: state.nextId++,
103
+ size: args.size,
104
+ crust: args.crust,
105
+ toppings: args.toppings,
106
+ quantity: args.quantity,
107
+ };
108
+ state.pizzas.push(pizza);
109
+ const total = calculateTotal(state.pizzas);
110
+ return {
111
+ added: pizza,
112
+ orderTotal: `$${total.toFixed(2)}`,
113
+ itemCount: state.pizzas.length,
114
+ };
115
+ },
116
+ },
117
+
118
+ remove_pizza: {
119
+ description: "Remove a pizza from the order by its ID.",
120
+ parameters: z.object({
121
+ pizza_id: z.number().describe("The pizza ID to remove"),
122
+ }),
123
+ execute: (args, ctx) => {
124
+ const state = ctx.state as OrderState;
125
+ const idx = state.pizzas.findIndex((p) => p.id === args.pizza_id);
126
+ if (idx === -1) return { error: "Pizza not found in the order." };
127
+ const removed = state.pizzas.splice(idx, 1)[0];
128
+ const total = calculateTotal(state.pizzas);
129
+ return {
130
+ removed,
131
+ orderTotal: `$${total.toFixed(2)}`,
132
+ itemCount: state.pizzas.length,
133
+ };
134
+ },
135
+ },
136
+
137
+ update_pizza: {
138
+ description:
139
+ "Update an existing pizza in the order. Only provided fields are changed.",
140
+ parameters: z.object({
141
+ pizza_id: z.number(),
142
+ size: z.enum(["small", "medium", "large"]).optional(),
143
+ crust: z.enum(["thin", "regular", "thick", "stuffed"]).optional(),
144
+ toppings: z.array(z.string()).optional(),
145
+ quantity: z.number().optional(),
146
+ }),
147
+ execute: (args: { pizza_id: number; size?: Pizza["size"]; crust?: Pizza["crust"]; toppings?: string[]; quantity?: number }, ctx) => {
148
+ const state = ctx.state as OrderState;
149
+ const pizza = state.pizzas.find((p) => p.id === args.pizza_id);
150
+ if (!pizza) return { error: "Pizza not found in the order." };
151
+ if (args.size) pizza.size = args.size;
152
+ if (args.crust) pizza.crust = args.crust;
153
+ if (args.toppings) pizza.toppings = args.toppings;
154
+ if (args.quantity) pizza.quantity = args.quantity;
155
+ const total = calculateTotal(state.pizzas);
156
+ return {
157
+ updated: pizza,
158
+ orderTotal: `$${total.toFixed(2)}`,
159
+ };
160
+ },
161
+ },
162
+
163
+ view_order: {
164
+ description:
165
+ "View the current order summary with all pizzas and total price.",
166
+ execute: (_args, ctx) => {
167
+ const state = ctx.state as OrderState;
168
+ if (state.pizzas.length === 0)
169
+ return { message: "The order is empty." };
170
+ const total = calculateTotal(state.pizzas);
171
+ return {
172
+ pizzas: state.pizzas.map((p) => ({
173
+ id: p.id,
174
+ description: `${p.quantity}x ${p.size} ${p.crust} crust with ${p.toppings.length > 0 ? p.toppings.join(", ") : "cheese only"}`,
175
+ size: p.size,
176
+ crust: p.crust,
177
+ toppings: p.toppings,
178
+ quantity: p.quantity,
179
+ })),
180
+ orderTotal: `$${total.toFixed(2)}`,
181
+ };
182
+ },
183
+ },
184
+
185
+ set_customer_name: {
186
+ description: "Set the customer name for the order.",
187
+ parameters: z.object({ name: z.string() }),
188
+ execute: (args: { name: string }, ctx) => {
189
+ const state = ctx.state as OrderState;
190
+ state.customerName = args.name;
191
+ return { name: args.name };
192
+ },
193
+ },
194
+
195
+ place_order: {
196
+ description:
197
+ "Place the final order. Use when the customer confirms they are done and ready to order.",
198
+ execute: (_args, ctx) => {
199
+ const state = ctx.state as OrderState;
200
+ if (state.pizzas.length === 0)
201
+ return { error: "Cannot place an empty order." };
202
+ state.orderPlaced = true;
203
+ const total = calculateTotal(state.pizzas);
204
+ const orderNumber = Math.floor(1000 + Math.random() * 9000);
205
+ return {
206
+ orderNumber,
207
+ customerName: state.customerName || "Guest",
208
+ pizzas: state.pizzas.length,
209
+ total: `$${total.toFixed(2)}`,
210
+ estimatedMinutes: 15 + state.pizzas.length * 5,
211
+ };
212
+ },
213
+ },
214
+ },
215
+ });