@absolutejs/absolute 0.19.0-beta.226 → 0.19.0-beta.228

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 (75) hide show
  1. package/.absolutejs/eslint-cache +1 -0
  2. package/.absolutejs/prettier.cache.json +42 -19
  3. package/.absolutejs/vue-tsc.tsbuildinfo +1 -1
  4. package/.claude/settings.local.json +2 -1
  5. package/ROADMAP.md +0 -25
  6. package/dist/{Image-y5bdvj57.vue → Image-b3r6hxqk.vue} +6 -1
  7. package/dist/ai/index.js +529 -0
  8. package/dist/ai/index.js.map +13 -0
  9. package/dist/ai/providers/anthropic.js +396 -0
  10. package/dist/ai/providers/anthropic.js.map +10 -0
  11. package/dist/ai/providers/ollama.js +233 -0
  12. package/dist/ai/providers/ollama.js.map +10 -0
  13. package/dist/ai/providers/openai.js +355 -0
  14. package/dist/ai/providers/openai.js.map +10 -0
  15. package/dist/ai-client/angular/ai/index.js +532 -0
  16. package/dist/ai-client/react/ai/index.js +499 -0
  17. package/dist/ai-client/vue/ai/index.js +460 -0
  18. package/dist/angular/ai/index.js +668 -0
  19. package/dist/angular/ai/index.js.map +15 -0
  20. package/dist/angular/components/image.component.js +1 -1
  21. package/dist/angular/index.js +11 -1
  22. package/dist/angular/index.js.map +3 -3
  23. package/dist/build.js +48 -2
  24. package/dist/build.js.map +4 -4
  25. package/dist/index.js +50 -2
  26. package/dist/index.js.map +6 -6
  27. package/dist/react/ai/index.js +635 -0
  28. package/dist/react/ai/index.js.map +16 -0
  29. package/dist/react/components/index.js +11 -1
  30. package/dist/react/components/index.js.map +2 -2
  31. package/dist/react/hooks/index.js +11 -1
  32. package/dist/react/hooks/index.js.map +2 -2
  33. package/dist/react/index.js +11 -1
  34. package/dist/react/index.js.map +3 -3
  35. package/dist/src/ai/client/actions.d.ts +46 -0
  36. package/dist/src/ai/client/connection.d.ts +9 -0
  37. package/dist/src/ai/client/messageStore.d.ts +12 -0
  38. package/dist/src/ai/conversationManager.d.ts +11 -0
  39. package/dist/src/ai/index.d.ts +3 -0
  40. package/dist/src/ai/protocol.d.ts +4 -0
  41. package/dist/src/ai/providers/anthropic.d.ts +3 -0
  42. package/dist/src/ai/providers/ollama.d.ts +6 -0
  43. package/dist/src/ai/providers/openai.d.ts +7 -0
  44. package/dist/src/ai/streamAI.d.ts +2 -0
  45. package/dist/src/angular/ai/ai-stream.service.d.ts +15 -0
  46. package/dist/src/angular/ai/index.d.ts +1 -0
  47. package/dist/src/react/ai/AIStreamProvider.d.ts +13 -0
  48. package/dist/src/react/ai/index.d.ts +2 -0
  49. package/dist/src/react/ai/useAIStream.d.ts +8 -0
  50. package/dist/src/svelte/ai/createAIStream.d.ts +10 -0
  51. package/dist/src/svelte/ai/index.d.ts +1 -0
  52. package/dist/src/vue/ai/index.d.ts +1 -0
  53. package/dist/src/vue/ai/useAIStream.d.ts +22 -0
  54. package/dist/svelte/ai/index.js +590 -0
  55. package/dist/svelte/ai/index.js.map +15 -0
  56. package/dist/svelte/components/Image.svelte +6 -1
  57. package/dist/svelte/index.js +11 -1
  58. package/dist/svelte/index.js.map +3 -3
  59. package/dist/types/ai.d.ts +188 -0
  60. package/dist/types/anthropic.d.ts +18 -0
  61. package/dist/types/index.d.ts +1 -0
  62. package/dist/types/typeGuards.d.ts +3 -0
  63. package/dist/vue/ai/index.js +596 -0
  64. package/dist/vue/ai/index.js.map +15 -0
  65. package/dist/vue/components/Image.vue +6 -1
  66. package/dist/vue/components/index.js +12 -2
  67. package/dist/vue/components/index.js.map +1 -1
  68. package/dist/vue/index.js +11 -1
  69. package/dist/vue/index.js.map +3 -3
  70. package/package.json +36 -1
  71. package/scripts/build.ts +33 -0
  72. package/types/ai.ts +235 -0
  73. package/types/anthropic.ts +17 -0
  74. package/types/index.ts +1 -0
  75. package/types/typeGuards.ts +72 -1
@@ -256,7 +256,8 @@
256
256
  "Bash(git status:*)",
257
257
  "Bash(find /home/alexkahn/abs/docs -path */src/frontend/* -type f \\\\\\(-name *.ts -o -name *.tsx \\\\\\))",
258
258
  "Bash(find /home/alexkahn/abs/absolutejs/example -path */generated/* -name *.js -type f)",
259
- "mcp__playwright__browser_take_screenshot"
259
+ "mcp__playwright__browser_take_screenshot",
260
+ "Bash(xargs -r kill -9)"
260
261
  ]
261
262
  }
262
263
  }
package/ROADMAP.md CHANGED
@@ -4,31 +4,6 @@ Features missing from AbsoluteJS that Next.js provides, ordered by priority. Eac
4
4
 
5
5
  ---
6
6
 
7
- ## 2. P1 — Loading / Error / Not-Found States
8
-
9
- **What Next.js does:**
10
- Per-route-segment `loading.tsx` (shows during async data fetch), `error.tsx` (catches runtime errors with React error boundary), and `not-found.tsx` (404 page). These are automatic — drop the file in and it works.
11
-
12
- **What AbsoluteJS has today:**
13
- - Dev error overlay (`src/dev/client/errorOverlay.ts`) for compilation/runtime errors in development
14
- - SSR error page (`src/utils/ssrErrorPage.ts`) that returns a styled error page when server rendering fails
15
- - No production error boundaries, no loading states, no 404 handling
16
-
17
- **What needs to be built:**
18
- - A documented pattern for error boundaries per framework (React has `ErrorBoundary`, Vue has `onErrorCaptured`, Svelte has `<svelte:boundary>`, Angular has `ErrorHandler`)
19
- - A helper or wrapper that each page handler can use to catch SSR errors and render a user-defined error page instead of the generic one
20
- - A loading state pattern — for React this means Suspense boundaries with fallback UI; for streaming SSR, sending the shell immediately and streaming content as it resolves
21
- - A 404 handler — an Elysia catch-all route that renders a user-defined not-found page
22
- - Framework-specific examples showing how to wire each of these up
23
-
24
- **Files likely involved:**
25
- - `src/utils/ssrErrorPage.ts` — make it accept a user-defined error component
26
- - Each framework's `pageHandler.ts` — add error/loading handling to the streaming pipeline
27
- - New: `src/utils/notFoundPage.ts` or a convention for 404 pages
28
- - Example directory — add error/loading/not-found examples
29
-
30
- ---
31
-
32
7
  ## 3. P1 — Client-Side Navigation / SPA Mode with `<Link>`
33
8
 
34
9
  **What Next.js does:**
@@ -1,6 +1,11 @@
1
1
  <script setup lang="ts">
2
2
  import { computed, ref } from 'vue';
3
- import { DEFAULT_QUALITY, buildOptimizedUrl, generateBlurSvg, generateSrcSet } from '@absolutejs/absolute/image';
3
+ import {
4
+ DEFAULT_QUALITY,
5
+ buildOptimizedUrl,
6
+ generateBlurSvg,
7
+ generateSrcSet
8
+ } from '@absolutejs/absolute/image';
4
9
 
5
10
  type ImageLoader = (params: {
6
11
  src: string;
@@ -0,0 +1,529 @@
1
+ // @bun
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ function __accessProp(key) {
9
+ return this[key];
10
+ }
11
+ var __toESMCache_node;
12
+ var __toESMCache_esm;
13
+ var __toESM = (mod, isNodeMode, target) => {
14
+ var canCache = mod != null && typeof mod === "object";
15
+ if (canCache) {
16
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
17
+ var cached = cache.get(mod);
18
+ if (cached)
19
+ return cached;
20
+ }
21
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
22
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
23
+ for (let key of __getOwnPropNames(mod))
24
+ if (!__hasOwnProp.call(to, key))
25
+ __defProp(to, key, {
26
+ get: __accessProp.bind(mod, key),
27
+ enumerable: true
28
+ });
29
+ if (canCache)
30
+ cache.set(mod, to);
31
+ return to;
32
+ };
33
+ var __toCommonJS = (from) => {
34
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
35
+ if (entry)
36
+ return entry;
37
+ entry = __defProp({}, "__esModule", { value: true });
38
+ if (from && typeof from === "object" || typeof from === "function") {
39
+ for (var key of __getOwnPropNames(from))
40
+ if (!__hasOwnProp.call(entry, key))
41
+ __defProp(entry, key, {
42
+ get: __accessProp.bind(from, key),
43
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
44
+ });
45
+ }
46
+ __moduleCache.set(from, entry);
47
+ return entry;
48
+ };
49
+ var __moduleCache;
50
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
51
+ var __returnValue = (v) => v;
52
+ function __exportSetter(name, newValue) {
53
+ this[name] = __returnValue.bind(null, newValue);
54
+ }
55
+ var __export = (target, all) => {
56
+ for (var name in all)
57
+ __defProp(target, name, {
58
+ get: all[name],
59
+ enumerable: true,
60
+ configurable: true,
61
+ set: __exportSetter.bind(all, name)
62
+ });
63
+ };
64
+ var __legacyDecorateClassTS = function(decorators, target, key, desc) {
65
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
66
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
67
+ r = Reflect.decorate(decorators, target, key, desc);
68
+ else
69
+ for (var i = decorators.length - 1;i >= 0; i--)
70
+ if (d = decorators[i])
71
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
72
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
73
+ };
74
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
75
+ var __require = import.meta.require;
76
+
77
+ // types/typeGuards.ts
78
+ var isValidAIClientMessage = (data) => {
79
+ if (!data || typeof data !== "object") {
80
+ return false;
81
+ }
82
+ if (!("type" in data) || typeof data.type !== "string") {
83
+ return false;
84
+ }
85
+ switch (data.type) {
86
+ case "message":
87
+ return "content" in data && typeof data.content === "string";
88
+ case "cancel":
89
+ return "conversationId" in data && typeof data.conversationId === "string";
90
+ case "branch":
91
+ return "messageId" in data && typeof data.messageId === "string" && "content" in data && typeof data.content === "string" && "conversationId" in data && typeof data.conversationId === "string";
92
+ default:
93
+ return false;
94
+ }
95
+ }, isValidAIServerMessage = (data) => {
96
+ if (!data || typeof data !== "object") {
97
+ return false;
98
+ }
99
+ if (!("type" in data) || typeof data.type !== "string") {
100
+ return false;
101
+ }
102
+ switch (data.type) {
103
+ case "chunk":
104
+ return "content" in data && typeof data.content === "string" && "messageId" in data && "conversationId" in data;
105
+ case "tool_status":
106
+ return "name" in data && "status" in data && "messageId" in data && "conversationId" in data;
107
+ case "complete":
108
+ return "messageId" in data && "conversationId" in data;
109
+ case "error":
110
+ return "message" in data && typeof data.message === "string";
111
+ default:
112
+ return false;
113
+ }
114
+ }, isValidHMRClientMessage = (data) => {
115
+ if (!data || typeof data !== "object") {
116
+ return false;
117
+ }
118
+ if (!("type" in data) || typeof data.type !== "string") {
119
+ return false;
120
+ }
121
+ switch (data.type) {
122
+ case "ping":
123
+ return true;
124
+ case "ready":
125
+ return true;
126
+ case "request-rebuild":
127
+ return true;
128
+ case "hydration-error":
129
+ return true;
130
+ case "hmr-timing":
131
+ return true;
132
+ default:
133
+ return false;
134
+ }
135
+ };
136
+
137
+ // src/ai/protocol.ts
138
+ var generateId = () => crypto.randomUUID();
139
+ var parseAIMessage = (raw) => {
140
+ if (raw === null || raw === undefined) {
141
+ return null;
142
+ }
143
+ let text;
144
+ if (typeof raw === "string") {
145
+ text = raw;
146
+ } else if (raw instanceof ArrayBuffer) {
147
+ text = new TextDecoder().decode(raw);
148
+ } else if (ArrayBuffer.isView(raw)) {
149
+ text = new TextDecoder().decode(raw);
150
+ } else if (typeof raw === "object") {
151
+ if (isValidAIClientMessage(raw)) {
152
+ return raw;
153
+ }
154
+ return null;
155
+ } else {
156
+ return null;
157
+ }
158
+ try {
159
+ const parsed = JSON.parse(text);
160
+ if (isValidAIClientMessage(parsed)) {
161
+ return parsed;
162
+ }
163
+ return null;
164
+ } catch {
165
+ return null;
166
+ }
167
+ };
168
+ var serializeAIMessage = (msg) => JSON.stringify(msg);
169
+
170
+ // src/ai/streamAI.ts
171
+ var WS_OPEN = 1;
172
+ var BACKPRESSURE_THRESHOLD = 1048576;
173
+ var BACKPRESSURE_DELAY = 10;
174
+ var DEFAULT_MAX_TURNS = 10;
175
+ var INITIAL_TURN = 0;
176
+ var delay = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
177
+ var checkBackpressure = async (socket) => {
178
+ if (!("raw" in socket)) {
179
+ return;
180
+ }
181
+ const { raw } = socket;
182
+ if (raw && typeof raw === "object" && "bufferedAmount" in raw && typeof raw.bufferedAmount === "number" && raw.bufferedAmount > BACKPRESSURE_THRESHOLD) {
183
+ await delay(BACKPRESSURE_DELAY);
184
+ }
185
+ };
186
+ var sendMessage = async (socket, msg) => {
187
+ if (socket.readyState !== WS_OPEN) {
188
+ return false;
189
+ }
190
+ await checkBackpressure(socket);
191
+ socket.send(serializeAIMessage(msg));
192
+ return true;
193
+ };
194
+ var buildToolDefinitions = (tools) => Object.entries(tools).map(([name, def]) => ({
195
+ description: def.description,
196
+ input_schema: def.input,
197
+ name
198
+ }));
199
+ var extractTextContent = (chunk, onChunk) => {
200
+ if (!onChunk) {
201
+ return chunk.content;
202
+ }
203
+ const transformed = onChunk(chunk);
204
+ if (transformed && typeof transformed === "object" && "content" in transformed) {
205
+ return transformed.content;
206
+ }
207
+ return chunk.content;
208
+ };
209
+ var sendToolRunning = async (socket, toolName, toolInput, messageId, conversationId) => sendMessage(socket, {
210
+ conversationId,
211
+ input: toolInput,
212
+ messageId,
213
+ name: toolName,
214
+ status: "running",
215
+ type: "tool_status"
216
+ });
217
+ var sendToolComplete = async (socket, toolName, result, messageId, conversationId) => sendMessage(socket, {
218
+ conversationId,
219
+ messageId,
220
+ name: toolName,
221
+ result,
222
+ status: "complete",
223
+ type: "tool_status"
224
+ });
225
+ var executeTool = async (options, toolName, toolInput) => {
226
+ const toolDef = options.tools?.[toolName];
227
+ if (!toolDef) {
228
+ return `Error: unknown tool "${toolName}"`;
229
+ }
230
+ try {
231
+ return await toolDef.handler(toolInput);
232
+ } catch (err) {
233
+ return `Error: ${err instanceof Error ? err.message : String(err)}`;
234
+ }
235
+ };
236
+ var buildToolUseBlock = (toolUseId, toolName, toolInput) => [
237
+ {
238
+ id: toolUseId,
239
+ input: toolInput,
240
+ name: toolName,
241
+ type: "tool_use"
242
+ }
243
+ ];
244
+ var buildToolResultBlock = (toolUseId, result) => [
245
+ {
246
+ content: result,
247
+ tool_use_id: toolUseId,
248
+ type: "tool_result"
249
+ }
250
+ ];
251
+ var handleToolChunkText = (chunk, state, options, socket, messageId, conversationId) => {
252
+ const textContent = extractTextContent(chunk, options.onChunk);
253
+ state.currentFullResponse += textContent;
254
+ sendMessage(socket, {
255
+ content: textContent,
256
+ conversationId,
257
+ messageId,
258
+ type: "chunk"
259
+ });
260
+ };
261
+ var handleToolChunkToolUse = (chunk, state) => {
262
+ state.currentToolUseId = chunk.id;
263
+ state.currentToolName = chunk.name;
264
+ state.currentToolInput = chunk.input;
265
+ };
266
+ var processToolChunk = (chunk, state, options, socket, messageId, conversationId) => {
267
+ let hitAnotherTool = false;
268
+ switch (chunk.type) {
269
+ case "text":
270
+ handleToolChunkText(chunk, state, options, socket, messageId, conversationId);
271
+ break;
272
+ case "tool_use":
273
+ handleToolChunkToolUse(chunk, state);
274
+ hitAnotherTool = true;
275
+ break;
276
+ case "done":
277
+ state.currentUsage = chunk.usage;
278
+ break;
279
+ }
280
+ return hitAnotherTool;
281
+ };
282
+ var processToolTurn = async (socket, options, state, messageId, conversationId, signal) => {
283
+ await sendToolRunning(socket, state.currentToolName, state.currentToolInput, messageId, conversationId);
284
+ const result = await executeTool(options, state.currentToolName, state.currentToolInput);
285
+ await sendToolComplete(socket, state.currentToolName, result, messageId, conversationId);
286
+ options.onToolUse?.(state.currentToolName, state.currentToolInput, result);
287
+ state.currentMessages.push({
288
+ content: buildToolUseBlock(state.currentToolUseId, state.currentToolName, state.currentToolInput),
289
+ role: "assistant"
290
+ });
291
+ state.currentMessages.push({
292
+ content: buildToolResultBlock(state.currentToolUseId, result),
293
+ role: "user"
294
+ });
295
+ const toolDefs = options.tools ? buildToolDefinitions(options.tools) : undefined;
296
+ const stream = options.provider.stream({
297
+ messages: state.currentMessages,
298
+ model: options.model,
299
+ signal,
300
+ systemPrompt: options.systemPrompt,
301
+ tools: toolDefs
302
+ });
303
+ return consumeToolStream(stream, state, options, socket, messageId, conversationId, signal);
304
+ };
305
+ var consumeToolStream = async (stream, state, options, socket, messageId, conversationId, signal) => {
306
+ for await (const chunk of stream) {
307
+ if (signal.aborted)
308
+ break;
309
+ const isToolHit = processToolChunk(chunk, state, options, socket, messageId, conversationId);
310
+ if (isToolHit)
311
+ return true;
312
+ }
313
+ return false;
314
+ };
315
+ var shouldContinueToolLoop = (state, maxTurns, signal) => state.currentTurn < maxTurns && !signal.aborted;
316
+ var executeToolLoop = async (socket, options, messages, toolUseId, toolName, toolInput, messageId, conversationId, signal, fullResponse, turn) => {
317
+ const maxTurns = options.maxTurns ?? DEFAULT_MAX_TURNS;
318
+ const state = {
319
+ currentFullResponse: fullResponse,
320
+ currentMessages: [...messages],
321
+ currentToolInput: toolInput,
322
+ currentToolName: toolName,
323
+ currentToolUseId: toolUseId,
324
+ currentTurn: turn,
325
+ currentUsage: undefined
326
+ };
327
+ while (shouldContinueToolLoop(state, maxTurns, signal)) {
328
+ const hitAnotherTool = await processToolTurn(socket, options, state, messageId, conversationId, signal);
329
+ if (!hitAnotherTool) {
330
+ return {
331
+ fullResponse: state.currentFullResponse,
332
+ usage: state.currentUsage
333
+ };
334
+ }
335
+ state.currentTurn++;
336
+ }
337
+ return {
338
+ fullResponse: state.currentFullResponse,
339
+ usage: state.currentUsage
340
+ };
341
+ };
342
+ var sendComplete = async (socket, messageId, conversationId, usage) => sendMessage(socket, {
343
+ conversationId,
344
+ messageId,
345
+ type: "complete",
346
+ usage
347
+ });
348
+ var sendError = async (socket, err, messageId, conversationId) => sendMessage(socket, {
349
+ conversationId,
350
+ message: err instanceof Error ? err.message : String(err),
351
+ messageId,
352
+ type: "error"
353
+ });
354
+ var handleTextChunk = async (chunk, options, socket, messageId, conversationId) => {
355
+ const textContent = extractTextContent(chunk, options.onChunk);
356
+ await sendMessage(socket, {
357
+ content: textContent,
358
+ conversationId,
359
+ messageId,
360
+ type: "chunk"
361
+ });
362
+ return textContent;
363
+ };
364
+ var handleToolUseChunk = async (socket, options, messages, chunkId, chunkName, chunkInput, messageId, conversationId, signal, fullResponse) => {
365
+ const toolResult = await executeToolLoop(socket, options, messages, chunkId, chunkName, chunkInput, messageId, conversationId, signal, fullResponse, INITIAL_TURN);
366
+ await sendComplete(socket, messageId, conversationId, toolResult.usage);
367
+ options.onComplete?.(toolResult.fullResponse, toolResult.usage);
368
+ return toolResult;
369
+ };
370
+ var processStreamTextChunk = async (chunk, options, socket, messageId, conversationId) => {
371
+ const textContent = await handleTextChunk(chunk, options, socket, messageId, conversationId);
372
+ return textContent;
373
+ };
374
+ var processStreamToolUseChunk = async (chunk, socket, options, messages, messageId, conversationId, signal, fullResponse) => {
375
+ await handleToolUseChunk(socket, options, messages, chunk.id, chunk.name, chunk.input, messageId, conversationId, signal, fullResponse);
376
+ };
377
+ var processStream = async (socket, options, messages, messageId, conversationId, signal) => {
378
+ const toolDefs = options.tools ? buildToolDefinitions(options.tools) : undefined;
379
+ const stream = options.provider.stream({
380
+ messages,
381
+ model: options.model,
382
+ signal,
383
+ systemPrompt: options.systemPrompt,
384
+ tools: toolDefs
385
+ });
386
+ const result = await consumeStream(stream, options, socket, messages, messageId, conversationId, signal);
387
+ if (!result.earlyReturn) {
388
+ await sendComplete(socket, messageId, conversationId, result.usage);
389
+ options.onComplete?.(result.fullResponse, result.usage);
390
+ }
391
+ };
392
+ var consumeStreamChunk = async (chunk, options, socket, messages, messageId, conversationId, signal, fullResponse) => {
393
+ switch (chunk.type) {
394
+ case "text":
395
+ return processStreamTextChunk(chunk, options, socket, messageId, conversationId);
396
+ case "tool_use":
397
+ await processStreamToolUseChunk(chunk, socket, options, messages, messageId, conversationId, signal, fullResponse);
398
+ return { earlyReturn: true, fullResponse, usage: undefined };
399
+ case "done":
400
+ return { earlyReturn: false, fullResponse, usage: chunk.usage };
401
+ }
402
+ return "";
403
+ };
404
+ var applyStreamChunkResult = (result, state) => {
405
+ if (typeof result === "string") {
406
+ state.fullResponse += result;
407
+ return;
408
+ }
409
+ if (result.earlyReturn)
410
+ return result;
411
+ state.usage = result.usage;
412
+ return;
413
+ };
414
+ var consumeStream = async (stream, options, socket, messages, messageId, conversationId, signal) => {
415
+ const state = { fullResponse: "", usage: undefined };
416
+ for await (const chunk of stream) {
417
+ if (signal.aborted)
418
+ break;
419
+ const result = await consumeStreamChunk(chunk, options, socket, messages, messageId, conversationId, signal, state.fullResponse);
420
+ const earlyExit = applyStreamChunkResult(result, state);
421
+ if (earlyExit)
422
+ return earlyExit;
423
+ }
424
+ const finalResult = {
425
+ earlyReturn: false,
426
+ fullResponse: state.fullResponse,
427
+ usage: state.usage
428
+ };
429
+ return finalResult;
430
+ };
431
+ var streamAI = async (socket, conversationId, messageId, options) => {
432
+ const signal = options.signal ?? new AbortController().signal;
433
+ const messages = options.messages ? [...options.messages] : [];
434
+ try {
435
+ await processStream(socket, options, messages, messageId, conversationId, signal);
436
+ } catch (err) {
437
+ await handleStreamError(socket, err, messageId, conversationId, signal);
438
+ }
439
+ };
440
+ var handleStreamError = async (socket, err, messageId, conversationId, signal) => {
441
+ if (signal.aborted) {
442
+ await sendComplete(socket, messageId, conversationId);
443
+ return;
444
+ }
445
+ await sendError(socket, err, messageId, conversationId);
446
+ };
447
+ // src/ai/conversationManager.ts
448
+ var NOT_FOUND = -1;
449
+ var createConversationManager = () => {
450
+ const conversations = new Map;
451
+ const getOrCreate = (conversationId) => {
452
+ const id = conversationId ?? generateId();
453
+ let conversation = conversations.get(id);
454
+ if (!conversation) {
455
+ conversation = { id, messages: [] };
456
+ conversations.set(id, conversation);
457
+ }
458
+ return conversation;
459
+ };
460
+ const appendMessage = (conversationId, message) => {
461
+ const conversation = getOrCreate(conversationId);
462
+ conversation.messages.push(message);
463
+ };
464
+ const branch = (fromMessageId, sourceConversationId) => {
465
+ const source = conversations.get(sourceConversationId);
466
+ if (!source) {
467
+ return null;
468
+ }
469
+ const cutoffIndex = source.messages.findIndex((msg) => msg.id === fromMessageId);
470
+ if (cutoffIndex === NOT_FOUND) {
471
+ return null;
472
+ }
473
+ const newId = generateId();
474
+ const branchedMessages = source.messages.slice(0, cutoffIndex + 1).map((msg) => ({ ...msg, conversationId: newId }));
475
+ const newConversation = {
476
+ id: newId,
477
+ messages: branchedMessages
478
+ };
479
+ conversations.set(newId, newConversation);
480
+ return newId;
481
+ };
482
+ const emptyHistory = [];
483
+ const getHistory = (conversationId) => {
484
+ const conversation = conversations.get(conversationId);
485
+ if (!conversation) {
486
+ return emptyHistory;
487
+ }
488
+ const history = conversation.messages.map((msg) => ({
489
+ content: msg.content,
490
+ role: msg.role
491
+ }));
492
+ return history;
493
+ };
494
+ const getAbortController = (conversationId) => {
495
+ const conversation = getOrCreate(conversationId);
496
+ const controller = new AbortController;
497
+ conversation.activeStreamAbort = controller;
498
+ return controller;
499
+ };
500
+ const abort = (conversationId) => {
501
+ const conversation = conversations.get(conversationId);
502
+ if (conversation?.activeStreamAbort) {
503
+ conversation.activeStreamAbort.abort();
504
+ conversation.activeStreamAbort = undefined;
505
+ }
506
+ };
507
+ const get = (conversationId) => conversations.get(conversationId);
508
+ const remove = (conversationId) => conversations.delete(conversationId);
509
+ return {
510
+ abort,
511
+ appendMessage,
512
+ branch,
513
+ get,
514
+ getAbortController,
515
+ getHistory,
516
+ getOrCreate,
517
+ remove
518
+ };
519
+ };
520
+ export {
521
+ streamAI,
522
+ serializeAIMessage,
523
+ parseAIMessage,
524
+ generateId,
525
+ createConversationManager
526
+ };
527
+
528
+ //# debugId=522D65A44B1E30AF64756E2164756E21
529
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,13 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../types/typeGuards.ts", "../src/ai/protocol.ts", "../src/ai/streamAI.ts", "../src/ai/conversationManager.ts"],
4
+ "sourcesContent": [
5
+ "import type { AIClientMessage, AIServerMessage } from './ai';\nimport type { HMRClientMessage } from './messages';\n\n/* Type guard for AI client messages */\nexport const isValidAIClientMessage = (\n\tdata: unknown\n): data is AIClientMessage => {\n\tif (!data || typeof data !== 'object') {\n\t\treturn false;\n\t}\n\n\tif (!('type' in data) || typeof data.type !== 'string') {\n\t\treturn false;\n\t}\n\n\tswitch (data.type) {\n\t\tcase 'message':\n\t\t\treturn 'content' in data && typeof data.content === 'string';\n\t\tcase 'cancel':\n\t\t\treturn (\n\t\t\t\t'conversationId' in data &&\n\t\t\t\ttypeof data.conversationId === 'string'\n\t\t\t);\n\t\tcase 'branch':\n\t\t\treturn (\n\t\t\t\t'messageId' in data &&\n\t\t\t\ttypeof data.messageId === 'string' &&\n\t\t\t\t'content' in data &&\n\t\t\t\ttypeof data.content === 'string' &&\n\t\t\t\t'conversationId' in data &&\n\t\t\t\ttypeof data.conversationId === 'string'\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n};\n\n/* Type guard for AI server messages */\nexport const isValidAIServerMessage = (\n\tdata: unknown\n): data is AIServerMessage => {\n\tif (!data || typeof data !== 'object') {\n\t\treturn false;\n\t}\n\n\tif (!('type' in data) || typeof data.type !== 'string') {\n\t\treturn false;\n\t}\n\n\tswitch (data.type) {\n\t\tcase 'chunk':\n\t\t\treturn (\n\t\t\t\t'content' in data &&\n\t\t\t\ttypeof data.content === 'string' &&\n\t\t\t\t'messageId' in data &&\n\t\t\t\t'conversationId' in data\n\t\t\t);\n\t\tcase 'tool_status':\n\t\t\treturn (\n\t\t\t\t'name' in data &&\n\t\t\t\t'status' in data &&\n\t\t\t\t'messageId' in data &&\n\t\t\t\t'conversationId' in data\n\t\t\t);\n\t\tcase 'complete':\n\t\t\treturn 'messageId' in data && 'conversationId' in data;\n\t\tcase 'error':\n\t\t\treturn 'message' in data && typeof data.message === 'string';\n\t\tdefault:\n\t\t\treturn false;\n\t}\n};\n\n/* Type guard for HMR client messages */\nexport const isValidHMRClientMessage = (\n\tdata: unknown\n): data is HMRClientMessage => {\n\tif (!data || typeof data !== 'object') {\n\t\treturn false;\n\t}\n\n\tif (!('type' in data) || typeof data.type !== 'string') {\n\t\treturn false;\n\t}\n\n\tswitch (data.type) {\n\t\tcase 'ping':\n\t\t\treturn true;\n\t\tcase 'ready':\n\t\t\treturn true;\n\t\tcase 'request-rebuild':\n\t\t\treturn true;\n\t\tcase 'hydration-error':\n\t\t\treturn true;\n\t\tcase 'hmr-timing':\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n};\n",
6
+ "import type { AIServerMessage } from '../../types/ai';\nimport { isValidAIClientMessage } from '../../types/typeGuards';\n\nexport const generateId = () => crypto.randomUUID();\n\nexport const parseAIMessage = (raw: unknown) => {\n\tif (raw === null || raw === undefined) {\n\t\treturn null;\n\t}\n\n\tlet text: string;\n\n\tif (typeof raw === 'string') {\n\t\ttext = raw;\n\t} else if (raw instanceof ArrayBuffer) {\n\t\ttext = new TextDecoder().decode(raw);\n\t} else if (ArrayBuffer.isView(raw)) {\n\t\ttext = new TextDecoder().decode(raw);\n\t} else if (typeof raw === 'object') {\n\t\tif (isValidAIClientMessage(raw)) {\n\t\t\treturn raw;\n\t\t}\n\n\t\treturn null;\n\t} else {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(text);\n\n\t\tif (isValidAIClientMessage(parsed)) {\n\t\t\treturn parsed;\n\t\t}\n\n\t\treturn null;\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nexport const serializeAIMessage = (msg: AIServerMessage) => JSON.stringify(msg);\n",
7
+ "import type {\n\tAIChunk,\n\tAIProviderMessage,\n\tAIServerMessage,\n\tAITextChunk,\n\tAIToolMap,\n\tAIUsage,\n\tAIWebSocket,\n\tStreamAIOptions\n} from '../../types/ai';\nimport { serializeAIMessage } from './protocol';\n\nconst WS_OPEN = 1;\nconst BACKPRESSURE_THRESHOLD = 1_048_576;\nconst BACKPRESSURE_DELAY = 10;\nconst DEFAULT_MAX_TURNS = 10;\nconst INITIAL_TURN = 0;\n\nconst delay = (milliseconds: number) =>\n\t// eslint-disable-next-line promise/avoid-new\n\tnew Promise<void>((resolve) => setTimeout(resolve, milliseconds));\n\nconst checkBackpressure = async (socket: AIWebSocket) => {\n\tif (!('raw' in socket)) {\n\t\treturn;\n\t}\n\n\tconst { raw } = socket;\n\n\tif (\n\t\traw &&\n\t\ttypeof raw === 'object' &&\n\t\t'bufferedAmount' in raw &&\n\t\ttypeof raw.bufferedAmount === 'number' &&\n\t\traw.bufferedAmount > BACKPRESSURE_THRESHOLD\n\t) {\n\t\tawait delay(BACKPRESSURE_DELAY);\n\t}\n};\n\nconst sendMessage = async (socket: AIWebSocket, msg: AIServerMessage) => {\n\tif (socket.readyState !== WS_OPEN) {\n\t\treturn false;\n\t}\n\n\tawait checkBackpressure(socket);\n\n\tsocket.send(serializeAIMessage(msg));\n\n\treturn true;\n};\n\nconst buildToolDefinitions = (tools: AIToolMap) =>\n\tObject.entries(tools).map(([name, def]) => ({\n\t\tdescription: def.description,\n\t\tinput_schema: def.input,\n\t\tname\n\t}));\n\nconst extractTextContent = (\n\tchunk: AITextChunk,\n\tonChunk?: (chunk: AITextChunk) => AITextChunk | void\n) => {\n\tif (!onChunk) {\n\t\treturn chunk.content;\n\t}\n\n\tconst transformed = onChunk(chunk);\n\n\tif (\n\t\ttransformed &&\n\t\ttypeof transformed === 'object' &&\n\t\t'content' in transformed\n\t) {\n\t\treturn transformed.content;\n\t}\n\n\treturn chunk.content;\n};\n\nconst sendToolRunning = async (\n\tsocket: AIWebSocket,\n\ttoolName: string,\n\ttoolInput: unknown,\n\tmessageId: string,\n\tconversationId: string\n) =>\n\tsendMessage(socket, {\n\t\tconversationId,\n\t\tinput: toolInput,\n\t\tmessageId,\n\t\tname: toolName,\n\t\tstatus: 'running',\n\t\ttype: 'tool_status'\n\t});\n\nconst sendToolComplete = async (\n\tsocket: AIWebSocket,\n\ttoolName: string,\n\tresult: string,\n\tmessageId: string,\n\tconversationId: string\n) =>\n\tsendMessage(socket, {\n\t\tconversationId,\n\t\tmessageId,\n\t\tname: toolName,\n\t\tresult,\n\t\tstatus: 'complete',\n\t\ttype: 'tool_status'\n\t});\n\nconst executeTool = async (\n\toptions: StreamAIOptions,\n\ttoolName: string,\n\ttoolInput: unknown\n) => {\n\tconst toolDef = options.tools?.[toolName];\n\n\tif (!toolDef) {\n\t\treturn `Error: unknown tool \"${toolName}\"`;\n\t}\n\n\ttry {\n\t\treturn await toolDef.handler(toolInput);\n\t} catch (err) {\n\t\treturn `Error: ${err instanceof Error ? err.message : String(err)}`;\n\t}\n};\n\nconst buildToolUseBlock = (\n\ttoolUseId: string,\n\ttoolName: string,\n\ttoolInput: unknown\n) => [\n\t{\n\t\tid: toolUseId,\n\t\tinput: toolInput,\n\t\tname: toolName,\n\t\ttype: 'tool_use' as const\n\t}\n];\n\nconst buildToolResultBlock = (toolUseId: string, result: string) => [\n\t{\n\t\tcontent: result,\n\t\ttool_use_id: toolUseId,\n\t\ttype: 'tool_result' as const\n\t}\n];\n\ntype ToolLoopState = {\n\tcurrentFullResponse: string;\n\tcurrentMessages: AIProviderMessage[];\n\tcurrentToolInput: unknown;\n\tcurrentToolName: string;\n\tcurrentToolUseId: string;\n\tcurrentTurn: number;\n\tcurrentUsage: AIUsage | undefined;\n};\n\ntype ToolLoopResult = {\n\tfullResponse: string;\n\tusage: AIUsage | undefined;\n};\n\nconst handleToolChunkText = (\n\tchunk: AITextChunk,\n\tstate: ToolLoopState,\n\toptions: StreamAIOptions,\n\tsocket: AIWebSocket,\n\tmessageId: string,\n\tconversationId: string\n) => {\n\tconst textContent = extractTextContent(chunk, options.onChunk);\n\tstate.currentFullResponse += textContent;\n\tsendMessage(socket, {\n\t\tcontent: textContent,\n\t\tconversationId,\n\t\tmessageId,\n\t\ttype: 'chunk'\n\t});\n};\n\nconst handleToolChunkToolUse = (\n\tchunk: AIChunk & { type: 'tool_use' },\n\tstate: ToolLoopState\n) => {\n\tstate.currentToolUseId = chunk.id;\n\tstate.currentToolName = chunk.name;\n\tstate.currentToolInput = chunk.input;\n};\n\nconst processToolChunk = (\n\tchunk: AIChunk,\n\tstate: ToolLoopState,\n\toptions: StreamAIOptions,\n\tsocket: AIWebSocket,\n\tmessageId: string,\n\tconversationId: string\n) => {\n\tlet hitAnotherTool = false;\n\n\tswitch (chunk.type) {\n\t\tcase 'text':\n\t\t\thandleToolChunkText(\n\t\t\t\tchunk,\n\t\t\t\tstate,\n\t\t\t\toptions,\n\t\t\t\tsocket,\n\t\t\t\tmessageId,\n\t\t\t\tconversationId\n\t\t\t);\n\t\t\tbreak;\n\n\t\tcase 'tool_use':\n\t\t\thandleToolChunkToolUse(chunk, state);\n\t\t\thitAnotherTool = true;\n\t\t\tbreak;\n\n\t\tcase 'done':\n\t\t\tstate.currentUsage = chunk.usage;\n\t\t\tbreak;\n\t}\n\n\treturn hitAnotherTool;\n};\n\nconst processToolTurn = async (\n\tsocket: AIWebSocket,\n\toptions: StreamAIOptions,\n\tstate: ToolLoopState,\n\tmessageId: string,\n\tconversationId: string,\n\tsignal: AbortSignal\n) => {\n\tawait sendToolRunning(\n\t\tsocket,\n\t\tstate.currentToolName,\n\t\tstate.currentToolInput,\n\t\tmessageId,\n\t\tconversationId\n\t);\n\n\tconst result = await executeTool(\n\t\toptions,\n\t\tstate.currentToolName,\n\t\tstate.currentToolInput\n\t);\n\n\tawait sendToolComplete(\n\t\tsocket,\n\t\tstate.currentToolName,\n\t\tresult,\n\t\tmessageId,\n\t\tconversationId\n\t);\n\n\toptions.onToolUse?.(state.currentToolName, state.currentToolInput, result);\n\n\tstate.currentMessages.push({\n\t\tcontent: buildToolUseBlock(\n\t\t\tstate.currentToolUseId,\n\t\t\tstate.currentToolName,\n\t\t\tstate.currentToolInput\n\t\t),\n\t\trole: 'assistant'\n\t});\n\n\tstate.currentMessages.push({\n\t\tcontent: buildToolResultBlock(state.currentToolUseId, result),\n\t\trole: 'user'\n\t});\n\n\tconst toolDefs = options.tools\n\t\t? buildToolDefinitions(options.tools)\n\t\t: undefined;\n\n\tconst stream = options.provider.stream({\n\t\tmessages: state.currentMessages,\n\t\tmodel: options.model,\n\t\tsignal,\n\t\tsystemPrompt: options.systemPrompt,\n\t\ttools: toolDefs\n\t});\n\n\treturn consumeToolStream(\n\t\tstream,\n\t\tstate,\n\t\toptions,\n\t\tsocket,\n\t\tmessageId,\n\t\tconversationId,\n\t\tsignal\n\t);\n};\n\nconst consumeToolStream = async (\n\tstream: AsyncIterable<AIChunk>,\n\tstate: ToolLoopState,\n\toptions: StreamAIOptions,\n\tsocket: AIWebSocket,\n\tmessageId: string,\n\tconversationId: string,\n\tsignal: AbortSignal\n) => {\n\tfor await (const chunk of stream) {\n\t\tif (signal.aborted) break;\n\n\t\tconst isToolHit = processToolChunk(\n\t\t\tchunk,\n\t\t\tstate,\n\t\t\toptions,\n\t\t\tsocket,\n\t\t\tmessageId,\n\t\t\tconversationId\n\t\t);\n\n\t\tif (isToolHit) return true;\n\t}\n\n\treturn false;\n};\n\nconst shouldContinueToolLoop = (\n\tstate: ToolLoopState,\n\tmaxTurns: number,\n\tsignal: AbortSignal\n) => state.currentTurn < maxTurns && !signal.aborted;\n\nconst executeToolLoop = async (\n\tsocket: AIWebSocket,\n\toptions: StreamAIOptions,\n\tmessages: AIProviderMessage[],\n\ttoolUseId: string,\n\ttoolName: string,\n\ttoolInput: unknown,\n\tmessageId: string,\n\tconversationId: string,\n\tsignal: AbortSignal,\n\tfullResponse: string,\n\tturn: number\n): Promise<ToolLoopResult> => {\n\tconst maxTurns = options.maxTurns ?? DEFAULT_MAX_TURNS;\n\n\tconst state: ToolLoopState = {\n\t\tcurrentFullResponse: fullResponse,\n\t\tcurrentMessages: [...messages],\n\t\tcurrentToolInput: toolInput,\n\t\tcurrentToolName: toolName,\n\t\tcurrentToolUseId: toolUseId,\n\t\tcurrentTurn: turn,\n\t\tcurrentUsage: undefined\n\t};\n\n\twhile (shouldContinueToolLoop(state, maxTurns, signal)) {\n\t\t// eslint-disable-next-line no-await-in-loop\n\t\tconst hitAnotherTool = await processToolTurn(\n\t\t\tsocket,\n\t\t\toptions,\n\t\t\tstate,\n\t\t\tmessageId,\n\t\t\tconversationId,\n\t\t\tsignal\n\t\t);\n\n\t\tif (!hitAnotherTool) {\n\t\t\treturn {\n\t\t\t\tfullResponse: state.currentFullResponse,\n\t\t\t\tusage: state.currentUsage\n\t\t\t};\n\t\t}\n\n\t\tstate.currentTurn++;\n\t}\n\n\treturn {\n\t\tfullResponse: state.currentFullResponse,\n\t\tusage: state.currentUsage\n\t};\n};\n\nconst sendComplete = async (\n\tsocket: AIWebSocket,\n\tmessageId: string,\n\tconversationId: string,\n\tusage?: AIUsage\n) =>\n\tsendMessage(socket, {\n\t\tconversationId,\n\t\tmessageId,\n\t\ttype: 'complete',\n\t\tusage\n\t});\n\nconst sendError = async (\n\tsocket: AIWebSocket,\n\terr: unknown,\n\tmessageId: string,\n\tconversationId: string\n) =>\n\tsendMessage(socket, {\n\t\tconversationId,\n\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\tmessageId,\n\t\ttype: 'error'\n\t});\n\nconst handleTextChunk = async (\n\tchunk: AITextChunk,\n\toptions: StreamAIOptions,\n\tsocket: AIWebSocket,\n\tmessageId: string,\n\tconversationId: string\n) => {\n\tconst textContent = extractTextContent(chunk, options.onChunk);\n\n\tawait sendMessage(socket, {\n\t\tcontent: textContent,\n\t\tconversationId,\n\t\tmessageId,\n\t\ttype: 'chunk'\n\t});\n\n\treturn textContent;\n};\n\nconst handleToolUseChunk = async (\n\tsocket: AIWebSocket,\n\toptions: StreamAIOptions,\n\tmessages: AIProviderMessage[],\n\tchunkId: string,\n\tchunkName: string,\n\tchunkInput: unknown,\n\tmessageId: string,\n\tconversationId: string,\n\tsignal: AbortSignal,\n\tfullResponse: string\n) => {\n\tconst toolResult = await executeToolLoop(\n\t\tsocket,\n\t\toptions,\n\t\tmessages,\n\t\tchunkId,\n\t\tchunkName,\n\t\tchunkInput,\n\t\tmessageId,\n\t\tconversationId,\n\t\tsignal,\n\t\tfullResponse,\n\t\tINITIAL_TURN\n\t);\n\n\tawait sendComplete(socket, messageId, conversationId, toolResult.usage);\n\toptions.onComplete?.(toolResult.fullResponse, toolResult.usage);\n\n\treturn toolResult;\n};\n\nconst processStreamTextChunk = async (\n\tchunk: AITextChunk,\n\toptions: StreamAIOptions,\n\tsocket: AIWebSocket,\n\tmessageId: string,\n\tconversationId: string\n) => {\n\tconst textContent = await handleTextChunk(\n\t\tchunk,\n\t\toptions,\n\t\tsocket,\n\t\tmessageId,\n\t\tconversationId\n\t);\n\n\treturn textContent;\n};\n\nconst processStreamToolUseChunk = async (\n\tchunk: AIChunk & { type: 'tool_use' },\n\tsocket: AIWebSocket,\n\toptions: StreamAIOptions,\n\tmessages: AIProviderMessage[],\n\tmessageId: string,\n\tconversationId: string,\n\tsignal: AbortSignal,\n\tfullResponse: string\n) => {\n\tawait handleToolUseChunk(\n\t\tsocket,\n\t\toptions,\n\t\tmessages,\n\t\tchunk.id,\n\t\tchunk.name,\n\t\tchunk.input,\n\t\tmessageId,\n\t\tconversationId,\n\t\tsignal,\n\t\tfullResponse\n\t);\n};\n\nconst processStream = async (\n\tsocket: AIWebSocket,\n\toptions: StreamAIOptions,\n\tmessages: AIProviderMessage[],\n\tmessageId: string,\n\tconversationId: string,\n\tsignal: AbortSignal\n) => {\n\tconst toolDefs = options.tools\n\t\t? buildToolDefinitions(options.tools)\n\t\t: undefined;\n\n\tconst stream = options.provider.stream({\n\t\tmessages,\n\t\tmodel: options.model,\n\t\tsignal,\n\t\tsystemPrompt: options.systemPrompt,\n\t\ttools: toolDefs\n\t});\n\n\tconst result = await consumeStream(\n\t\tstream,\n\t\toptions,\n\t\tsocket,\n\t\tmessages,\n\t\tmessageId,\n\t\tconversationId,\n\t\tsignal\n\t);\n\n\tif (!result.earlyReturn) {\n\t\tawait sendComplete(socket, messageId, conversationId, result.usage);\n\t\toptions.onComplete?.(result.fullResponse, result.usage);\n\t}\n};\n\ntype ConsumeStreamResult = {\n\tearlyReturn: boolean;\n\tfullResponse: string;\n\tusage: AIUsage | undefined;\n};\n\nconst consumeStreamChunk = async (\n\tchunk: AIChunk,\n\toptions: StreamAIOptions,\n\tsocket: AIWebSocket,\n\tmessages: AIProviderMessage[],\n\tmessageId: string,\n\tconversationId: string,\n\tsignal: AbortSignal,\n\tfullResponse: string\n) => {\n\tswitch (chunk.type) {\n\t\tcase 'text':\n\t\t\treturn processStreamTextChunk(\n\t\t\t\tchunk,\n\t\t\t\toptions,\n\t\t\t\tsocket,\n\t\t\t\tmessageId,\n\t\t\t\tconversationId\n\t\t\t);\n\n\t\tcase 'tool_use':\n\t\t\tawait processStreamToolUseChunk(\n\t\t\t\tchunk,\n\t\t\t\tsocket,\n\t\t\t\toptions,\n\t\t\t\tmessages,\n\t\t\t\tmessageId,\n\t\t\t\tconversationId,\n\t\t\t\tsignal,\n\t\t\t\tfullResponse\n\t\t\t);\n\n\t\t\treturn { earlyReturn: true, fullResponse, usage: undefined };\n\n\t\tcase 'done':\n\t\t\treturn { earlyReturn: false, fullResponse, usage: chunk.usage };\n\t}\n\n\treturn '';\n};\n\ntype ConsumeStreamState = {\n\tfullResponse: string;\n\tusage: AIUsage | undefined;\n};\n\nconst applyStreamChunkResult = (\n\tresult: ConsumeStreamResult | string,\n\tstate: ConsumeStreamState\n) => {\n\tif (typeof result === 'string') {\n\t\tstate.fullResponse += result;\n\n\t\treturn undefined;\n\t}\n\n\tif (result.earlyReturn) return result;\n\n\tstate.usage = result.usage;\n\n\treturn undefined;\n};\n\nconst consumeStream = async (\n\tstream: AsyncIterable<AIChunk>,\n\toptions: StreamAIOptions,\n\tsocket: AIWebSocket,\n\tmessages: AIProviderMessage[],\n\tmessageId: string,\n\tconversationId: string,\n\tsignal: AbortSignal\n) => {\n\tconst state: ConsumeStreamState = { fullResponse: '', usage: undefined };\n\n\tfor await (const chunk of stream) {\n\t\tif (signal.aborted) break;\n\n\t\tconst result = await consumeStreamChunk(\n\t\t\tchunk,\n\t\t\toptions,\n\t\t\tsocket,\n\t\t\tmessages,\n\t\t\tmessageId,\n\t\t\tconversationId,\n\t\t\tsignal,\n\t\t\tstate.fullResponse\n\t\t);\n\t\tconst earlyExit = applyStreamChunkResult(result, state);\n\n\t\tif (earlyExit) return earlyExit;\n\t}\n\n\tconst finalResult: ConsumeStreamResult = {\n\t\tearlyReturn: false,\n\t\tfullResponse: state.fullResponse,\n\t\tusage: state.usage\n\t};\n\n\treturn finalResult;\n};\n\nexport const streamAI = async (\n\tsocket: AIWebSocket,\n\tconversationId: string,\n\tmessageId: string,\n\toptions: StreamAIOptions\n) => {\n\tconst signal = options.signal ?? new AbortController().signal;\n\n\tconst messages: AIProviderMessage[] = options.messages\n\t\t? [...options.messages]\n\t\t: [];\n\n\ttry {\n\t\tawait processStream(\n\t\t\tsocket,\n\t\t\toptions,\n\t\t\tmessages,\n\t\t\tmessageId,\n\t\t\tconversationId,\n\t\t\tsignal\n\t\t);\n\t} catch (err) {\n\t\tawait handleStreamError(socket, err, messageId, conversationId, signal);\n\t}\n};\n\nconst handleStreamError = async (\n\tsocket: AIWebSocket,\n\terr: unknown,\n\tmessageId: string,\n\tconversationId: string,\n\tsignal: AbortSignal\n) => {\n\tif (signal.aborted) {\n\t\tawait sendComplete(socket, messageId, conversationId);\n\n\t\treturn;\n\t}\n\n\tawait sendError(socket, err, messageId, conversationId);\n};\n",
8
+ "import type {\n\tAIConversation,\n\tAIMessage,\n\tAIProviderMessage\n} from '../../types/ai';\nimport { generateId } from './protocol';\n\nconst NOT_FOUND = -1;\n\nexport const createConversationManager = () => {\n\tconst conversations = new Map<string, AIConversation>();\n\n\tconst getOrCreate = (conversationId?: string) => {\n\t\tconst id = conversationId ?? generateId();\n\t\tlet conversation = conversations.get(id);\n\n\t\tif (!conversation) {\n\t\t\tconversation = { id, messages: [] };\n\t\t\tconversations.set(id, conversation);\n\t\t}\n\n\t\treturn conversation;\n\t};\n\n\tconst appendMessage = (conversationId: string, message: AIMessage) => {\n\t\tconst conversation = getOrCreate(conversationId);\n\t\tconversation.messages.push(message);\n\t};\n\n\tconst branch = (fromMessageId: string, sourceConversationId: string) => {\n\t\tconst source = conversations.get(sourceConversationId);\n\n\t\tif (!source) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst cutoffIndex = source.messages.findIndex(\n\t\t\t(msg) => msg.id === fromMessageId\n\t\t);\n\n\t\tif (cutoffIndex === NOT_FOUND) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst newId = generateId();\n\t\tconst branchedMessages = source.messages\n\t\t\t.slice(0, cutoffIndex + 1)\n\t\t\t.map((msg) => ({ ...msg, conversationId: newId }));\n\n\t\tconst newConversation: AIConversation = {\n\t\t\tid: newId,\n\t\t\tmessages: branchedMessages\n\t\t};\n\t\tconversations.set(newId, newConversation);\n\n\t\treturn newId;\n\t};\n\n\tconst emptyHistory: AIProviderMessage[] = [];\n\n\tconst getHistory = (conversationId: string) => {\n\t\tconst conversation = conversations.get(conversationId);\n\n\t\tif (!conversation) {\n\t\t\treturn emptyHistory;\n\t\t}\n\n\t\tconst history: AIProviderMessage[] = conversation.messages.map(\n\t\t\t(msg) => ({\n\t\t\t\tcontent: msg.content,\n\t\t\t\trole: msg.role\n\t\t\t})\n\t\t);\n\n\t\treturn history;\n\t};\n\n\tconst getAbortController = (conversationId: string) => {\n\t\tconst conversation = getOrCreate(conversationId);\n\t\tconst controller = new AbortController();\n\t\tconversation.activeStreamAbort = controller;\n\n\t\treturn controller;\n\t};\n\n\tconst abort = (conversationId: string) => {\n\t\tconst conversation = conversations.get(conversationId);\n\n\t\tif (conversation?.activeStreamAbort) {\n\t\t\tconversation.activeStreamAbort.abort();\n\t\t\tconversation.activeStreamAbort = undefined;\n\t\t}\n\t};\n\n\tconst get = (conversationId: string) => conversations.get(conversationId);\n\n\tconst remove = (conversationId: string) =>\n\t\tconversations.delete(conversationId);\n\n\treturn {\n\t\tabort,\n\t\tappendMessage,\n\t\tbranch,\n\t\tget,\n\t\tgetAbortController,\n\t\tgetHistory,\n\t\tgetOrCreate,\n\t\tremove\n\t};\n};\n"
9
+ ],
10
+ "mappings": "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",
11
+ "debugId": "522D65A44B1E30AF64756E2164756E21",
12
+ "names": []
13
+ }