@kubuild/ai 0.3.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 (68) hide show
  1. package/LICENSE +21 -0
  2. package/dist/chunk-27AY2KBI.js +500 -0
  3. package/dist/chunk-27AY2KBI.js.map +1 -0
  4. package/dist/chunk-JY4NHD3Q.js +227 -0
  5. package/dist/chunk-JY4NHD3Q.js.map +1 -0
  6. package/dist/chunk-UH24LHRY.js +443 -0
  7. package/dist/chunk-UH24LHRY.js.map +1 -0
  8. package/dist/client/ai-client.d.ts +59 -0
  9. package/dist/client/ai-client.d.ts.map +1 -0
  10. package/dist/client/index.cjs +254 -0
  11. package/dist/client/index.cjs.map +1 -0
  12. package/dist/client/index.d.ts +2 -0
  13. package/dist/client/index.d.ts.map +1 -0
  14. package/dist/client/index.js +9 -0
  15. package/dist/client/index.js.map +1 -0
  16. package/dist/core/index.d.ts +3 -0
  17. package/dist/core/index.d.ts.map +1 -0
  18. package/dist/core/normalizer.d.ts +9 -0
  19. package/dist/core/normalizer.d.ts.map +1 -0
  20. package/dist/core/prompt-compiler.d.ts +10 -0
  21. package/dist/core/prompt-compiler.d.ts.map +1 -0
  22. package/dist/index.cjs +468 -0
  23. package/dist/index.cjs.map +1 -0
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +23 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/react/index.cjs +584 -0
  29. package/dist/react/index.cjs.map +1 -0
  30. package/dist/react/index.d.ts +3 -0
  31. package/dist/react/index.d.ts.map +1 -0
  32. package/dist/react/index.js +336 -0
  33. package/dist/react/index.js.map +1 -0
  34. package/dist/react/use-ai-chat.d.ts +63 -0
  35. package/dist/react/use-ai-chat.d.ts.map +1 -0
  36. package/dist/react/use-ai-generator.d.ts +19 -0
  37. package/dist/react/use-ai-generator.d.ts.map +1 -0
  38. package/dist/server/adapters/anthropic.d.ts +30 -0
  39. package/dist/server/adapters/anthropic.d.ts.map +1 -0
  40. package/dist/server/adapters/base.d.ts +2 -0
  41. package/dist/server/adapters/base.d.ts.map +1 -0
  42. package/dist/server/adapters/custom.d.ts +18 -0
  43. package/dist/server/adapters/custom.d.ts.map +1 -0
  44. package/dist/server/adapters/gemini.d.ts +22 -0
  45. package/dist/server/adapters/gemini.d.ts.map +1 -0
  46. package/dist/server/adapters/index.cjs +529 -0
  47. package/dist/server/adapters/index.cjs.map +1 -0
  48. package/dist/server/adapters/index.d.ts +6 -0
  49. package/dist/server/adapters/index.d.ts.map +1 -0
  50. package/dist/server/adapters/index.js +13 -0
  51. package/dist/server/adapters/index.js.map +1 -0
  52. package/dist/server/adapters/openai.d.ts +26 -0
  53. package/dist/server/adapters/openai.d.ts.map +1 -0
  54. package/dist/server/adapters/stream-utils.d.ts +12 -0
  55. package/dist/server/adapters/stream-utils.d.ts.map +1 -0
  56. package/dist/server/engine.d.ts +59 -0
  57. package/dist/server/engine.d.ts.map +1 -0
  58. package/dist/server/handler.d.ts +66 -0
  59. package/dist/server/handler.d.ts.map +1 -0
  60. package/dist/server/index.cjs +1824 -0
  61. package/dist/server/index.cjs.map +1 -0
  62. package/dist/server/index.d.ts +4 -0
  63. package/dist/server/index.d.ts.map +1 -0
  64. package/dist/server/index.js +890 -0
  65. package/dist/server/index.js.map +1 -0
  66. package/dist/types.d.ts +184 -0
  67. package/dist/types.d.ts.map +1 -0
  68. package/package.json +94 -0
@@ -0,0 +1,584 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/react/index.ts
21
+ var react_exports = {};
22
+ __export(react_exports, {
23
+ useAiChat: () => useAiChat,
24
+ useAiGenerator: () => useAiGenerator
25
+ });
26
+ module.exports = __toCommonJS(react_exports);
27
+
28
+ // src/react/use-ai-generator.ts
29
+ var import_react = require("react");
30
+
31
+ // src/client/ai-client.ts
32
+ var KubuildAiClient = class {
33
+ endpoint;
34
+ headers;
35
+ fetchFn;
36
+ constructor(options) {
37
+ if (!options.endpoint) {
38
+ throw new Error("KubuildAiClient requires an endpoint URL");
39
+ }
40
+ this.endpoint = options.endpoint;
41
+ this.headers = options.headers;
42
+ this.fetchFn = options.fetch || globalThis.fetch.bind(globalThis);
43
+ }
44
+ async resolveHeaders() {
45
+ if (!this.headers) return {};
46
+ if (typeof this.headers === "function") {
47
+ return await this.headers();
48
+ }
49
+ return this.headers;
50
+ }
51
+ async sendRequest(body, signal) {
52
+ const dynamicHeaders = await this.resolveHeaders();
53
+ const res = await this.fetchFn(this.endpoint, {
54
+ method: "POST",
55
+ headers: {
56
+ "Content-Type": "application/json",
57
+ ...dynamicHeaders
58
+ },
59
+ body: JSON.stringify(body),
60
+ signal
61
+ });
62
+ const json = await res.json();
63
+ if (!res.ok || !json.success || !json.data) {
64
+ const errMessage = json?.error?.message || `HTTP ${res.status}: ${res.statusText}`;
65
+ const error = new Error(errMessage);
66
+ error.code = json?.error?.code;
67
+ error.details = json?.error?.details;
68
+ throw error;
69
+ }
70
+ return json.data;
71
+ }
72
+ /**
73
+ * Standard single-pass full page generator (non-streaming).
74
+ */
75
+ async generatePage(params, options) {
76
+ return this.sendRequest(
77
+ {
78
+ mode: "full-page",
79
+ ...params
80
+ },
81
+ options?.signal
82
+ );
83
+ }
84
+ /**
85
+ * Low-level SSE frame consumer shared by every streaming method on this client
86
+ * (`streamPage`, `chatStream`) — one transport implementation, reused rather than
87
+ * duplicated per stream "flavor" (STORA-515).
88
+ *
89
+ * Reads `res.body`, decodes `data: <json>\n\n` frames into `AiStreamEvent`s, and
90
+ * invokes `onEvent` for each one in arrival order. If `onEvent` throws (the
91
+ * conventional way callers signal a fatal `error` event), the throw propagates out of
92
+ * this method after the reader lock is released.
93
+ */
94
+ async consumeSse(res, onEvent) {
95
+ if (!res.body) {
96
+ throw new Error("Response body is null, cannot stream");
97
+ }
98
+ const reader = res.body.getReader();
99
+ const decoder = new TextDecoder();
100
+ let buffer = "";
101
+ try {
102
+ while (true) {
103
+ const { done, value } = await reader.read();
104
+ if (done) break;
105
+ buffer += decoder.decode(value, { stream: true });
106
+ const parts = buffer.split("\n\n");
107
+ buffer = parts.pop() || "";
108
+ for (const part of parts) {
109
+ const lines = part.split("\n");
110
+ for (const line of lines) {
111
+ if (line.startsWith("data: ")) {
112
+ let event;
113
+ try {
114
+ event = JSON.parse(line.slice(6).trim());
115
+ } catch {
116
+ continue;
117
+ }
118
+ onEvent(event);
119
+ }
120
+ }
121
+ }
122
+ }
123
+ } finally {
124
+ reader.releaseLock();
125
+ }
126
+ }
127
+ /**
128
+ * Progressive section streamer (SSE).
129
+ * Calls callbacks on each event (status, metadata, section, complete).
130
+ */
131
+ async streamPage(params, callbacks, options) {
132
+ const dynamicHeaders = await this.resolveHeaders();
133
+ const res = await this.fetchFn(this.endpoint, {
134
+ method: "POST",
135
+ headers: {
136
+ "Content-Type": "application/json",
137
+ ...dynamicHeaders
138
+ },
139
+ body: JSON.stringify({
140
+ mode: "full-page",
141
+ stream: true,
142
+ ...params
143
+ }),
144
+ signal: options?.signal
145
+ });
146
+ if (!res.ok) {
147
+ const errText = await res.text().catch(() => "");
148
+ const err = new Error(`Streaming failed [${res.status} ${res.statusText}]: ${errText}`);
149
+ callbacks?.onError?.(err);
150
+ throw err;
151
+ }
152
+ let finalDoc = null;
153
+ await this.consumeSse(res, (event) => {
154
+ if (event.type === "status") {
155
+ callbacks?.onStatus?.(event.message);
156
+ } else if (event.type === "metadata") {
157
+ callbacks?.onMetadata?.(event.metadata, event.rootPageNode);
158
+ } else if (event.type === "section") {
159
+ callbacks?.onSection?.(event.section, event.index, event.total);
160
+ } else if (event.type === "complete") {
161
+ finalDoc = event.document;
162
+ callbacks?.onComplete?.(event.document);
163
+ } else if (event.type === "error") {
164
+ const err = new Error(event.error.message || "Stream error");
165
+ err.code = event.error.code;
166
+ callbacks?.onError?.(err);
167
+ throw err;
168
+ }
169
+ });
170
+ if (!finalDoc) {
171
+ throw new Error("Stream ended without receiving complete document");
172
+ }
173
+ return finalDoc;
174
+ }
175
+ /**
176
+ * Token-level streaming chat (STORA-515). Calls `onChatChunk` for every partial chunk
177
+ * as it arrives and resolves with the fully assembled assistant `AiChatMessage` once
178
+ * the stream's terminal `chat-complete` event is received. Reuses the exact same SSE
179
+ * transport as `streamPage` via `consumeSse` — no separate parsing path.
180
+ */
181
+ async chatStream(params, callbacks, options) {
182
+ const dynamicHeaders = await this.resolveHeaders();
183
+ const res = await this.fetchFn(this.endpoint, {
184
+ method: "POST",
185
+ headers: {
186
+ "Content-Type": "application/json",
187
+ ...dynamicHeaders
188
+ },
189
+ body: JSON.stringify({
190
+ mode: "chat",
191
+ stream: true,
192
+ ...params
193
+ }),
194
+ signal: options?.signal
195
+ });
196
+ if (!res.ok) {
197
+ const errText = await res.text().catch(() => "");
198
+ const err = new Error(`Chat streaming failed [${res.status} ${res.statusText}]: ${errText}`);
199
+ callbacks?.onError?.(err);
200
+ throw err;
201
+ }
202
+ let finalMessage = null;
203
+ await this.consumeSse(res, (event) => {
204
+ if (event.type === "chat-chunk") {
205
+ callbacks?.onChatChunk?.(event.delta, event.content);
206
+ } else if (event.type === "chat-complete") {
207
+ finalMessage = event.message;
208
+ callbacks?.onChatComplete?.(event.message);
209
+ } else if (event.type === "error") {
210
+ const err = new Error(event.error.message || "Stream error");
211
+ err.code = event.error.code;
212
+ callbacks?.onError?.(err);
213
+ throw err;
214
+ }
215
+ });
216
+ if (!finalMessage) {
217
+ throw new Error("Chat stream ended without receiving a complete message");
218
+ }
219
+ return finalMessage;
220
+ }
221
+ async generateSection(params, options) {
222
+ return this.sendRequest(
223
+ {
224
+ mode: "section",
225
+ ...params
226
+ },
227
+ options?.signal
228
+ );
229
+ }
230
+ async refactorNode(params, options) {
231
+ return this.sendRequest(
232
+ {
233
+ mode: "refactor",
234
+ ...params
235
+ },
236
+ options?.signal
237
+ );
238
+ }
239
+ async chat(params, options) {
240
+ return this.sendRequest(
241
+ {
242
+ mode: "chat",
243
+ ...params
244
+ },
245
+ options?.signal
246
+ );
247
+ }
248
+ };
249
+ function createAiClient(options) {
250
+ return new KubuildAiClient(options);
251
+ }
252
+
253
+ // src/react/use-ai-generator.ts
254
+ function useAiGenerator(options) {
255
+ const [isGenerating, setIsGenerating] = (0, import_react.useState)(false);
256
+ const [isStreaming, setIsStreaming] = (0, import_react.useState)(false);
257
+ const [currentStep, setCurrentStep] = (0, import_react.useState)("");
258
+ const [error, setError] = (0, import_react.useState)(null);
259
+ const abortControllerRef = (0, import_react.useRef)(null);
260
+ const clientRef = (0, import_react.useRef)(createAiClient(options));
261
+ const cancel = (0, import_react.useCallback)(() => {
262
+ if (abortControllerRef.current) {
263
+ abortControllerRef.current.abort();
264
+ abortControllerRef.current = null;
265
+ setIsGenerating(false);
266
+ setIsStreaming(false);
267
+ setCurrentStep("");
268
+ }
269
+ }, []);
270
+ const generatePage = (0, import_react.useCallback)(
271
+ async (params) => {
272
+ cancel();
273
+ const ac = new AbortController();
274
+ abortControllerRef.current = ac;
275
+ setIsGenerating(true);
276
+ setIsStreaming(false);
277
+ setError(null);
278
+ setCurrentStep("Generating full page...");
279
+ try {
280
+ const doc = await clientRef.current.generatePage(params, {
281
+ signal: ac.signal
282
+ });
283
+ options.onSuccess?.(doc);
284
+ return doc;
285
+ } catch (err) {
286
+ if (ac.signal.aborted) return null;
287
+ const e = err instanceof Error ? err : new Error(String(err));
288
+ setError(e);
289
+ options.onError?.(e);
290
+ return null;
291
+ } finally {
292
+ if (abortControllerRef.current === ac) {
293
+ setIsGenerating(false);
294
+ setCurrentStep("");
295
+ abortControllerRef.current = null;
296
+ }
297
+ }
298
+ },
299
+ [cancel, options]
300
+ );
301
+ const streamPage = (0, import_react.useCallback)(
302
+ async (params, streamCallbacks) => {
303
+ cancel();
304
+ const ac = new AbortController();
305
+ abortControllerRef.current = ac;
306
+ setIsGenerating(true);
307
+ setIsStreaming(true);
308
+ setError(null);
309
+ setCurrentStep("Connecting to AI stream...");
310
+ try {
311
+ const doc = await clientRef.current.streamPage(
312
+ params,
313
+ {
314
+ onStatus: (msg) => {
315
+ setCurrentStep(msg);
316
+ streamCallbacks?.onStatus?.(msg);
317
+ },
318
+ onMetadata: (metadata, rootPage) => {
319
+ streamCallbacks?.onMetadata?.(metadata, rootPage);
320
+ },
321
+ onSection: (section, index, total) => {
322
+ setCurrentStep(`Section ${index + 1}/${total} rendered`);
323
+ streamCallbacks?.onSection?.(section, index, total);
324
+ },
325
+ onComplete: (completedDoc) => {
326
+ setCurrentStep("Completed");
327
+ streamCallbacks?.onComplete?.(completedDoc);
328
+ options.onSuccess?.(completedDoc);
329
+ },
330
+ onError: (err) => {
331
+ setError(err);
332
+ streamCallbacks?.onError?.(err);
333
+ options.onError?.(err);
334
+ }
335
+ },
336
+ { signal: ac.signal }
337
+ );
338
+ return doc;
339
+ } catch (err) {
340
+ if (ac.signal.aborted) return null;
341
+ const e = err instanceof Error ? err : new Error(String(err));
342
+ setError(e);
343
+ options.onError?.(e);
344
+ return null;
345
+ } finally {
346
+ if (abortControllerRef.current === ac) {
347
+ setIsGenerating(false);
348
+ setIsStreaming(false);
349
+ setCurrentStep("");
350
+ abortControllerRef.current = null;
351
+ }
352
+ }
353
+ },
354
+ [cancel, options]
355
+ );
356
+ const generateSection = (0, import_react.useCallback)(
357
+ async (params) => {
358
+ cancel();
359
+ const ac = new AbortController();
360
+ abortControllerRef.current = ac;
361
+ setIsGenerating(true);
362
+ setIsStreaming(false);
363
+ setError(null);
364
+ setCurrentStep("Generating section...");
365
+ try {
366
+ const node = await clientRef.current.generateSection(params, {
367
+ signal: ac.signal
368
+ });
369
+ options.onSuccess?.(node);
370
+ return node;
371
+ } catch (err) {
372
+ if (ac.signal.aborted) return null;
373
+ const e = err instanceof Error ? err : new Error(String(err));
374
+ setError(e);
375
+ options.onError?.(e);
376
+ return null;
377
+ } finally {
378
+ if (abortControllerRef.current === ac) {
379
+ setIsGenerating(false);
380
+ setCurrentStep("");
381
+ abortControllerRef.current = null;
382
+ }
383
+ }
384
+ },
385
+ [cancel, options]
386
+ );
387
+ const refactorNode = (0, import_react.useCallback)(
388
+ async (params) => {
389
+ cancel();
390
+ const ac = new AbortController();
391
+ abortControllerRef.current = ac;
392
+ setIsGenerating(true);
393
+ setIsStreaming(false);
394
+ setError(null);
395
+ setCurrentStep("Refactoring node...");
396
+ try {
397
+ const node = await clientRef.current.refactorNode(params, {
398
+ signal: ac.signal
399
+ });
400
+ options.onSuccess?.(node);
401
+ return node;
402
+ } catch (err) {
403
+ if (ac.signal.aborted) return null;
404
+ const e = err instanceof Error ? err : new Error(String(err));
405
+ setError(e);
406
+ options.onError?.(e);
407
+ return null;
408
+ } finally {
409
+ if (abortControllerRef.current === ac) {
410
+ setIsGenerating(false);
411
+ setCurrentStep("");
412
+ abortControllerRef.current = null;
413
+ }
414
+ }
415
+ },
416
+ [cancel, options]
417
+ );
418
+ return {
419
+ generatePage,
420
+ streamPage,
421
+ generateSection,
422
+ refactorNode,
423
+ isGenerating,
424
+ isStreaming,
425
+ currentStep,
426
+ error,
427
+ cancel
428
+ };
429
+ }
430
+
431
+ // src/react/use-ai-chat.ts
432
+ var import_react2 = require("react");
433
+ function useAiChat(options) {
434
+ const [messages, setMessages] = (0, import_react2.useState)(options.initialMessages || []);
435
+ const [isLoading, setIsLoading] = (0, import_react2.useState)(false);
436
+ const [isStreaming, setIsStreaming] = (0, import_react2.useState)(false);
437
+ const [error, setError] = (0, import_react2.useState)(null);
438
+ const abortControllerRef = (0, import_react2.useRef)(null);
439
+ const clientRef = (0, import_react2.useRef)(createAiClient(options));
440
+ const historyStorageRef = (0, import_react2.useRef)(options.historyStorage);
441
+ historyStorageRef.current = options.historyStorage;
442
+ const persistHistory = (0, import_react2.useCallback)((history) => {
443
+ const adapter = historyStorageRef.current;
444
+ if (!adapter) return;
445
+ try {
446
+ void Promise.resolve(adapter.saveHistory(history)).catch(() => void 0);
447
+ } catch {
448
+ }
449
+ }, []);
450
+ (0, import_react2.useEffect)(() => {
451
+ const adapter = historyStorageRef.current;
452
+ if (!adapter) return;
453
+ let cancelled = false;
454
+ Promise.resolve(adapter.loadHistory()).then((loaded) => {
455
+ if (!cancelled && Array.isArray(loaded) && loaded.length > 0) {
456
+ setMessages(loaded);
457
+ }
458
+ }).catch((err) => {
459
+ if (cancelled) return;
460
+ const e = err instanceof Error ? err : new Error(String(err));
461
+ options.onError?.(e);
462
+ });
463
+ return () => {
464
+ cancelled = true;
465
+ };
466
+ }, []);
467
+ const cancel = (0, import_react2.useCallback)(() => {
468
+ if (abortControllerRef.current) {
469
+ abortControllerRef.current.abort();
470
+ abortControllerRef.current = null;
471
+ setIsLoading(false);
472
+ setIsStreaming(false);
473
+ }
474
+ }, []);
475
+ const clearMessages = (0, import_react2.useCallback)(() => {
476
+ setMessages([]);
477
+ setError(null);
478
+ persistHistory([]);
479
+ }, [persistHistory]);
480
+ const sendMessage = (0, import_react2.useCallback)(
481
+ async (content, sendOptions) => {
482
+ if (!content.trim()) return null;
483
+ cancel();
484
+ const ac = new AbortController();
485
+ abortControllerRef.current = ac;
486
+ const userMessage = {
487
+ role: "user",
488
+ content: content.trim(),
489
+ timestamp: Date.now()
490
+ };
491
+ const updatedHistory = [...messages, userMessage];
492
+ setMessages(updatedHistory);
493
+ setIsLoading(true);
494
+ setError(null);
495
+ persistHistory(updatedHistory);
496
+ const useStream = sendOptions?.stream !== false;
497
+ try {
498
+ if (useStream) {
499
+ setIsStreaming(true);
500
+ let assistantIndex = -1;
501
+ setMessages((prev) => {
502
+ assistantIndex = prev.length;
503
+ return [...prev, { role: "assistant", content: "", timestamp: Date.now() }];
504
+ });
505
+ const finalMessage = await clientRef.current.chatStream(
506
+ {
507
+ messages: updatedHistory,
508
+ currentDocument: sendOptions?.currentDocument,
509
+ selectedNodeId: sendOptions?.selectedNodeId,
510
+ systemPrompt: sendOptions?.systemPrompt
511
+ },
512
+ {
513
+ onChatChunk: (delta, contentSoFar) => {
514
+ options.onChunk?.(delta, contentSoFar);
515
+ setMessages((prev) => {
516
+ if (assistantIndex < 0 || assistantIndex >= prev.length) return prev;
517
+ const next = prev.slice();
518
+ next[assistantIndex] = { ...next[assistantIndex], content: contentSoFar };
519
+ return next;
520
+ });
521
+ },
522
+ onChatComplete: (message) => {
523
+ setMessages((prev) => {
524
+ if (assistantIndex < 0 || assistantIndex >= prev.length) return prev;
525
+ const next = prev.slice();
526
+ next[assistantIndex] = message;
527
+ return next;
528
+ });
529
+ }
530
+ },
531
+ { signal: ac.signal }
532
+ );
533
+ persistHistory([...updatedHistory, finalMessage]);
534
+ options.onMessage?.(finalMessage);
535
+ return finalMessage;
536
+ }
537
+ const response = await clientRef.current.chat(
538
+ {
539
+ messages: updatedHistory,
540
+ currentDocument: sendOptions?.currentDocument,
541
+ selectedNodeId: sendOptions?.selectedNodeId,
542
+ systemPrompt: sendOptions?.systemPrompt
543
+ },
544
+ { signal: ac.signal }
545
+ );
546
+ const assistantMsg = response.message;
547
+ setMessages((prev) => [...prev, assistantMsg]);
548
+ persistHistory([...updatedHistory, assistantMsg]);
549
+ options.onMessage?.(assistantMsg);
550
+ return assistantMsg;
551
+ } catch (err) {
552
+ if (ac.signal.aborted) return null;
553
+ const e = err instanceof Error ? err : new Error(String(err));
554
+ setError(e);
555
+ options.onError?.(e);
556
+ return null;
557
+ } finally {
558
+ if (abortControllerRef.current === ac) {
559
+ setIsLoading(false);
560
+ setIsStreaming(false);
561
+ abortControllerRef.current = null;
562
+ }
563
+ }
564
+ },
565
+ [cancel, messages, options, persistHistory]
566
+ );
567
+ return {
568
+ messages,
569
+ sendMessage,
570
+ isLoading,
571
+ /** Whether the in-flight `sendMessage` call is a token-level stream (STORA-516). */
572
+ isStreaming,
573
+ error,
574
+ cancel,
575
+ clearMessages,
576
+ setMessages
577
+ };
578
+ }
579
+ // Annotate the CommonJS export names for ESM import in node:
580
+ 0 && (module.exports = {
581
+ useAiChat,
582
+ useAiGenerator
583
+ });
584
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/react/index.ts","../../src/react/use-ai-generator.ts","../../src/client/ai-client.ts","../../src/react/use-ai-chat.ts"],"sourcesContent":["export * from './use-ai-generator';\nexport * from './use-ai-chat';\n\n","import { useState, useCallback, useRef } from 'react';\nimport type { PageDocument, Node } from '@kubuild/schema';\nimport type {\n AiGeneratePageRequest,\n AiGenerateSectionRequest,\n AiRefactorNodeRequest,\n AiStreamCallbacks,\n} from '../types';\nimport { createAiClient, type AiClientOptions, KubuildAiClient } from '../client/ai-client';\n\nexport interface UseAiGeneratorOptions extends AiClientOptions {\n onSuccess?: (data: PageDocument | Node) => void;\n onError?: (error: Error) => void;\n}\n\nexport function useAiGenerator(options: UseAiGeneratorOptions) {\n const [isGenerating, setIsGenerating] = useState(false);\n const [isStreaming, setIsStreaming] = useState(false);\n const [currentStep, setCurrentStep] = useState<string>('');\n const [error, setError] = useState<Error | null>(null);\n\n const abortControllerRef = useRef<AbortController | null>(null);\n const clientRef = useRef<KubuildAiClient>(createAiClient(options));\n\n // Cancel any in-flight request\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n setIsGenerating(false);\n setIsStreaming(false);\n setCurrentStep('');\n }\n }, []);\n\n /**\n * Standard full page generator (non-streaming).\n */\n const generatePage = useCallback(\n async (params: AiGeneratePageRequest): Promise<PageDocument | null> => {\n cancel();\n const ac = new AbortController();\n abortControllerRef.current = ac;\n\n setIsGenerating(true);\n setIsStreaming(false);\n setError(null);\n setCurrentStep('Generating full page...');\n\n try {\n const doc = await clientRef.current.generatePage(params, {\n signal: ac.signal,\n });\n options.onSuccess?.(doc);\n return doc;\n } catch (err: unknown) {\n if (ac.signal.aborted) return null;\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n options.onError?.(e);\n return null;\n } finally {\n if (abortControllerRef.current === ac) {\n setIsGenerating(false);\n setCurrentStep('');\n abortControllerRef.current = null;\n }\n }\n },\n [cancel, options],\n );\n\n /**\n * Progressive section streamer (SSE).\n * Calls callbacks on each step (onStatus, onMetadata, onSection, onComplete).\n */\n const streamPage = useCallback(\n async (\n params: AiGeneratePageRequest,\n streamCallbacks?: AiStreamCallbacks,\n ): Promise<PageDocument | null> => {\n cancel();\n const ac = new AbortController();\n abortControllerRef.current = ac;\n\n setIsGenerating(true);\n setIsStreaming(true);\n setError(null);\n setCurrentStep('Connecting to AI stream...');\n\n try {\n const doc = await clientRef.current.streamPage(\n params,\n {\n onStatus: (msg) => {\n setCurrentStep(msg);\n streamCallbacks?.onStatus?.(msg);\n },\n onMetadata: (metadata, rootPage) => {\n streamCallbacks?.onMetadata?.(metadata, rootPage);\n },\n onSection: (section, index, total) => {\n setCurrentStep(`Section ${index + 1}/${total} rendered`);\n streamCallbacks?.onSection?.(section, index, total);\n },\n onComplete: (completedDoc) => {\n setCurrentStep('Completed');\n streamCallbacks?.onComplete?.(completedDoc);\n options.onSuccess?.(completedDoc);\n },\n onError: (err) => {\n setError(err);\n streamCallbacks?.onError?.(err);\n options.onError?.(err);\n },\n },\n { signal: ac.signal },\n );\n\n return doc;\n } catch (err: unknown) {\n if (ac.signal.aborted) return null;\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n options.onError?.(e);\n return null;\n } finally {\n if (abortControllerRef.current === ac) {\n setIsGenerating(false);\n setIsStreaming(false);\n setCurrentStep('');\n abortControllerRef.current = null;\n }\n }\n },\n [cancel, options],\n );\n\n const generateSection = useCallback(\n async (params: AiGenerateSectionRequest): Promise<Node | null> => {\n cancel();\n const ac = new AbortController();\n abortControllerRef.current = ac;\n\n setIsGenerating(true);\n setIsStreaming(false);\n setError(null);\n setCurrentStep('Generating section...');\n\n try {\n const node = await clientRef.current.generateSection(params, {\n signal: ac.signal,\n });\n options.onSuccess?.(node);\n return node;\n } catch (err: unknown) {\n if (ac.signal.aborted) return null;\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n options.onError?.(e);\n return null;\n } finally {\n if (abortControllerRef.current === ac) {\n setIsGenerating(false);\n setCurrentStep('');\n abortControllerRef.current = null;\n }\n }\n },\n [cancel, options],\n );\n\n const refactorNode = useCallback(\n async (params: AiRefactorNodeRequest): Promise<Node | null> => {\n cancel();\n const ac = new AbortController();\n abortControllerRef.current = ac;\n\n setIsGenerating(true);\n setIsStreaming(false);\n setError(null);\n setCurrentStep('Refactoring node...');\n\n try {\n const node = await clientRef.current.refactorNode(params, {\n signal: ac.signal,\n });\n options.onSuccess?.(node);\n return node;\n } catch (err: unknown) {\n if (ac.signal.aborted) return null;\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n options.onError?.(e);\n return null;\n } finally {\n if (abortControllerRef.current === ac) {\n setIsGenerating(false);\n setCurrentStep('');\n abortControllerRef.current = null;\n }\n }\n },\n [cancel, options],\n );\n\n return {\n generatePage,\n streamPage,\n generateSection,\n refactorNode,\n isGenerating,\n isStreaming,\n currentStep,\n error,\n cancel,\n };\n}\n","import type { PageDocument, Node } from '@kubuild/schema';\nimport type {\n AiGeneratePageRequest,\n AiGenerateSectionRequest,\n AiRefactorNodeRequest,\n AiChatRequest,\n AiChatResponse,\n AiChatMessage,\n AiGenerateResponse,\n AiStreamCallbacks,\n AiStreamEvent,\n} from '../types';\n\nexport interface AiClientOptions {\n endpoint: string;\n headers?:\n | Record<string, string>\n | (() => Promise<Record<string, string>> | Record<string, string>);\n fetch?: typeof fetch;\n}\n\nexport class KubuildAiClient {\n private endpoint: string;\n private headers?: AiClientOptions['headers'];\n private fetchFn: typeof fetch;\n\n constructor(options: AiClientOptions) {\n if (!options.endpoint) {\n throw new Error('KubuildAiClient requires an endpoint URL');\n }\n this.endpoint = options.endpoint;\n this.headers = options.headers;\n this.fetchFn = options.fetch || globalThis.fetch.bind(globalThis);\n }\n\n private async resolveHeaders(): Promise<Record<string, string>> {\n if (!this.headers) return {};\n if (typeof this.headers === 'function') {\n return await this.headers();\n }\n return this.headers;\n }\n\n private async sendRequest<T>(\n body: Record<string, unknown>,\n signal?: AbortSignal,\n ): Promise<T> {\n const dynamicHeaders = await this.resolveHeaders();\n\n const res = await this.fetchFn(this.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...dynamicHeaders,\n },\n body: JSON.stringify(body),\n signal,\n });\n\n const json = (await res.json()) as AiGenerateResponse<T>;\n\n if (!res.ok || !json.success || !json.data) {\n const errMessage = json?.error?.message || `HTTP ${res.status}: ${res.statusText}`;\n const error = new Error(errMessage);\n (error as unknown as { code?: string; details?: unknown }).code = json?.error?.code;\n (error as unknown as { code?: string; details?: unknown }).details = json?.error?.details;\n throw error;\n }\n\n return json.data;\n }\n\n /**\n * Standard single-pass full page generator (non-streaming).\n */\n async generatePage(\n params: AiGeneratePageRequest,\n options?: { signal?: AbortSignal },\n ): Promise<PageDocument> {\n return this.sendRequest<PageDocument>(\n {\n mode: 'full-page',\n ...params,\n },\n options?.signal,\n );\n }\n\n /**\n * Low-level SSE frame consumer shared by every streaming method on this client\n * (`streamPage`, `chatStream`) — one transport implementation, reused rather than\n * duplicated per stream \"flavor\" (STORA-515).\n *\n * Reads `res.body`, decodes `data: <json>\\n\\n` frames into `AiStreamEvent`s, and\n * invokes `onEvent` for each one in arrival order. If `onEvent` throws (the\n * conventional way callers signal a fatal `error` event), the throw propagates out of\n * this method after the reader lock is released.\n */\n private async consumeSse(\n res: Response,\n onEvent: (event: AiStreamEvent) => void,\n ): Promise<void> {\n if (!res.body) {\n throw new Error('Response body is null, cannot stream');\n }\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const parts = buffer.split('\\n\\n');\n buffer = parts.pop() || '';\n\n for (const part of parts) {\n const lines = part.split('\\n');\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n let event: AiStreamEvent;\n try {\n event = JSON.parse(line.slice(6).trim()) as AiStreamEvent;\n } catch {\n // Ignore incomplete or non-JSON data frames\n continue;\n }\n onEvent(event);\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Progressive section streamer (SSE).\n * Calls callbacks on each event (status, metadata, section, complete).\n */\n async streamPage(\n params: AiGeneratePageRequest,\n callbacks?: AiStreamCallbacks,\n options?: { signal?: AbortSignal },\n ): Promise<PageDocument> {\n const dynamicHeaders = await this.resolveHeaders();\n\n const res = await this.fetchFn(this.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...dynamicHeaders,\n },\n body: JSON.stringify({\n mode: 'full-page',\n stream: true,\n ...params,\n }),\n signal: options?.signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n const err = new Error(`Streaming failed [${res.status} ${res.statusText}]: ${errText}`);\n callbacks?.onError?.(err);\n throw err;\n }\n\n let finalDoc: PageDocument | null = null;\n\n await this.consumeSse(res, (event) => {\n if (event.type === 'status') {\n callbacks?.onStatus?.(event.message);\n } else if (event.type === 'metadata') {\n callbacks?.onMetadata?.(event.metadata, event.rootPageNode);\n } else if (event.type === 'section') {\n callbacks?.onSection?.(event.section, event.index, event.total);\n } else if (event.type === 'complete') {\n finalDoc = event.document;\n callbacks?.onComplete?.(event.document);\n } else if (event.type === 'error') {\n const err = new Error(event.error.message || 'Stream error');\n (err as unknown as { code?: string }).code = event.error.code;\n callbacks?.onError?.(err);\n throw err;\n }\n });\n\n if (!finalDoc) {\n throw new Error('Stream ended without receiving complete document');\n }\n\n return finalDoc;\n }\n\n /**\n * Token-level streaming chat (STORA-515). Calls `onChatChunk` for every partial chunk\n * as it arrives and resolves with the fully assembled assistant `AiChatMessage` once\n * the stream's terminal `chat-complete` event is received. Reuses the exact same SSE\n * transport as `streamPage` via `consumeSse` — no separate parsing path.\n */\n async chatStream(\n params: AiChatRequest,\n callbacks?: Pick<AiStreamCallbacks, 'onChatChunk' | 'onChatComplete' | 'onError'>,\n options?: { signal?: AbortSignal },\n ): Promise<AiChatMessage> {\n const dynamicHeaders = await this.resolveHeaders();\n\n const res = await this.fetchFn(this.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...dynamicHeaders,\n },\n body: JSON.stringify({\n mode: 'chat',\n stream: true,\n ...params,\n }),\n signal: options?.signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n const err = new Error(`Chat streaming failed [${res.status} ${res.statusText}]: ${errText}`);\n callbacks?.onError?.(err);\n throw err;\n }\n\n let finalMessage: AiChatMessage | null = null;\n\n await this.consumeSse(res, (event) => {\n if (event.type === 'chat-chunk') {\n callbacks?.onChatChunk?.(event.delta, event.content);\n } else if (event.type === 'chat-complete') {\n finalMessage = event.message;\n callbacks?.onChatComplete?.(event.message);\n } else if (event.type === 'error') {\n const err = new Error(event.error.message || 'Stream error');\n (err as unknown as { code?: string }).code = event.error.code;\n callbacks?.onError?.(err);\n throw err;\n }\n });\n\n if (!finalMessage) {\n throw new Error('Chat stream ended without receiving a complete message');\n }\n\n return finalMessage;\n }\n\n async generateSection(\n params: AiGenerateSectionRequest,\n options?: { signal?: AbortSignal },\n ): Promise<Node> {\n return this.sendRequest<Node>(\n {\n mode: 'section',\n ...params,\n },\n options?.signal,\n );\n }\n\n async refactorNode(\n params: AiRefactorNodeRequest,\n options?: { signal?: AbortSignal },\n ): Promise<Node> {\n return this.sendRequest<Node>(\n {\n mode: 'refactor',\n ...params,\n },\n options?.signal,\n );\n }\n\n async chat(\n params: AiChatRequest,\n options?: { signal?: AbortSignal },\n ): Promise<AiChatResponse> {\n return this.sendRequest<AiChatResponse>(\n {\n mode: 'chat',\n ...params,\n },\n options?.signal,\n );\n }\n}\n\nexport function createAiClient(options: AiClientOptions): KubuildAiClient {\n return new KubuildAiClient(options);\n}\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport type { PageDocument } from '@kubuild/schema';\nimport type { AiChatMessage, AiChatResponse } from '../types';\nimport { createAiClient, type AiClientOptions, KubuildAiClient } from '../client/ai-client';\n\n/**\n * Optional, host-implemented chat history persistence (STORA-520). `@kubuild/ai` stays\n * storage-agnostic — it never imports `localStorage` or any concrete storage mechanism\n * itself; the host supplies an adapter backed by whatever it wants (browser\n * `localStorage`, IndexedDB, a Stora.page backend call, etc.).\n */\nexport interface AiChatHistoryStorageAdapter {\n /** Called once on mount to seed `messages` before the user sends anything. */\n loadHistory(): Promise<AiChatMessage[]> | AiChatMessage[];\n /**\n * Called at completed-message boundaries (a user message just sent, or an assistant\n * reply that just finished/streamed to completion) — never on every mid-stream token,\n * see `useAiChat`'s persistence notes.\n */\n saveHistory(messages: AiChatMessage[]): Promise<void> | void;\n}\n\nexport interface UseAiChatOptions extends AiClientOptions {\n initialMessages?: AiChatMessage[];\n onMessage?: (message: AiChatMessage) => void;\n onError?: (error: Error) => void;\n /**\n * Fired for every partial token/chunk of a streaming chat response (STORA-516),\n * mirroring `useAiGenerator`'s `AiStreamCallbacks` naming convention. Optional — the\n * `messages` array already updates incrementally on its own, this is only for hosts\n * that want a side-channel (e.g. custom rendering, telemetry) into the raw chunks.\n */\n onChunk?: (delta: string, content: string) => void;\n /**\n * Optional storage adapter (STORA-520) used to persist/restore chat history across\n * reloads. Without it, behavior is exactly as before: pure in-memory React state, lost\n * on reload/unmount. `loadHistory()` is called once on mount to hydrate `messages`\n * (only overriding `initialMessages` when it resolves a non-empty array);\n * `saveHistory()` is called at completed-message boundaries — after a user message is\n * appended, and after an assistant reply finishes (streamed or not) — intentionally\n * *not* on every streaming chunk, to avoid hammering the adapter mid-stream.\n */\n historyStorage?: AiChatHistoryStorageAdapter;\n}\n\nexport interface SendMessageOptions {\n currentDocument?: PageDocument;\n selectedNodeId?: string;\n systemPrompt?: string;\n /**\n * Opt out of token-level streaming for this call (STORA-515/516 default to `true`).\n * When `false`, behaves exactly like the pre-streaming single request/response call.\n */\n stream?: boolean;\n}\n\nexport function useAiChat(options: UseAiChatOptions) {\n const [messages, setMessages] = useState<AiChatMessage[]>(options.initialMessages || []);\n const [isLoading, setIsLoading] = useState(false);\n const [isStreaming, setIsStreaming] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const abortControllerRef = useRef<AbortController | null>(null);\n const clientRef = useRef<KubuildAiClient>(createAiClient(options));\n const historyStorageRef = useRef(options.historyStorage);\n historyStorageRef.current = options.historyStorage;\n\n /**\n * STORA-520 — best-effort persistence: a storage failure (quota exceeded, network\n * error on a remote adapter, etc.) must never break the chat itself, so errors are\n * swallowed here rather than surfaced through `setError`/`onError` (those are reserved\n * for the actual chat request failing).\n */\n const persistHistory = useCallback((history: AiChatMessage[]) => {\n const adapter = historyStorageRef.current;\n if (!adapter) return;\n try {\n void Promise.resolve(adapter.saveHistory(history)).catch(() => undefined);\n } catch {\n // Synchronous throw from a non-Promise-returning adapter — ignore, same reasoning.\n }\n }, []);\n\n // STORA-520 — hydrate from storage once on mount. Only overrides `initialMessages`\n // when the adapter actually resolves a non-empty history, so a fresh/empty adapter\n // (e.g. first-ever visit) doesn't clobber a host-provided `initialMessages` seed.\n useEffect(() => {\n const adapter = historyStorageRef.current;\n if (!adapter) return;\n let cancelled = false;\n Promise.resolve(adapter.loadHistory())\n .then((loaded) => {\n if (!cancelled && Array.isArray(loaded) && loaded.length > 0) {\n setMessages(loaded);\n }\n })\n .catch((err: unknown) => {\n if (cancelled) return;\n const e = err instanceof Error ? err : new Error(String(err));\n options.onError?.(e);\n });\n return () => {\n cancelled = true;\n };\n // Deliberately empty deps: `historyStorage`/`onError` are read via refs/closures at\n // call time and this must run exactly once per mount, not whenever the caller passes\n // a fresh options object.\n }, []);\n\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n // Aborts the underlying fetch (and, for a streaming request, the in-flight\n // ReadableStream read) — not just local UI state (STORA-516 AC).\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n setIsLoading(false);\n setIsStreaming(false);\n }\n }, []);\n\n const clearMessages = useCallback(() => {\n setMessages([]);\n setError(null);\n persistHistory([]);\n }, [persistHistory]);\n\n const sendMessage = useCallback(\n async (content: string, sendOptions?: SendMessageOptions): Promise<AiChatMessage | null> => {\n if (!content.trim()) return null;\n\n cancel();\n const ac = new AbortController();\n abortControllerRef.current = ac;\n\n const userMessage: AiChatMessage = {\n role: 'user',\n content: content.trim(),\n timestamp: Date.now(),\n };\n\n const updatedHistory = [...messages, userMessage];\n setMessages(updatedHistory);\n setIsLoading(true);\n setError(null);\n // Completed-message boundary #1 (STORA-520): the user's message is final the\n // instant it's sent — persist it now rather than waiting for the assistant reply,\n // so a reload mid-request doesn't lose it.\n persistHistory(updatedHistory);\n\n const useStream = sendOptions?.stream !== false;\n\n try {\n if (useStream) {\n setIsStreaming(true);\n\n // Placeholder assistant message, filled in incrementally as chunks arrive.\n let assistantIndex = -1;\n setMessages((prev) => {\n assistantIndex = prev.length;\n return [...prev, { role: 'assistant', content: '', timestamp: Date.now() }];\n });\n\n const finalMessage = await clientRef.current.chatStream(\n {\n messages: updatedHistory,\n currentDocument: sendOptions?.currentDocument,\n selectedNodeId: sendOptions?.selectedNodeId,\n systemPrompt: sendOptions?.systemPrompt,\n },\n {\n onChatChunk: (delta, contentSoFar) => {\n options.onChunk?.(delta, contentSoFar);\n setMessages((prev) => {\n if (assistantIndex < 0 || assistantIndex >= prev.length) return prev;\n const next = prev.slice();\n next[assistantIndex] = { ...next[assistantIndex], content: contentSoFar };\n return next;\n });\n },\n onChatComplete: (message) => {\n setMessages((prev) => {\n if (assistantIndex < 0 || assistantIndex >= prev.length) return prev;\n const next = prev.slice();\n next[assistantIndex] = message;\n return next;\n });\n },\n },\n { signal: ac.signal },\n );\n\n // Completed-message boundary #2 (STORA-520): the stream finished — persist the\n // fully assembled assistant message, never the intermediate per-chunk content\n // (`onChatChunk` above deliberately does not call `persistHistory`).\n persistHistory([...updatedHistory, finalMessage]);\n options.onMessage?.(finalMessage);\n return finalMessage;\n }\n\n const response: AiChatResponse = await clientRef.current.chat(\n {\n messages: updatedHistory,\n currentDocument: sendOptions?.currentDocument,\n selectedNodeId: sendOptions?.selectedNodeId,\n systemPrompt: sendOptions?.systemPrompt,\n },\n { signal: ac.signal },\n );\n\n const assistantMsg = response.message;\n setMessages((prev) => [...prev, assistantMsg]);\n // Completed-message boundary #2 (non-streaming variant): a single request/response\n // call has no intermediate chunks at all, so this is simply \"after the reply\".\n persistHistory([...updatedHistory, assistantMsg]);\n options.onMessage?.(assistantMsg);\n return assistantMsg;\n } catch (err: unknown) {\n if (ac.signal.aborted) return null;\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n options.onError?.(e);\n return null;\n } finally {\n if (abortControllerRef.current === ac) {\n setIsLoading(false);\n setIsStreaming(false);\n abortControllerRef.current = null;\n }\n }\n },\n [cancel, messages, options, persistHistory],\n );\n\n return {\n messages,\n sendMessage,\n isLoading,\n /** Whether the in-flight `sendMessage` call is a token-level stream (STORA-516). */\n isStreaming,\n error,\n cancel,\n clearMessages,\n setMessages,\n };\n}\n"],"mappings":"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","names":["import_react"]}
@@ -0,0 +1,3 @@
1
+ export * from './use-ai-generator';
2
+ export * from './use-ai-chat';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC"}