@puckeditor/plugin-ai 0.8.2 → 0.9.0-canary.50fad349

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.
package/dist/index.js CHANGED
@@ -43,37 +43,6 @@ var init_react_import = __esm({
43
43
  }
44
44
  });
45
45
 
46
- // ../../node_modules/.pnpm/throttleit@2.1.0/node_modules/throttleit/index.js
47
- var require_throttleit = __commonJS({
48
- "../../node_modules/.pnpm/throttleit@2.1.0/node_modules/throttleit/index.js"(exports2, module2) {
49
- "use strict";
50
- init_react_import();
51
- function throttle2(function_, wait) {
52
- if (typeof function_ !== "function") {
53
- throw new TypeError(`Expected the first argument to be a \`function\`, got \`${typeof function_}\`.`);
54
- }
55
- let timeoutId;
56
- let lastCallTime = 0;
57
- return function throttled(...arguments_) {
58
- clearTimeout(timeoutId);
59
- const now = Date.now();
60
- const timeSinceLastCall = now - lastCallTime;
61
- const delayForNextCall = wait - timeSinceLastCall;
62
- if (delayForNextCall <= 0) {
63
- lastCallTime = now;
64
- function_.apply(this, arguments_);
65
- } else {
66
- timeoutId = setTimeout(() => {
67
- lastCallTime = Date.now();
68
- function_.apply(this, arguments_);
69
- }, delayForNextCall);
70
- }
71
- };
72
- }
73
- module2.exports = throttle2;
74
- }
75
- });
76
-
77
46
  // ../../node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.js
78
47
  var require_classnames = __commonJS({
79
48
  "../../node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.js"(exports2, module2) {
@@ -136,267 +105,34 @@ var require_classnames = __commonJS({
136
105
  }
137
106
  });
138
107
 
139
- // ../reducer/dist/index.js
140
- var require_dist = __commonJS({
141
- "../reducer/dist/index.js"(exports2, module2) {
108
+ // ../../node_modules/.pnpm/throttleit@2.1.0/node_modules/throttleit/index.js
109
+ var require_throttleit = __commonJS({
110
+ "../../node_modules/.pnpm/throttleit@2.1.0/node_modules/throttleit/index.js"(exports2, module2) {
142
111
  "use strict";
143
112
  init_react_import();
144
- var __defProp2 = Object.defineProperty;
145
- var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
146
- var __getOwnPropNames2 = Object.getOwnPropertyNames;
147
- var __hasOwnProp2 = Object.prototype.hasOwnProperty;
148
- var __export2 = (target, all) => {
149
- for (var name in all)
150
- __defProp2(target, name, { get: all[name], enumerable: true });
151
- };
152
- var __copyProps2 = (to, from, except, desc) => {
153
- if (from && typeof from === "object" || typeof from === "function") {
154
- for (let key of __getOwnPropNames2(from))
155
- if (!__hasOwnProp2.call(to, key) && key !== except)
156
- __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
157
- }
158
- return to;
159
- };
160
- var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
161
- var index_exports2 = {};
162
- __export2(index_exports2, {
163
- dispatchOp: () => dispatchOp2,
164
- resolveAppends: () => resolveAppends
165
- });
166
- module2.exports = __toCommonJS2(index_exports2);
167
- var parseAppendPath = (path) => {
168
- const segments = [];
169
- const pattern = /([^.[\]]+)|\[(\d+)\]/g;
170
- let match;
171
- while ((match = pattern.exec(path)) !== null) {
172
- segments.push(match[2] !== void 0 ? Number(match[2]) : match[1]);
173
- }
174
- return segments;
175
- };
176
- var appendAtPath = (base, segments, tail) => {
177
- if (segments.length === 0) {
178
- return `${typeof base === "string" ? base : ""}${tail}`;
179
- }
180
- const [head, ...rest] = segments;
181
- if (typeof head === "number") {
182
- const arr = Array.isArray(base) ? [...base] : [];
183
- arr[head] = appendAtPath(arr[head], rest, tail);
184
- return arr;
185
- }
186
- const obj = typeof base === "object" && base !== null && !Array.isArray(base) ? { ...base } : {};
187
- obj[head] = appendAtPath(obj[head], rest, tail);
188
- return obj;
189
- };
190
- var resolveAppends = (existingProps, props, appends) => {
191
- if (!appends) return props;
192
- const resolved = { ...props };
193
- for (const [path, tail] of Object.entries(appends)) {
194
- const [rootKey, ...rest] = parseAppendPath(path);
195
- if (typeof rootKey !== "string") continue;
196
- const base = rootKey in resolved ? resolved[rootKey] : existingProps == null ? void 0 : existingProps[rootKey];
197
- resolved[rootKey] = appendAtPath(base, rest, tail);
198
- }
199
- return resolved;
200
- };
201
- var getSelectorForId = (state, id) => {
202
- const node = state.indexes.nodes[id];
203
- if (!node) return;
204
- const zoneCompound = `${node.parentId}:${node.zone}`;
205
- const zone = state.indexes.zones[zoneCompound];
206
- if (!zone) return;
207
- const index = zone.contentIds.indexOf(id);
208
- return { zone: zoneCompound, index };
209
- };
210
- var getItemById = (state, id) => {
211
- var _a;
212
- return (_a = state.indexes.nodes[id]) == null ? void 0 : _a.data;
213
- };
214
- var applyArrayDefaults = (oldProps, newProps, fields) => {
215
- const updatedProps = {
216
- ...oldProps,
217
- ...newProps
218
- };
219
- for (const fieldName in fields) {
220
- const field = fields[fieldName];
221
- if (field.type === "array") {
222
- const arrayField = field;
223
- const arrayFields = arrayField.arrayFields;
224
- const value = updatedProps[fieldName];
225
- if (value === void 0) continue;
226
- if (!Array.isArray(value)) {
227
- const oldValue = oldProps[fieldName];
228
- if (Array.isArray(oldValue)) {
229
- updatedProps[fieldName] = oldValue;
230
- } else {
231
- delete updatedProps[fieldName];
232
- }
233
- continue;
234
- }
235
- updatedProps[fieldName] = value.map(
236
- (item, index) => {
237
- var _a, _b;
238
- const newItem = {};
239
- const defaultValue = typeof arrayField.defaultItemProps === "function" ? arrayField.defaultItemProps(index) : arrayField.defaultItemProps;
240
- for (const arrayFieldName in arrayFields) {
241
- const subField = arrayFields[arrayFieldName];
242
- if (subField.type === "slot") {
243
- newItem[arrayFieldName] = item[arrayFieldName] ?? ((_b = (_a = oldProps[fieldName]) == null ? void 0 : _a[index]) == null ? void 0 : _b[arrayFieldName]) ?? (defaultValue == null ? void 0 : defaultValue[arrayFieldName]);
244
- } else {
245
- newItem[arrayFieldName] = item[arrayFieldName] ?? (defaultValue == null ? void 0 : defaultValue[arrayFieldName]);
246
- }
247
- }
248
- return newItem;
249
- }
250
- );
251
- }
113
+ function throttle2(function_, wait) {
114
+ if (typeof function_ !== "function") {
115
+ throw new TypeError(`Expected the first argument to be a \`function\`, got \`${typeof function_}\`.`);
252
116
  }
253
- return updatedProps;
254
- };
255
- var dispatchOp2 = (operation, {
256
- getState,
257
- dispatchAction,
258
- config
259
- }) => {
260
- var _a, _b;
261
- const state = getState();
262
- try {
263
- if (operation.op === "add") {
264
- if (operation.zone) {
265
- dispatchAction({
266
- type: "insert",
267
- destinationIndex: operation.index,
268
- destinationZone: operation.zone,
269
- componentType: operation.type,
270
- id: operation.id,
271
- recordHistory: false
272
- });
273
- const existing = getItemById(getState(), operation.id);
274
- if (!existing) {
275
- throw new Error(
276
- `Tried to update an item that doesn't exist: ${operation.id}`
277
- );
278
- }
279
- const newData = {
280
- ...existing,
281
- props: applyArrayDefaults(
282
- existing.props,
283
- operation.props,
284
- config.components[existing.type].fields
285
- )
286
- };
287
- newData.props.id ||= operation.id;
288
- const selector = getSelectorForId(getState(), operation.id);
289
- if (!selector) {
290
- throw new Error(
291
- `Tried to replace an item that doesn't exist: ${operation.id}`
292
- );
293
- }
294
- dispatchAction({
295
- type: "replace",
296
- destinationIndex: selector.index,
297
- destinationZone: selector.zone,
298
- data: newData,
299
- recordHistory: false
300
- });
301
- }
302
- } else if (operation.op === "update") {
303
- const selector = getSelectorForId(state, operation.id);
304
- const existing = getItemById(state, operation.id);
305
- if (!selector || !existing) {
306
- throw new Error(
307
- `Tried to update an item that doesn't exist: ${operation.id}`
308
- );
309
- }
310
- const newData = {
311
- ...existing,
312
- props: applyArrayDefaults(
313
- existing.props,
314
- resolveAppends(
315
- existing.props,
316
- operation.props,
317
- operation.appends
318
- ),
319
- config.components[existing.type].fields
320
- )
321
- };
322
- dispatchAction({
323
- type: "replace",
324
- destinationIndex: selector.index,
325
- destinationZone: selector.zone,
326
- data: newData,
327
- recordHistory: false
328
- });
329
- } else if (operation.op === "updateRoot") {
330
- const existing = state.data.root;
331
- const defaultProps = ((_a = config.root) == null ? void 0 : _a.defaultProps) ?? {};
332
- dispatchAction({
333
- type: "replaceRoot",
334
- root: {
335
- ...existing,
336
- props: {
337
- ...defaultProps,
338
- ...existing.props,
339
- ...resolveAppends(
340
- existing.props ?? {},
341
- operation.props,
342
- operation.appends
343
- )
344
- }
345
- },
346
- recordHistory: false
347
- });
348
- } else if (operation.op === "delete") {
349
- const selector = getSelectorForId(state, operation.id);
350
- if (selector) {
351
- dispatchAction({
352
- type: "remove",
353
- zone: selector.zone,
354
- index: selector.index,
355
- recordHistory: false
356
- });
357
- }
358
- } else if (operation.op === "duplicate") {
359
- const selector = getSelectorForId(state, operation.id);
360
- if (!selector) {
361
- throw new Error(
362
- `Tried to duplicate an item that doesn't exist: ${operation.id}`
363
- );
364
- }
365
- dispatchAction({
366
- type: "duplicate",
367
- sourceZone: selector.zone,
368
- sourceIndex: selector.index,
369
- recordHistory: false
370
- });
371
- } else if (operation.op === "move") {
372
- const selector = getSelectorForId(state, operation.id);
373
- if (!selector) {
374
- throw new Error(
375
- `Tried to move an item that doesn't exist: ${operation.id}`
376
- );
377
- }
378
- dispatchAction({
379
- type: "move",
380
- sourceZone: selector.zone,
381
- sourceIndex: selector.index,
382
- destinationIndex: operation.index,
383
- destinationZone: operation.zone,
384
- recordHistory: false
385
- });
386
- } else if (operation.op === "reset") {
387
- const defaultRootProps = ((_b = config.root) == null ? void 0 : _b.defaultProps) ?? {};
388
- dispatchAction({
389
- type: "setData",
390
- data: { content: [], root: defaultRootProps },
391
- recordHistory: false
392
- });
117
+ let timeoutId;
118
+ let lastCallTime = 0;
119
+ return function throttled(...arguments_) {
120
+ clearTimeout(timeoutId);
121
+ const now = Date.now();
122
+ const timeSinceLastCall = now - lastCallTime;
123
+ const delayForNextCall = wait - timeSinceLastCall;
124
+ if (delayForNextCall <= 0) {
125
+ lastCallTime = now;
126
+ function_.apply(this, arguments_);
393
127
  } else {
394
- throw new Error(`Unknown operation: ${operation.op}`);
128
+ timeoutId = setTimeout(() => {
129
+ lastCallTime = Date.now();
130
+ function_.apply(this, arguments_);
131
+ }, delayForNextCall);
395
132
  }
396
- } catch (e) {
397
- console.error("Error applying operation, skipping...", operation, e);
398
- }
399
- };
133
+ };
134
+ }
135
+ module2.exports = throttle2;
400
136
  }
401
137
  });
402
138
 
@@ -404,6 +140,7 @@ var require_dist = __commonJS({
404
140
  var index_exports = {};
405
141
  __export(index_exports, {
406
142
  createAiPlugin: () => createAiPlugin,
143
+ usePuckAi: () => usePuckAi,
407
144
  withDynamicConfig: () => withDynamicConfig
408
145
  });
409
146
  module.exports = __toCommonJS(index_exports);
@@ -741,293 +478,39 @@ var import_ulid2 = require("ulid");
741
478
 
742
479
  // src/components/Chat/index.tsx
743
480
  init_react_import();
481
+ var import_core6 = require("@puckeditor/core");
482
+ var import_react28 = require("react");
744
483
 
745
- // ../../node_modules/.pnpm/@ai-sdk+react@3.0.232_react@19.2.8_zod@4.4.3/node_modules/@ai-sdk/react/dist/index.mjs
484
+ // ../utils/lib/get-class-name-factory.ts
746
485
  init_react_import();
747
- var import_ai = require("ai");
748
- var import_react4 = require("react");
749
- var import_ai2 = require("ai");
750
- var import_throttleit = __toESM(require_throttleit(), 1);
751
- var import_ai3 = require("ai");
752
- var import_react5 = require("react");
753
- var import_ai4 = require("ai");
754
- var import_react6 = require("react");
755
- var __accessCheck = (obj, member, msg) => {
756
- if (!member.has(obj))
757
- throw TypeError("Cannot " + msg);
758
- };
759
- var __privateGet = (obj, member, getter) => {
760
- __accessCheck(obj, member, "read from private field");
761
- return getter ? getter.call(obj) : member.get(obj);
762
- };
763
- var __privateAdd = (obj, member, value) => {
764
- if (member.has(obj))
765
- throw TypeError("Cannot add the same private member more than once");
766
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
767
- };
768
- var __privateSet = (obj, member, value, setter) => {
769
- __accessCheck(obj, member, "write to private field");
770
- setter ? setter.call(obj, value) : member.set(obj, value);
771
- return value;
772
- };
773
- function throttle(fn, waitMs) {
774
- return waitMs != null ? (0, import_throttleit.default)(fn, waitMs) : fn;
775
- }
776
- var _messages;
777
- var _status;
778
- var _error;
779
- var _messagesCallbacks;
780
- var _statusCallbacks;
781
- var _errorCallbacks;
782
- var _callMessagesCallbacks;
783
- var _callStatusCallbacks;
784
- var _callErrorCallbacks;
785
- var ReactChatState = class {
786
- constructor(initialMessages = []) {
787
- __privateAdd(this, _messages, void 0);
788
- __privateAdd(this, _status, "ready");
789
- __privateAdd(this, _error, void 0);
790
- __privateAdd(this, _messagesCallbacks, /* @__PURE__ */ new Set());
791
- __privateAdd(this, _statusCallbacks, /* @__PURE__ */ new Set());
792
- __privateAdd(this, _errorCallbacks, /* @__PURE__ */ new Set());
793
- this.pushMessage = (message) => {
794
- __privateSet(this, _messages, __privateGet(this, _messages).concat(message));
795
- __privateGet(this, _callMessagesCallbacks).call(this);
796
- };
797
- this.popMessage = () => {
798
- __privateSet(this, _messages, __privateGet(this, _messages).slice(0, -1));
799
- __privateGet(this, _callMessagesCallbacks).call(this);
800
- };
801
- this.replaceMessage = (index, message) => {
802
- __privateSet(this, _messages, [
803
- ...__privateGet(this, _messages).slice(0, index),
804
- // We deep clone the message here to ensure the new React Compiler (currently in RC) detects deeply nested parts/metadata changes:
805
- this.snapshot(message),
806
- ...__privateGet(this, _messages).slice(index + 1)
807
- ]);
808
- __privateGet(this, _callMessagesCallbacks).call(this);
809
- };
810
- this.snapshot = (value) => structuredClone(value);
811
- this["~registerMessagesCallback"] = (onChange, throttleWaitMs) => {
812
- const callback = throttleWaitMs ? throttle(onChange, throttleWaitMs) : onChange;
813
- __privateGet(this, _messagesCallbacks).add(callback);
814
- return () => {
815
- __privateGet(this, _messagesCallbacks).delete(callback);
816
- };
817
- };
818
- this["~registerStatusCallback"] = (onChange) => {
819
- __privateGet(this, _statusCallbacks).add(onChange);
820
- return () => {
821
- __privateGet(this, _statusCallbacks).delete(onChange);
822
- };
823
- };
824
- this["~registerErrorCallback"] = (onChange) => {
825
- __privateGet(this, _errorCallbacks).add(onChange);
826
- return () => {
827
- __privateGet(this, _errorCallbacks).delete(onChange);
828
- };
829
- };
830
- __privateAdd(this, _callMessagesCallbacks, () => {
831
- __privateGet(this, _messagesCallbacks).forEach((callback) => callback());
832
- });
833
- __privateAdd(this, _callStatusCallbacks, () => {
834
- __privateGet(this, _statusCallbacks).forEach((callback) => callback());
835
- });
836
- __privateAdd(this, _callErrorCallbacks, () => {
837
- __privateGet(this, _errorCallbacks).forEach((callback) => callback());
838
- });
839
- __privateSet(this, _messages, initialMessages);
840
- }
841
- get status() {
842
- return __privateGet(this, _status);
843
- }
844
- set status(newStatus) {
845
- __privateSet(this, _status, newStatus);
846
- __privateGet(this, _callStatusCallbacks).call(this);
847
- }
848
- get error() {
849
- return __privateGet(this, _error);
850
- }
851
- set error(newError) {
852
- __privateSet(this, _error, newError);
853
- __privateGet(this, _callErrorCallbacks).call(this);
854
- }
855
- get messages() {
856
- return __privateGet(this, _messages);
486
+ var import_classnames = __toESM(require_classnames());
487
+ var getClassNameFactory = (rootClass, styles, { baseClass = "" } = {}) => (options = {}) => {
488
+ let descendant = false;
489
+ let modifiers = false;
490
+ if (typeof options === "string") {
491
+ descendant = options;
492
+ } else if (typeof options === "object") {
493
+ modifiers = options;
857
494
  }
858
- set messages(newMessages) {
859
- __privateSet(this, _messages, [...newMessages]);
860
- __privateGet(this, _callMessagesCallbacks).call(this);
861
- }
862
- };
863
- _messages = /* @__PURE__ */ new WeakMap();
864
- _status = /* @__PURE__ */ new WeakMap();
865
- _error = /* @__PURE__ */ new WeakMap();
866
- _messagesCallbacks = /* @__PURE__ */ new WeakMap();
867
- _statusCallbacks = /* @__PURE__ */ new WeakMap();
868
- _errorCallbacks = /* @__PURE__ */ new WeakMap();
869
- _callMessagesCallbacks = /* @__PURE__ */ new WeakMap();
870
- _callStatusCallbacks = /* @__PURE__ */ new WeakMap();
871
- _callErrorCallbacks = /* @__PURE__ */ new WeakMap();
872
- var _state;
873
- var Chat = class extends import_ai2.AbstractChat {
874
- constructor({ messages, ...init }) {
875
- const state = new ReactChatState(messages);
876
- super({ ...init, state });
877
- __privateAdd(this, _state, void 0);
878
- this["~registerMessagesCallback"] = (onChange, throttleWaitMs) => __privateGet(this, _state)["~registerMessagesCallback"](onChange, throttleWaitMs);
879
- this["~registerStatusCallback"] = (onChange) => __privateGet(this, _state)["~registerStatusCallback"](onChange);
880
- this["~registerErrorCallback"] = (onChange) => __privateGet(this, _state)["~registerErrorCallback"](onChange);
881
- __privateSet(this, _state, state);
882
- }
883
- };
884
- _state = /* @__PURE__ */ new WeakMap();
885
- function useChat({
886
- experimental_throttle: throttleWaitMs,
887
- resume = false,
888
- ...options
889
- } = {}) {
890
- const latestRef = (0, import_react4.useRef)({});
891
- if (!("chat" in options)) {
892
- latestRef.current = {
893
- onToolCall: options.onToolCall,
894
- onData: options.onData,
895
- onFinish: options.onFinish,
896
- onError: options.onError,
897
- sendAutomaticallyWhen: options.sendAutomaticallyWhen,
898
- transport: options.transport
899
- };
900
- }
901
- let defaultTransport;
902
- const getTransport = () => {
903
- var _a;
904
- return (_a = latestRef.current.transport) != null ? _a : defaultTransport != null ? defaultTransport : defaultTransport = new import_ai.DefaultChatTransport();
905
- };
906
- const chatOptions = {
907
- ...options,
908
- transport: {
909
- sendMessages: (sendOptions) => getTransport().sendMessages(sendOptions),
910
- reconnectToStream: (reconnectOptions) => getTransport().reconnectToStream(reconnectOptions)
911
- },
912
- onToolCall: (arg) => {
913
- var _a, _b;
914
- return (_b = (_a = latestRef.current).onToolCall) == null ? void 0 : _b.call(_a, arg);
915
- },
916
- onData: (arg) => {
917
- var _a, _b;
918
- return (_b = (_a = latestRef.current).onData) == null ? void 0 : _b.call(_a, arg);
919
- },
920
- onFinish: (arg) => {
921
- var _a, _b;
922
- return (_b = (_a = latestRef.current).onFinish) == null ? void 0 : _b.call(_a, arg);
923
- },
924
- onError: (arg) => {
925
- var _a, _b;
926
- return (_b = (_a = latestRef.current).onError) == null ? void 0 : _b.call(_a, arg);
927
- },
928
- sendAutomaticallyWhen: (arg) => {
929
- var _a, _b, _c;
930
- return (_c = (_b = (_a = latestRef.current).sendAutomaticallyWhen) == null ? void 0 : _b.call(_a, arg)) != null ? _c : false;
931
- }
932
- };
933
- const chatRef = (0, import_react4.useRef)(
934
- "chat" in options ? options.chat : new Chat(chatOptions)
935
- );
936
- const shouldRecreateChat = "chat" in options && options.chat !== chatRef.current || "id" in options && options.id != null && chatRef.current.id !== options.id;
937
- if (shouldRecreateChat) {
938
- chatRef.current = "chat" in options ? options.chat : new Chat(chatOptions);
939
- }
940
- const subscribeToMessages = (0, import_react4.useCallback)(
941
- (update) => chatRef.current["~registerMessagesCallback"](update, throttleWaitMs),
942
- // `chatRef.current.id` is required to trigger re-subscription when the chat ID changes
943
- // eslint-disable-next-line react-hooks/exhaustive-deps
944
- [throttleWaitMs, chatRef.current.id]
945
- );
946
- const messages = (0, import_react4.useSyncExternalStore)(
947
- subscribeToMessages,
948
- () => chatRef.current.messages,
949
- () => chatRef.current.messages
950
- );
951
- const status = (0, import_react4.useSyncExternalStore)(
952
- chatRef.current["~registerStatusCallback"],
953
- () => chatRef.current.status,
954
- () => chatRef.current.status
955
- );
956
- const error = (0, import_react4.useSyncExternalStore)(
957
- chatRef.current["~registerErrorCallback"],
958
- () => chatRef.current.error,
959
- () => chatRef.current.error
960
- );
961
- const setMessages = (0, import_react4.useCallback)(
962
- (messagesParam) => {
963
- if (typeof messagesParam === "function") {
964
- messagesParam = messagesParam(chatRef.current.messages);
965
- }
966
- chatRef.current.messages = messagesParam;
967
- },
968
- [chatRef]
969
- );
970
- (0, import_react4.useEffect)(() => {
971
- if (resume) {
972
- chatRef.current.resumeStream();
973
- }
974
- }, [resume, chatRef]);
975
- return {
976
- id: chatRef.current.id,
977
- messages,
978
- setMessages,
979
- sendMessage: chatRef.current.sendMessage,
980
- regenerate: chatRef.current.regenerate,
981
- clearError: chatRef.current.clearError,
982
- stop: chatRef.current.stop,
983
- error,
984
- resumeStream: chatRef.current.resumeStream,
985
- status,
986
- /**
987
- * @deprecated Use `addToolOutput` instead.
988
- */
989
- addToolResult: chatRef.current.addToolOutput,
990
- addToolOutput: chatRef.current.addToolOutput,
991
- addToolApprovalResponse: chatRef.current.addToolApprovalResponse
992
- };
993
- }
994
-
995
- // src/components/Chat/index.tsx
996
- var import_core5 = require("@puckeditor/core");
997
- var import_ai5 = require("ai");
998
- var import_react27 = require("react");
999
- var import_ulid = require("ulid");
1000
-
1001
- // ../utils/lib/get-class-name-factory.ts
1002
- init_react_import();
1003
- var import_classnames = __toESM(require_classnames());
1004
- var getClassNameFactory = (rootClass, styles, { baseClass = "" } = {}) => (options = {}) => {
1005
- let descendant = false;
1006
- let modifiers = false;
1007
- if (typeof options === "string") {
1008
- descendant = options;
1009
- } else if (typeof options === "object") {
1010
- modifiers = options;
1011
- }
1012
- if (descendant) {
1013
- const style = styles[`${rootClass}-${descendant}`];
1014
- if (style) {
1015
- return baseClass + styles[`${rootClass}-${descendant}`] || "";
1016
- }
1017
- return "";
1018
- } else if (modifiers) {
1019
- const prefixedModifiers = {};
1020
- for (let modifier in modifiers) {
1021
- prefixedModifiers[styles[`${rootClass}--${modifier}`]] = modifiers[modifier];
1022
- }
1023
- const c = styles[rootClass];
1024
- return baseClass + (0, import_classnames.default)({
1025
- [c]: !!c,
1026
- // only apply the class if it exists
1027
- ...prefixedModifiers
1028
- });
1029
- } else {
1030
- return baseClass + styles[rootClass] || "";
495
+ if (descendant) {
496
+ const style = styles[`${rootClass}-${descendant}`];
497
+ if (style) {
498
+ return baseClass + styles[`${rootClass}-${descendant}`] || "";
499
+ }
500
+ return "";
501
+ } else if (modifiers) {
502
+ const prefixedModifiers = {};
503
+ for (let modifier in modifiers) {
504
+ prefixedModifiers[styles[`${rootClass}--${modifier}`]] = modifiers[modifier];
505
+ }
506
+ const c = styles[rootClass];
507
+ return baseClass + (0, import_classnames.default)({
508
+ [c]: !!c,
509
+ // only apply the class if it exists
510
+ ...prefixedModifiers
511
+ });
512
+ } else {
513
+ return baseClass + styles[rootClass] || "";
1031
514
  }
1032
515
  };
1033
516
  var get_class_name_factory_default = getClassNameFactory;
@@ -1038,7 +521,7 @@ var styles_module_default = { "Chat": "_Chat_1ei0a_1", "Chat-header": "_Chat-hea
1038
521
 
1039
522
  // src/components/ChatBody/index.tsx
1040
523
  init_react_import();
1041
- var import_react21 = require("react");
524
+ var import_react18 = require("react");
1042
525
  var import_use_stick_to_bottom = require("use-stick-to-bottom");
1043
526
  var import_react_markdown = __toESM(require("react-markdown"));
1044
527
 
@@ -1100,15 +583,15 @@ init_react_import();
1100
583
  var Modal_module_default = { "Modal-background": "_Modal-background_1bedq_1", "Modal--visible": "_Modal--visible_1bedq_16", "Modal-modal": "_Modal-modal_1bedq_22" };
1101
584
 
1102
585
  // ../platform-client/components/Modal/Modal.tsx
1103
- var import_react9 = require("react");
586
+ var import_react6 = require("react");
1104
587
 
1105
588
  // ../platform-client/lib/use-modal-visible.ts
1106
589
  init_react_import();
1107
- var import_react7 = require("react");
590
+ var import_react4 = require("react");
1108
591
  var useModalVisible = (defaultVisible) => {
1109
- const [visible, setVisible] = (0, import_react7.useState)(defaultVisible ?? false);
1110
- const ref = (0, import_react7.useRef)(null);
1111
- (0, import_react7.useEffect)(() => {
592
+ const [visible, setVisible] = (0, import_react4.useState)(defaultVisible ?? false);
593
+ const ref = (0, import_react4.useRef)(null);
594
+ (0, import_react4.useEffect)(() => {
1112
595
  if (!visible) {
1113
596
  return;
1114
597
  }
@@ -1130,7 +613,7 @@ init_react_import();
1130
613
 
1131
614
  // ../platform-client/components/Button/Button.tsx
1132
615
  init_react_import();
1133
- var import_react8 = require("react");
616
+ var import_react5 = require("react");
1134
617
 
1135
618
  // css-module:/home/runner/work/platform/platform/packages/platform-client/components/Button/Button.module.css#css-module
1136
619
  init_react_import();
@@ -1183,8 +666,8 @@ var Button = ({
1183
666
  size = "medium",
1184
667
  loading: loadingProp = false
1185
668
  }) => {
1186
- const [loading, setLoading] = (0, import_react8.useState)(loadingProp);
1187
- (0, import_react8.useEffect)(() => {
669
+ const [loading, setLoading] = (0, import_react5.useState)(loadingProp);
670
+ (0, import_react5.useEffect)(() => {
1188
671
  const resetLoading = () => setLoading(loadingProp);
1189
672
  resetLoading();
1190
673
  window.addEventListener("pageshow", resetLoading);
@@ -1234,7 +717,7 @@ var Button = ({
1234
717
  // ../platform-client/components/Modal/Modal.tsx
1235
718
  var import_jsx_runtime3 = require("react/jsx-runtime");
1236
719
  var getClassName3 = getClassNameFactory2("Modal", Modal_module_default);
1237
- var modalContext = (0, import_react9.createContext)({
720
+ var modalContext = (0, import_react6.createContext)({
1238
721
  buttonVariant: "primary",
1239
722
  buttonSize: "medium",
1240
723
  visible: false,
@@ -1258,7 +741,7 @@ var ModalProvider = ({
1258
741
  );
1259
742
  };
1260
743
  var useModal = () => {
1261
- const { visible, setVisible } = (0, import_react9.useContext)(modalContext);
744
+ const { visible, setVisible } = (0, import_react6.useContext)(modalContext);
1262
745
  return { visible, setVisible };
1263
746
  };
1264
747
  var Modal = ({
@@ -1266,7 +749,7 @@ var Modal = ({
1266
749
  children,
1267
750
  hideButton = false
1268
751
  }) => {
1269
- const { visible, setVisible, buttonVariant, buttonSize, ref } = (0, import_react9.useContext)(modalContext);
752
+ const { visible, setVisible, buttonVariant, buttonSize, ref } = (0, import_react6.useContext)(modalContext);
1270
753
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: getClassName3({ visible }), children: [
1271
754
  !hideButton && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: getClassName3("button"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1272
755
  Button,
@@ -1349,7 +832,7 @@ init_react_import();
1349
832
 
1350
833
  // ../platform-client/components/Align/Align.tsx
1351
834
  init_react_import();
1352
- var import_react10 = __toESM(require("react"));
835
+ var import_react7 = __toESM(require("react"));
1353
836
 
1354
837
  // css-module:/home/runner/work/platform/platform/packages/platform-client/components/Align/Align.module.css#css-module
1355
838
  init_react_import();
@@ -1373,7 +856,7 @@ init_react_import();
1373
856
  // ../platform-client/components/AutoForm/AutoForm.tsx
1374
857
  init_react_import();
1375
858
  var import_core = require("@puckeditor/core");
1376
- var import_react11 = require("react");
859
+ var import_react8 = require("react");
1377
860
 
1378
861
  // css-module:/home/runner/work/platform/platform/packages/platform-client/components/AutoForm/AutoForm.module.css#css-module
1379
862
  init_react_import();
@@ -1421,11 +904,11 @@ var Code_module_default = { "Code": "_Code_d4378_1", "Code-body": "_Code-body_d4
1421
904
 
1422
905
  // ../platform-client/components/Code/CopyAction.tsx
1423
906
  init_react_import();
1424
- var import_react12 = require("react");
907
+ var import_react9 = require("react");
1425
908
  var import_jsx_runtime11 = require("react/jsx-runtime");
1426
909
 
1427
910
  // ../platform-client/components/Code/Code.tsx
1428
- var import_react13 = require("react");
911
+ var import_react10 = require("react");
1429
912
  var import_jsx_runtime12 = require("react/jsx-runtime");
1430
913
  var getClassName9 = get_class_name_factory_default("Code", Code_module_default);
1431
914
  var getClassNameTab = get_class_name_factory_default("Tab", Code_module_default);
@@ -1435,7 +918,7 @@ init_react_import();
1435
918
 
1436
919
  // ../platform-client/components/IconButton/IconButton.tsx
1437
920
  init_react_import();
1438
- var import_react14 = require("react");
921
+ var import_react11 = require("react");
1439
922
 
1440
923
  // css-module:/home/runner/work/platform/platform/packages/platform-client/components/IconButton/IconButton.module.css#css-module
1441
924
  init_react_import();
@@ -1457,7 +940,7 @@ var IconButton = ({
1457
940
  title,
1458
941
  dark
1459
942
  }) => {
1460
- const [loading, setLoading] = (0, import_react14.useState)(false);
943
+ const [loading, setLoading] = (0, import_react11.useState)(false);
1461
944
  const ElementType = href ? "a" : onClick ? "button" : "div";
1462
945
  const el = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1463
946
  ElementType,
@@ -1589,7 +1072,7 @@ var getClassName12 = get_class_name_factory_default2("Link", Link_module_default
1589
1072
 
1590
1073
  // ../platform-client/components/Menu/index.tsx
1591
1074
  init_react_import();
1592
- var import_react15 = require("react");
1075
+ var import_react12 = require("react");
1593
1076
 
1594
1077
  // css-module:/home/runner/work/platform/platform/packages/platform-client/components/Menu/styles.module.css#css-module
1595
1078
  init_react_import();
@@ -1622,7 +1105,7 @@ init_react_import();
1622
1105
 
1623
1106
  // ../platform-client/components/Pagination/Pagination.tsx
1624
1107
  init_react_import();
1625
- var import_react16 = require("react");
1108
+ var import_react13 = require("react");
1626
1109
 
1627
1110
  // css-module:/home/runner/work/platform/platform/packages/platform-client/components/Pagination/Pagination.module.css#css-module
1628
1111
  init_react_import();
@@ -1718,7 +1201,7 @@ init_react_import();
1718
1201
 
1719
1202
  // ../platform-client/components/Table/Table.tsx
1720
1203
  init_react_import();
1721
- var import_react17 = require("react");
1204
+ var import_react14 = require("react");
1722
1205
 
1723
1206
  // css-module:/home/runner/work/platform/platform/packages/platform-client/components/Table/Table.module.css#css-module
1724
1207
  init_react_import();
@@ -1760,9 +1243,9 @@ var cx6 = getClassNameFactory("Viewport", styles_module_default6);
1760
1243
 
1761
1244
  // ../platform-client/context/editor.tsx
1762
1245
  init_react_import();
1763
- var import_react18 = require("react");
1246
+ var import_react15 = require("react");
1764
1247
  var import_jsx_runtime27 = require("react/jsx-runtime");
1765
- var ctx = (0, import_react18.createContext)({});
1248
+ var ctx = (0, import_react15.createContext)({});
1766
1249
 
1767
1250
  // css-module:/home/runner/work/platform/platform/packages/plugin-ai/src/components/ChatBody/styles.module.css#css-module
1768
1251
  init_react_import();
@@ -1770,7 +1253,7 @@ var styles_module_default7 = { "Chat": "_Chat_5z5yi_1", "Chat--hasMessages": "_C
1770
1253
 
1771
1254
  // src/components/PromptForm/index.tsx
1772
1255
  init_react_import();
1773
- var import_react19 = require("react");
1256
+ var import_react16 = require("react");
1774
1257
 
1775
1258
  // css-module:/home/runner/work/platform/platform/packages/plugin-ai/src/components/PromptForm/styles.module.css#css-module
1776
1259
  init_react_import();
@@ -1856,13 +1339,13 @@ function PromptForm({
1856
1339
  maxRows = 5,
1857
1340
  value = ""
1858
1341
  }) {
1859
- const hasSetInitialPrompt = (0, import_react19.useRef)(false);
1860
- const [prompt, setPrompt] = (0, import_react19.useState)(value);
1861
- const internalRef = (0, import_react19.useRef)(null);
1862
- const [isDragOver, setIsDragOver] = (0, import_react19.useState)(false);
1863
- const dragCounterRef = (0, import_react19.useRef)(0);
1342
+ const hasSetInitialPrompt = (0, import_react16.useRef)(false);
1343
+ const [prompt, setPrompt] = (0, import_react16.useState)(value);
1344
+ const internalRef = (0, import_react16.useRef)(null);
1345
+ const [isDragOver, setIsDragOver] = (0, import_react16.useState)(false);
1346
+ const dragCounterRef = (0, import_react16.useRef)(0);
1864
1347
  const canDrop = !!onFileDrop && !isDisabled && !isLoading;
1865
- const handleDragEnter = (0, import_react19.useCallback)(
1348
+ const handleDragEnter = (0, import_react16.useCallback)(
1866
1349
  (e) => {
1867
1350
  e.preventDefault();
1868
1351
  dragCounterRef.current++;
@@ -1872,17 +1355,17 @@ function PromptForm({
1872
1355
  },
1873
1356
  [canDrop]
1874
1357
  );
1875
- const handleDragLeave = (0, import_react19.useCallback)((e) => {
1358
+ const handleDragLeave = (0, import_react16.useCallback)((e) => {
1876
1359
  e.preventDefault();
1877
1360
  dragCounterRef.current--;
1878
1361
  if (dragCounterRef.current === 0) {
1879
1362
  setIsDragOver(false);
1880
1363
  }
1881
1364
  }, []);
1882
- const handleDragOver = (0, import_react19.useCallback)((e) => {
1365
+ const handleDragOver = (0, import_react16.useCallback)((e) => {
1883
1366
  e.preventDefault();
1884
1367
  }, []);
1885
- const handleDrop = (0, import_react19.useCallback)(
1368
+ const handleDrop = (0, import_react16.useCallback)(
1886
1369
  (e) => {
1887
1370
  e.preventDefault();
1888
1371
  dragCounterRef.current = 0;
@@ -1896,7 +1379,7 @@ function PromptForm({
1896
1379
  },
1897
1380
  [canDrop, onFileDrop]
1898
1381
  );
1899
- (0, import_react19.useEffect)(() => {
1382
+ (0, import_react16.useEffect)(() => {
1900
1383
  setPrompt(value);
1901
1384
  }, [setPrompt, value]);
1902
1385
  const sendPrompt = async () => {
@@ -1911,7 +1394,7 @@ function PromptForm({
1911
1394
  setPrompt("");
1912
1395
  }
1913
1396
  };
1914
- (0, import_react19.useEffect)(() => {
1397
+ (0, import_react16.useEffect)(() => {
1915
1398
  const currentUrl = new URL(location.href);
1916
1399
  const initialPrompt = currentUrl.searchParams.get("initialPrompt");
1917
1400
  if (!hasSetInitialPrompt.current && initialPrompt && prompt === "") {
@@ -2056,12 +1539,12 @@ function PromptForm({
2056
1539
 
2057
1540
  // src/lib/context.ts
2058
1541
  init_react_import();
2059
- var import_react20 = require("react");
2060
- var toolStatusContext = (0, import_react20.createContext)({});
1542
+ var import_react17 = require("react");
1543
+ var toolStatusContext = (0, import_react17.createContext)({});
2061
1544
  var ToolStatusProvider = toolStatusContext.Provider;
2062
- var hostContext = (0, import_react20.createContext)(void 0);
1545
+ var hostContext = (0, import_react17.createContext)(void 0);
2063
1546
  var HostProvider = hostContext.Provider;
2064
- var subagentStateContext = (0, import_react20.createContext)({});
1547
+ var subagentStateContext = (0, import_react17.createContext)({});
2065
1548
  var SubagentStateProvider = subagentStateContext.Provider;
2066
1549
 
2067
1550
  // src/components/ChatBody/index.tsx
@@ -2167,7 +1650,7 @@ function mergeReasoningParts(parts) {
2167
1650
  }
2168
1651
  function ChatMessage({ message }) {
2169
1652
  const { role, parts: rawParts } = message;
2170
- const parts = (0, import_react21.useMemo)(() => mergeReasoningParts(rawParts), [rawParts]);
1653
+ const parts = (0, import_react18.useMemo)(() => mergeReasoningParts(rawParts), [rawParts]);
2171
1654
  if (role === "user") {
2172
1655
  const attachmentParts = parts.filter((part) => part.type === "file");
2173
1656
  const otherParts = parts.filter((part) => part.type !== "file");
@@ -2219,7 +1702,7 @@ function ChatAttachmentThumbnail({
2219
1702
  mediaType,
2220
1703
  url
2221
1704
  }) {
2222
- const host = (0, import_react21.useContext)(hostContext);
1705
+ const host = (0, import_react18.useContext)(hostContext);
2223
1706
  const endpoint = host ? `${host.replace(/\/$/, "")}/attachments` : "/api/puck/chat/attachments";
2224
1707
  const resolvedUrl = resolveAttachmentUrl(url, endpoint);
2225
1708
  const attachmentId = getAttachmentIdFromRef(url);
@@ -2256,12 +1739,12 @@ function ChatMessageWrapper({
2256
1739
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children });
2257
1740
  }
2258
1741
  function ReasoningBlock({ part }) {
2259
- const startTimeRef = (0, import_react21.useRef)(null);
2260
- const [durationSecs, setDurationSecs] = (0, import_react21.useState)(null);
1742
+ const startTimeRef = (0, import_react18.useRef)(null);
1743
+ const [durationSecs, setDurationSecs] = (0, import_react18.useState)(null);
2261
1744
  if (part.state !== "done" && startTimeRef.current === null) {
2262
1745
  startTimeRef.current = Date.now();
2263
1746
  }
2264
- (0, import_react21.useEffect)(() => {
1747
+ (0, import_react18.useEffect)(() => {
2265
1748
  if (part.state === "done" && startTimeRef.current !== null) {
2266
1749
  setDurationSecs(Math.round((Date.now() - startTimeRef.current) / 1e3));
2267
1750
  }
@@ -2313,7 +1796,7 @@ function ChatAttachment({
2313
1796
  mediaType,
2314
1797
  url
2315
1798
  }) {
2316
- const host = (0, import_react21.useContext)(hostContext);
1799
+ const host = (0, import_react18.useContext)(hostContext);
2317
1800
  const endpoint = host ? `${host.replace(/\/$/, "")}/attachments` : "/api/puck/chat/attachments";
2318
1801
  const resolvedUrl = resolveAttachmentUrl(url, endpoint);
2319
1802
  const attachmentId = getAttachmentIdFromRef(url);
@@ -2332,10 +1815,10 @@ function PuckTool({
2332
1815
  defaultLabel = "Thinking...",
2333
1816
  type
2334
1817
  }) {
2335
- const toolStatus = (0, import_react21.useContext)(toolStatusContext)[toolCallId];
1818
+ const toolStatus = (0, import_react18.useContext)(toolStatusContext)[toolCallId];
2336
1819
  const outputObj = output;
2337
1820
  const status = outputObj && "status" in outputObj ? outputObj.status : toolStatus ?? { loading: true, label: defaultLabel };
2338
- let icon = (0, import_react21.useMemo)(() => {
1821
+ let icon = (0, import_react18.useMemo)(() => {
2339
1822
  if (type === "tool-write") {
2340
1823
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Pen, { size: 18 });
2341
1824
  } else if (type === "tool-refreshPageData") {
@@ -2352,16 +1835,16 @@ function PuckTool({
2352
1835
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ChatEvent, { status, icon });
2353
1836
  }
2354
1837
  function SubagentBlock({ toolCallId }) {
2355
- const subagentState = (0, import_react21.useContext)(subagentStateContext);
1838
+ const subagentState = (0, import_react18.useContext)(subagentStateContext);
2356
1839
  const state = subagentState[toolCallId];
2357
- const toolStatusMap = (0, import_react21.useContext)(toolStatusContext);
1840
+ const toolStatusMap = (0, import_react18.useContext)(toolStatusContext);
2358
1841
  const toolStatus = toolStatusMap[toolCallId];
2359
1842
  const fallbackLabel = toolStatus?.label ?? "Running subagent";
2360
1843
  const label = state?.label ? state.state === "done" ? `${state.agentType} subagent complete` : state.label : fallbackLabel;
2361
1844
  const loading = state ? state.state !== "done" : toolStatus?.loading ?? true;
2362
1845
  const hasBody = !!state && state.parts.length > 0;
2363
1846
  const parts = state?.parts ?? [];
2364
- const [isOpen, setIsOpen] = (0, import_react21.useState)(false);
1847
+ const [isOpen, setIsOpen] = (0, import_react18.useState)(false);
2365
1848
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
2366
1849
  "details",
2367
1850
  {
@@ -2420,7 +1903,7 @@ function ChatEvent({
2420
1903
  status,
2421
1904
  icon = /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Check, { size: 18 })
2422
1905
  }) {
2423
- const [isOpen, setIsOpen] = (0, import_react21.useState)(false);
1906
+ const [isOpen, setIsOpen] = (0, import_react18.useState)(false);
2424
1907
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
2425
1908
  "details",
2426
1909
  {
@@ -2487,12 +1970,6 @@ function ExamplePrompt({
2487
1970
  );
2488
1971
  }
2489
1972
 
2490
- // src/components/Chat/index.tsx
2491
- var import_qler = __toESM(require("qler"));
2492
- var import_reducer = __toESM(require_dist());
2493
- var import_html2canvas_pro = __toESM(require("html2canvas-pro"));
2494
- var import_use_debounce = require("use-debounce");
2495
-
2496
1973
  // src/lib/scroll-tracking-events.ts
2497
1974
  init_react_import();
2498
1975
  var listeners = /* @__PURE__ */ new Set();
@@ -2536,8 +2013,502 @@ function DesignModeToggle({
2536
2013
  "Design"
2537
2014
  ]
2538
2015
  }
2539
- ) });
2540
- }
2016
+ ) });
2017
+ }
2018
+
2019
+ // src/lib/use-puck-ai.ts
2020
+ init_react_import();
2021
+
2022
+ // ../../node_modules/.pnpm/@ai-sdk+react@3.0.232_react@19.2.8_zod@4.4.3/node_modules/@ai-sdk/react/dist/index.mjs
2023
+ init_react_import();
2024
+ var import_ai = require("ai");
2025
+ var import_react19 = require("react");
2026
+ var import_ai2 = require("ai");
2027
+ var import_throttleit = __toESM(require_throttleit(), 1);
2028
+ var import_ai3 = require("ai");
2029
+ var import_react20 = require("react");
2030
+ var import_ai4 = require("ai");
2031
+ var import_react21 = require("react");
2032
+ var __accessCheck = (obj, member, msg) => {
2033
+ if (!member.has(obj))
2034
+ throw TypeError("Cannot " + msg);
2035
+ };
2036
+ var __privateGet = (obj, member, getter) => {
2037
+ __accessCheck(obj, member, "read from private field");
2038
+ return getter ? getter.call(obj) : member.get(obj);
2039
+ };
2040
+ var __privateAdd = (obj, member, value) => {
2041
+ if (member.has(obj))
2042
+ throw TypeError("Cannot add the same private member more than once");
2043
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
2044
+ };
2045
+ var __privateSet = (obj, member, value, setter) => {
2046
+ __accessCheck(obj, member, "write to private field");
2047
+ setter ? setter.call(obj, value) : member.set(obj, value);
2048
+ return value;
2049
+ };
2050
+ function throttle(fn, waitMs) {
2051
+ return waitMs != null ? (0, import_throttleit.default)(fn, waitMs) : fn;
2052
+ }
2053
+ var _messages;
2054
+ var _status;
2055
+ var _error;
2056
+ var _messagesCallbacks;
2057
+ var _statusCallbacks;
2058
+ var _errorCallbacks;
2059
+ var _callMessagesCallbacks;
2060
+ var _callStatusCallbacks;
2061
+ var _callErrorCallbacks;
2062
+ var ReactChatState = class {
2063
+ constructor(initialMessages = []) {
2064
+ __privateAdd(this, _messages, void 0);
2065
+ __privateAdd(this, _status, "ready");
2066
+ __privateAdd(this, _error, void 0);
2067
+ __privateAdd(this, _messagesCallbacks, /* @__PURE__ */ new Set());
2068
+ __privateAdd(this, _statusCallbacks, /* @__PURE__ */ new Set());
2069
+ __privateAdd(this, _errorCallbacks, /* @__PURE__ */ new Set());
2070
+ this.pushMessage = (message) => {
2071
+ __privateSet(this, _messages, __privateGet(this, _messages).concat(message));
2072
+ __privateGet(this, _callMessagesCallbacks).call(this);
2073
+ };
2074
+ this.popMessage = () => {
2075
+ __privateSet(this, _messages, __privateGet(this, _messages).slice(0, -1));
2076
+ __privateGet(this, _callMessagesCallbacks).call(this);
2077
+ };
2078
+ this.replaceMessage = (index, message) => {
2079
+ __privateSet(this, _messages, [
2080
+ ...__privateGet(this, _messages).slice(0, index),
2081
+ // We deep clone the message here to ensure the new React Compiler (currently in RC) detects deeply nested parts/metadata changes:
2082
+ this.snapshot(message),
2083
+ ...__privateGet(this, _messages).slice(index + 1)
2084
+ ]);
2085
+ __privateGet(this, _callMessagesCallbacks).call(this);
2086
+ };
2087
+ this.snapshot = (value) => structuredClone(value);
2088
+ this["~registerMessagesCallback"] = (onChange, throttleWaitMs) => {
2089
+ const callback = throttleWaitMs ? throttle(onChange, throttleWaitMs) : onChange;
2090
+ __privateGet(this, _messagesCallbacks).add(callback);
2091
+ return () => {
2092
+ __privateGet(this, _messagesCallbacks).delete(callback);
2093
+ };
2094
+ };
2095
+ this["~registerStatusCallback"] = (onChange) => {
2096
+ __privateGet(this, _statusCallbacks).add(onChange);
2097
+ return () => {
2098
+ __privateGet(this, _statusCallbacks).delete(onChange);
2099
+ };
2100
+ };
2101
+ this["~registerErrorCallback"] = (onChange) => {
2102
+ __privateGet(this, _errorCallbacks).add(onChange);
2103
+ return () => {
2104
+ __privateGet(this, _errorCallbacks).delete(onChange);
2105
+ };
2106
+ };
2107
+ __privateAdd(this, _callMessagesCallbacks, () => {
2108
+ __privateGet(this, _messagesCallbacks).forEach((callback) => callback());
2109
+ });
2110
+ __privateAdd(this, _callStatusCallbacks, () => {
2111
+ __privateGet(this, _statusCallbacks).forEach((callback) => callback());
2112
+ });
2113
+ __privateAdd(this, _callErrorCallbacks, () => {
2114
+ __privateGet(this, _errorCallbacks).forEach((callback) => callback());
2115
+ });
2116
+ __privateSet(this, _messages, initialMessages);
2117
+ }
2118
+ get status() {
2119
+ return __privateGet(this, _status);
2120
+ }
2121
+ set status(newStatus) {
2122
+ __privateSet(this, _status, newStatus);
2123
+ __privateGet(this, _callStatusCallbacks).call(this);
2124
+ }
2125
+ get error() {
2126
+ return __privateGet(this, _error);
2127
+ }
2128
+ set error(newError) {
2129
+ __privateSet(this, _error, newError);
2130
+ __privateGet(this, _callErrorCallbacks).call(this);
2131
+ }
2132
+ get messages() {
2133
+ return __privateGet(this, _messages);
2134
+ }
2135
+ set messages(newMessages) {
2136
+ __privateSet(this, _messages, [...newMessages]);
2137
+ __privateGet(this, _callMessagesCallbacks).call(this);
2138
+ }
2139
+ };
2140
+ _messages = /* @__PURE__ */ new WeakMap();
2141
+ _status = /* @__PURE__ */ new WeakMap();
2142
+ _error = /* @__PURE__ */ new WeakMap();
2143
+ _messagesCallbacks = /* @__PURE__ */ new WeakMap();
2144
+ _statusCallbacks = /* @__PURE__ */ new WeakMap();
2145
+ _errorCallbacks = /* @__PURE__ */ new WeakMap();
2146
+ _callMessagesCallbacks = /* @__PURE__ */ new WeakMap();
2147
+ _callStatusCallbacks = /* @__PURE__ */ new WeakMap();
2148
+ _callErrorCallbacks = /* @__PURE__ */ new WeakMap();
2149
+ var _state;
2150
+ var Chat = class extends import_ai2.AbstractChat {
2151
+ constructor({ messages, ...init }) {
2152
+ const state = new ReactChatState(messages);
2153
+ super({ ...init, state });
2154
+ __privateAdd(this, _state, void 0);
2155
+ this["~registerMessagesCallback"] = (onChange, throttleWaitMs) => __privateGet(this, _state)["~registerMessagesCallback"](onChange, throttleWaitMs);
2156
+ this["~registerStatusCallback"] = (onChange) => __privateGet(this, _state)["~registerStatusCallback"](onChange);
2157
+ this["~registerErrorCallback"] = (onChange) => __privateGet(this, _state)["~registerErrorCallback"](onChange);
2158
+ __privateSet(this, _state, state);
2159
+ }
2160
+ };
2161
+ _state = /* @__PURE__ */ new WeakMap();
2162
+ function useChat({
2163
+ experimental_throttle: throttleWaitMs,
2164
+ resume = false,
2165
+ ...options
2166
+ } = {}) {
2167
+ const latestRef = (0, import_react19.useRef)({});
2168
+ if (!("chat" in options)) {
2169
+ latestRef.current = {
2170
+ onToolCall: options.onToolCall,
2171
+ onData: options.onData,
2172
+ onFinish: options.onFinish,
2173
+ onError: options.onError,
2174
+ sendAutomaticallyWhen: options.sendAutomaticallyWhen,
2175
+ transport: options.transport
2176
+ };
2177
+ }
2178
+ let defaultTransport;
2179
+ const getTransport = () => {
2180
+ var _a;
2181
+ return (_a = latestRef.current.transport) != null ? _a : defaultTransport != null ? defaultTransport : defaultTransport = new import_ai.DefaultChatTransport();
2182
+ };
2183
+ const chatOptions = {
2184
+ ...options,
2185
+ transport: {
2186
+ sendMessages: (sendOptions) => getTransport().sendMessages(sendOptions),
2187
+ reconnectToStream: (reconnectOptions) => getTransport().reconnectToStream(reconnectOptions)
2188
+ },
2189
+ onToolCall: (arg) => {
2190
+ var _a, _b;
2191
+ return (_b = (_a = latestRef.current).onToolCall) == null ? void 0 : _b.call(_a, arg);
2192
+ },
2193
+ onData: (arg) => {
2194
+ var _a, _b;
2195
+ return (_b = (_a = latestRef.current).onData) == null ? void 0 : _b.call(_a, arg);
2196
+ },
2197
+ onFinish: (arg) => {
2198
+ var _a, _b;
2199
+ return (_b = (_a = latestRef.current).onFinish) == null ? void 0 : _b.call(_a, arg);
2200
+ },
2201
+ onError: (arg) => {
2202
+ var _a, _b;
2203
+ return (_b = (_a = latestRef.current).onError) == null ? void 0 : _b.call(_a, arg);
2204
+ },
2205
+ sendAutomaticallyWhen: (arg) => {
2206
+ var _a, _b, _c;
2207
+ return (_c = (_b = (_a = latestRef.current).sendAutomaticallyWhen) == null ? void 0 : _b.call(_a, arg)) != null ? _c : false;
2208
+ }
2209
+ };
2210
+ const chatRef = (0, import_react19.useRef)(
2211
+ "chat" in options ? options.chat : new Chat(chatOptions)
2212
+ );
2213
+ const shouldRecreateChat = "chat" in options && options.chat !== chatRef.current || "id" in options && options.id != null && chatRef.current.id !== options.id;
2214
+ if (shouldRecreateChat) {
2215
+ chatRef.current = "chat" in options ? options.chat : new Chat(chatOptions);
2216
+ }
2217
+ const subscribeToMessages = (0, import_react19.useCallback)(
2218
+ (update) => chatRef.current["~registerMessagesCallback"](update, throttleWaitMs),
2219
+ // `chatRef.current.id` is required to trigger re-subscription when the chat ID changes
2220
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2221
+ [throttleWaitMs, chatRef.current.id]
2222
+ );
2223
+ const messages = (0, import_react19.useSyncExternalStore)(
2224
+ subscribeToMessages,
2225
+ () => chatRef.current.messages,
2226
+ () => chatRef.current.messages
2227
+ );
2228
+ const status = (0, import_react19.useSyncExternalStore)(
2229
+ chatRef.current["~registerStatusCallback"],
2230
+ () => chatRef.current.status,
2231
+ () => chatRef.current.status
2232
+ );
2233
+ const error = (0, import_react19.useSyncExternalStore)(
2234
+ chatRef.current["~registerErrorCallback"],
2235
+ () => chatRef.current.error,
2236
+ () => chatRef.current.error
2237
+ );
2238
+ const setMessages = (0, import_react19.useCallback)(
2239
+ (messagesParam) => {
2240
+ if (typeof messagesParam === "function") {
2241
+ messagesParam = messagesParam(chatRef.current.messages);
2242
+ }
2243
+ chatRef.current.messages = messagesParam;
2244
+ },
2245
+ [chatRef]
2246
+ );
2247
+ (0, import_react19.useEffect)(() => {
2248
+ if (resume) {
2249
+ chatRef.current.resumeStream();
2250
+ }
2251
+ }, [resume, chatRef]);
2252
+ return {
2253
+ id: chatRef.current.id,
2254
+ messages,
2255
+ setMessages,
2256
+ sendMessage: chatRef.current.sendMessage,
2257
+ regenerate: chatRef.current.regenerate,
2258
+ clearError: chatRef.current.clearError,
2259
+ stop: chatRef.current.stop,
2260
+ error,
2261
+ resumeStream: chatRef.current.resumeStream,
2262
+ status,
2263
+ /**
2264
+ * @deprecated Use `addToolOutput` instead.
2265
+ */
2266
+ addToolResult: chatRef.current.addToolOutput,
2267
+ addToolOutput: chatRef.current.addToolOutput,
2268
+ addToolApprovalResponse: chatRef.current.addToolApprovalResponse
2269
+ };
2270
+ }
2271
+
2272
+ // src/lib/use-puck-ai.ts
2273
+ var import_core5 = require("@puckeditor/core");
2274
+ var import_ai5 = require("ai");
2275
+ var import_react27 = require("react");
2276
+ var import_ulid = require("ulid");
2277
+ var import_qler = __toESM(require("qler"));
2278
+ var import_html2canvas_pro = __toESM(require("html2canvas-pro"));
2279
+ var import_use_debounce = require("use-debounce");
2280
+
2281
+ // ../reducer/index.ts
2282
+ init_react_import();
2283
+ var import_internal = require("@puckeditor/core/internal");
2284
+ var parseAppendPath = (path) => {
2285
+ const segments = [];
2286
+ const pattern = /([^.[\]]+)|\[(\d+)\]/g;
2287
+ let match;
2288
+ while ((match = pattern.exec(path)) !== null) {
2289
+ segments.push(match[2] !== void 0 ? Number(match[2]) : match[1]);
2290
+ }
2291
+ return segments;
2292
+ };
2293
+ var appendAtPath = (base, segments, tail) => {
2294
+ if (segments.length === 0) {
2295
+ return `${typeof base === "string" ? base : ""}${tail}`;
2296
+ }
2297
+ const [head, ...rest] = segments;
2298
+ if (typeof head === "number") {
2299
+ const arr = Array.isArray(base) ? [...base] : [];
2300
+ arr[head] = appendAtPath(arr[head], rest, tail);
2301
+ return arr;
2302
+ }
2303
+ const obj = typeof base === "object" && base !== null && !Array.isArray(base) ? { ...base } : {};
2304
+ obj[head] = appendAtPath(obj[head], rest, tail);
2305
+ return obj;
2306
+ };
2307
+ var resolveAppends = (existingProps, props, appends) => {
2308
+ if (!appends) return props;
2309
+ const resolved = { ...props };
2310
+ for (const [path, tail] of Object.entries(appends)) {
2311
+ const [rootKey, ...rest] = parseAppendPath(path);
2312
+ if (typeof rootKey !== "string") continue;
2313
+ const base = rootKey in resolved ? resolved[rootKey] : existingProps?.[rootKey];
2314
+ resolved[rootKey] = appendAtPath(base, rest, tail);
2315
+ }
2316
+ return resolved;
2317
+ };
2318
+ var getSelectorForId = (state, id) => {
2319
+ const node = state.indexes.nodes[id];
2320
+ if (!node) return;
2321
+ const zoneCompound = `${node.parentId}:${node.zone}`;
2322
+ const zone = state.indexes.zones[zoneCompound];
2323
+ if (!zone) return;
2324
+ const index = zone.contentIds.indexOf(id);
2325
+ return { zone: zoneCompound, index };
2326
+ };
2327
+ var getItemById = (state, id) => state.indexes.nodes[id]?.data;
2328
+ var applyArrayDefaults = (oldProps, newProps, fields) => {
2329
+ const updatedProps = {
2330
+ ...oldProps,
2331
+ ...newProps
2332
+ };
2333
+ for (const fieldName in fields) {
2334
+ const field = fields[fieldName];
2335
+ if (field.type === "array") {
2336
+ const arrayField = field;
2337
+ const arrayFields = arrayField.arrayFields;
2338
+ const value = updatedProps[fieldName];
2339
+ if (value === void 0) continue;
2340
+ if (!Array.isArray(value)) {
2341
+ const oldValue = oldProps[fieldName];
2342
+ if (Array.isArray(oldValue)) {
2343
+ updatedProps[fieldName] = oldValue;
2344
+ } else {
2345
+ delete updatedProps[fieldName];
2346
+ }
2347
+ continue;
2348
+ }
2349
+ updatedProps[fieldName] = value.map(
2350
+ (item, index) => {
2351
+ const newItem = {};
2352
+ const defaultValue = typeof arrayField.defaultItemProps === "function" ? arrayField.defaultItemProps(index) : arrayField.defaultItemProps;
2353
+ for (const arrayFieldName in arrayFields) {
2354
+ const subField = arrayFields[arrayFieldName];
2355
+ if (subField.type === "slot") {
2356
+ newItem[arrayFieldName] = item[arrayFieldName] ?? oldProps[fieldName]?.[index]?.[arrayFieldName] ?? defaultValue?.[arrayFieldName];
2357
+ } else {
2358
+ newItem[arrayFieldName] = item[arrayFieldName] ?? defaultValue?.[arrayFieldName];
2359
+ }
2360
+ }
2361
+ return newItem;
2362
+ }
2363
+ );
2364
+ }
2365
+ }
2366
+ return updatedProps;
2367
+ };
2368
+ var dispatchOp = (operation, {
2369
+ getState,
2370
+ dispatchAction,
2371
+ config
2372
+ }) => {
2373
+ const state = getState();
2374
+ try {
2375
+ if (operation.op === "add") {
2376
+ if (operation.zone) {
2377
+ dispatchAction({
2378
+ type: "insert",
2379
+ destinationIndex: operation.index,
2380
+ destinationZone: operation.zone,
2381
+ componentType: operation.type,
2382
+ id: operation.id,
2383
+ recordHistory: false
2384
+ });
2385
+ const existing = getItemById(getState(), operation.id);
2386
+ if (!existing) {
2387
+ throw new Error(
2388
+ `Tried to update an item that doesn't exist: ${operation.id}`
2389
+ );
2390
+ }
2391
+ const newData = {
2392
+ ...existing,
2393
+ props: applyArrayDefaults(
2394
+ existing.props,
2395
+ operation.props,
2396
+ config.components[existing.type].fields
2397
+ )
2398
+ };
2399
+ newData.props.id ||= operation.id;
2400
+ const selector = getSelectorForId(getState(), operation.id);
2401
+ if (!selector) {
2402
+ throw new Error(
2403
+ `Tried to replace an item that doesn't exist: ${operation.id}`
2404
+ );
2405
+ }
2406
+ dispatchAction({
2407
+ type: "replace",
2408
+ destinationIndex: selector.index,
2409
+ destinationZone: selector.zone,
2410
+ data: newData,
2411
+ recordHistory: false
2412
+ });
2413
+ }
2414
+ } else if (operation.op === "update") {
2415
+ const selector = getSelectorForId(state, operation.id);
2416
+ const existing = getItemById(state, operation.id);
2417
+ if (!selector || !existing) {
2418
+ throw new Error(
2419
+ `Tried to update an item that doesn't exist: ${operation.id}`
2420
+ );
2421
+ }
2422
+ const newData = {
2423
+ ...existing,
2424
+ props: applyArrayDefaults(
2425
+ existing.props,
2426
+ resolveAppends(
2427
+ existing.props,
2428
+ operation.props,
2429
+ operation.appends
2430
+ ),
2431
+ config.components[existing.type].fields
2432
+ )
2433
+ };
2434
+ dispatchAction({
2435
+ type: "replace",
2436
+ destinationIndex: selector.index,
2437
+ destinationZone: selector.zone,
2438
+ data: newData,
2439
+ recordHistory: false
2440
+ });
2441
+ } else if (operation.op === "updateRoot") {
2442
+ const existing = state.data.root;
2443
+ const defaultProps = config.root?.defaultProps ?? {};
2444
+ dispatchAction({
2445
+ type: "replaceRoot",
2446
+ root: {
2447
+ ...existing,
2448
+ props: {
2449
+ ...defaultProps,
2450
+ ...existing.props,
2451
+ ...resolveAppends(
2452
+ existing.props ?? {},
2453
+ operation.props,
2454
+ operation.appends
2455
+ )
2456
+ }
2457
+ },
2458
+ recordHistory: false
2459
+ });
2460
+ } else if (operation.op === "delete") {
2461
+ const selector = getSelectorForId(state, operation.id);
2462
+ if (selector) {
2463
+ dispatchAction({
2464
+ type: "remove",
2465
+ zone: selector.zone,
2466
+ index: selector.index,
2467
+ recordHistory: false
2468
+ });
2469
+ }
2470
+ } else if (operation.op === "duplicate") {
2471
+ const selector = getSelectorForId(state, operation.id);
2472
+ if (!selector) {
2473
+ throw new Error(
2474
+ `Tried to duplicate an item that doesn't exist: ${operation.id}`
2475
+ );
2476
+ }
2477
+ dispatchAction({
2478
+ type: "duplicate",
2479
+ sourceZone: selector.zone,
2480
+ sourceIndex: selector.index,
2481
+ recordHistory: false
2482
+ });
2483
+ } else if (operation.op === "move") {
2484
+ const selector = getSelectorForId(state, operation.id);
2485
+ if (!selector) {
2486
+ throw new Error(
2487
+ `Tried to move an item that doesn't exist: ${operation.id}`
2488
+ );
2489
+ }
2490
+ dispatchAction({
2491
+ type: "move",
2492
+ sourceZone: selector.zone,
2493
+ sourceIndex: selector.index,
2494
+ destinationIndex: operation.index,
2495
+ destinationZone: operation.zone,
2496
+ recordHistory: false
2497
+ });
2498
+ } else if (operation.op === "reset") {
2499
+ const defaultRootProps = config.root?.defaultProps ?? {};
2500
+ dispatchAction({
2501
+ type: "setData",
2502
+ data: { content: [], root: defaultRootProps },
2503
+ recordHistory: false
2504
+ });
2505
+ } else {
2506
+ throw new Error(`Unknown operation: ${operation.op}`);
2507
+ }
2508
+ } catch (e) {
2509
+ console.error("Error applying operation, skipping...", operation, e);
2510
+ }
2511
+ };
2541
2512
 
2542
2513
  // src/lib/design/runtime.tsx
2543
2514
  init_react_import();
@@ -3444,9 +3415,9 @@ var attachInlineEditing = (el, {
3444
3415
  nextValue = parsed;
3445
3416
  lastValidNumberText = String(parsed);
3446
3417
  }
3447
- const { dispatch, getSelectorForId, getItemById, resolveDataById } = getPuck();
3448
- const selector = getSelectorForId(componentId);
3449
- const item = getItemById(componentId);
3418
+ const { dispatch, getSelectorForId: getSelectorForId2, getItemById: getItemById2, resolveDataById } = getPuck();
3419
+ const selector = getSelectorForId2(componentId);
3420
+ const item = getItemById2(componentId);
3450
3421
  if (!selector || !item) return;
3451
3422
  dispatch({
3452
3423
  type: "replace",
@@ -3459,8 +3430,8 @@ var attachInlineEditing = (el, {
3459
3430
  const handleClick = (e) => {
3460
3431
  e.preventDefault();
3461
3432
  e.stopPropagation();
3462
- const { getSelectorForId, dispatch } = getPuck();
3463
- const itemSelector = getSelectorForId(componentId);
3433
+ const { getSelectorForId: getSelectorForId2, dispatch } = getPuck();
3434
+ const itemSelector = getSelectorForId2(componentId);
3464
3435
  if (itemSelector) {
3465
3436
  dispatch({ type: "setUi", ui: { itemSelector } });
3466
3437
  }
@@ -4368,40 +4339,60 @@ var waitForIframeReady = async (root, imageTimeout = 1e4) => {
4368
4339
  await waitForNextPaint(document2);
4369
4340
  };
4370
4341
 
4371
- // src/components/Chat/index.tsx
4372
- var import_jsx_runtime35 = require("react/jsx-runtime");
4342
+ // ../utils/lib/iterate-sse.ts
4343
+ init_react_import();
4344
+ async function* iterateSSE(body) {
4345
+ const reader = body.getReader();
4346
+ const dec = new TextDecoder();
4347
+ let buf = "";
4348
+ try {
4349
+ while (true) {
4350
+ const { done, value } = await reader.read();
4351
+ if (done) break;
4352
+ buf += dec.decode(value, { stream: true });
4353
+ let idx;
4354
+ while ((idx = buf.indexOf("\n\n")) >= 0) {
4355
+ const chunk = buf.slice(0, idx).trim();
4356
+ buf = buf.slice(idx + 2);
4357
+ if (!chunk) continue;
4358
+ const line = chunk.startsWith("data: ") ? chunk.slice(6) : chunk;
4359
+ try {
4360
+ yield JSON.parse(line);
4361
+ } catch {
4362
+ }
4363
+ }
4364
+ }
4365
+ } finally {
4366
+ reader.cancel().catch(() => {
4367
+ });
4368
+ reader.releaseLock();
4369
+ }
4370
+ }
4371
+
4372
+ // src/lib/use-puck-ai.ts
4373
4373
  var q = (0, import_qler.default)();
4374
+ var usePuck = (0, import_core5.createUsePuck)();
4374
4375
  var DEFAULT_API_VERSION = "v2";
4375
4376
  var BUILD_OP_DEBOUNCE_MS = 1e3 / 60;
4376
- var PLUGIN_AI_VERSION = true ? "0.8.2" : "unknown";
4377
- var BENCHMARK = false;
4377
+ var PLUGIN_AI_VERSION = true ? "0.9.0-canary.50fad349" : "unknown";
4378
4378
  var prefixedUlid = (prefix = "") => `${prefix ? `${prefix}_` : ""}${(0, import_ulid.ulid)()}`;
4379
- var getClassName18 = getClassNameFactory("Chat", styles_module_default);
4380
- var usePuck = (0, import_core5.createUsePuck)();
4381
- function Chat2(props) {
4382
- const {
4383
- apiVersion = DEFAULT_API_VERSION,
4384
- chat,
4385
- designMode = false,
4386
- defaultMode = "assembly",
4387
- host = "/api/puck/chat",
4388
- prepareRequest,
4389
- scrollTrackingId
4390
- } = props;
4391
- const {
4392
- attachments,
4393
- examplePrompts,
4394
- actions: chatActions,
4395
- placeholder
4396
- } = chat ?? {};
4379
+ function usePuckAi({
4380
+ host = "/api/puck/chat",
4381
+ streamHost = "/api/puck/stream",
4382
+ mode = "assembly",
4383
+ apiVersion = DEFAULT_API_VERSION,
4384
+ prepareRequest,
4385
+ onFinish,
4386
+ onError
4387
+ } = {}) {
4397
4388
  const puckDispatch = usePuck((s) => s.dispatch);
4398
4389
  const getPuck = (0, import_core5.useGetPuck)();
4399
4390
  const localChatId = (0, import_react27.useRef)("");
4400
- const inputRef = (0, import_react27.useRef)(null);
4401
- const pluginRef = (0, import_react27.useRef)(null);
4402
- const [mode, setMode] = (0, import_react27.useState)(defaultMode);
4391
+ const pendingBuildOpsRef = (0, import_react27.useRef)([]);
4392
+ const [error, setError] = (0, import_react27.useState)();
4393
+ const [toolStatus, setToolStatus] = (0, import_react27.useState)({});
4394
+ const [subagentState, setSubagentState] = (0, import_react27.useState)({});
4403
4395
  const modeRef = (0, import_react27.useRef)(mode);
4404
- const designModeVisible = typeof designMode === "boolean" ? designMode : designMode.visible ?? false;
4405
4396
  (0, import_react27.useEffect)(() => {
4406
4397
  modeRef.current = mode;
4407
4398
  }, [mode]);
@@ -4409,43 +4400,6 @@ function Chat2(props) {
4409
4400
  (0, import_react27.useEffect)(() => {
4410
4401
  syncDesignComponents(getPuck);
4411
4402
  }, [puckData, getPuck]);
4412
- const [error, setError] = (0, import_react27.useState)();
4413
- const [userError, setUserError] = (0, import_react27.useState)();
4414
- const [composerAttachments, setComposerAttachments] = (0, import_react27.useState)([]);
4415
- const removedAttachmentClientIdsRef = (0, import_react27.useRef)(/* @__PURE__ */ new Set());
4416
- const uploadControllersRef = (0, import_react27.useRef)(/* @__PURE__ */ new Map());
4417
- const pendingBuildOpsRef = (0, import_react27.useRef)([]);
4418
- const [toolStatus, setToolStatus] = (0, import_react27.useState)({});
4419
- const [subagentState, setSubagentState] = (0, import_react27.useState)({});
4420
- const attachmentConfig = (0, import_react27.useMemo)(
4421
- () => ({
4422
- accept: attachments?.accept ?? defaultAttachmentAccept,
4423
- enabled: attachments?.enabled ?? true,
4424
- endpoint: `${host.replace(/\/$/, "")}/attachments`,
4425
- maxFiles: attachments?.maxFiles ?? defaultAttachmentConfig.maxFiles,
4426
- maxSizeBytes: attachments?.maxSizeBytes ?? defaultAttachmentConfig.maxSizeBytes
4427
- }),
4428
- [attachments, host]
4429
- );
4430
- (0, import_react27.useEffect)(
4431
- () => () => {
4432
- uploadControllersRef.current.forEach((controller) => controller.abort());
4433
- uploadControllersRef.current.clear();
4434
- },
4435
- []
4436
- );
4437
- const deleteAttachment = (0, import_react27.useCallback)(
4438
- async (attachmentId) => {
4439
- try {
4440
- await fetch(`${attachmentConfig.endpoint}/${attachmentId}`, {
4441
- method: "DELETE"
4442
- });
4443
- } catch (e) {
4444
- console.error(e);
4445
- }
4446
- },
4447
- [attachmentConfig.endpoint]
4448
- );
4449
4403
  const uploadScreenshot = (0, import_react27.useCallback)(
4450
4404
  async (width, bucketUrl) => {
4451
4405
  try {
@@ -4495,7 +4449,7 @@ function Chat2(props) {
4495
4449
  nextFrame(() => {
4496
4450
  const { dispatch, config, resolveDataById } = getPuck();
4497
4451
  operations.forEach((queuedOperation) => {
4498
- (0, import_reducer.dispatchOp)(queuedOperation, {
4452
+ dispatchOp(queuedOperation, {
4499
4453
  getState: () => {
4500
4454
  const { __private } = getPuck();
4501
4455
  return __private.appState;
@@ -4527,6 +4481,9 @@ function Chat2(props) {
4527
4481
  );
4528
4482
  const processData = (0, import_react27.useCallback)(
4529
4483
  (dataPart) => {
4484
+ if (dataPart.type.indexOf("data-") !== 0) {
4485
+ return;
4486
+ }
4530
4487
  switch (dataPart.type) {
4531
4488
  case "data-new-chat-created": {
4532
4489
  localChatId.current = dataPart.data.chatId;
@@ -4644,6 +4601,9 @@ function Chat2(props) {
4644
4601
  debouncedFlushBuildOps.flush();
4645
4602
  return;
4646
4603
  }
4604
+ case "data-page": {
4605
+ return;
4606
+ }
4647
4607
  case "data-version-notice": {
4648
4608
  console.warn(dataPart.data.message);
4649
4609
  return;
@@ -4661,32 +4621,54 @@ function Chat2(props) {
4661
4621
  uploadScreenshot
4662
4622
  ]
4663
4623
  );
4664
- const { messages, status, sendMessage, regenerate, setMessages, stop } = useChat({
4624
+ const getRequestConfig = (0, import_react27.useCallback)(() => {
4625
+ const { config, appState } = getPuck();
4626
+ const root = config.root ?? {
4627
+ fields: {
4628
+ title: {
4629
+ type: "text",
4630
+ ai: { instructions: "The title for the page" }
4631
+ }
4632
+ }
4633
+ };
4634
+ return {
4635
+ ...config,
4636
+ root,
4637
+ components: {
4638
+ ...config.components,
4639
+ ...getRequestComponentConfigs(appState.data)
4640
+ }
4641
+ };
4642
+ }, [getPuck]);
4643
+ const settle = (0, import_react27.useCallback)(
4644
+ async ({ isAbort } = {}) => {
4645
+ debouncedFlushBuildOps.flush();
4646
+ await q.wait();
4647
+ if (!isAbort) {
4648
+ puckDispatch({
4649
+ type: "set",
4650
+ state: getPuck().appState,
4651
+ recordHistory: true
4652
+ });
4653
+ }
4654
+ },
4655
+ [debouncedFlushBuildOps, getPuck, puckDispatch]
4656
+ );
4657
+ const {
4658
+ messages,
4659
+ status: chatStatus,
4660
+ sendMessage: chatSendMessage,
4661
+ regenerate,
4662
+ setMessages,
4663
+ stop
4664
+ } = useChat({
4665
4665
  generateId: () => prefixedUlid("msg"),
4666
4666
  messages: [],
4667
4667
  transport: new import_ai5.DefaultChatTransport({
4668
4668
  api: host,
4669
4669
  prepareSendMessagesRequest: async (opts) => {
4670
- const { config, appState } = getPuck();
4671
- if (BENCHMARK) {
4672
- console.time("chat");
4673
- }
4674
- const root = config.root ?? {
4675
- fields: {
4676
- title: {
4677
- type: "text",
4678
- ai: { instructions: "The title for the page" }
4679
- }
4680
- }
4681
- };
4682
- const configWithRoot = {
4683
- ...config,
4684
- root,
4685
- components: {
4686
- ...config.components,
4687
- ...getRequestComponentConfigs(appState.data)
4688
- }
4689
- };
4670
+ const { appState } = getPuck();
4671
+ const configWithRoot = getRequestConfig();
4690
4672
  const defaultOptions = {
4691
4673
  headers: {
4692
4674
  ...opts.headers,
@@ -4703,62 +4685,346 @@ function Chat2(props) {
4703
4685
  config: configWithRoot,
4704
4686
  mode: modeRef.current
4705
4687
  }
4706
- };
4707
- if (prepareRequest) {
4708
- const userOptions = await prepareRequest(defaultOptions);
4709
- return {
4710
- headers: {
4711
- ...defaultOptions.headers,
4712
- ...userOptions.headers
4713
- },
4714
- credentials: userOptions.credentials ?? defaultOptions.credentials,
4715
- body: {
4716
- ...defaultOptions.body,
4717
- ...userOptions.body
4718
- }
4719
- };
4720
- }
4721
- return defaultOptions;
4688
+ };
4689
+ if (prepareRequest) {
4690
+ const userOptions = await prepareRequest(defaultOptions);
4691
+ return {
4692
+ headers: {
4693
+ ...defaultOptions.headers,
4694
+ ...userOptions.headers
4695
+ },
4696
+ credentials: userOptions.credentials ?? defaultOptions.credentials,
4697
+ body: {
4698
+ ...defaultOptions.body,
4699
+ ...userOptions.body
4700
+ }
4701
+ };
4702
+ }
4703
+ return defaultOptions;
4704
+ }
4705
+ }),
4706
+ onData: processData,
4707
+ onError: (e) => {
4708
+ console.error(e);
4709
+ setError(e.message);
4710
+ onError?.(e);
4711
+ },
4712
+ onFinish: (options) => {
4713
+ settle(options).then(() => onFinish?.(options));
4714
+ }
4715
+ });
4716
+ const sendMessage = (0, import_react27.useCallback)(
4717
+ async (prompt, opts = {}) => {
4718
+ const text = prompt.trim();
4719
+ const files = opts.files ?? [];
4720
+ if (!text && files.length === 0) return;
4721
+ if (opts.mode) modeRef.current = opts.mode;
4722
+ setError(void 0);
4723
+ await chatSendMessage({
4724
+ role: "user",
4725
+ parts: [...text ? [{ type: "text", text }] : [], ...files]
4726
+ });
4727
+ },
4728
+ [chatSendMessage]
4729
+ );
4730
+ const [isStreaming, setIsStreaming] = (0, import_react27.useState)(false);
4731
+ const streamAbortRef = (0, import_react27.useRef)(null);
4732
+ const stream = (0, import_react27.useCallback)(
4733
+ async (prompt, opts = {}) => {
4734
+ const text = prompt.trim();
4735
+ if (!text) return;
4736
+ streamAbortRef.current?.abort();
4737
+ const controller = new AbortController();
4738
+ streamAbortRef.current = controller;
4739
+ setError(void 0);
4740
+ setIsStreaming(true);
4741
+ try {
4742
+ const { appState } = getPuck();
4743
+ const response = await fetch(streamHost, {
4744
+ method: "POST",
4745
+ headers: {
4746
+ "Content-Type": "application/json",
4747
+ "puck-api-version": apiVersion,
4748
+ "x-puck-plugin-ai-version": PLUGIN_AI_VERSION
4749
+ },
4750
+ body: JSON.stringify({
4751
+ prompt: text,
4752
+ config: getRequestConfig(),
4753
+ pageData: appState.data,
4754
+ mode: opts.mode ?? modeRef.current,
4755
+ context: opts.context
4756
+ }),
4757
+ signal: controller.signal
4758
+ });
4759
+ if (!response.ok || !response.body) {
4760
+ throw new Error(
4761
+ `Puck AI request failed: ${response.status} ${response.statusText}`
4762
+ );
4763
+ }
4764
+ for await (const part of iterateSSE(response.body)) {
4765
+ if (controller.signal.aborted) return;
4766
+ if (part.type === "error") throw new Error(part.errorText);
4767
+ processData(part);
4768
+ }
4769
+ await settle();
4770
+ } catch (e) {
4771
+ if (controller.signal.aborted) return;
4772
+ const err = e instanceof Error ? e : new Error(String(e));
4773
+ console.error(err);
4774
+ setError(err.message);
4775
+ onError?.(err);
4776
+ } finally {
4777
+ if (streamAbortRef.current === controller) {
4778
+ streamAbortRef.current = null;
4779
+ setIsStreaming(false);
4780
+ }
4781
+ }
4782
+ },
4783
+ [
4784
+ apiVersion,
4785
+ getPuck,
4786
+ getRequestConfig,
4787
+ onError,
4788
+ processData,
4789
+ settle,
4790
+ streamHost
4791
+ ]
4792
+ );
4793
+ const stopAll = (0, import_react27.useCallback)(() => {
4794
+ streamAbortRef.current?.abort();
4795
+ streamAbortRef.current = null;
4796
+ setIsStreaming(false);
4797
+ stop();
4798
+ }, [stop]);
4799
+ (0, import_react27.useEffect)(() => () => stopAll(), [stopAll]);
4800
+ return {
4801
+ /**
4802
+ * Send a prompt as the next turn of a conversation. The agent sees the
4803
+ * history, and can write, check its work and correct itself.
4804
+ */
4805
+ sendMessage,
4806
+ /**
4807
+ * Run a one-shot generation from a prompt, with no conversation. Cheaper
4808
+ * and more predictable than `sendMessage`, but it stops after its first
4809
+ * write rather than reviewing the result.
4810
+ */
4811
+ stream,
4812
+ /** Abort whichever request is in flight */
4813
+ stop: stopAll,
4814
+ status: isStreaming ? "streaming" : chatStatus,
4815
+ /** The conversation so far, for building a transcript */
4816
+ messages,
4817
+ setMessages,
4818
+ regenerate,
4819
+ error,
4820
+ /** Live per-tool progress, keyed by tool call id */
4821
+ toolStatus,
4822
+ /** Live subagent progress, keyed by tool call id */
4823
+ subagentState,
4824
+ /**
4825
+ * @internal Apply a single stream part to the editor. Exposed for
4826
+ * replaying a recorded stream (the marketing demo) — a real agent should
4827
+ * go through `stream`.
4828
+ */
4829
+ processData
4830
+ };
4831
+ }
4832
+ function finalizeReasoningParts(parts) {
4833
+ return parts.map(
4834
+ (part) => part.kind === "reasoning" && part.state !== "done" ? { ...part, state: "done" } : part
4835
+ );
4836
+ }
4837
+ function reduceSubagentEvent(current, event) {
4838
+ if (event.kind === "start") {
4839
+ if (current[event.toolCallId]) return current;
4840
+ return {
4841
+ ...current,
4842
+ [event.toolCallId]: {
4843
+ toolCallId: event.toolCallId,
4844
+ parentToolCallId: event.parentToolCallId,
4845
+ agentType: event.agentType,
4846
+ depth: event.depth,
4847
+ label: event.label,
4848
+ state: "running",
4849
+ parts: []
4850
+ }
4851
+ };
4852
+ }
4853
+ const existing = current[event.toolCallId];
4854
+ if (!existing) return current;
4855
+ if (event.kind === "finish") {
4856
+ return {
4857
+ ...current,
4858
+ [event.toolCallId]: {
4859
+ ...existing,
4860
+ state: "done",
4861
+ parts: finalizeReasoningParts(existing.parts)
4862
+ }
4863
+ };
4864
+ }
4865
+ if (event.kind === "reasoning-delta") {
4866
+ const parts = [...existing.parts];
4867
+ const last = parts[parts.length - 1];
4868
+ if (last && last.kind === "reasoning" && last.state !== "done") {
4869
+ const separator = last.blockId !== event.blockId ? "\n\n" : "";
4870
+ parts[parts.length - 1] = {
4871
+ ...last,
4872
+ blockId: event.blockId,
4873
+ text: last.text + separator + event.text
4874
+ };
4875
+ } else {
4876
+ parts.push({
4877
+ kind: "reasoning",
4878
+ blockId: event.blockId,
4879
+ text: event.text,
4880
+ state: "streaming"
4881
+ });
4882
+ }
4883
+ return {
4884
+ ...current,
4885
+ [event.toolCallId]: { ...existing, parts }
4886
+ };
4887
+ }
4888
+ if (event.kind === "text-delta") {
4889
+ const parts = finalizeReasoningParts(existing.parts);
4890
+ const last = parts[parts.length - 1];
4891
+ if (last && last.kind === "text" && last.blockId === event.blockId) {
4892
+ parts[parts.length - 1] = { ...last, text: last.text + event.text };
4893
+ } else {
4894
+ parts.push({ kind: "text", blockId: event.blockId, text: event.text });
4895
+ }
4896
+ return {
4897
+ ...current,
4898
+ [event.toolCallId]: { ...existing, parts }
4899
+ };
4900
+ }
4901
+ if (event.kind === "tool-call") {
4902
+ return {
4903
+ ...current,
4904
+ [event.toolCallId]: {
4905
+ ...existing,
4906
+ parts: [
4907
+ ...finalizeReasoningParts(existing.parts),
4908
+ {
4909
+ kind: "tool",
4910
+ childToolCallId: event.childToolCallId,
4911
+ toolName: event.toolName,
4912
+ input: event.input
4913
+ }
4914
+ ]
4722
4915
  }
4723
- }),
4724
- onData: processData,
4725
- onError: (e) => {
4726
- console.error(e);
4727
- if (BENCHMARK) {
4728
- console.timeEnd("chat");
4916
+ };
4917
+ }
4918
+ if (event.kind === "tool-result") {
4919
+ return {
4920
+ ...current,
4921
+ [event.toolCallId]: {
4922
+ ...existing,
4923
+ parts: existing.parts.map(
4924
+ (part) => part.kind === "tool" && part.childToolCallId === event.childToolCallId ? { ...part, output: event.output } : part
4925
+ )
4729
4926
  }
4730
- setError(e.message);
4731
- },
4732
- onFinish: (options) => {
4733
- debouncedFlushBuildOps.flush();
4734
- q.wait().then(() => {
4735
- if (!options.isAbort) {
4736
- puckDispatch({
4737
- type: "set",
4738
- state: getPuck().appState,
4739
- recordHistory: true
4740
- });
4741
- }
4742
- chat?.onFinish?.(options);
4743
- }).finally(() => {
4744
- if (BENCHMARK) {
4745
- console.timeEnd("chat");
4746
- }
4747
- });
4748
- }
4749
- });
4750
- (0, import_react27.useEffect)(
4927
+ };
4928
+ }
4929
+ return current;
4930
+ }
4931
+ function nextFrame(cb) {
4932
+ let ran = false;
4933
+ const run = () => {
4934
+ if (ran) return;
4935
+ ran = true;
4936
+ cb();
4937
+ };
4938
+ if (typeof document !== "undefined" && document.hidden) {
4939
+ queueMicrotask(run);
4940
+ return;
4941
+ }
4942
+ requestAnimationFrame(run);
4943
+ setTimeout(run, 100);
4944
+ }
4945
+
4946
+ // src/components/Chat/index.tsx
4947
+ var import_jsx_runtime35 = require("react/jsx-runtime");
4948
+ var getClassName18 = getClassNameFactory("Chat", styles_module_default);
4949
+ var usePuck2 = (0, import_core6.createUsePuck)();
4950
+ function Chat2(props) {
4951
+ const {
4952
+ apiVersion = DEFAULT_API_VERSION,
4953
+ chat,
4954
+ designMode = false,
4955
+ defaultMode = "assembly",
4956
+ host = "/api/puck/chat",
4957
+ prepareRequest,
4958
+ scrollTrackingId
4959
+ } = props;
4960
+ const {
4961
+ attachments,
4962
+ examplePrompts,
4963
+ actions: chatActions,
4964
+ placeholder
4965
+ } = chat ?? {};
4966
+ const puckDispatch = usePuck2((s) => s.dispatch);
4967
+ const inputRef = (0, import_react28.useRef)(null);
4968
+ const pluginRef = (0, import_react28.useRef)(null);
4969
+ const [mode, setMode] = (0, import_react28.useState)(defaultMode);
4970
+ const designModeVisible = typeof designMode === "boolean" ? designMode : designMode.visible ?? false;
4971
+ const [error, setError] = (0, import_react28.useState)();
4972
+ const [userError, setUserError] = (0, import_react28.useState)();
4973
+ const [composerAttachments, setComposerAttachments] = (0, import_react28.useState)([]);
4974
+ const removedAttachmentClientIdsRef = (0, import_react28.useRef)(/* @__PURE__ */ new Set());
4975
+ const uploadControllersRef = (0, import_react28.useRef)(/* @__PURE__ */ new Map());
4976
+ const attachmentConfig = (0, import_react28.useMemo)(
4977
+ () => ({
4978
+ accept: attachments?.accept ?? defaultAttachmentAccept,
4979
+ enabled: attachments?.enabled ?? true,
4980
+ endpoint: `${host.replace(/\/$/, "")}/attachments`,
4981
+ maxFiles: attachments?.maxFiles ?? defaultAttachmentConfig.maxFiles,
4982
+ maxSizeBytes: attachments?.maxSizeBytes ?? defaultAttachmentConfig.maxSizeBytes
4983
+ }),
4984
+ [attachments, host]
4985
+ );
4986
+ (0, import_react28.useEffect)(
4751
4987
  () => () => {
4752
- stop();
4988
+ uploadControllersRef.current.forEach((controller) => controller.abort());
4989
+ uploadControllersRef.current.clear();
4990
+ },
4991
+ []
4992
+ );
4993
+ const deleteAttachment = (0, import_react28.useCallback)(
4994
+ async (attachmentId) => {
4995
+ try {
4996
+ await fetch(`${attachmentConfig.endpoint}/${attachmentId}`, {
4997
+ method: "DELETE"
4998
+ });
4999
+ } catch (e) {
5000
+ console.error(e);
5001
+ }
4753
5002
  },
4754
- [stop]
5003
+ [attachmentConfig.endpoint]
4755
5004
  );
4756
- const [forcedStatus, setForcedStatus] = (0, import_react27.useState)();
4757
- const resolvedStatus = (0, import_react27.useMemo)(
5005
+ const {
5006
+ sendMessage,
5007
+ status,
5008
+ messages,
5009
+ setMessages,
5010
+ regenerate,
5011
+ error: aiError,
5012
+ toolStatus,
5013
+ subagentState,
5014
+ processData
5015
+ } = usePuckAi({
5016
+ host,
5017
+ mode,
5018
+ apiVersion,
5019
+ prepareRequest,
5020
+ onFinish: chat?.onFinish
5021
+ });
5022
+ const [forcedStatus, setForcedStatus] = (0, import_react28.useState)();
5023
+ const resolvedStatus = (0, import_react28.useMemo)(
4758
5024
  () => forcedStatus ?? status,
4759
5025
  [status, forcedStatus]
4760
5026
  );
4761
- (0, import_react27.useEffect)(() => {
5027
+ (0, import_react28.useEffect)(() => {
4762
5028
  if (!scrollTrackingId) return;
4763
5029
  dispatchScrollTrackingEvent({
4764
5030
  id: scrollTrackingId,
@@ -4771,12 +5037,16 @@ function Chat2(props) {
4771
5037
  });
4772
5038
  };
4773
5039
  }, [resolvedStatus, scrollTrackingId]);
4774
- (0, import_react27.useEffect)(() => {
5040
+ (0, import_react28.useEffect)(() => {
4775
5041
  window.__PUCK_AI = {
4776
5042
  processData,
4777
5043
  setMessages,
4778
5044
  setStatus: setForcedStatus,
4779
- sendMessage,
5045
+ sendMessage: (message) => sendMessage(
5046
+ message.parts.filter(
5047
+ (part) => Boolean(part && part.type === "text")
5048
+ ).map((part) => part.text).join("")
5049
+ ),
4780
5050
  focus: () => inputRef?.current?.focus()
4781
5051
  };
4782
5052
  }, [processData]);
@@ -4818,13 +5088,7 @@ function Chat2(props) {
4818
5088
  }
4819
5089
  setComposerAttachments([]);
4820
5090
  removedAttachmentClientIdsRef.current.clear();
4821
- sendMessage({
4822
- role: "user",
4823
- parts: [
4824
- ...text ? [{ type: "text", text }] : [],
4825
- ...readyAttachments
4826
- ]
4827
- }).catch((e) => {
5091
+ sendMessage(text, { files: readyAttachments }).catch((e) => {
4828
5092
  console.error(e);
4829
5093
  setError("Failed to send message.");
4830
5094
  setComposerAttachments(composerAttachments);
@@ -4980,7 +5244,7 @@ function Chat2(props) {
4980
5244
  if (!target?.attachmentId) return;
4981
5245
  await deleteAttachment(target.attachmentId);
4982
5246
  };
4983
- const messagesWithStatuses = (0, import_react27.useMemo)(() => {
5247
+ const messagesWithStatuses = (0, import_react28.useMemo)(() => {
4984
5248
  return messages.map((msg) => {
4985
5249
  return {
4986
5250
  ...msg,
@@ -5040,7 +5304,7 @@ function Chat2(props) {
5040
5304
  label
5041
5305
  )
5042
5306
  ),
5043
- error,
5307
+ error: error ?? aiError,
5044
5308
  handleRetry: () => {
5045
5309
  setError("");
5046
5310
  regenerate();
@@ -5058,105 +5322,6 @@ function Chat2(props) {
5058
5322
  }
5059
5323
  ) }) }) }) });
5060
5324
  }
5061
- function finalizeReasoningParts(parts) {
5062
- return parts.map(
5063
- (part) => part.kind === "reasoning" && part.state !== "done" ? { ...part, state: "done" } : part
5064
- );
5065
- }
5066
- function reduceSubagentEvent(current, event) {
5067
- if (event.kind === "start") {
5068
- if (current[event.toolCallId]) return current;
5069
- return {
5070
- ...current,
5071
- [event.toolCallId]: {
5072
- toolCallId: event.toolCallId,
5073
- parentToolCallId: event.parentToolCallId,
5074
- agentType: event.agentType,
5075
- depth: event.depth,
5076
- label: event.label,
5077
- state: "running",
5078
- parts: []
5079
- }
5080
- };
5081
- }
5082
- const existing = current[event.toolCallId];
5083
- if (!existing) return current;
5084
- if (event.kind === "finish") {
5085
- return {
5086
- ...current,
5087
- [event.toolCallId]: {
5088
- ...existing,
5089
- state: "done",
5090
- parts: finalizeReasoningParts(existing.parts)
5091
- }
5092
- };
5093
- }
5094
- if (event.kind === "reasoning-delta") {
5095
- const parts = [...existing.parts];
5096
- const last = parts[parts.length - 1];
5097
- if (last && last.kind === "reasoning" && last.state !== "done") {
5098
- const separator = last.blockId !== event.blockId ? "\n\n" : "";
5099
- parts[parts.length - 1] = {
5100
- ...last,
5101
- blockId: event.blockId,
5102
- text: last.text + separator + event.text
5103
- };
5104
- } else {
5105
- parts.push({
5106
- kind: "reasoning",
5107
- blockId: event.blockId,
5108
- text: event.text,
5109
- state: "streaming"
5110
- });
5111
- }
5112
- return {
5113
- ...current,
5114
- [event.toolCallId]: { ...existing, parts }
5115
- };
5116
- }
5117
- if (event.kind === "text-delta") {
5118
- const parts = finalizeReasoningParts(existing.parts);
5119
- const last = parts[parts.length - 1];
5120
- if (last && last.kind === "text" && last.blockId === event.blockId) {
5121
- parts[parts.length - 1] = { ...last, text: last.text + event.text };
5122
- } else {
5123
- parts.push({ kind: "text", blockId: event.blockId, text: event.text });
5124
- }
5125
- return {
5126
- ...current,
5127
- [event.toolCallId]: { ...existing, parts }
5128
- };
5129
- }
5130
- if (event.kind === "tool-call") {
5131
- return {
5132
- ...current,
5133
- [event.toolCallId]: {
5134
- ...existing,
5135
- parts: [
5136
- ...finalizeReasoningParts(existing.parts),
5137
- {
5138
- kind: "tool",
5139
- childToolCallId: event.childToolCallId,
5140
- toolName: event.toolName,
5141
- input: event.input
5142
- }
5143
- ]
5144
- }
5145
- };
5146
- }
5147
- if (event.kind === "tool-result") {
5148
- return {
5149
- ...current,
5150
- [event.toolCallId]: {
5151
- ...existing,
5152
- parts: existing.parts.map(
5153
- (part) => part.kind === "tool" && part.childToolCallId === event.childToolCallId ? { ...part, output: event.output } : part
5154
- )
5155
- }
5156
- };
5157
- }
5158
- return current;
5159
- }
5160
5325
  function AttachmentComposer({
5161
5326
  accept,
5162
5327
  attachments,
@@ -5164,8 +5329,8 @@ function AttachmentComposer({
5164
5329
  maxFiles,
5165
5330
  onChange
5166
5331
  }) {
5167
- const id = (0, import_react27.useId)();
5168
- const inputId = (0, import_react27.useMemo)(() => `attachment-input-${id}`, []);
5332
+ const id = (0, import_react28.useId)();
5333
+ const inputId = (0, import_react28.useMemo)(() => `attachment-input-${id}`, []);
5169
5334
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: getClassName18("attachmentControls"), children: [
5170
5335
  /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
5171
5336
  "input",
@@ -5242,20 +5407,6 @@ function Placeholder({
5242
5407
  ] })
5243
5408
  ] });
5244
5409
  }
5245
- function nextFrame(cb) {
5246
- let ran = false;
5247
- const run = () => {
5248
- if (ran) return;
5249
- ran = true;
5250
- cb();
5251
- };
5252
- if (typeof document !== "undefined" && document.hidden) {
5253
- queueMicrotask(run);
5254
- return;
5255
- }
5256
- requestAnimationFrame(run);
5257
- setTimeout(run, 100);
5258
- }
5259
5410
  function isScrolledIntoView(el) {
5260
5411
  const rect = el.getBoundingClientRect();
5261
5412
  const elemTop = rect.top;
@@ -5265,7 +5416,7 @@ function isScrolledIntoView(el) {
5265
5416
 
5266
5417
  // src/components/ScrollTracking/ScrollTracking.tsx
5267
5418
  init_react_import();
5268
- var import_react29 = require("react");
5419
+ var import_react30 = require("react");
5269
5420
 
5270
5421
  // src/lib/scroll-into-view-local.ts
5271
5422
  init_react_import();
@@ -5288,9 +5439,9 @@ function scrollIntoViewLocal(el, win, behavior = "smooth") {
5288
5439
 
5289
5440
  // src/lib/use-frame-mutation-observer.ts
5290
5441
  init_react_import();
5291
- var import_react28 = require("react");
5442
+ var import_react29 = require("react");
5292
5443
  function useFrameMutationObserver(callback) {
5293
- return (0, import_react28.useCallback)(() => {
5444
+ return (0, import_react29.useCallback)(() => {
5294
5445
  const frame = document?.getElementById(
5295
5446
  "preview-frame"
5296
5447
  );
@@ -5335,9 +5486,9 @@ var ScrollTracking = ({
5335
5486
  children,
5336
5487
  trackingId
5337
5488
  }) => {
5338
- const followedRefs = (0, import_react29.useRef)([]);
5339
- const enabledRef = (0, import_react29.useRef)(false);
5340
- (0, import_react29.useEffect)(() => {
5489
+ const followedRefs = (0, import_react30.useRef)([]);
5490
+ const enabledRef = (0, import_react30.useRef)(false);
5491
+ (0, import_react30.useEffect)(() => {
5341
5492
  return subscribeToScrollTrackingEvents(({ id, enabled }) => {
5342
5493
  if (id !== trackingId) return;
5343
5494
  enabledRef.current = enabled;
@@ -5356,7 +5507,7 @@ var ScrollTracking = ({
5356
5507
  });
5357
5508
  }
5358
5509
  });
5359
- (0, import_react29.useEffect)(() => {
5510
+ (0, import_react30.useEffect)(() => {
5360
5511
  follow();
5361
5512
  }, [follow]);
5362
5513
  return children;
@@ -5364,12 +5515,12 @@ var ScrollTracking = ({
5364
5515
 
5365
5516
  // src/components/Drawer/index.tsx
5366
5517
  init_react_import();
5367
- var import_core7 = require("@puckeditor/core");
5518
+ var import_core8 = require("@puckeditor/core");
5368
5519
 
5369
5520
  // src/components/ManageComponents/index.tsx
5370
5521
  init_react_import();
5371
- var import_core6 = require("@puckeditor/core");
5372
- var import_react30 = require("react");
5522
+ var import_core7 = require("@puckeditor/core");
5523
+ var import_react31 = require("react");
5373
5524
 
5374
5525
  // css-module:/home/runner/work/platform/platform/packages/plugin-ai/src/components/ManageComponents/styles.module.css#css-module
5375
5526
  init_react_import();
@@ -5378,17 +5529,17 @@ var styles_module_default10 = { "ManageComponents-cta": "_ManageComponents-cta_x
5378
5529
  // src/components/ManageComponents/index.tsx
5379
5530
  var import_jsx_runtime36 = require("react/jsx-runtime");
5380
5531
  var cx10 = getClassNameFactory2("ManageComponents", styles_module_default10);
5381
- var useRegistrations = () => (0, import_react30.useSyncExternalStore)(
5532
+ var useRegistrations = () => (0, import_react31.useSyncExternalStore)(
5382
5533
  registrationStore.subscribe,
5383
5534
  () => registrationStore.getAll(),
5384
5535
  () => registrationStore.getAll()
5385
5536
  );
5386
5537
  function ManageModalContent({ onClose }) {
5387
- const getPuck = (0, import_core6.useGetPuck)();
5538
+ const getPuck = (0, import_core7.useGetPuck)();
5388
5539
  const { visible, setVisible } = useModal();
5389
- const [confirmTarget, setConfirmTarget] = (0, import_react30.useState)(null);
5540
+ const [confirmTarget, setConfirmTarget] = (0, import_react31.useState)(null);
5390
5541
  const entries = useRegistrations();
5391
- (0, import_react30.useEffect)(() => {
5542
+ (0, import_react31.useEffect)(() => {
5392
5543
  if (!visible) onClose();
5393
5544
  }, [visible, onClose]);
5394
5545
  const handleDelete = (name) => {
@@ -5443,9 +5594,9 @@ function ManageModalContent({ onClose }) {
5443
5594
  ] }) });
5444
5595
  }
5445
5596
  function ManageComponentsCta() {
5446
- const [open, setOpen] = (0, import_react30.useState)(false);
5597
+ const [open, setOpen] = (0, import_react31.useState)(false);
5447
5598
  const entries = useRegistrations();
5448
- const handleClose = (0, import_react30.useCallback)(() => setOpen(false), []);
5599
+ const handleClose = (0, import_react31.useCallback)(() => setOpen(false), []);
5449
5600
  if (entries.length === 0) return null;
5450
5601
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
5451
5602
  /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("button", { className: cx10("cta"), onClick: () => setOpen(true), type: "button", children: [
@@ -5462,10 +5613,10 @@ var styles_module_default11 = { "Drawer--empty": "_Drawer--empty_8e8cs_1" };
5462
5613
 
5463
5614
  // src/components/Drawer/index.tsx
5464
5615
  var import_jsx_runtime37 = require("react/jsx-runtime");
5465
- var usePuck2 = (0, import_core7.createUsePuck)();
5616
+ var usePuck3 = (0, import_core8.createUsePuck)();
5466
5617
  var cx11 = get_class_name_factory_default("Drawer", styles_module_default11);
5467
5618
  var createDrawer = (designModeVisible) => function Drawer({ children }) {
5468
- const config = usePuck2((s) => s.config);
5619
+ const config = usePuck3((s) => s.config);
5469
5620
  if (Object.keys(config.components).length === 0) {
5470
5621
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cx11({ empty: true }), children: "No blocks" });
5471
5622
  }
@@ -5475,8 +5626,8 @@ var createDrawer = (designModeVisible) => function Drawer({ children }) {
5475
5626
  ] });
5476
5627
  };
5477
5628
 
5478
- // src/index.tsx
5479
- var import_jsx_runtime38 = require("react/jsx-runtime");
5629
+ // src/lib/design/with-dynamic-config.ts
5630
+ init_react_import();
5480
5631
  function withDynamicConfig(config, data) {
5481
5632
  const registrations = getPersistedRegistrations(data);
5482
5633
  const dynamicConfig = {};
@@ -5506,6 +5657,9 @@ function withDynamicConfig(config, data) {
5506
5657
  applyConfigFieldMetadata(result, dynamicConfig);
5507
5658
  return result;
5508
5659
  }
5660
+
5661
+ // src/index.tsx
5662
+ var import_jsx_runtime38 = require("react/jsx-runtime");
5509
5663
  function createAiPlugin(opts) {
5510
5664
  const { scrollTracking = true, ...rest } = opts || {};
5511
5665
  const scrollTrackingId = `puck-ai-scroll-${(0, import_ulid2.ulid)()}`;
@@ -5530,6 +5684,7 @@ function createAiPlugin(opts) {
5530
5684
  // Annotate the CommonJS export names for ESM import in node:
5531
5685
  0 && (module.exports = {
5532
5686
  createAiPlugin,
5687
+ usePuckAi,
5533
5688
  withDynamicConfig
5534
5689
  });
5535
5690
  /*! Bundled license information: