@pgege/kaboo-react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,1366 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ ActivityPanel: () => ActivityPanel,
24
+ AgentCard: () => AgentCard,
25
+ DrillDetailView: () => DrillDetailView,
26
+ DrillProvider: () => DrillProvider,
27
+ GlassTabs: () => GlassTabs,
28
+ InterruptBridgeProvider: () => InterruptBridgeProvider,
29
+ InterruptBridgePublisher: () => InterruptBridgePublisher,
30
+ InterruptRenderer: () => InterruptRenderer,
31
+ KabooActivityProvider: () => KabooActivityProvider,
32
+ KabooProvider: () => KabooProvider,
33
+ MarkdownContent: () => MarkdownContent,
34
+ MiniTable: () => MiniTable,
35
+ StructuredRenderersContext: () => StructuredRenderersContext,
36
+ Timeline: () => Timeline,
37
+ ToolRow: () => ToolRow,
38
+ directChildren: () => directChildren,
39
+ formatToolInput: () => formatToolInput,
40
+ formatToolResult: () => formatToolResult,
41
+ normalizeResult: () => normalizeResult,
42
+ topLevelGroups: () => topLevelGroups,
43
+ useActivity: () => useActivity,
44
+ useDrill: () => useDrill,
45
+ useInterruptBridge: () => useInterruptBridge,
46
+ useInterruptFor: () => useInterruptFor
47
+ });
48
+ module.exports = __toCommonJS(src_exports);
49
+
50
+ // src/context/ActivityProvider.tsx
51
+ var import_react = require("react");
52
+ var import_v2 = require("@copilotkit/react-core/v2");
53
+ var import_jsx_runtime = require("react/jsx-runtime");
54
+ var EMPTY = { groups: {} };
55
+ var ActivityContext = (0, import_react.createContext)(EMPTY);
56
+ var StructuredRenderersContext = (0, import_react.createContext)({});
57
+ function KabooActivityProvider({ agentId, structuredRenderers, children }) {
58
+ const { agent } = (0, import_v2.useAgent)(agentId ? { agentId } : void 0);
59
+ const [state, setState] = (0, import_react.useState)(EMPTY);
60
+ (0, import_react.useEffect)(() => {
61
+ if (!agent) return;
62
+ const { unsubscribe } = agent.subscribe({
63
+ onActivitySnapshotEvent: ({ event }) => {
64
+ setState(event.content);
65
+ }
66
+ });
67
+ return unsubscribe;
68
+ }, [agent]);
69
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ActivityContext.Provider, { value: state, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StructuredRenderersContext.Provider, { value: structuredRenderers ?? {}, children }) });
70
+ }
71
+
72
+ // src/context/DrillContext.tsx
73
+ var import_react2 = require("react");
74
+ var import_jsx_runtime2 = require("react/jsx-runtime");
75
+ var NOOP = () => {
76
+ };
77
+ var DrillContext = (0, import_react2.createContext)({
78
+ drillPath: [],
79
+ activeDrill: null,
80
+ drillIn: NOOP,
81
+ drillUp: NOOP,
82
+ drillToRoot: NOOP,
83
+ drillToLevel: NOOP
84
+ });
85
+ function DrillProvider({ children }) {
86
+ const [drillPath, setDrillPath] = (0, import_react2.useState)([]);
87
+ const drillIn = (0, import_react2.useCallback)((groupId) => {
88
+ setDrillPath((prev) => [...prev, groupId]);
89
+ }, []);
90
+ const drillUp = (0, import_react2.useCallback)(() => {
91
+ setDrillPath((prev) => prev.slice(0, -1));
92
+ }, []);
93
+ const drillToRoot = (0, import_react2.useCallback)(() => {
94
+ setDrillPath([]);
95
+ }, []);
96
+ const drillToLevel = (0, import_react2.useCallback)((level) => {
97
+ setDrillPath((prev) => prev.slice(0, level + 1));
98
+ }, []);
99
+ const activeDrill = drillPath.length > 0 ? drillPath[drillPath.length - 1] : null;
100
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DrillContext.Provider, { value: { drillPath, activeDrill, drillIn, drillUp, drillToRoot, drillToLevel }, children });
101
+ }
102
+
103
+ // src/context/KabooProvider.tsx
104
+ var import_v26 = require("@copilotkit/react-core/v2");
105
+
106
+ // src/context/InterruptBridge.tsx
107
+ var import_react3 = require("react");
108
+ var import_jsx_runtime3 = require("react/jsx-runtime");
109
+ var InterruptBridgeContext = (0, import_react3.createContext)({
110
+ active: [],
111
+ publish: () => {
112
+ }
113
+ });
114
+ function InterruptBridgeProvider({ children }) {
115
+ const [active, setActive] = (0, import_react3.useState)([]);
116
+ const publish = (0, import_react3.useCallback)((interrupts) => {
117
+ setActive(interrupts);
118
+ }, []);
119
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InterruptBridgeContext.Provider, { value: { active, publish }, children });
120
+ }
121
+ function useInterruptBridge() {
122
+ return (0, import_react3.useContext)(InterruptBridgeContext);
123
+ }
124
+ function useInterruptFor(toolCallId) {
125
+ const { active } = useInterruptBridge();
126
+ if (!toolCallId) return void 0;
127
+ return active.find((i) => i.toolCallId === toolCallId);
128
+ }
129
+ function InterruptBridgePublisher({
130
+ interrupts
131
+ }) {
132
+ const { publish } = useInterruptBridge();
133
+ const listRef = (0, import_react3.useRef)(interrupts);
134
+ listRef.current = interrupts;
135
+ const key = interrupts.map((i) => `${i.id}:${i.toolCallId ?? ""}:${JSON.stringify(i.reason)}`).join("|");
136
+ (0, import_react3.useEffect)(() => {
137
+ publish(
138
+ listRef.current.map((i) => ({
139
+ id: i.id,
140
+ reason: i.reason,
141
+ toolCallId: i.toolCallId,
142
+ onResolve: (payload) => listRef.current.find((x) => x.id === i.id)?.onResolve(payload),
143
+ onCancel: () => listRef.current.find((x) => x.id === i.id)?.onCancel()
144
+ }))
145
+ );
146
+ return () => publish([]);
147
+ }, [key, publish]);
148
+ return null;
149
+ }
150
+
151
+ // src/integrations/KabooInterruptHandler.tsx
152
+ var import_v23 = require("@copilotkit/react-core/v2");
153
+
154
+ // src/components/InterruptRenderer.tsx
155
+ var import_react4 = require("react");
156
+ var import_jsx_runtime4 = require("react/jsx-runtime");
157
+ function ApprovalVariant({ reason, onResolve, onCancel }) {
158
+ const [responded, setResponded] = (0, import_react4.useState)(false);
159
+ if (reason.type !== "approval") return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, {});
160
+ if (responded) {
161
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "kaboo-interrupt-responded", children: "Response submitted" });
162
+ }
163
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "kaboo-interrupt kaboo-interrupt-approval", children: [
164
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "kaboo-interrupt-header", children: [
165
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width: 16, height: 16, viewBox: "0 0 16 16", className: "kaboo-interrupt-icon", children: [
166
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { cx: "8", cy: "8", r: "7", fill: "none", stroke: "currentColor", strokeWidth: "1.5" }),
167
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M8 4.5v4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
168
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { cx: "8", cy: "11", r: "0.75", fill: "currentColor" })
169
+ ] }),
170
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "kaboo-interrupt-message", children: reason.message })
171
+ ] }),
172
+ reason.tool_input != null && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("details", { className: "kaboo-interrupt-details", children: [
173
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("summary", { children: "View input" }),
174
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("pre", { className: "kaboo-interrupt-pre", children: JSON.stringify(reason.tool_input, null, 2) })
175
+ ] }),
176
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "kaboo-interrupt-actions", children: [
177
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
178
+ "button",
179
+ {
180
+ className: "kaboo-interrupt-btn kaboo-interrupt-btn-approve",
181
+ onClick: () => {
182
+ setResponded(true);
183
+ onResolve({ status: "approved" });
184
+ },
185
+ children: "Approve"
186
+ }
187
+ ),
188
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
189
+ "button",
190
+ {
191
+ className: "kaboo-interrupt-btn kaboo-interrupt-btn-reject",
192
+ onClick: () => {
193
+ setResponded(true);
194
+ onCancel();
195
+ },
196
+ children: "Reject"
197
+ }
198
+ )
199
+ ] })
200
+ ] });
201
+ }
202
+ function withoutOther(options) {
203
+ return (options ?? []).filter((o) => o.trim().toLowerCase() !== "other");
204
+ }
205
+ function buildAnswerPayload(questions, answers) {
206
+ const out = {};
207
+ questions.forEach((q, idx) => {
208
+ out[q.question] = answers[String(idx)] ?? "";
209
+ });
210
+ return out;
211
+ }
212
+ function RadioInput({
213
+ question,
214
+ value,
215
+ onChange
216
+ }) {
217
+ const [otherText, setOtherText] = (0, import_react4.useState)("");
218
+ const [isOther, setIsOther] = (0, import_react4.useState)(false);
219
+ const options = withoutOther(question.options);
220
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "kaboo-interrupt-radio-group", children: [
221
+ options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: `kaboo-interrupt-option ${value === opt && !isOther ? "kaboo-interrupt-option-selected" : ""}`, children: [
222
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
223
+ "input",
224
+ {
225
+ type: "radio",
226
+ name: question.question,
227
+ checked: value === opt && !isOther,
228
+ onChange: () => {
229
+ setIsOther(false);
230
+ onChange(opt);
231
+ },
232
+ className: "kaboo-interrupt-radio"
233
+ }
234
+ ),
235
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: opt })
236
+ ] }, opt)),
237
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `kaboo-interrupt-option kaboo-interrupt-option-other ${isOther ? "kaboo-interrupt-option-selected" : ""}`, children: [
238
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
239
+ "input",
240
+ {
241
+ type: "radio",
242
+ name: question.question,
243
+ checked: isOther,
244
+ onChange: () => {
245
+ setIsOther(true);
246
+ onChange(otherText);
247
+ },
248
+ className: "kaboo-interrupt-radio"
249
+ }
250
+ ),
251
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
252
+ "input",
253
+ {
254
+ type: "text",
255
+ className: "kaboo-interrupt-text-input kaboo-interrupt-other-input",
256
+ placeholder: "Other (type your own answer)\u2026",
257
+ value: otherText,
258
+ onChange: (e) => {
259
+ setOtherText(e.target.value);
260
+ setIsOther(true);
261
+ onChange(e.target.value);
262
+ },
263
+ onFocus: () => {
264
+ setIsOther(true);
265
+ onChange(otherText);
266
+ }
267
+ }
268
+ )
269
+ ] })
270
+ ] });
271
+ }
272
+ function CheckboxInput({
273
+ question,
274
+ value,
275
+ onChange
276
+ }) {
277
+ const [otherText, setOtherText] = (0, import_react4.useState)("");
278
+ const options = withoutOther(question.options);
279
+ const toggle = (opt) => {
280
+ const next = value.includes(opt) ? value.filter((v) => v !== opt) : [...value, opt];
281
+ onChange(next);
282
+ };
283
+ const otherSelected = otherText !== "" && value.includes(otherText);
284
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "kaboo-interrupt-checkbox-group", children: [
285
+ options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: `kaboo-interrupt-option ${value.includes(opt) ? "kaboo-interrupt-option-selected" : ""}`, children: [
286
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
287
+ "input",
288
+ {
289
+ type: "checkbox",
290
+ checked: value.includes(opt),
291
+ onChange: () => toggle(opt),
292
+ className: "kaboo-interrupt-checkbox"
293
+ }
294
+ ),
295
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: opt })
296
+ ] }, opt)),
297
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `kaboo-interrupt-option kaboo-interrupt-option-other ${otherSelected ? "kaboo-interrupt-option-selected" : ""}`, children: [
298
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
299
+ "input",
300
+ {
301
+ type: "checkbox",
302
+ checked: otherSelected,
303
+ onChange: () => {
304
+ if (otherSelected) onChange(value.filter((v) => v !== otherText));
305
+ else if (otherText) onChange([...value, otherText]);
306
+ },
307
+ className: "kaboo-interrupt-checkbox"
308
+ }
309
+ ),
310
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
311
+ "input",
312
+ {
313
+ type: "text",
314
+ className: "kaboo-interrupt-text-input kaboo-interrupt-other-input",
315
+ placeholder: "Other (type your own answer)\u2026",
316
+ value: otherText,
317
+ onChange: (e) => {
318
+ const prev = otherText;
319
+ const nextText = e.target.value;
320
+ setOtherText(nextText);
321
+ const filtered = value.filter((v) => v !== prev);
322
+ onChange(nextText ? [...filtered, nextText] : filtered);
323
+ }
324
+ }
325
+ )
326
+ ] })
327
+ ] });
328
+ }
329
+ function TextInput({
330
+ value,
331
+ onChange
332
+ }) {
333
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
334
+ "textarea",
335
+ {
336
+ className: "kaboo-interrupt-textarea",
337
+ placeholder: "Type your answer...",
338
+ value,
339
+ onChange: (e) => onChange(e.target.value),
340
+ rows: 3,
341
+ autoFocus: true
342
+ }
343
+ );
344
+ }
345
+ function FormVariant({ reason, onResolve, onCancel }) {
346
+ const questions = reason.type === "form" ? reason.questions : [];
347
+ const isSingle = questions.length === 1;
348
+ const [step, setStep] = (0, import_react4.useState)(0);
349
+ const [answers, setAnswers] = (0, import_react4.useState)({});
350
+ const [responded, setResponded] = (0, import_react4.useState)(false);
351
+ if (responded) {
352
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "kaboo-interrupt-responded", children: "Response submitted" });
353
+ }
354
+ const setAnswer = (idx, val) => {
355
+ setAnswers((prev) => ({ ...prev, [String(idx)]: val }));
356
+ };
357
+ const current = questions[step];
358
+ if (!current) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, {});
359
+ const renderQuestion = (q, idx) => {
360
+ if (q.type === "radio") {
361
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
362
+ RadioInput,
363
+ {
364
+ question: q,
365
+ value: answers[String(idx)] ?? "",
366
+ onChange: (v) => setAnswer(idx, v)
367
+ }
368
+ );
369
+ }
370
+ if (q.type === "checkbox") {
371
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
372
+ CheckboxInput,
373
+ {
374
+ question: q,
375
+ value: answers[String(idx)] ?? [],
376
+ onChange: (v) => setAnswer(idx, v)
377
+ }
378
+ );
379
+ }
380
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
381
+ TextInput,
382
+ {
383
+ value: answers[String(idx)] ?? "",
384
+ onChange: (v) => setAnswer(idx, v)
385
+ }
386
+ );
387
+ };
388
+ const isLast = step === questions.length - 1;
389
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "kaboo-interrupt kaboo-interrupt-form", children: [
390
+ !isSingle && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "kaboo-interrupt-progress", children: [
391
+ step + 1,
392
+ " of ",
393
+ questions.length
394
+ ] }),
395
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "kaboo-interrupt-question", children: current.question }),
396
+ renderQuestion(current, step),
397
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "kaboo-interrupt-actions", children: [
398
+ !isSingle && step > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
399
+ "button",
400
+ {
401
+ className: "kaboo-interrupt-btn kaboo-interrupt-btn-back",
402
+ onClick: () => setStep(step - 1),
403
+ children: "Back"
404
+ }
405
+ ),
406
+ isLast ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
407
+ "button",
408
+ {
409
+ className: "kaboo-interrupt-btn kaboo-interrupt-btn-approve",
410
+ onClick: () => {
411
+ setResponded(true);
412
+ onResolve(buildAnswerPayload(questions, answers));
413
+ },
414
+ children: "Submit"
415
+ }
416
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
417
+ "button",
418
+ {
419
+ className: "kaboo-interrupt-btn kaboo-interrupt-btn-next",
420
+ onClick: () => setStep(step + 1),
421
+ children: "Next"
422
+ }
423
+ ),
424
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
425
+ "button",
426
+ {
427
+ className: "kaboo-interrupt-btn kaboo-interrupt-btn-reject",
428
+ onClick: () => {
429
+ setResponded(true);
430
+ onCancel();
431
+ },
432
+ children: "Cancel"
433
+ }
434
+ )
435
+ ] })
436
+ ] });
437
+ }
438
+ function InterruptRenderer(props) {
439
+ if (props.reason.type === "approval") {
440
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ApprovalVariant, { ...props });
441
+ }
442
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FormVariant, { ...props });
443
+ }
444
+
445
+ // src/hooks/useActivity.ts
446
+ var import_react5 = require("react");
447
+ function useActivity() {
448
+ return (0, import_react5.useContext)(ActivityContext);
449
+ }
450
+
451
+ // src/utils/groups.ts
452
+ function partitionChildrenByToolCall(childEntries, timeline) {
453
+ const toolUseIds = new Set(
454
+ timeline.filter((e) => e.type === "tool").map((e) => e.tool.toolUseId)
455
+ );
456
+ const byToolCall = /* @__PURE__ */ new Map();
457
+ const leftover = [];
458
+ for (const [id, g] of childEntries) {
459
+ if (g.toolCallId && toolUseIds.has(g.toolCallId)) {
460
+ byToolCall.set(g.toolCallId, [id, g]);
461
+ } else {
462
+ leftover.push([id, g]);
463
+ }
464
+ }
465
+ return { byToolCall, leftover };
466
+ }
467
+ function topLevelGroups(groups) {
468
+ return Object.entries(groups).filter(([, g]) => g.parentGroup == null);
469
+ }
470
+ function directChildren(groups, parentId) {
471
+ return Object.entries(groups).filter(([, g]) => g.parentGroup === parentId);
472
+ }
473
+ function pendingToolAnchorExists(groups, toolCallId) {
474
+ if (!toolCallId) return false;
475
+ for (const g of Object.values(groups)) {
476
+ for (const t of g.tools) {
477
+ if (t.toolUseId === toolCallId && t.toolResult == null) {
478
+ return true;
479
+ }
480
+ }
481
+ }
482
+ return false;
483
+ }
484
+ function findGroupForCard(groups, agentName, toolCallId) {
485
+ return Object.entries(groups).find(
486
+ ([, g]) => g.agentName === agentName && g.toolCallId === toolCallId
487
+ );
488
+ }
489
+
490
+ // src/integrations/KabooAskUser.tsx
491
+ var import_v22 = require("@copilotkit/react-core/v2");
492
+
493
+ // src/components/AskUserSummary.tsx
494
+ var import_jsx_runtime5 = require("react/jsx-runtime");
495
+ function formatAnswer(value) {
496
+ if (value == null) return "";
497
+ if (Array.isArray(value)) return value.map((v) => String(v)).join(", ");
498
+ if (typeof value === "object") return JSON.stringify(value);
499
+ return String(value);
500
+ }
501
+ function AskUserSummary({
502
+ questions,
503
+ answers,
504
+ declined = false
505
+ }) {
506
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kaboo-askuser", children: questions.map((q, idx) => {
507
+ const answer = answers[q.question];
508
+ const hasAnswer = answer != null && formatAnswer(answer) !== "";
509
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kaboo-askuser-qa", children: [
510
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kaboo-askuser-question", children: q.question }),
511
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
512
+ "div",
513
+ {
514
+ className: `kaboo-askuser-answer ${hasAnswer ? "" : declined ? "kaboo-askuser-answer-declined" : "kaboo-askuser-answer-empty"}`,
515
+ children: hasAnswer ? formatAnswer(answer) : declined ? "Declined by user" : "No answer"
516
+ }
517
+ )
518
+ ] }, idx);
519
+ }) });
520
+ }
521
+
522
+ // src/formatters/askUser.ts
523
+ function normalizeQuestions(params) {
524
+ if (!params) return [];
525
+ if (Array.isArray(params.questions)) {
526
+ return params.questions.map((q) => ({
527
+ question: q.question ?? "",
528
+ type: q.type ?? (q.options ? "radio" : "text"),
529
+ options: q.options
530
+ }));
531
+ }
532
+ if (typeof params.question === "string") {
533
+ return [
534
+ {
535
+ question: params.question,
536
+ type: params.input_type ?? (params.options ? "radio" : "text"),
537
+ options: params.options
538
+ }
539
+ ];
540
+ }
541
+ return [];
542
+ }
543
+ function parseAnswers(result) {
544
+ let value = result;
545
+ for (let i = 0; i < 2 && typeof value === "string"; i++) {
546
+ const trimmed = value.trim();
547
+ if (trimmed === "") return null;
548
+ try {
549
+ value = JSON.parse(trimmed);
550
+ } catch {
551
+ return null;
552
+ }
553
+ }
554
+ if (value && typeof value === "object" && !Array.isArray(value)) {
555
+ const obj = value;
556
+ return Object.keys(obj).length > 0 ? obj : null;
557
+ }
558
+ return null;
559
+ }
560
+
561
+ // src/integrations/KabooAskUser.tsx
562
+ var import_jsx_runtime6 = require("react/jsx-runtime");
563
+ var ANY_PARAMETERS = {
564
+ "~standard": {
565
+ version: 1,
566
+ vendor: "kaboo",
567
+ validate: (value) => ({ value })
568
+ }
569
+ };
570
+ function KabooAskUser({ agentId }) {
571
+ (0, import_v22.useRenderTool)({
572
+ name: "ask_user",
573
+ ...agentId ? { agentId } : {},
574
+ parameters: ANY_PARAMETERS,
575
+ render: ({ parameters, result }) => {
576
+ const questions = normalizeQuestions(parameters);
577
+ if (questions.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, {});
578
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AskUserCard, { questions, result });
579
+ }
580
+ });
581
+ return null;
582
+ }
583
+ function AskUserCard({
584
+ questions,
585
+ result
586
+ }) {
587
+ const answers = parseAnswers(result);
588
+ if (!answers) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, {});
589
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AskUserSummary, { questions, answers });
590
+ }
591
+
592
+ // src/integrations/KabooInterruptHandler.tsx
593
+ var import_jsx_runtime7 = require("react/jsx-runtime");
594
+ function ChatInterruptSlot({
595
+ interrupt,
596
+ Renderer
597
+ }) {
598
+ const { groups } = useActivity();
599
+ if (pendingToolAnchorExists(groups, interrupt.toolCallId)) {
600
+ return null;
601
+ }
602
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
603
+ Renderer,
604
+ {
605
+ reason: interrupt.reason,
606
+ toolCallId: interrupt.toolCallId,
607
+ onResolve: interrupt.onResolve,
608
+ onCancel: interrupt.onCancel
609
+ }
610
+ );
611
+ }
612
+ function KabooInterruptHandler({
613
+ agentId,
614
+ renderers,
615
+ bridge = true
616
+ }) {
617
+ (0, import_v23.useInterrupt)({
618
+ ...agentId ? { agentId } : {},
619
+ render: ({ interrupts, resolve, cancel }) => {
620
+ const active = (interrupts ?? []).map((intr) => {
621
+ const reason = intr?.metadata ?? intr?.reason;
622
+ if (!reason || !reason.type) return null;
623
+ return {
624
+ id: intr.id,
625
+ reason,
626
+ toolCallId: intr.toolCallId,
627
+ onResolve: (payload) => resolve(payload, intr.id),
628
+ onCancel: () => cancel(intr.id)
629
+ };
630
+ }).filter((x) => x !== null);
631
+ if (active.length === 0) {
632
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, {});
633
+ }
634
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
635
+ bridge && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(InterruptBridgePublisher, { interrupts: active }),
636
+ active.map((a) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
637
+ ChatInterruptSlot,
638
+ {
639
+ interrupt: a,
640
+ Renderer: renderers?.[a.reason.type] ?? InterruptRenderer
641
+ },
642
+ a.id
643
+ ))
644
+ ] });
645
+ }
646
+ });
647
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(KabooAskUser, { agentId });
648
+ }
649
+
650
+ // src/integrations/KabooInlineCards.tsx
651
+ var import_v25 = require("@copilotkit/react-core/v2");
652
+
653
+ // src/components/AgentCard.tsx
654
+ var import_react9 = require("react");
655
+
656
+ // src/formatters/output.ts
657
+ function formatToolResult(raw) {
658
+ try {
659
+ const parsed = JSON.parse(raw);
660
+ if (parsed.rows && Array.isArray(parsed.rows) && parsed.rows.length > 0) {
661
+ return { rows: parsed.rows, text: "" };
662
+ }
663
+ if (Array.isArray(parsed) && parsed.length > 0 && typeof parsed[0] === "object") {
664
+ return { rows: parsed, text: "" };
665
+ }
666
+ if (typeof parsed === "object" && parsed !== null) {
667
+ const entries = Object.entries(parsed).filter(([, v]) => v != null).map(([k, v]) => `${k}: ${typeof v === "string" ? v : JSON.stringify(v)}`);
668
+ return { rows: null, text: entries.join("\n") };
669
+ }
670
+ return { rows: null, text: String(parsed) };
671
+ } catch {
672
+ return { rows: null, text: raw };
673
+ }
674
+ }
675
+ function unwrapJson(raw) {
676
+ let value = raw;
677
+ for (let i = 0; i < 2 && typeof value === "string"; i++) {
678
+ const trimmed = value.trim();
679
+ if (trimmed === "") return value;
680
+ try {
681
+ value = JSON.parse(trimmed);
682
+ } catch {
683
+ break;
684
+ }
685
+ }
686
+ return value;
687
+ }
688
+ function statusIsCancelled(status) {
689
+ if (typeof status !== "string") return false;
690
+ const s = status.toLowerCase();
691
+ return s === "cancelled" || s === "canceled" || s === "rejected" || s === "declined";
692
+ }
693
+ function statusIsControl(status) {
694
+ if (typeof status !== "string") return false;
695
+ const s = status.toLowerCase();
696
+ return statusIsCancelled(status) || s === "approved" || s === "accepted";
697
+ }
698
+ function isCancelledResult(raw) {
699
+ if (raw == null) return false;
700
+ const text = typeof raw === "string" ? raw : JSON.stringify(raw);
701
+ if (/user rejected this action/i.test(text)) return true;
702
+ if (/user declined to answer/i.test(text)) return true;
703
+ const value = unwrapJson(text);
704
+ if (value && typeof value === "object" && !Array.isArray(value)) {
705
+ return statusIsCancelled(value.status);
706
+ }
707
+ return false;
708
+ }
709
+ function isControlOnlyStatus(raw) {
710
+ if (raw == null) return false;
711
+ const value = unwrapJson(typeof raw === "string" ? raw : JSON.stringify(raw));
712
+ if (value && typeof value === "object" && !Array.isArray(value)) {
713
+ const keys = Object.keys(value);
714
+ return keys.length === 1 && keys[0] === "status" && statusIsControl(value.status);
715
+ }
716
+ return false;
717
+ }
718
+ function normalizeResult(result) {
719
+ if (!result) return null;
720
+ let text = typeof result === "string" ? result : JSON.stringify(result, null, 2);
721
+ if (text.startsWith('"') && text.endsWith('"')) {
722
+ try {
723
+ text = JSON.parse(text);
724
+ } catch {
725
+ }
726
+ }
727
+ text = text.replace(/\\n/g, "\n");
728
+ return text || null;
729
+ }
730
+
731
+ // src/components/MarkdownContent.tsx
732
+ var import_jsx_runtime8 = require("react/jsx-runtime");
733
+ function MarkdownContent({ text }) {
734
+ const lines = text.split("\n");
735
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "kaboo-md", children: lines.map((line, i) => {
736
+ if (line.startsWith("# ") && !line.startsWith("## ")) {
737
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { className: "kaboo-md-h2", children: line.slice(2) }, i);
738
+ }
739
+ if (line.startsWith("## ")) {
740
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { className: "kaboo-md-h3", children: line.slice(3) }, i);
741
+ }
742
+ if (line.startsWith("### ")) {
743
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h4", { className: "kaboo-md-h4", children: line.slice(4) }, i);
744
+ }
745
+ if (line.startsWith("- ") || line.startsWith("* ")) {
746
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("li", { className: "kaboo-md-li", children: renderInline(line.slice(2)) }, i);
747
+ }
748
+ if (line.trim() === "") {
749
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "kaboo-md-spacer" }, i);
750
+ }
751
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "kaboo-md-p", children: renderInline(line) }, i);
752
+ }) });
753
+ }
754
+ function renderInline(text) {
755
+ const parts = [];
756
+ let remaining = text;
757
+ let key = 0;
758
+ while (remaining.length > 0) {
759
+ const boldMatch = remaining.match(/\*\*(.+?)\*\*/);
760
+ if (boldMatch && boldMatch.index !== void 0) {
761
+ if (boldMatch.index > 0) {
762
+ parts.push(remaining.slice(0, boldMatch.index));
763
+ }
764
+ parts.push(/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: boldMatch[1] }, key++));
765
+ remaining = remaining.slice(boldMatch.index + boldMatch[0].length);
766
+ continue;
767
+ }
768
+ parts.push(remaining);
769
+ break;
770
+ }
771
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: parts });
772
+ }
773
+
774
+ // src/components/Timeline.tsx
775
+ var import_react7 = require("react");
776
+
777
+ // src/components/ToolRow.tsx
778
+ var import_react6 = require("react");
779
+
780
+ // src/formatters/input.ts
781
+ function formatToolInput(input) {
782
+ if (input == null) return { summary: "", detail: null };
783
+ if (typeof input === "string") return { summary: input, detail: null };
784
+ const obj = input;
785
+ if (obj.query && typeof obj.query === "string") {
786
+ return { summary: String(obj.query).trim(), detail: null };
787
+ }
788
+ if (obj.table_name && typeof obj.table_name === "string") {
789
+ return { summary: obj.table_name, detail: null };
790
+ }
791
+ if (obj.url && typeof obj.url === "string") {
792
+ return { summary: obj.url, detail: null };
793
+ }
794
+ const keys = Object.keys(obj);
795
+ if (keys.length === 1) {
796
+ const val = obj[keys[0]];
797
+ return { summary: typeof val === "string" ? val : JSON.stringify(val), detail: null };
798
+ }
799
+ const parts = keys.filter((k) => obj[k] != null && obj[k] !== "").map((k) => {
800
+ const v = obj[k];
801
+ return `${k}: ${typeof v === "string" ? v : JSON.stringify(v)}`;
802
+ });
803
+ return { summary: parts.join(", "), detail: null };
804
+ }
805
+
806
+ // src/components/MiniTable.tsx
807
+ var import_jsx_runtime9 = require("react/jsx-runtime");
808
+ function MiniTable({ rows, maxRows = 8 }) {
809
+ if (rows.length === 0) return null;
810
+ const cols = Object.keys(rows[0]);
811
+ const display = rows.slice(0, maxRows);
812
+ const remaining = rows.length - maxRows;
813
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { overflowX: "auto" }, children: [
814
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("table", { className: "kaboo-mini-table", children: [
815
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tr", { children: cols.map((c) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("th", { children: c.replace(/_/g, " ") }, c)) }) }),
816
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tbody", { children: display.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tr", { children: cols.map((c) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("td", { children: String(row[c] ?? "") }, c)) }, i)) })
817
+ ] }),
818
+ remaining > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "kaboo-mini-table-overflow", children: [
819
+ "+",
820
+ remaining,
821
+ " more row",
822
+ remaining !== 1 ? "s" : ""
823
+ ] })
824
+ ] });
825
+ }
826
+
827
+ // src/components/ToolRow.tsx
828
+ var import_jsx_runtime10 = require("react/jsx-runtime");
829
+ function ToolRow({ tool }) {
830
+ const [open, setOpen] = (0, import_react6.useState)(false);
831
+ const cancelled = tool.status === "cancelled" || isCancelledResult(tool.toolResult);
832
+ const isDone = tool.status !== "running";
833
+ const label = tool.toolLabel || tool.toolName;
834
+ const { summary: inputSummary } = formatToolInput(tool.toolInput);
835
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "kaboo-tool-row", children: [
836
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "kaboo-tool-row-header", onClick: () => setOpen(!open), children: [
837
+ tool.status === "running" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { width: 10, height: 10, viewBox: "0 0 16 16", className: "kaboo-icon-shrink", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
838
+ "circle",
839
+ {
840
+ cx: "8",
841
+ cy: "8",
842
+ r: "5",
843
+ fill: "none",
844
+ className: "kaboo-tool-spinner",
845
+ strokeWidth: "2",
846
+ strokeDasharray: "22",
847
+ strokeDashoffset: "6",
848
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
849
+ "animateTransform",
850
+ {
851
+ attributeName: "transform",
852
+ type: "rotate",
853
+ from: "0 8 8",
854
+ to: "360 8 8",
855
+ dur: "0.8s",
856
+ repeatCount: "indefinite"
857
+ }
858
+ )
859
+ }
860
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { width: 10, height: 10, viewBox: "0 0 10 10", className: "kaboo-icon-shrink", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
861
+ "circle",
862
+ {
863
+ cx: "5",
864
+ cy: "5",
865
+ r: "3",
866
+ className: cancelled ? "kaboo-tool-dot-cancelled" : tool.status === "error" ? "kaboo-tool-dot-error" : "kaboo-tool-dot-success"
867
+ }
868
+ ) }),
869
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "kaboo-tool-row-label", children: label }),
870
+ isDone && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "kaboo-tool-row-status", children: cancelled ? "cancelled" : tool.status === "error" ? "error" : "done" }),
871
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
872
+ "svg",
873
+ {
874
+ width: 14,
875
+ height: 14,
876
+ viewBox: "0 0 16 16",
877
+ className: `kaboo-chevron ${open ? "kaboo-chevron-open" : ""}`,
878
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 6l4 4 4-4", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
879
+ }
880
+ )
881
+ ] }),
882
+ !open && inputSummary && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "kaboo-tool-row-summary", children: inputSummary.length > 80 ? inputSummary.slice(0, 80) + "..." : inputSummary }),
883
+ open && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "kaboo-tool-row-detail", children: [
884
+ inputSummary && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "kaboo-tool-input", children: inputSummary }),
885
+ tool.toolResult && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ToolResultBlock, { raw: tool.toolResult, cancelled })
886
+ ] })
887
+ ] });
888
+ }
889
+ function ToolResultBlock({ raw, cancelled }) {
890
+ if (cancelled) {
891
+ const { text: text2 } = formatToolResult(raw);
892
+ const message = /user (rejected|declined)/i.test(text2) ? text2 : "Declined by user.";
893
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "kaboo-tool-result kaboo-tool-result-cancelled", children: message });
894
+ }
895
+ const { rows, text } = formatToolResult(raw);
896
+ if (rows) {
897
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "kaboo-tool-result kaboo-tool-result-table", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MiniTable, { rows }) });
898
+ }
899
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "kaboo-tool-result", children: text });
900
+ }
901
+
902
+ // src/components/Timeline.tsx
903
+ var import_jsx_runtime11 = require("react/jsx-runtime");
904
+ function AskUserTimelineRow({ tool }) {
905
+ const interrupt = useInterruptFor(tool.toolUseId);
906
+ const questions = normalizeQuestions(tool.toolInput);
907
+ const answers = parseAnswers(tool.toolResult);
908
+ if (answers) {
909
+ if (questions.length === 0) return null;
910
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AskUserSummary, { questions, answers });
911
+ }
912
+ if (interrupt && interrupt.reason.type === "form") {
913
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
914
+ InterruptRenderer,
915
+ {
916
+ reason: interrupt.reason,
917
+ toolCallId: interrupt.toolCallId,
918
+ onResolve: interrupt.onResolve,
919
+ onCancel: interrupt.onCancel
920
+ }
921
+ );
922
+ }
923
+ if (questions.length > 0 && isCancelledResult(tool.toolResult)) {
924
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AskUserSummary, { questions, answers: {}, declined: true });
925
+ }
926
+ return null;
927
+ }
928
+ function ToolTimelineRow({ tool }) {
929
+ const interrupt = useInterruptFor(tool.toolUseId);
930
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
931
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ToolRow, { tool }),
932
+ interrupt && interrupt.reason.type === "approval" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
933
+ InterruptRenderer,
934
+ {
935
+ reason: interrupt.reason,
936
+ toolCallId: interrupt.toolCallId,
937
+ onResolve: interrupt.onResolve,
938
+ onCancel: interrupt.onCancel
939
+ }
940
+ )
941
+ ] });
942
+ }
943
+ function Timeline({ timeline, active, variant = "card", renderToolCard }) {
944
+ const textClass = variant === "drill" ? "kaboo-drill-tokens-content" : "kaboo-agent-card-tokens";
945
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: timeline.map((entry, i) => {
946
+ if (entry.type === "tool") {
947
+ const key = entry.tool.toolUseId || i;
948
+ const card = renderToolCard?.(entry.tool.toolUseId);
949
+ if (card) return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react7.Fragment, { children: card }, key);
950
+ if (entry.tool.toolName === "ask_user") {
951
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AskUserTimelineRow, { tool: entry.tool }, key);
952
+ }
953
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ToolTimelineRow, { tool: entry.tool }, key);
954
+ }
955
+ const isLast = i === timeline.length - 1;
956
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: textClass, children: [
957
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MarkdownContent, { text: entry.text }),
958
+ active && isLast && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "kaboo-blink-cursor" })
959
+ ] }, `text-${i}`);
960
+ }) });
961
+ }
962
+
963
+ // src/hooks/useDrill.ts
964
+ var import_react8 = require("react");
965
+ function useDrill() {
966
+ return (0, import_react8.useContext)(DrillContext);
967
+ }
968
+
969
+ // src/components/AgentCard.tsx
970
+ var import_jsx_runtime12 = require("react/jsx-runtime");
971
+ function AgentCard({ groupId, group, input, result, actionStatus, showChildren }) {
972
+ const { drillIn } = useDrill();
973
+ const { groups } = useActivity();
974
+ const structuredRenderers = (0, import_react9.useContext)(StructuredRenderersContext);
975
+ const childEntries = showChildren ? directChildren(groups, groupId) : [];
976
+ const isDone = group.status === "completed" || actionStatus === "complete";
977
+ const isInterrupted = group.status === "interrupted" && group.interrupt;
978
+ const [expanded, setExpanded] = (0, import_react9.useState)(true);
979
+ const prevDone = (0, import_react9.useRef)(isDone);
980
+ const bodyRef = (0, import_react9.useRef)(null);
981
+ const hasInteraction = group.tools.some((t) => t.toolName === "ask_user");
982
+ (0, import_react9.useEffect)(() => {
983
+ if (!prevDone.current && isDone && !hasInteraction) setExpanded(false);
984
+ prevDone.current = isDone;
985
+ }, [isDone, hasInteraction]);
986
+ const resultText = isControlOnlyStatus(result) ? null : normalizeResult(result);
987
+ const displayTask = input ?? group.task ?? void 0;
988
+ const timeline = showChildren && group.isChatReply ? (group.timeline ?? []).filter((e) => e.type === "tool") : group.timeline ?? [];
989
+ (0, import_react9.useEffect)(() => {
990
+ if (expanded && !isDone && bodyRef.current) {
991
+ bodyRef.current.scrollTop = bodyRef.current.scrollHeight;
992
+ }
993
+ }, [expanded, isDone, timeline]);
994
+ const { byToolCall: childByToolCall, leftover: leftoverChildren } = partitionChildrenByToolCall(childEntries, timeline);
995
+ const renderToolCard = (toolUseId) => {
996
+ const entry = childByToolCall.get(toolUseId);
997
+ if (!entry) return null;
998
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(AgentCard, { groupId: entry[0], group: entry[1], showChildren: true });
999
+ };
1000
+ const hasContent = timeline.length > 0 || resultText || childEntries.length > 0 || !!displayTask;
1001
+ const cardClass = `kaboo-agent-card${isDone ? " kaboo-agent-card-done" : ""}`;
1002
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: cardClass, children: [
1003
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "kaboo-agent-card-header", onClick: () => setExpanded(!expanded), children: [
1004
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "kaboo-agent-card-title-area", children: [
1005
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "kaboo-agent-card-title-row", children: [
1006
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "kaboo-agent-card-title", children: group.title }),
1007
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: `kaboo-status-badge ${isDone ? "kaboo-status-done" : isInterrupted ? "kaboo-status-interrupted" : "kaboo-status-active"}`, children: [
1008
+ isDone ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { width: 10, height: 10, viewBox: "0 0 16 16", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M3.5 8.5L6.5 11.5L12.5 4.5", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) : isInterrupted ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: 10, height: 10, viewBox: "0 0 16 16", children: [
1009
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("circle", { cx: "8", cy: "8", r: "7", fill: "none", stroke: "currentColor", strokeWidth: "1.5" }),
1010
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M8 4.5v4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
1011
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("circle", { cx: "8", cy: "11", r: "0.75", fill: "currentColor" })
1012
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { width: 10, height: 10, viewBox: "0 0 16 16", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("circle", { cx: "8", cy: "8", r: "5", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeDasharray: "22", strokeDashoffset: "6", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("animateTransform", { attributeName: "transform", type: "rotate", from: "0 8 8", to: "360 8 8", dur: "0.8s", repeatCount: "indefinite" }) }) }),
1013
+ isDone ? "done" : isInterrupted ? "needs input" : "working..."
1014
+ ] })
1015
+ ] }),
1016
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "kaboo-agent-card-subtitle", children: group.agentName })
1017
+ ] }),
1018
+ group.tools.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: `kaboo-tool-count ${isDone ? "kaboo-tool-count-done" : ""}`, children: [
1019
+ group.tools.length,
1020
+ " tool",
1021
+ group.tools.length !== 1 ? "s" : ""
1022
+ ] }),
1023
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1024
+ "svg",
1025
+ {
1026
+ width: 14,
1027
+ height: 14,
1028
+ viewBox: "0 0 16 16",
1029
+ className: `kaboo-chevron ${expanded ? "kaboo-chevron-open" : ""}`,
1030
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M4 6l4 4 4-4", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
1031
+ }
1032
+ )
1033
+ ] }),
1034
+ !expanded && displayTask && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "kaboo-agent-card-collapsed", children: [
1035
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("strong", { children: "Task:" }),
1036
+ " ",
1037
+ displayTask
1038
+ ] }),
1039
+ expanded && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { ref: bodyRef, className: "kaboo-agent-card-body", children: [
1040
+ displayTask && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "kaboo-agent-card-task", children: [
1041
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("strong", { children: "Task:" }),
1042
+ " ",
1043
+ displayTask
1044
+ ] }),
1045
+ timeline.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "kaboo-agent-card-timeline", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Timeline, { timeline, active: !isDone, variant: "card", renderToolCard }) }),
1046
+ resultText && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "kaboo-agent-card-result", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MarkdownContent, { text: resultText }) }),
1047
+ group.structuredOutput && group.outputSchemaName && (() => {
1048
+ const Renderer = structuredRenderers[group.outputSchemaName];
1049
+ if (Renderer) {
1050
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Renderer, { ...group.structuredOutput });
1051
+ }
1052
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("details", { className: "kaboo-agent-card-structured", children: [
1053
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("summary", { className: "kaboo-agent-card-structured-summary", children: [
1054
+ "Structured output (",
1055
+ group.outputSchemaName,
1056
+ ")"
1057
+ ] }),
1058
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("pre", { className: "kaboo-agent-card-structured-pre", children: JSON.stringify(group.structuredOutput, null, 2) })
1059
+ ] });
1060
+ })(),
1061
+ leftoverChildren.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "kaboo-agent-card-children", children: leftoverChildren.map(([childId, child]) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1062
+ AgentCard,
1063
+ {
1064
+ groupId: childId,
1065
+ group: child,
1066
+ showChildren: true
1067
+ },
1068
+ childId
1069
+ )) }),
1070
+ !displayTask && !hasContent && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "kaboo-agent-card-empty", children: "Working..." })
1071
+ ] }),
1072
+ hasContent && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1073
+ "button",
1074
+ {
1075
+ className: "kaboo-drill-btn",
1076
+ onClick: (e) => {
1077
+ e.stopPropagation();
1078
+ drillIn(groupId);
1079
+ },
1080
+ children: [
1081
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "View details" }),
1082
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { width: 12, height: 12, viewBox: "0 0 16 16", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M6 4l4 4-4 4", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) })
1083
+ ]
1084
+ }
1085
+ )
1086
+ ] });
1087
+ }
1088
+
1089
+ // src/integrations/KabooToolRender.tsx
1090
+ var import_v24 = require("@copilotkit/react-core/v2");
1091
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1092
+ function findTool(groups, toolCallId) {
1093
+ for (const group of Object.values(groups)) {
1094
+ const match = group.tools.find((t) => t.toolUseId === toolCallId);
1095
+ if (match) return match;
1096
+ }
1097
+ return void 0;
1098
+ }
1099
+ function isDelegateSpawn(groups, name, toolCallId) {
1100
+ for (const group of Object.values(groups)) {
1101
+ if (!group.toolCallId) continue;
1102
+ if (group.toolCallId === toolCallId || group.agentName === name) return true;
1103
+ }
1104
+ return false;
1105
+ }
1106
+ function KabooToolRender() {
1107
+ const { groups } = useActivity();
1108
+ (0, import_v24.useDefaultRenderTool)(
1109
+ {
1110
+ render: ({ name, toolCallId, parameters, status, result }) => {
1111
+ if (isDelegateSpawn(groups, name, toolCallId)) return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, {});
1112
+ const fromActivity = findTool(groups, toolCallId);
1113
+ const controlEcho = !fromActivity && isControlOnlyStatus(result);
1114
+ const tool = fromActivity ?? {
1115
+ toolUseId: toolCallId,
1116
+ toolName: name,
1117
+ toolInput: parameters,
1118
+ toolResult: controlEcho || typeof result !== "string" ? void 0 : result,
1119
+ status: status === "complete" ? "success" : "running"
1120
+ };
1121
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "kaboo-inline-tool", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolRow, { tool }) });
1122
+ }
1123
+ },
1124
+ [groups]
1125
+ );
1126
+ return null;
1127
+ }
1128
+
1129
+ // src/integrations/KabooInlineCards.tsx
1130
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1131
+ var ANY_PARAMETERS2 = {
1132
+ "~standard": {
1133
+ version: 1,
1134
+ vendor: "kaboo",
1135
+ validate: (value) => ({ value })
1136
+ }
1137
+ };
1138
+ function KabooInlineCards() {
1139
+ const { groups } = useActivity();
1140
+ const toolAgentNames = /* @__PURE__ */ new Set();
1141
+ for (const group of Object.values(groups)) {
1142
+ if (group.agentName && group.toolCallId) toolAgentNames.add(group.agentName);
1143
+ }
1144
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
1145
+ Array.from(toolAgentNames).map((agentName) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(InlineCardAction, { agentName }, agentName)),
1146
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(KabooToolRender, {})
1147
+ ] });
1148
+ }
1149
+ function InlineCardAction({ agentName }) {
1150
+ (0, import_v25.useRenderTool)({
1151
+ name: agentName,
1152
+ parameters: ANY_PARAMETERS2,
1153
+ render: ({ toolCallId, parameters, result, status }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1154
+ InlineCardRenderer,
1155
+ {
1156
+ agentName,
1157
+ toolCallId,
1158
+ input: parameters?.input,
1159
+ result: typeof result === "string" ? result : void 0,
1160
+ actionStatus: status
1161
+ }
1162
+ )
1163
+ });
1164
+ return null;
1165
+ }
1166
+ function InlineCardRenderer({
1167
+ agentName,
1168
+ toolCallId,
1169
+ input,
1170
+ result,
1171
+ actionStatus
1172
+ }) {
1173
+ const { groups } = useActivity();
1174
+ const entry = findGroupForCard(groups, agentName, toolCallId);
1175
+ if (!entry) {
1176
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "kaboo-agent-card-empty", children: [
1177
+ "Loading ",
1178
+ agentName,
1179
+ "..."
1180
+ ] });
1181
+ }
1182
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1183
+ AgentCard,
1184
+ {
1185
+ groupId: entry[0],
1186
+ group: entry[1],
1187
+ input,
1188
+ result,
1189
+ actionStatus
1190
+ }
1191
+ );
1192
+ }
1193
+
1194
+ // src/context/KabooProvider.tsx
1195
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1196
+ function KabooProvider({
1197
+ runtimeUrl,
1198
+ agent,
1199
+ threadId,
1200
+ structuredRenderers,
1201
+ interruptRenderers,
1202
+ disableInterruptHandler = false,
1203
+ disableInlineCards = false,
1204
+ copilotKitProps,
1205
+ children
1206
+ }) {
1207
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1208
+ import_v26.CopilotKit,
1209
+ {
1210
+ runtimeUrl,
1211
+ agent,
1212
+ threadId,
1213
+ useSingleEndpoint: false,
1214
+ ...copilotKitProps,
1215
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(KabooActivityProvider, { agentId: agent, structuredRenderers, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DrillProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(InterruptBridgeProvider, { children: [
1216
+ !disableInterruptHandler && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(KabooInterruptHandler, { agentId: agent, renderers: interruptRenderers }),
1217
+ !disableInlineCards && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(KabooInlineCards, {}),
1218
+ children
1219
+ ] }) }) })
1220
+ }
1221
+ );
1222
+ }
1223
+
1224
+ // src/components/ActivityPanel.tsx
1225
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1226
+ function ActivityPanel() {
1227
+ const { groups } = useActivity();
1228
+ const { activeDrill } = useDrill();
1229
+ if (Object.keys(groups).length === 0) return null;
1230
+ const filtered = activeDrill ? directChildren(groups, activeDrill) : topLevelGroups(groups).filter(([, g]) => !g.inlineChatOwner);
1231
+ if (filtered.length === 0 && activeDrill) {
1232
+ const exact = groups[activeDrill];
1233
+ if (exact) {
1234
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "kaboo-activity-panel", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AgentCard, { groupId: activeDrill, group: exact }) });
1235
+ }
1236
+ }
1237
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "kaboo-activity-panel", children: filtered.map(([id, group]) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AgentCard, { groupId: id, group }, id)) });
1238
+ }
1239
+
1240
+ // src/components/GlassTabs.tsx
1241
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1242
+ function GlassTabs() {
1243
+ const { drillPath, drillToRoot, drillToLevel } = useDrill();
1244
+ const { groups } = useActivity();
1245
+ if (drillPath.length === 0) return null;
1246
+ const tabs = [
1247
+ { id: "root", label: "Chat", level: -1 },
1248
+ ...drillPath.map((id, i) => ({
1249
+ id,
1250
+ label: groups[id]?.title || id,
1251
+ level: i
1252
+ }))
1253
+ ];
1254
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("nav", { className: "kaboo-breadcrumb-bar", children: tabs.map((tab, i) => {
1255
+ const isLast = i === tabs.length - 1;
1256
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "kaboo-breadcrumb-item", children: [
1257
+ i > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("svg", { width: 12, height: 12, viewBox: "0 0 16 16", className: "kaboo-breadcrumb-sep", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M6 4l4 4-4 4", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }),
1258
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1259
+ "button",
1260
+ {
1261
+ className: `kaboo-breadcrumb-link ${isLast ? "kaboo-breadcrumb-current" : ""}`,
1262
+ onClick: () => {
1263
+ if (isLast) return;
1264
+ if (tab.level === -1) drillToRoot();
1265
+ else drillToLevel(tab.level);
1266
+ },
1267
+ disabled: isLast,
1268
+ children: [
1269
+ i === 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("svg", { width: 14, height: 14, viewBox: "0 0 16 16", className: "kaboo-breadcrumb-icon", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M3 8.5L8 4l5 4.5M4.5 7.5V12h2.5V9.5h2V12h2.5V7.5", fill: "none", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
1270
+ tab.label
1271
+ ]
1272
+ }
1273
+ )
1274
+ ] }, tab.id);
1275
+ }) });
1276
+ }
1277
+
1278
+ // src/components/DrillDetailView.tsx
1279
+ var import_react10 = require("react");
1280
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1281
+ function DrillDetailView() {
1282
+ const { activeDrill } = useDrill();
1283
+ const { groups } = useActivity();
1284
+ const { active: activeInterrupts } = useInterruptBridge();
1285
+ const bodyRef = (0, import_react10.useRef)(null);
1286
+ (0, import_react10.useEffect)(() => {
1287
+ if (activeDrill && bodyRef.current) {
1288
+ bodyRef.current.scrollTop = 0;
1289
+ }
1290
+ }, [activeDrill]);
1291
+ if (!activeDrill) {
1292
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "kaboo-drill-detail kaboo-hidden" });
1293
+ }
1294
+ const group = groups[activeDrill];
1295
+ const timeline = group?.timeline ?? [];
1296
+ const unanchoredInterrupts = group?.status === "interrupted" ? activeInterrupts.filter(
1297
+ (i) => !pendingToolAnchorExists(groups, i.toolCallId)
1298
+ ) : [];
1299
+ const childEntries = directChildren(groups, activeDrill);
1300
+ const { byToolCall: childByToolCall, leftover: leftoverChildren } = partitionChildrenByToolCall(childEntries, timeline);
1301
+ const renderToolCard = (toolUseId) => {
1302
+ const entry = childByToolCall.get(toolUseId);
1303
+ if (!entry) return null;
1304
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AgentCard, { groupId: entry[0], group: entry[1] });
1305
+ };
1306
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { ref: bodyRef, className: "kaboo-drill-detail", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "kaboo-drill-detail-inner", children: [
1307
+ group?.task && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "kaboo-agent-card-task kaboo-drill-task", children: [
1308
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("strong", { children: "Task:" }),
1309
+ " ",
1310
+ group.task
1311
+ ] }),
1312
+ group && timeline.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "kaboo-drill-timeline", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1313
+ Timeline,
1314
+ {
1315
+ timeline,
1316
+ active: group.status === "active",
1317
+ variant: "drill",
1318
+ renderToolCard
1319
+ }
1320
+ ) }),
1321
+ unanchoredInterrupts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "kaboo-drill-interrupt", children: unanchoredInterrupts.map((it) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1322
+ InterruptRenderer,
1323
+ {
1324
+ reason: it.reason,
1325
+ toolCallId: it.toolCallId,
1326
+ onResolve: it.onResolve,
1327
+ onCancel: it.onCancel
1328
+ },
1329
+ it.id
1330
+ )) }),
1331
+ leftoverChildren.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "kaboo-drill-children", children: [
1332
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "kaboo-drill-section-label", children: "Sub-agents" }),
1333
+ leftoverChildren.map(([id, childGroup]) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AgentCard, { groupId: id, group: childGroup }, id))
1334
+ ] }),
1335
+ group && timeline.length === 0 && childEntries.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "kaboo-agent-card-empty", children: "Working..." }),
1336
+ !group && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "kaboo-agent-card-empty", children: "No activity data for this group." })
1337
+ ] }) });
1338
+ }
1339
+ // Annotate the CommonJS export names for ESM import in node:
1340
+ 0 && (module.exports = {
1341
+ ActivityPanel,
1342
+ AgentCard,
1343
+ DrillDetailView,
1344
+ DrillProvider,
1345
+ GlassTabs,
1346
+ InterruptBridgeProvider,
1347
+ InterruptBridgePublisher,
1348
+ InterruptRenderer,
1349
+ KabooActivityProvider,
1350
+ KabooProvider,
1351
+ MarkdownContent,
1352
+ MiniTable,
1353
+ StructuredRenderersContext,
1354
+ Timeline,
1355
+ ToolRow,
1356
+ directChildren,
1357
+ formatToolInput,
1358
+ formatToolResult,
1359
+ normalizeResult,
1360
+ topLevelGroups,
1361
+ useActivity,
1362
+ useDrill,
1363
+ useInterruptBridge,
1364
+ useInterruptFor
1365
+ });
1366
+ //# sourceMappingURL=index.cjs.map