@alexkroman1/aai 0.4.0 → 0.6.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 (249) hide show
  1. package/README.md +0 -6
  2. package/dist/aai.js +3 -0
  3. package/dist/cli.js +244 -245
  4. package/dist/sdk/_internal_types.d.ts +73 -0
  5. package/dist/sdk/_internal_types.d.ts.map +1 -0
  6. package/dist/sdk/_internal_types.js +24 -0
  7. package/dist/sdk/_internal_types.js.map +1 -0
  8. package/dist/sdk/_mock_ws.d.ts +105 -0
  9. package/dist/sdk/_mock_ws.d.ts.map +1 -0
  10. package/dist/sdk/_mock_ws.js +154 -0
  11. package/dist/sdk/_mock_ws.js.map +1 -0
  12. package/dist/sdk/_timeout.d.ts +14 -0
  13. package/dist/sdk/_timeout.d.ts.map +1 -0
  14. package/{sdk/_timeout.ts → dist/sdk/_timeout.js} +9 -9
  15. package/dist/sdk/_timeout.js.map +1 -0
  16. package/dist/sdk/builtin_tools.d.ts +33 -0
  17. package/dist/sdk/builtin_tools.d.ts.map +1 -0
  18. package/dist/sdk/builtin_tools.js +263 -0
  19. package/dist/sdk/builtin_tools.js.map +1 -0
  20. package/dist/sdk/capnweb.d.ts +69 -0
  21. package/dist/sdk/capnweb.d.ts.map +1 -0
  22. package/dist/sdk/capnweb.js +291 -0
  23. package/dist/sdk/capnweb.js.map +1 -0
  24. package/dist/sdk/define_agent.d.ts +36 -0
  25. package/dist/sdk/define_agent.d.ts.map +1 -0
  26. package/dist/sdk/define_agent.js +63 -0
  27. package/dist/sdk/define_agent.js.map +1 -0
  28. package/dist/sdk/direct_executor.d.ts +42 -0
  29. package/dist/sdk/direct_executor.d.ts.map +1 -0
  30. package/dist/sdk/direct_executor.js +143 -0
  31. package/dist/sdk/direct_executor.js.map +1 -0
  32. package/dist/sdk/kv.d.ts +123 -0
  33. package/dist/sdk/kv.d.ts.map +1 -0
  34. package/dist/sdk/kv.js +91 -0
  35. package/dist/sdk/kv.js.map +1 -0
  36. package/{sdk/mod.ts → dist/sdk/mod.d.ts} +2 -11
  37. package/dist/sdk/mod.d.ts.map +1 -0
  38. package/dist/sdk/mod.js +26 -0
  39. package/dist/sdk/mod.js.map +1 -0
  40. package/dist/sdk/protocol.d.ts +218 -0
  41. package/dist/sdk/protocol.d.ts.map +1 -0
  42. package/dist/sdk/protocol.js +140 -0
  43. package/dist/sdk/protocol.js.map +1 -0
  44. package/dist/sdk/runtime.d.ts +35 -0
  45. package/dist/sdk/runtime.d.ts.map +1 -0
  46. package/dist/sdk/runtime.js +46 -0
  47. package/dist/sdk/runtime.js.map +1 -0
  48. package/dist/sdk/s2s.d.ts +60 -0
  49. package/dist/sdk/s2s.d.ts.map +1 -0
  50. package/dist/sdk/s2s.js +171 -0
  51. package/dist/sdk/s2s.js.map +1 -0
  52. package/dist/sdk/server.d.ts +51 -0
  53. package/dist/sdk/server.d.ts.map +1 -0
  54. package/dist/sdk/server.js +145 -0
  55. package/dist/sdk/server.js.map +1 -0
  56. package/dist/sdk/session.d.ts +66 -0
  57. package/dist/sdk/session.d.ts.map +1 -0
  58. package/dist/sdk/session.js +324 -0
  59. package/dist/sdk/session.js.map +1 -0
  60. package/dist/sdk/system_prompt.d.ts +6 -0
  61. package/dist/sdk/system_prompt.d.ts.map +1 -0
  62. package/dist/sdk/system_prompt.js +35 -0
  63. package/dist/sdk/system_prompt.js.map +1 -0
  64. package/dist/sdk/types.d.ts +326 -0
  65. package/dist/sdk/types.d.ts.map +1 -0
  66. package/dist/sdk/types.js +38 -0
  67. package/dist/sdk/types.js.map +1 -0
  68. package/dist/sdk/vector.d.ts +90 -0
  69. package/dist/sdk/vector.d.ts.map +1 -0
  70. package/dist/sdk/vector.js +61 -0
  71. package/dist/sdk/vector.js.map +1 -0
  72. package/dist/sdk/winterc_server.d.ts +53 -0
  73. package/dist/sdk/winterc_server.d.ts.map +1 -0
  74. package/dist/sdk/winterc_server.js +82 -0
  75. package/dist/sdk/winterc_server.js.map +1 -0
  76. package/dist/sdk/worker_entry.d.ts +48 -0
  77. package/dist/sdk/worker_entry.d.ts.map +1 -0
  78. package/dist/sdk/worker_entry.js +67 -0
  79. package/dist/sdk/worker_entry.js.map +1 -0
  80. package/dist/sdk/worker_shim.d.ts +20 -0
  81. package/dist/sdk/worker_shim.d.ts.map +1 -0
  82. package/dist/sdk/worker_shim.js +132 -0
  83. package/dist/sdk/worker_shim.js.map +1 -0
  84. package/dist/sdk/ws_handler.d.ts +50 -0
  85. package/dist/sdk/ws_handler.d.ts.map +1 -0
  86. package/dist/sdk/ws_handler.js +156 -0
  87. package/dist/sdk/ws_handler.js.map +1 -0
  88. package/dist/ui/_components/app.d.ts +3 -0
  89. package/dist/ui/_components/app.d.ts.map +1 -0
  90. package/dist/ui/_components/app.js +14 -0
  91. package/dist/ui/_components/app.js.map +1 -0
  92. package/dist/ui/_components/chat_view.d.ts +3 -0
  93. package/dist/ui/_components/chat_view.d.ts.map +1 -0
  94. package/dist/ui/_components/chat_view.js +14 -0
  95. package/dist/ui/_components/chat_view.js.map +1 -0
  96. package/dist/ui/_components/controls.d.ts +2 -0
  97. package/dist/ui/_components/controls.d.ts.map +1 -0
  98. package/dist/ui/_components/controls.js +11 -0
  99. package/dist/ui/_components/controls.js.map +1 -0
  100. package/dist/ui/_components/error_banner.d.ts +7 -0
  101. package/dist/ui/_components/error_banner.d.ts.map +1 -0
  102. package/dist/ui/_components/error_banner.js +7 -0
  103. package/dist/ui/_components/error_banner.js.map +1 -0
  104. package/dist/ui/_components/message_bubble.d.ts +6 -0
  105. package/dist/ui/_components/message_bubble.d.ts.map +1 -0
  106. package/dist/ui/_components/message_bubble.js +9 -0
  107. package/dist/ui/_components/message_bubble.js.map +1 -0
  108. package/dist/ui/_components/message_list.d.ts +2 -0
  109. package/dist/ui/_components/message_list.d.ts.map +1 -0
  110. package/dist/ui/_components/message_list.js +48 -0
  111. package/dist/ui/_components/message_list.js.map +1 -0
  112. package/dist/ui/_components/state_indicator.d.ts +7 -0
  113. package/dist/ui/_components/state_indicator.d.ts.map +1 -0
  114. package/dist/ui/_components/state_indicator.js +5 -0
  115. package/dist/ui/_components/state_indicator.js.map +1 -0
  116. package/dist/ui/_components/thinking_indicator.d.ts +3 -0
  117. package/dist/ui/_components/thinking_indicator.d.ts.map +1 -0
  118. package/dist/ui/_components/thinking_indicator.js +8 -0
  119. package/dist/ui/_components/thinking_indicator.js.map +1 -0
  120. package/dist/ui/_components/tool_call_block.d.ts +6 -0
  121. package/dist/ui/_components/tool_call_block.d.ts.map +1 -0
  122. package/dist/ui/_components/tool_call_block.js +58 -0
  123. package/dist/ui/_components/tool_call_block.js.map +1 -0
  124. package/dist/ui/_components/tool_icons.d.ts +18 -0
  125. package/dist/ui/_components/tool_icons.d.ts.map +1 -0
  126. package/dist/ui/_components/tool_icons.js +26 -0
  127. package/dist/ui/_components/tool_icons.js.map +1 -0
  128. package/dist/ui/_components/transcript.d.ts +6 -0
  129. package/dist/ui/_components/transcript.d.ts.map +1 -0
  130. package/dist/ui/_components/transcript.js +8 -0
  131. package/dist/ui/_components/transcript.js.map +1 -0
  132. package/dist/ui/_dom_shim.d.ts +7 -0
  133. package/dist/ui/_dom_shim.d.ts.map +1 -0
  134. package/dist/ui/_dom_shim.js +21 -0
  135. package/dist/ui/_dom_shim.js.map +1 -0
  136. package/dist/ui/_test_utils.js +272 -0
  137. package/dist/ui/_test_utils.js.map +1 -0
  138. package/dist/ui/audio.d.ts +46 -0
  139. package/dist/ui/audio.d.ts.map +1 -0
  140. package/dist/ui/audio.js +130 -0
  141. package/dist/ui/audio.js.map +1 -0
  142. package/dist/ui/components.d.ts +36 -0
  143. package/dist/ui/components.d.ts.map +1 -0
  144. package/dist/ui/components.js +32 -0
  145. package/dist/ui/components.js.map +1 -0
  146. package/{ui/components_mod.ts → dist/ui/components_mod.d.ts} +3 -18
  147. package/dist/ui/components_mod.d.ts.map +1 -0
  148. package/dist/ui/components_mod.js +20 -0
  149. package/dist/ui/components_mod.js.map +1 -0
  150. package/dist/ui/mod.d.ts +21 -0
  151. package/dist/ui/mod.d.ts.map +1 -0
  152. package/{ui/mod.ts → dist/ui/mod.js} +3 -29
  153. package/dist/ui/mod.js.map +1 -0
  154. package/dist/ui/mount.d.ts +56 -0
  155. package/dist/ui/mount.d.ts.map +1 -0
  156. package/dist/ui/mount.js +60 -0
  157. package/dist/ui/mount.js.map +1 -0
  158. package/dist/ui/mount_context.d.ts +10 -0
  159. package/dist/ui/mount_context.d.ts.map +1 -0
  160. package/dist/ui/mount_context.js +10 -0
  161. package/dist/ui/mount_context.js.map +1 -0
  162. package/dist/ui/session.d.ts +91 -0
  163. package/dist/ui/session.d.ts.map +1 -0
  164. package/dist/ui/session.js +366 -0
  165. package/dist/ui/session.js.map +1 -0
  166. package/{ui/session_mod.ts → dist/ui/session_mod.d.ts} +2 -10
  167. package/dist/ui/session_mod.d.ts.map +1 -0
  168. package/dist/ui/session_mod.js +18 -0
  169. package/dist/ui/session_mod.js.map +1 -0
  170. package/dist/ui/signals.d.ts +61 -0
  171. package/dist/ui/signals.d.ts.map +1 -0
  172. package/dist/ui/signals.js +74 -0
  173. package/dist/ui/signals.js.map +1 -0
  174. package/dist/ui/types.d.ts +36 -0
  175. package/dist/ui/types.d.ts.map +1 -0
  176. package/dist/ui/types.js +4 -0
  177. package/dist/ui/types.js.map +1 -0
  178. package/package.json +103 -28
  179. package/sdk/_internal_types.ts +0 -89
  180. package/sdk/_mock_ws.ts +0 -172
  181. package/sdk/builtin_tools.ts +0 -309
  182. package/sdk/capnweb.ts +0 -341
  183. package/sdk/define_agent.ts +0 -70
  184. package/sdk/direct_executor.ts +0 -195
  185. package/sdk/kv.ts +0 -183
  186. package/sdk/protocol.ts +0 -313
  187. package/sdk/runtime.ts +0 -65
  188. package/sdk/s2s.ts +0 -271
  189. package/sdk/server.ts +0 -198
  190. package/sdk/session.ts +0 -438
  191. package/sdk/system_prompt.ts +0 -47
  192. package/sdk/types.ts +0 -406
  193. package/sdk/vector.ts +0 -133
  194. package/sdk/winterc_server.ts +0 -141
  195. package/sdk/worker_entry.ts +0 -99
  196. package/sdk/worker_shim.ts +0 -170
  197. package/sdk/ws_handler.ts +0 -190
  198. package/templates/_shared/.env.example +0 -5
  199. package/templates/_shared/package.json +0 -17
  200. package/templates/code-interpreter/agent.ts +0 -27
  201. package/templates/code-interpreter/client.tsx +0 -2
  202. package/templates/dispatch-center/agent.ts +0 -1536
  203. package/templates/dispatch-center/client.tsx +0 -504
  204. package/templates/embedded-assets/agent.ts +0 -49
  205. package/templates/embedded-assets/client.tsx +0 -2
  206. package/templates/embedded-assets/knowledge.json +0 -20
  207. package/templates/health-assistant/agent.ts +0 -160
  208. package/templates/health-assistant/client.tsx +0 -2
  209. package/templates/infocom-adventure/agent.ts +0 -164
  210. package/templates/infocom-adventure/client.tsx +0 -299
  211. package/templates/math-buddy/agent.ts +0 -21
  212. package/templates/math-buddy/client.tsx +0 -2
  213. package/templates/memory-agent/agent.ts +0 -74
  214. package/templates/memory-agent/client.tsx +0 -2
  215. package/templates/night-owl/agent.ts +0 -98
  216. package/templates/night-owl/client.tsx +0 -28
  217. package/templates/personal-finance/agent.ts +0 -26
  218. package/templates/personal-finance/client.tsx +0 -2
  219. package/templates/simple/agent.ts +0 -6
  220. package/templates/simple/client.tsx +0 -2
  221. package/templates/smart-research/agent.ts +0 -164
  222. package/templates/smart-research/client.tsx +0 -2
  223. package/templates/support/README.md +0 -62
  224. package/templates/support/agent.ts +0 -19
  225. package/templates/support/client.tsx +0 -2
  226. package/templates/travel-concierge/agent.ts +0 -29
  227. package/templates/travel-concierge/client.tsx +0 -2
  228. package/templates/web-researcher/agent.ts +0 -17
  229. package/templates/web-researcher/client.tsx +0 -2
  230. package/ui/_components/app.tsx +0 -37
  231. package/ui/_components/chat_view.tsx +0 -36
  232. package/ui/_components/controls.tsx +0 -32
  233. package/ui/_components/error_banner.tsx +0 -18
  234. package/ui/_components/message_bubble.tsx +0 -21
  235. package/ui/_components/message_list.tsx +0 -61
  236. package/ui/_components/state_indicator.tsx +0 -17
  237. package/ui/_components/thinking_indicator.tsx +0 -19
  238. package/ui/_components/tool_call_block.tsx +0 -110
  239. package/ui/_components/tool_icons.tsx +0 -101
  240. package/ui/_components/transcript.tsx +0 -20
  241. package/ui/audio.ts +0 -170
  242. package/ui/components.ts +0 -49
  243. package/ui/mount.tsx +0 -112
  244. package/ui/mount_context.ts +0 -19
  245. package/ui/session.ts +0 -456
  246. package/ui/signals.ts +0 -111
  247. package/ui/types.ts +0 -50
  248. package/ui/worklets/capture-processor.js +0 -62
  249. package/ui/worklets/playback-processor.js +0 -110
@@ -0,0 +1,82 @@
1
+ // Copyright 2025 the AAI authors. MIT license.
2
+ /**
3
+ * WinterTC-compatible server factory.
4
+ *
5
+ * Creates a server with `fetch(Request): Response` and `handleWebSocket(ws)`
6
+ * that can run both in-process (self-hosted) and inside a sandboxed Worker
7
+ * (platform). This is the shared core for both modes.
8
+ *
9
+ * @module
10
+ */
11
+ import { createDirectExecutor } from "./direct_executor.js";
12
+ import { createMemoryKv } from "./kv.js";
13
+ import { AUDIO_FORMAT, PROTOCOL_VERSION } from "./protocol.js";
14
+ import { consoleLogger, DEFAULT_S2S_CONFIG, noopMetrics } from "./runtime.js";
15
+ import { wireSessionSocket } from "./ws_handler.js";
16
+ /**
17
+ * Create a WinterTC-compatible server from an agent definition.
18
+ *
19
+ * The returned object has a standard `fetch` handler and a `handleWebSocket`
20
+ * method. Self-hosted mode calls these directly; platform mode calls them
21
+ * from inside a sandboxed Worker via capnweb RPC.
22
+ */
23
+ export function createWintercServer(options) {
24
+ const { agent, env, kv = createMemoryKv(), vectorSearch, clientHtml, logger = consoleLogger, metrics = noopMetrics, s2sConfig = DEFAULT_S2S_CONFIG, } = options;
25
+ const executor = createDirectExecutor({
26
+ agent,
27
+ env,
28
+ kv,
29
+ ...(vectorSearch ? { vectorSearch } : {}),
30
+ createWebSocket: options.createWebSocket,
31
+ logger,
32
+ metrics,
33
+ s2sConfig,
34
+ });
35
+ const sessions = new Map();
36
+ const readyConfig = {
37
+ protocolVersion: PROTOCOL_VERSION,
38
+ audioFormat: AUDIO_FORMAT,
39
+ sampleRate: s2sConfig.inputSampleRate,
40
+ ttsSampleRate: s2sConfig.outputSampleRate,
41
+ mode: "s2s",
42
+ };
43
+ return {
44
+ async fetch(request) {
45
+ const url = new URL(request.url);
46
+ if (url.pathname === "/health") {
47
+ return new Response(JSON.stringify({ status: "ok", name: agent.name }), {
48
+ headers: { "Content-Type": "application/json" },
49
+ });
50
+ }
51
+ if (url.pathname === "/" && clientHtml) {
52
+ return new Response(clientHtml, {
53
+ headers: { "Content-Type": "text/html" },
54
+ });
55
+ }
56
+ if (url.pathname === "/") {
57
+ return new Response(`<!DOCTYPE html><html><body><h1>${agent.name}</h1><p>Agent server running.</p></body></html>`, { headers: { "Content-Type": "text/html" } });
58
+ }
59
+ return new Response("Not Found", { status: 404 });
60
+ },
61
+ handleWebSocket(ws, wsOpts) {
62
+ wireSessionSocket(ws, {
63
+ sessions,
64
+ createSession: (sid, client) => executor.createSession({
65
+ id: sid,
66
+ agent: agent.name,
67
+ client,
68
+ skipGreeting: wsOpts?.skipGreeting ?? false,
69
+ }),
70
+ readyConfig,
71
+ logger,
72
+ });
73
+ },
74
+ async close() {
75
+ for (const session of sessions.values()) {
76
+ await session.stop();
77
+ }
78
+ sessions.clear();
79
+ },
80
+ };
81
+ }
82
+ //# sourceMappingURL=winterc_server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"winterc_server.js","sourceRoot":"","sources":["../../sdk/winterc_server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Worker entry point — shared tool execution logic.
3
+ *
4
+ * @module
5
+ */
6
+ import type { Kv } from "./kv.ts";
7
+ import type { Message, ToolDef } from "./types.ts";
8
+ /**
9
+ * Maximum time in milliseconds a tool handler may run before being aborted.
10
+ *
11
+ * If a tool's `execute` function exceeds this duration, it is cancelled via
12
+ * `AbortSignal.timeout` and an error message is returned to the LLM.
13
+ */
14
+ export declare const TOOL_HANDLER_TIMEOUT = 30000;
15
+ /**
16
+ * Function signature for executing a tool by name.
17
+ *
18
+ * @param name - The tool name to execute.
19
+ * @param args - Key-value arguments to pass to the tool handler.
20
+ * @param sessionId - Optional session identifier for stateful tools.
21
+ * @param messages - Optional conversation history for context-aware tools.
22
+ * @returns The tool's string result, or an error message string.
23
+ */
24
+ export type ExecuteTool = (name: string, args: Readonly<Record<string, unknown>>, sessionId?: string, messages?: readonly Message[]) => Promise<string>;
25
+ /** Options for {@linkcode executeToolCall}. */
26
+ export type ExecuteToolCallOptions = {
27
+ tool: ToolDef;
28
+ env: Readonly<Record<string, string>>;
29
+ sessionId?: string | undefined;
30
+ state?: unknown;
31
+ kv?: Kv | undefined;
32
+ messages?: readonly Message[] | undefined;
33
+ };
34
+ /**
35
+ * Execute a tool call with argument validation, timeout, and error handling.
36
+ *
37
+ * Validates the provided arguments against the tool's Zod parameter schema,
38
+ * constructs a {@linkcode ToolContext}, invokes the tool's `execute` function,
39
+ * and serializes the result to a string. Errors and timeouts are caught and
40
+ * returned as `"Error: ..."` strings rather than thrown.
41
+ *
42
+ * @param name - The name of the tool being invoked.
43
+ * @param args - Raw arguments from the LLM to validate and pass to the tool.
44
+ * @param options - Tool definition, environment, and optional context.
45
+ * @returns The tool's result serialized as a string, or an error message.
46
+ */
47
+ export declare function executeToolCall(name: string, args: Readonly<Record<string, unknown>>, options: ExecuteToolCallOptions): Promise<string>;
48
+ //# sourceMappingURL=worker_entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker_entry.d.ts","sourceRoot":"","sources":["../../sdk/worker_entry.ts"],"names":[],"mappings":"AACA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,EAAE,OAAO,EAAe,OAAO,EAAE,MAAM,YAAY,CAAC;AAEhE;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAE3C;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG,CACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACvC,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,SAAS,OAAO,EAAE,KAC1B,OAAO,CAAC,MAAM,CAAC,CAAC;AAErB,+CAA+C;AAC/C,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,EAAE,CAAC,EAAE,EAAE,GAAG,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,CAAC;CAC3C,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACvC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAoCjB"}
@@ -0,0 +1,67 @@
1
+ // Copyright 2025 the AAI authors. MIT license.
2
+ /**
3
+ * Worker entry point — shared tool execution logic.
4
+ *
5
+ * @module
6
+ */
7
+ import { z } from "zod";
8
+ /**
9
+ * Maximum time in milliseconds a tool handler may run before being aborted.
10
+ *
11
+ * If a tool's `execute` function exceeds this duration, it is cancelled via
12
+ * `AbortSignal.timeout` and an error message is returned to the LLM.
13
+ */
14
+ export const TOOL_HANDLER_TIMEOUT = 30_000;
15
+ /**
16
+ * Execute a tool call with argument validation, timeout, and error handling.
17
+ *
18
+ * Validates the provided arguments against the tool's Zod parameter schema,
19
+ * constructs a {@linkcode ToolContext}, invokes the tool's `execute` function,
20
+ * and serializes the result to a string. Errors and timeouts are caught and
21
+ * returned as `"Error: ..."` strings rather than thrown.
22
+ *
23
+ * @param name - The name of the tool being invoked.
24
+ * @param args - Raw arguments from the LLM to validate and pass to the tool.
25
+ * @param options - Tool definition, environment, and optional context.
26
+ * @returns The tool's result serialized as a string, or an error message.
27
+ */
28
+ export async function executeToolCall(name, args, options) {
29
+ const { tool, env, sessionId, state, kv, messages } = options;
30
+ const schema = tool.parameters ?? z.object({});
31
+ const parsed = schema.safeParse(args);
32
+ if (!parsed.success) {
33
+ const issues = (parsed.error?.issues ?? [])
34
+ .map((i) => `${i.path.map(String).join(".")}: ${i.message}`)
35
+ .join(", ");
36
+ return `Error: Invalid arguments for tool "${name}": ${issues}`;
37
+ }
38
+ try {
39
+ const abortSignal = AbortSignal.timeout(TOOL_HANDLER_TIMEOUT);
40
+ const envCopy = { ...env };
41
+ const ctx = {
42
+ sessionId: sessionId ?? "",
43
+ env: envCopy,
44
+ abortSignal,
45
+ state: (state ?? {}),
46
+ get kv() {
47
+ if (!kv)
48
+ throw new Error("KV not available");
49
+ return kv;
50
+ },
51
+ messages: messages ?? [],
52
+ };
53
+ const result = await Promise.resolve(tool.execute(parsed.data, ctx));
54
+ if (result == null)
55
+ return "null";
56
+ return typeof result === "string" ? result : JSON.stringify(result);
57
+ }
58
+ catch (err) {
59
+ if (err instanceof DOMException && err.name === "TimeoutError") {
60
+ console.warn(`[tool-executor] Tool execution timed out: ${name}`);
61
+ return `Error: Tool "${name}" timed out after ${TOOL_HANDLER_TIMEOUT}ms`;
62
+ }
63
+ console.warn(`[tool-executor] Tool execution failed: ${name}`, err);
64
+ return `Error: ${err instanceof Error ? err.message : String(err)}`;
65
+ }
66
+ }
67
+ //# sourceMappingURL=worker_entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker_entry.js","sourceRoot":"","sources":["../../sdk/worker_entry.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AA4B3C;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAY,EACZ,IAAuC,EACvC,OAA+B;IAE/B,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC;aACxC,GAAG,CAAC,CAAC,CAAa,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;aACvE,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO,sCAAsC,IAAI,MAAM,MAAM,EAAE,CAAC;IAClE,CAAC;IAED,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC9D,MAAM,OAAO,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAgB;YACvB,SAAS,EAAE,SAAS,IAAI,EAAE;YAC1B,GAAG,EAAE,OAAO;YACZ,WAAW;YACX,KAAK,EAAE,CAAC,KAAK,IAAI,EAAE,CAA4B;YAC/C,IAAI,EAAE;gBACJ,IAAI,CAAC,EAAE;oBAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;gBAC7C,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,QAAQ,EAAE,QAAQ,IAAI,EAAE;SACzB,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QACrE,IAAI,MAAM,IAAI,IAAI;YAAE,OAAO,MAAM,CAAC;QAClC,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAC/D,OAAO,CAAC,IAAI,CAAC,6CAA6C,IAAI,EAAE,CAAC,CAAC;YAClE,OAAO,gBAAgB,IAAI,qBAAqB,oBAAoB,IAAI,CAAC;QAC3E,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,0CAA0C,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;QACpE,OAAO,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACtE,CAAC;AACH,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Sandboxed worker entry point for platform mode.
3
+ *
4
+ * Called from the bundled `worker.js` inside a Deno Worker with all
5
+ * permissions false. Monkeypatches `globalThis.fetch` to proxy through
6
+ * capnweb RPC, creates capnweb-backed KV/vector/WebSocket, and delegates
7
+ * to a {@linkcode WintercServer} for session management.
8
+ *
9
+ * @module
10
+ */
11
+ import type { AgentDef } from "./types.ts";
12
+ /**
13
+ * Initialize a sandboxed worker with the given agent definition.
14
+ *
15
+ * Sets up capnweb RPC, monkeypatches fetch, creates capability stubs,
16
+ * and waits for the host to send initialization data before creating
17
+ * the WinterTC server.
18
+ */
19
+ export declare function initWorker(agent: AgentDef): void;
20
+ //# sourceMappingURL=worker_shim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker_shim.d.ts","sourceRoot":"","sources":["../../sdk/worker_shim.ts"],"names":[],"mappings":"AACA;;;;;;;;;GASG;AAUH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAQ3C;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAsIhD"}
@@ -0,0 +1,132 @@
1
+ // Copyright 2025 the AAI authors. MIT license.
2
+ /**
3
+ * Sandboxed worker entry point for platform mode.
4
+ *
5
+ * Called from the bundled `worker.js` inside a Deno Worker with all
6
+ * permissions false. Monkeypatches `globalThis.fetch` to proxy through
7
+ * capnweb RPC, creates capnweb-backed KV/vector/WebSocket, and delegates
8
+ * to a {@linkcode WintercServer} for session management.
9
+ *
10
+ * @module
11
+ */
12
+ import { BridgedWebSocket, CapnwebEndpoint, createBridgedS2sWebSocket, } from "./capnweb.js";
13
+ import { createWintercServer } from "./winterc_server.js";
14
+ /**
15
+ * Initialize a sandboxed worker with the given agent definition.
16
+ *
17
+ * Sets up capnweb RPC, monkeypatches fetch, creates capability stubs,
18
+ * and waits for the host to send initialization data before creating
19
+ * the WinterTC server.
20
+ */
21
+ export function initWorker(agent) {
22
+ const endpoint = new CapnwebEndpoint(self);
23
+ // ─── Monkeypatch fetch to proxy through host ────────────────────────────
24
+ globalThis.fetch = async (input, init) => {
25
+ let url;
26
+ let method = "GET";
27
+ let headers = {};
28
+ let body;
29
+ if (typeof input === "string") {
30
+ url = input;
31
+ }
32
+ else if (input instanceof URL) {
33
+ url = input.toString();
34
+ }
35
+ else {
36
+ url = input.url;
37
+ method = input.method;
38
+ headers = Object.fromEntries(input.headers);
39
+ if (input.body) {
40
+ body = await new Response(input.body).text();
41
+ }
42
+ }
43
+ if (init?.method)
44
+ method = init.method;
45
+ if (init?.headers) {
46
+ headers = Object.fromEntries(new Headers(init.headers));
47
+ }
48
+ if (init?.body !== undefined) {
49
+ body = typeof init.body === "string" ? init.body : String(init.body);
50
+ }
51
+ const result = (await endpoint.call("host.fetch", [url, method, headers, body]));
52
+ return new Response(result.body, {
53
+ status: result.status,
54
+ headers: result.headers,
55
+ });
56
+ };
57
+ // ─── Capnweb-backed KV ─────────────────────────────────────────────────
58
+ const kv = {
59
+ async get(key) {
60
+ return (await endpoint.call("host.kv", ["get", key]));
61
+ },
62
+ async set(key, value, options) {
63
+ await endpoint.call("host.kv", ["set", key, value, options?.expireIn]);
64
+ },
65
+ async delete(key) {
66
+ await endpoint.call("host.kv", ["del", key]);
67
+ },
68
+ async list(prefix, options) {
69
+ return (await endpoint.call("host.kv", [
70
+ "list",
71
+ prefix,
72
+ options?.limit,
73
+ options?.reverse,
74
+ ]));
75
+ },
76
+ };
77
+ // ─── Capnweb-backed vector search ──────────────────────────────────────
78
+ const vectorSearch = async (query, topK) => {
79
+ return (await endpoint.call("host.vectorSearch", [query, topK]));
80
+ };
81
+ // ─── Capnweb-backed S2S WebSocket factory ──────────────────────────────
82
+ const createWebSocket = (url, opts) => {
83
+ const { port1, port2 } = new MessageChannel();
84
+ endpoint.notify("host.createWebSocket", [url, JSON.stringify(opts.headers)], [port2]);
85
+ return createBridgedS2sWebSocket(port1);
86
+ };
87
+ // ─── RPC handlers ──────────────────────────────────────────────────────
88
+ let wintercServer = null;
89
+ // Handle init from host — creates the WinterTC server
90
+ endpoint.handle("worker.init", (args) => {
91
+ const [env, clientHtml] = args;
92
+ wintercServer = createWintercServer({
93
+ agent,
94
+ env,
95
+ kv,
96
+ vectorSearch,
97
+ createWebSocket,
98
+ ...(clientHtml !== undefined ? { clientHtml } : {}),
99
+ });
100
+ return "ok";
101
+ });
102
+ // Handle HTTP request forwarding
103
+ endpoint.handle("worker.fetch", async (args) => {
104
+ if (!wintercServer)
105
+ throw new Error("Worker not initialized");
106
+ const [url, method, headers, body] = args;
107
+ const request = new Request(url, {
108
+ method,
109
+ headers,
110
+ ...(body ? { body } : {}),
111
+ });
112
+ const response = await wintercServer.fetch(request);
113
+ return {
114
+ status: response.status,
115
+ headers: Object.fromEntries(response.headers),
116
+ body: await response.text(),
117
+ };
118
+ });
119
+ // Handle new WebSocket client connection — port transferred from host
120
+ endpoint.handle("worker.handleWebSocket", (_args, ports) => {
121
+ if (!wintercServer)
122
+ throw new Error("Worker not initialized");
123
+ const [skipGreeting] = _args;
124
+ const port = ports[0];
125
+ if (!port)
126
+ throw new Error("No port transferred");
127
+ const ws = new BridgedWebSocket(port);
128
+ wintercServer.handleWebSocket(ws, { skipGreeting: skipGreeting ?? false });
129
+ return "ok";
130
+ });
131
+ }
132
+ //# sourceMappingURL=worker_shim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker_shim.js","sourceRoot":"","sources":["../../sdk/worker_shim.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * WebSocket session lifecycle handler.
3
+ *
4
+ * Cross-runtime: accepts a Logger parameter instead of importing `@std/log`.
5
+ * Audio validation is inlined (no dependency on server-side schemas).
6
+ *
7
+ * @module
8
+ */
9
+ import type { ClientSink, ReadyConfig } from "./protocol.ts";
10
+ import type { Logger } from "./runtime.ts";
11
+ import type { Session } from "./session.ts";
12
+ /**
13
+ * Minimal WebSocket interface accepted by {@linkcode wireSessionSocket}.
14
+ *
15
+ * Satisfied by the standard `WebSocket`, `BridgedWebSocket` (capnweb),
16
+ * and the `ws` npm package's WebSocket.
17
+ */
18
+ export type SessionWebSocket = {
19
+ readonly readyState: number;
20
+ send(data: string | ArrayBuffer | Uint8Array): void;
21
+ addEventListener(type: string, listener: EventListenerOrEventListenerObject): void;
22
+ };
23
+ /** Options for wiring a WebSocket to a session. */
24
+ export type WsSessionOptions = {
25
+ /** Map of active sessions (session is added on open, removed on close). */
26
+ sessions: Map<string, Session>;
27
+ /** Factory function to create a session for a given ID and client sink. */
28
+ createSession: (sessionId: string, client: ClientSink) => Session;
29
+ /** Protocol config sent to the client immediately on connect. */
30
+ readyConfig: ReadyConfig;
31
+ /** Additional key-value pairs included in log messages. */
32
+ logContext?: Record<string, string>;
33
+ /** Callback invoked when the WebSocket connection opens. */
34
+ onOpen?: () => void;
35
+ /** Callback invoked when the WebSocket connection closes. */
36
+ onClose?: () => void;
37
+ /** Logger instance. Defaults to console. */
38
+ logger?: Logger;
39
+ };
40
+ /**
41
+ * Attaches session lifecycle handlers to a native WebSocket using
42
+ * plain JSON text frames and binary audio frames.
43
+ *
44
+ * Connection flow:
45
+ * 1. WebSocket opens → server sends `{ type: "config", ...ReadyConfig }`
46
+ * 2. Client sets up audio → sends `{ type: "audio_ready" }`
47
+ * 3. If reconnecting → client sends `{ type: "history", messages: [...] }`
48
+ */
49
+ export declare function wireSessionSocket(ws: SessionWebSocket, opts: WsSessionOptions): void;
50
+ //# sourceMappingURL=ws_handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws_handler.d.ts","sourceRoot":"","sources":["../../sdk/ws_handler.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAiB,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,IAAI,CAAC;IACpD,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,kCAAkC,GAAG,IAAI,CAAC;CACpF,CAAC;AAYF,mDAAmD;AACnD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,2EAA2E;IAC3E,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,2EAA2E;IAC3E,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;IAClE,iEAAiE;IACjE,WAAW,EAAE,WAAW,CAAC;IACzB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AA+BF;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAmHpF"}
@@ -0,0 +1,156 @@
1
+ // Copyright 2025 the AAI authors. MIT license.
2
+ /**
3
+ * WebSocket session lifecycle handler.
4
+ *
5
+ * Cross-runtime: accepts a Logger parameter instead of importing `@std/log`.
6
+ * Audio validation is inlined (no dependency on server-side schemas).
7
+ *
8
+ * @module
9
+ */
10
+ import { ClientMessageSchema } from "./protocol.js";
11
+ import { consoleLogger } from "./runtime.js";
12
+ /** Max size for a single audio chunk from the browser (1 MB). */
13
+ const MAX_AUDIO_CHUNK_BYTES = 1_048_576;
14
+ /** Validate a PCM16 audio chunk: non-empty, within size bounds, even byte length. */
15
+ function isValidAudioChunk(data) {
16
+ return (data.byteLength > 0 && data.byteLength <= MAX_AUDIO_CHUNK_BYTES && data.byteLength % 2 === 0);
17
+ }
18
+ /**
19
+ * Creates a {@linkcode ClientSink} backed by a plain WebSocket.
20
+ *
21
+ * Text events are sent as JSON text frames; audio chunks are sent as
22
+ * binary frames (zero-copy).
23
+ */
24
+ function createClientSink(ws) {
25
+ return {
26
+ get open() {
27
+ return ws.readyState === 1;
28
+ },
29
+ event(e) {
30
+ if (ws.readyState === 1) {
31
+ ws.send(JSON.stringify(e));
32
+ }
33
+ },
34
+ playAudioChunk(chunk) {
35
+ if (ws.readyState === 1) {
36
+ ws.send(chunk);
37
+ }
38
+ },
39
+ playAudioDone() {
40
+ if (ws.readyState === 1) {
41
+ ws.send(JSON.stringify({ type: "audio_done" }));
42
+ }
43
+ },
44
+ };
45
+ }
46
+ /**
47
+ * Attaches session lifecycle handlers to a native WebSocket using
48
+ * plain JSON text frames and binary audio frames.
49
+ *
50
+ * Connection flow:
51
+ * 1. WebSocket opens → server sends `{ type: "config", ...ReadyConfig }`
52
+ * 2. Client sets up audio → sends `{ type: "audio_ready" }`
53
+ * 3. If reconnecting → client sends `{ type: "history", messages: [...] }`
54
+ */
55
+ export function wireSessionSocket(ws, opts) {
56
+ const { sessions, logger: log = consoleLogger } = opts;
57
+ const sessionId = crypto.randomUUID();
58
+ const sid = sessionId.slice(0, 8);
59
+ const ctx = opts.logContext ?? {};
60
+ let session = null;
61
+ function onOpen() {
62
+ opts.onOpen?.();
63
+ log.info("Session connected", { ...ctx, sid });
64
+ const client = createClientSink(ws);
65
+ session = opts.createSession(sessionId, client);
66
+ sessions.set(sessionId, session);
67
+ // Send config immediately — zero RTT
68
+ ws.send(JSON.stringify({ type: "config", ...opts.readyConfig }));
69
+ void session.start();
70
+ log.info("Session ready", { ...ctx, sid });
71
+ }
72
+ // readyState 1 = OPEN — socket already open (e.g. from ws handleUpgrade)
73
+ if (ws.readyState === 1) {
74
+ onOpen();
75
+ }
76
+ else {
77
+ ws.addEventListener("open", onOpen);
78
+ }
79
+ ws.addEventListener("message", (event) => {
80
+ if (!session)
81
+ return;
82
+ const msgEvent = event;
83
+ const { data } = msgEvent;
84
+ // Binary frame → raw PCM16 audio
85
+ // Node's ws package delivers Buffer; Deno/browsers deliver ArrayBuffer
86
+ // deno-lint-ignore no-explicit-any
87
+ const isBinary = globalThis.Buffer?.isBuffer(data) ||
88
+ data instanceof ArrayBuffer ||
89
+ data instanceof Uint8Array;
90
+ if (isBinary) {
91
+ const chunk = data instanceof Uint8Array
92
+ ? data
93
+ : new Uint8Array(data.buffer ?? data, data.byteOffset ?? 0, data.byteLength ?? data.byteLength);
94
+ if (!isValidAudioChunk(chunk)) {
95
+ log.warn("Invalid audio chunk, dropping", {
96
+ ...ctx,
97
+ sid,
98
+ bytes: chunk.byteLength,
99
+ aligned: chunk.byteLength % 2 === 0,
100
+ });
101
+ return;
102
+ }
103
+ session.onAudio(chunk);
104
+ return;
105
+ }
106
+ // Text frame → JSON message
107
+ if (typeof data !== "string")
108
+ return;
109
+ let json;
110
+ try {
111
+ json = JSON.parse(data);
112
+ }
113
+ catch {
114
+ log.warn("Invalid JSON from client", { ...ctx, sid });
115
+ return;
116
+ }
117
+ const parsed = ClientMessageSchema.safeParse(json);
118
+ if (!parsed.success) {
119
+ log.warn("Invalid client message", {
120
+ ...ctx,
121
+ sid,
122
+ error: parsed.error.message,
123
+ });
124
+ return;
125
+ }
126
+ const msg = parsed.data;
127
+ switch (msg.type) {
128
+ case "audio_ready":
129
+ session.onAudioReady();
130
+ break;
131
+ case "cancel":
132
+ session.onCancel();
133
+ break;
134
+ case "reset":
135
+ session.onReset();
136
+ break;
137
+ case "history":
138
+ session.onHistory(msg.messages);
139
+ break;
140
+ }
141
+ });
142
+ ws.addEventListener("close", () => {
143
+ log.info("Session disconnected", { ...ctx, sid });
144
+ if (session) {
145
+ void session.stop().finally(() => {
146
+ sessions.delete(sessionId);
147
+ });
148
+ }
149
+ opts.onClose?.();
150
+ });
151
+ ws.addEventListener("error", (event) => {
152
+ const msg = event instanceof ErrorEvent ? event.message : "WebSocket error";
153
+ log.error("WebSocket error", { ...ctx, sid, error: msg });
154
+ });
155
+ }
156
+ //# sourceMappingURL=ws_handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws_handler.js","sourceRoot":"","sources":["../../sdk/ws_handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type * as preact from "preact";
2
+ export declare function App(): preact.JSX.Element;
3
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../ui/_components/app.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,MAAM,QAAQ,CAAC;AAOtC,wBAAgB,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CA4BxC"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
+ import { useMountConfig } from "../mount_context.js";
3
+ import { useSession } from "../signals.js";
4
+ import { ChatView } from "./chat_view.js";
5
+ const AAI_LOGO = `▄▀█ ▄▀█ █\n█▀█ █▀█ █`;
6
+ export function App() {
7
+ const { started, start } = useSession();
8
+ const { title } = useMountConfig();
9
+ if (!started.value) {
10
+ return (_jsx("div", { class: "flex items-center justify-center h-screen bg-aai-bg font-aai", children: _jsxs("div", { class: "flex flex-col items-center gap-6 bg-aai-surface border border-aai-border rounded-lg px-12 py-10", children: [title ? (_jsx("span", { class: "text-lg font-semibold text-aai-primary", children: title })) : (_jsx("span", { class: "font-aai-mono text-lg leading-[1.1] font-bold text-aai-primary whitespace-pre", children: AAI_LOGO })), _jsx("button", { type: "button", class: "h-8 px-4 py-1.5 rounded-aai text-sm font-medium leading-[130%] cursor-pointer bg-aai-surface-hover text-aai-text-secondary border border-aai-border outline-none", onClick: start, children: "Start" })] }) }));
11
+ }
12
+ return _jsx(ChatView, {});
13
+ }
14
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../../ui/_components/app.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAiB,CAAC;AAE3C,MAAM,QAAQ,GAAG,sBAAsB,CAAC;AAExC,MAAM,UAAU,GAAG;IACjB,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,UAAU,EAAE,CAAC;IACxC,MAAM,EAAE,KAAK,EAAE,GAAG,cAAc,EAAE,CAAC;IAEnC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,CACL,cAAK,KAAK,EAAC,8DAA8D,YACvE,eAAK,KAAK,EAAC,iGAAiG,aACzG,KAAK,CAAC,CAAC,CAAC,CACP,eAAM,KAAK,EAAC,wCAAwC,YAAE,KAAK,GAAQ,CACpE,CAAC,CAAC,CAAC,CACF,eAAM,KAAK,EAAC,+EAA+E,YACxF,QAAQ,GACJ,CACR,EACD,iBACE,IAAI,EAAC,QAAQ,EACb,KAAK,EAAC,kKAAkK,EACxK,OAAO,EAAE,KAAK,sBAGP,IACL,GACF,CACP,CAAC;IACJ,CAAC;IAED,OAAO,KAAC,QAAQ,KAAG,CAAC;AACtB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type * as preact from "preact";
2
+ export declare function ChatView(): preact.JSX.Element;
3
+ //# sourceMappingURL=chat_view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat_view.d.ts","sourceRoot":"","sources":["../../../ui/_components/chat_view.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,MAAM,QAAQ,CAAC;AAUtC,wBAAgB,QAAQ,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAwB7C"}