@copilotkit/web-inspector 1.69.0 → 1.69.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/index.cjs +2418 -152
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +372 -6
  4. package/dist/index.d.cts.map +1 -1
  5. package/dist/index.d.mts +372 -6
  6. package/dist/index.d.mts.map +1 -1
  7. package/dist/index.mjs +2419 -156
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/index.umd.js +3134 -236
  10. package/dist/index.umd.js.map +1 -1
  11. package/dist/lib/event-snippets.cjs +559 -0
  12. package/dist/lib/event-snippets.cjs.map +1 -0
  13. package/dist/lib/event-snippets.d.cts +61 -0
  14. package/dist/lib/event-snippets.d.cts.map +1 -0
  15. package/dist/lib/event-snippets.d.mts +61 -0
  16. package/dist/lib/event-snippets.d.mts.map +1 -0
  17. package/dist/lib/event-snippets.mjs +537 -0
  18. package/dist/lib/event-snippets.mjs.map +1 -0
  19. package/dist/lib/home-briefing.cjs +23 -3
  20. package/dist/lib/home-briefing.cjs.map +1 -1
  21. package/dist/lib/home-briefing.mjs +23 -4
  22. package/dist/lib/home-briefing.mjs.map +1 -1
  23. package/dist/lib/inspector-nav.cjs +1 -0
  24. package/dist/lib/inspector-nav.cjs.map +1 -1
  25. package/dist/lib/inspector-nav.d.cts +11 -0
  26. package/dist/lib/inspector-nav.d.cts.map +1 -0
  27. package/dist/lib/inspector-nav.d.mts +11 -0
  28. package/dist/lib/inspector-nav.d.mts.map +1 -0
  29. package/dist/lib/inspector-nav.mjs +1 -0
  30. package/dist/lib/inspector-nav.mjs.map +1 -1
  31. package/dist/lib/telemetry.cjs +46 -1
  32. package/dist/lib/telemetry.cjs.map +1 -1
  33. package/dist/lib/telemetry.d.cts.map +1 -1
  34. package/dist/lib/telemetry.d.mts.map +1 -1
  35. package/dist/lib/telemetry.mjs +44 -2
  36. package/dist/lib/telemetry.mjs.map +1 -1
  37. package/dist/package.cjs +1 -1
  38. package/dist/package.mjs +1 -1
  39. package/dist/styles/generated.cjs +1 -1
  40. package/dist/styles/generated.cjs.map +1 -1
  41. package/dist/styles/generated.mjs +1 -1
  42. package/dist/styles/generated.mjs.map +1 -1
  43. package/package.json +3 -3
@@ -0,0 +1,61 @@
1
+ //#region src/lib/event-snippets.d.ts
2
+ declare const SNIPPET_RECIPES: readonly ["tool-call", "reasoning", "text", "activity", "raw"];
3
+ type SnippetRecipe = (typeof SNIPPET_RECIPES)[number];
4
+ type SnippetEvent = {
5
+ type: string;
6
+ [key: string]: unknown;
7
+ };
8
+ type EventSnippet = {
9
+ id: string;
10
+ name: string;
11
+ recipe: SnippetRecipe;
12
+ events: SnippetEvent[];
13
+ createdAt: string;
14
+ updatedAt: string;
15
+ };
16
+ type ActivitySnippetMessage = {
17
+ id: string;
18
+ activityType: string;
19
+ content: unknown;
20
+ };
21
+ type ChatSnippetCapture = {
22
+ kind: "text";
23
+ messageId: string;
24
+ content: string;
25
+ } | {
26
+ kind: "reasoning";
27
+ messageId: string;
28
+ content: string;
29
+ } | {
30
+ kind: "tool-call";
31
+ messageId: string;
32
+ toolCallId: string;
33
+ toolName: string;
34
+ argsJson: string | Record<string, unknown>;
35
+ } | {
36
+ kind: "activity";
37
+ messageId: string;
38
+ activityType: string;
39
+ content: unknown;
40
+ };
41
+ declare function compileChatSnippet(input: ChatSnippetCapture & {
42
+ threadId: string;
43
+ runId: string;
44
+ }): {
45
+ recipe: SnippetRecipe;
46
+ events: SnippetEvent[];
47
+ name: string;
48
+ };
49
+ declare function compileFromActivityMessage(input: {
50
+ message: ActivitySnippetMessage;
51
+ threadId: string;
52
+ runId: string;
53
+ }): {
54
+ recipe: SnippetRecipe;
55
+ events: SnippetEvent[];
56
+ name: string;
57
+ };
58
+ declare function upsertEventSnippet(snippet: EventSnippet, storage?: Pick<Storage, "getItem" | "setItem"> | null): EventSnippet[];
59
+ //#endregion
60
+ export { ActivitySnippetMessage, ChatSnippetCapture, EventSnippet, compileChatSnippet, compileFromActivityMessage, upsertEventSnippet };
61
+ //# sourceMappingURL=event-snippets.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-snippets.d.cts","names":[],"sources":["../../src/lib/event-snippets.ts"],"mappings":";cAEa,eAAA;AAAA,KAQD,aAAA,WAAwB,eAAA;AAAA,KAExB,YAAA;EACV,IAAA;EAAA,CACC,GAAA;AAAA;AAAA,KAGS,YAAA;EACV,EAAA;EACA,IAAA;EACA,MAAA,EAAQ,aAAA;EACR,MAAA,EAAQ,YAAA;EACR,SAAA;EACA,SAAA;AAAA;AAAA,KAmBU,sBAAA;EACV,EAAA;EACA,YAAA;EACA,OAAA;AAAA;AAAA,KA8bU,kBAAA;EAEN,IAAA;EACA,SAAA;EACA,OAAA;AAAA;EAGA,IAAA;EACA,SAAA;EACA,OAAA;AAAA;EAGA,IAAA;EACA,SAAA;EACA,UAAA;EACA,QAAA;EACA,QAAA,WAAmB,MAAA;AAAA;EAGnB,IAAA;EACA,SAAA;EACA,YAAA;EACA,OAAA;AAAA;AAAA,iBAuBU,kBAAA,CACd,KAAA,EAAO,kBAAA;EAAuB,QAAA;EAAkB,KAAA;AAAA;EAC7C,MAAA,EAAQ,aAAA;EAAe,MAAA,EAAQ,YAAA;EAAgB,IAAA;AAAA;AAAA,iBAmHpC,0BAAA,CAA2B,KAAA;EACzC,OAAA,EAAS,sBAAA;EACT,QAAA;EACA,KAAA;AAAA;EACI,MAAA,EAAQ,aAAA;EAAe,MAAA,EAAQ,YAAA;EAAgB,IAAA;AAAA;AAAA,iBAqErC,kBAAA,CACd,OAAA,EAAS,YAAA,EACT,OAAA,GAAS,IAAA,CAAK,OAAA,kCACb,YAAA"}
@@ -0,0 +1,61 @@
1
+ //#region src/lib/event-snippets.d.ts
2
+ declare const SNIPPET_RECIPES: readonly ["tool-call", "reasoning", "text", "activity", "raw"];
3
+ type SnippetRecipe = (typeof SNIPPET_RECIPES)[number];
4
+ type SnippetEvent = {
5
+ type: string;
6
+ [key: string]: unknown;
7
+ };
8
+ type EventSnippet = {
9
+ id: string;
10
+ name: string;
11
+ recipe: SnippetRecipe;
12
+ events: SnippetEvent[];
13
+ createdAt: string;
14
+ updatedAt: string;
15
+ };
16
+ type ActivitySnippetMessage = {
17
+ id: string;
18
+ activityType: string;
19
+ content: unknown;
20
+ };
21
+ type ChatSnippetCapture = {
22
+ kind: "text";
23
+ messageId: string;
24
+ content: string;
25
+ } | {
26
+ kind: "reasoning";
27
+ messageId: string;
28
+ content: string;
29
+ } | {
30
+ kind: "tool-call";
31
+ messageId: string;
32
+ toolCallId: string;
33
+ toolName: string;
34
+ argsJson: string | Record<string, unknown>;
35
+ } | {
36
+ kind: "activity";
37
+ messageId: string;
38
+ activityType: string;
39
+ content: unknown;
40
+ };
41
+ declare function compileChatSnippet(input: ChatSnippetCapture & {
42
+ threadId: string;
43
+ runId: string;
44
+ }): {
45
+ recipe: SnippetRecipe;
46
+ events: SnippetEvent[];
47
+ name: string;
48
+ };
49
+ declare function compileFromActivityMessage(input: {
50
+ message: ActivitySnippetMessage;
51
+ threadId: string;
52
+ runId: string;
53
+ }): {
54
+ recipe: SnippetRecipe;
55
+ events: SnippetEvent[];
56
+ name: string;
57
+ };
58
+ declare function upsertEventSnippet(snippet: EventSnippet, storage?: Pick<Storage, "getItem" | "setItem"> | null): EventSnippet[];
59
+ //#endregion
60
+ export { ActivitySnippetMessage, ChatSnippetCapture, EventSnippet, compileChatSnippet, compileFromActivityMessage, upsertEventSnippet };
61
+ //# sourceMappingURL=event-snippets.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-snippets.d.mts","names":[],"sources":["../../src/lib/event-snippets.ts"],"mappings":";cAEa,eAAA;AAAA,KAQD,aAAA,WAAwB,eAAA;AAAA,KAExB,YAAA;EACV,IAAA;EAAA,CACC,GAAA;AAAA;AAAA,KAGS,YAAA;EACV,EAAA;EACA,IAAA;EACA,MAAA,EAAQ,aAAA;EACR,MAAA,EAAQ,YAAA;EACR,SAAA;EACA,SAAA;AAAA;AAAA,KAmBU,sBAAA;EACV,EAAA;EACA,YAAA;EACA,OAAA;AAAA;AAAA,KA8bU,kBAAA;EAEN,IAAA;EACA,SAAA;EACA,OAAA;AAAA;EAGA,IAAA;EACA,SAAA;EACA,OAAA;AAAA;EAGA,IAAA;EACA,SAAA;EACA,UAAA;EACA,QAAA;EACA,QAAA,WAAmB,MAAA;AAAA;EAGnB,IAAA;EACA,SAAA;EACA,YAAA;EACA,OAAA;AAAA;AAAA,iBAuBU,kBAAA,CACd,KAAA,EAAO,kBAAA;EAAuB,QAAA;EAAkB,KAAA;AAAA;EAC7C,MAAA,EAAQ,aAAA;EAAe,MAAA,EAAQ,YAAA;EAAgB,IAAA;AAAA;AAAA,iBAmHpC,0BAAA,CAA2B,KAAA;EACzC,OAAA,EAAS,sBAAA;EACT,QAAA;EACA,KAAA;AAAA;EACI,MAAA,EAAQ,aAAA;EAAe,MAAA,EAAQ,YAAA;EAAgB,IAAA;AAAA;AAAA,iBAqErC,kBAAA,CACd,OAAA,EAAS,YAAA,EACT,OAAA,GAAS,IAAA,CAAK,OAAA,kCACb,YAAA"}
@@ -0,0 +1,537 @@
1
+ //#region src/lib/event-snippets.ts
2
+ const EVENT_SNIPPETS_STORAGE_KEY = "cpk:inspector:event-snippets";
3
+ const SNIPPET_RECIPES = [
4
+ "tool-call",
5
+ "reasoning",
6
+ "text",
7
+ "activity",
8
+ "raw"
9
+ ];
10
+ const ACTIVITY_STARTERS = ["a2ui-surface", "open-generative-ui"];
11
+ function isSnippetRecipe(value) {
12
+ return typeof value === "string" && SNIPPET_RECIPES.some((recipe) => recipe === value);
13
+ }
14
+ function createSnippetId() {
15
+ if (typeof crypto !== "undefined" && "randomUUID" in crypto) return crypto.randomUUID();
16
+ return `cpk-snippet-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
17
+ }
18
+ function autoSnippetName(recipe, label) {
19
+ const time = (/* @__PURE__ */ new Date()).toLocaleTimeString([], {
20
+ hour: "2-digit",
21
+ minute: "2-digit"
22
+ });
23
+ return `${label.trim() || recipeLabel(recipe)} - ${time}`;
24
+ }
25
+ function recipeLabel(recipe) {
26
+ switch (recipe) {
27
+ case "tool-call": return "Tool call";
28
+ case "reasoning": return "Reasoning";
29
+ case "text": return "Assistant text";
30
+ case "activity": return "Activity";
31
+ case "raw": return "Raw events";
32
+ }
33
+ }
34
+ const GENERATE_SANDBOXED_UI_TOOL_NAME = "generateSandboxedUi";
35
+ const OPEN_GENERATIVE_UI_ACTIVITY_TYPE = "open-generative-ui";
36
+ function recipeIconName(recipe) {
37
+ switch (recipe) {
38
+ case "tool-call": return "Hammer";
39
+ case "reasoning": return "Brain";
40
+ case "text": return "MessageSquare";
41
+ case "activity": return "LayoutDashboard";
42
+ case "raw": return "Code";
43
+ }
44
+ }
45
+ function recipeIconWrapClass(recipe) {
46
+ switch (recipe) {
47
+ case "tool-call": return "bg-amber-100 text-amber-700";
48
+ case "reasoning": return "bg-violet-100 text-violet-700";
49
+ case "text": return "bg-sky-100 text-sky-700";
50
+ case "activity": return "bg-emerald-100 text-emerald-700";
51
+ case "raw": return "bg-gray-200 text-gray-700";
52
+ }
53
+ }
54
+ function groupEventSnippets(snippets) {
55
+ return SNIPPET_RECIPES.flatMap((recipe) => {
56
+ const items = snippets.filter((snippet) => snippet.recipe === recipe);
57
+ if (items.length === 0) return [];
58
+ return [{
59
+ recipe,
60
+ label: recipeLabel(recipe),
61
+ snippets: items
62
+ }];
63
+ });
64
+ }
65
+ function snippetJsonIsRunnable(raw) {
66
+ try {
67
+ return parseSnippetEvents(raw).length > 0;
68
+ } catch {
69
+ return false;
70
+ }
71
+ }
72
+ function expandSnippetEventsForRun(events) {
73
+ const next = [...events];
74
+ const hasOpenGenUi = next.some((event) => event.type === "ACTIVITY_SNAPSHOT" && event.activityType === OPEN_GENERATIVE_UI_ACTIVITY_TYPE);
75
+ const toolCallIds = [];
76
+ for (const event of next) if (event.type === "TOOL_CALL_START" && event.toolCallName === GENERATE_SANDBOXED_UI_TOOL_NAME && typeof event.toolCallId === "string") toolCallIds.push(event.toolCallId);
77
+ if (toolCallIds.length === 0) return next;
78
+ const argParts = /* @__PURE__ */ new Map();
79
+ for (const event of next) if (event.type === "TOOL_CALL_ARGS" && typeof event.toolCallId === "string" && typeof event.delta === "string") {
80
+ const parts = argParts.get(event.toolCallId) ?? [];
81
+ parts.push(event.delta);
82
+ argParts.set(event.toolCallId, parts);
83
+ }
84
+ const extras = [];
85
+ for (const toolCallId of toolCallIds) {
86
+ let addedSnapshot = false;
87
+ if (!hasOpenGenUi) {
88
+ const snapshot = activitySnapshotFromSandboxedUiArgs(toolCallId, (argParts.get(toolCallId) ?? []).join(""));
89
+ if (snapshot) {
90
+ extras.push(snapshot);
91
+ addedSnapshot = true;
92
+ }
93
+ }
94
+ if (!hasOpenGenUi && !addedSnapshot) continue;
95
+ if (!next.some((event) => event.type === "TOOL_CALL_RESULT" && event.toolCallId === toolCallId)) extras.push({
96
+ type: "TOOL_CALL_RESULT",
97
+ toolCallId,
98
+ messageId: `${toolCallId}-result`,
99
+ role: "tool",
100
+ content: "UI generated"
101
+ });
102
+ }
103
+ if (extras.length === 0) return next;
104
+ const finishIndex = next.findIndex((event) => event.type === "RUN_FINISHED");
105
+ if (finishIndex === -1) return [...next, ...extras];
106
+ return [
107
+ ...next.slice(0, finishIndex),
108
+ ...extras,
109
+ ...next.slice(finishIndex)
110
+ ];
111
+ }
112
+ function activitySnapshotFromSandboxedUiArgs(toolCallId, rawArgs) {
113
+ let args;
114
+ try {
115
+ const parsed = JSON.parse(snippetArgsJson(rawArgs));
116
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
117
+ args = parsed;
118
+ } catch {
119
+ return null;
120
+ }
121
+ const html = sandboxedUiHtmlChunks(args.html);
122
+ const css = typeof args.css === "string" ? args.css : void 0;
123
+ const jsFunctions = typeof args.jsFunctions === "string" ? args.jsFunctions : void 0;
124
+ const jsExpressions = Array.isArray(args.jsExpressions) ? args.jsExpressions.filter((item) => typeof item === "string") : void 0;
125
+ if (html.length === 0 && css === void 0 && jsFunctions === void 0 && (jsExpressions === void 0 || jsExpressions.length === 0)) return null;
126
+ return {
127
+ type: "ACTIVITY_SNAPSHOT",
128
+ messageId: `${toolCallId}-activity`,
129
+ activityType: OPEN_GENERATIVE_UI_ACTIVITY_TYPE,
130
+ content: {
131
+ initialHeight: typeof args.initialHeight === "number" ? args.initialHeight : void 0,
132
+ generating: false,
133
+ css,
134
+ cssComplete: true,
135
+ html,
136
+ htmlComplete: true,
137
+ jsFunctions,
138
+ jsFunctionsComplete: true,
139
+ jsExpressions,
140
+ jsExpressionsComplete: true
141
+ },
142
+ replace: true
143
+ };
144
+ }
145
+ function sandboxedUiHtmlChunks(html) {
146
+ if (typeof html === "string" && html.length > 0) return [html];
147
+ if (Array.isArray(html)) return html.filter((item) => typeof item === "string");
148
+ return [];
149
+ }
150
+ function snippetContainsToolCall(events) {
151
+ return events.some((event) => typeof event.type === "string" && event.type.startsWith("TOOL_CALL"));
152
+ }
153
+ function ensureRunEnvelope(events, ids) {
154
+ const next = [...events];
155
+ const hasStart = next.some((event) => event.type === "RUN_STARTED");
156
+ const hasFinish = next.some((event) => event.type === "RUN_FINISHED");
157
+ if (!hasStart) next.unshift({
158
+ type: "RUN_STARTED",
159
+ threadId: ids.threadId,
160
+ runId: ids.runId
161
+ });
162
+ if (!hasFinish) next.push({
163
+ type: "RUN_FINISHED",
164
+ threadId: ids.threadId,
165
+ runId: ids.runId
166
+ });
167
+ return next;
168
+ }
169
+ function snippetArgsJson(value) {
170
+ if (value && typeof value === "object") return JSON.stringify(value);
171
+ if (typeof value !== "string") return "{}";
172
+ const trimmed = value.trim() || "{}";
173
+ try {
174
+ return JSON.stringify(JSON.parse(trimmed));
175
+ } catch {
176
+ const recovered = firstJsonValue(trimmed);
177
+ if (recovered !== void 0) return JSON.stringify(recovered);
178
+ throw new Error("Tool args JSON is invalid.");
179
+ }
180
+ }
181
+ function firstJsonValue(raw) {
182
+ const start = raw.indexOf("{");
183
+ if (start === -1) return;
184
+ let depth = 0;
185
+ let inString = false;
186
+ let escaped = false;
187
+ for (let index = start; index < raw.length; index += 1) {
188
+ const char = raw[index];
189
+ if (inString) {
190
+ if (escaped) escaped = false;
191
+ else if (char === "\\") escaped = true;
192
+ else if (char === "\"") inString = false;
193
+ continue;
194
+ }
195
+ if (char === "\"") inString = true;
196
+ else if (char === "{") depth += 1;
197
+ else if (char === "}") {
198
+ depth -= 1;
199
+ if (depth === 0) try {
200
+ return JSON.parse(raw.slice(start, index + 1));
201
+ } catch {
202
+ return;
203
+ }
204
+ }
205
+ }
206
+ }
207
+ function compileToolCallRecipe(input) {
208
+ const toolName = input.toolName.trim();
209
+ if (!toolName) throw new Error("Tool name is required.");
210
+ const argsJson = snippetArgsJson(input.argsJson);
211
+ parseObjectJson(argsJson, "Tool args");
212
+ const parentMessageId = input.parentMessageId ?? createSnippetId();
213
+ const toolCallId = input.toolCallId ?? createSnippetId();
214
+ return ensureRunEnvelope([
215
+ {
216
+ type: "TOOL_CALL_START",
217
+ toolCallId,
218
+ toolCallName: toolName,
219
+ parentMessageId
220
+ },
221
+ {
222
+ type: "TOOL_CALL_ARGS",
223
+ toolCallId,
224
+ delta: argsJson
225
+ },
226
+ {
227
+ type: "TOOL_CALL_END",
228
+ toolCallId
229
+ }
230
+ ], input);
231
+ }
232
+ function compileReasoningRecipe(input) {
233
+ const text = input.text.trim();
234
+ if (!text) throw new Error("Reasoning text is required.");
235
+ const messageId = createSnippetId();
236
+ return ensureRunEnvelope([
237
+ {
238
+ type: "REASONING_START",
239
+ messageId
240
+ },
241
+ {
242
+ type: "REASONING_MESSAGE_START",
243
+ messageId,
244
+ role: "reasoning"
245
+ },
246
+ {
247
+ type: "REASONING_MESSAGE_CONTENT",
248
+ messageId,
249
+ delta: text
250
+ },
251
+ {
252
+ type: "REASONING_MESSAGE_END",
253
+ messageId
254
+ },
255
+ {
256
+ type: "REASONING_END",
257
+ messageId
258
+ }
259
+ ], input);
260
+ }
261
+ function compileTextRecipe(input) {
262
+ const text = input.text.trim();
263
+ if (!text) throw new Error("Assistant text is required.");
264
+ const messageId = input.messageId ?? createSnippetId();
265
+ return ensureRunEnvelope([
266
+ {
267
+ type: "TEXT_MESSAGE_START",
268
+ messageId,
269
+ role: "assistant"
270
+ },
271
+ {
272
+ type: "TEXT_MESSAGE_CONTENT",
273
+ messageId,
274
+ delta: text
275
+ },
276
+ {
277
+ type: "TEXT_MESSAGE_END",
278
+ messageId
279
+ }
280
+ ], input);
281
+ }
282
+ function compileActivityRecipe(input) {
283
+ const activityType = input.activityType.trim();
284
+ if (!activityType) throw new Error("Activity type is required.");
285
+ const content = parseObjectJson(input.contentJson, "Activity content");
286
+ return ensureRunEnvelope([{
287
+ type: "ACTIVITY_SNAPSHOT",
288
+ messageId: input.messageId ?? createSnippetId(),
289
+ activityType,
290
+ content,
291
+ replace: true
292
+ }], input);
293
+ }
294
+ function emptyRecipeDraft() {
295
+ return {
296
+ toolName: "",
297
+ toolArgs: "{}",
298
+ reasoningText: "",
299
+ textContent: "",
300
+ activityType: "a2ui-surface",
301
+ activityContent: "{}"
302
+ };
303
+ }
304
+ function compileChatSnippet(input) {
305
+ switch (input.kind) {
306
+ case "text": return {
307
+ recipe: "text",
308
+ events: compileTextRecipe({
309
+ text: input.content,
310
+ threadId: input.threadId,
311
+ runId: input.runId,
312
+ messageId: input.messageId
313
+ }),
314
+ name: autoSnippetName("text", snippetLabelFromText(input.content))
315
+ };
316
+ case "reasoning": return {
317
+ recipe: "reasoning",
318
+ events: compileReasoningRecipe({
319
+ text: input.content,
320
+ threadId: input.threadId,
321
+ runId: input.runId
322
+ }),
323
+ name: autoSnippetName("reasoning", snippetLabelFromText(input.content))
324
+ };
325
+ case "tool-call": return {
326
+ recipe: "tool-call",
327
+ events: compileToolCallRecipe({
328
+ toolName: input.toolName,
329
+ argsJson: snippetArgsJson(input.argsJson),
330
+ threadId: input.threadId,
331
+ runId: input.runId,
332
+ parentMessageId: input.messageId,
333
+ toolCallId: input.toolCallId
334
+ }),
335
+ name: autoSnippetName("tool-call", input.toolName)
336
+ };
337
+ case "activity": return {
338
+ recipe: "activity",
339
+ events: compileActivityRecipe({
340
+ activityType: input.activityType,
341
+ contentJson: JSON.stringify(input.content ?? {}),
342
+ threadId: input.threadId,
343
+ runId: input.runId,
344
+ messageId: input.messageId
345
+ }),
346
+ name: autoSnippetName("activity", input.activityType)
347
+ };
348
+ }
349
+ }
350
+ function editorStateFromSnippet(snippet) {
351
+ return {
352
+ recipe: snippet.recipe,
353
+ name: snippet.name,
354
+ json: JSON.stringify(snippet.events, null, 2),
355
+ draft: recipeDraftFromEvents(snippet.events)
356
+ };
357
+ }
358
+ function recipeDraftFromEvents(events) {
359
+ const draft = emptyRecipeDraft();
360
+ const textParts = [];
361
+ const reasoningParts = [];
362
+ const argParts = [];
363
+ for (const event of events) {
364
+ if (event.type === "TEXT_MESSAGE_CONTENT") {
365
+ const delta = readEventString(event, "delta");
366
+ if (delta) textParts.push(delta);
367
+ }
368
+ if (event.type === "REASONING_MESSAGE_CONTENT") {
369
+ const delta = readEventString(event, "delta");
370
+ if (delta) reasoningParts.push(delta);
371
+ }
372
+ if (event.type === "TOOL_CALL_START") {
373
+ const toolName = readEventString(event, "toolCallName");
374
+ if (toolName) draft.toolName = toolName;
375
+ }
376
+ if (event.type === "TOOL_CALL_ARGS") {
377
+ const delta = readEventString(event, "delta");
378
+ if (delta) argParts.push(delta);
379
+ }
380
+ if (event.type === "ACTIVITY_SNAPSHOT") {
381
+ const activityType = readEventString(event, "activityType");
382
+ if (activityType) draft.activityType = activityType;
383
+ draft.activityContent = prettyJson(event.content ?? {});
384
+ }
385
+ }
386
+ draft.textContent = textParts.join("");
387
+ draft.reasoningText = reasoningParts.join("");
388
+ if (argParts.length > 0) draft.toolArgs = prettyJson(argParts.join(""));
389
+ return draft;
390
+ }
391
+ function compileFromActivityMessage(input) {
392
+ return compileChatSnippet({
393
+ kind: "activity",
394
+ messageId: input.message.id,
395
+ activityType: input.message.activityType,
396
+ content: input.message.content,
397
+ threadId: input.threadId,
398
+ runId: input.runId
399
+ });
400
+ }
401
+ function parseSnippetEvents(raw) {
402
+ let parsed;
403
+ try {
404
+ parsed = JSON.parse(raw);
405
+ } catch {
406
+ throw new Error("Snippet JSON is invalid.");
407
+ }
408
+ if (!Array.isArray(parsed)) throw new Error("Snippet JSON must be an array of events.");
409
+ const events = [];
410
+ for (const item of parsed) {
411
+ if (!item || typeof item !== "object" || Array.isArray(item)) throw new Error("Each event must be an object with a string type.");
412
+ const record = item;
413
+ if (typeof record.type !== "string" || record.type.length === 0) throw new Error("Each event must have a string type.");
414
+ events.push(item);
415
+ }
416
+ return events;
417
+ }
418
+ function loadEventSnippets(storage = defaultStorage()) {
419
+ if (!storage) return [];
420
+ try {
421
+ const raw = storage.getItem(EVENT_SNIPPETS_STORAGE_KEY);
422
+ if (!raw) return [];
423
+ const parsed = JSON.parse(raw);
424
+ if (!Array.isArray(parsed)) return [];
425
+ return parsed.flatMap((item) => {
426
+ const snippet = parseStoredSnippet(item);
427
+ return snippet ? [snippet] : [];
428
+ });
429
+ } catch {
430
+ return [];
431
+ }
432
+ }
433
+ function saveEventSnippets(snippets, storage = defaultStorage()) {
434
+ if (!storage) throw new Error("Snippet storage is not available.");
435
+ storage.setItem(EVENT_SNIPPETS_STORAGE_KEY, JSON.stringify(snippets));
436
+ }
437
+ function upsertEventSnippet(snippet, storage = defaultStorage()) {
438
+ const current = loadEventSnippets(storage);
439
+ const index = current.findIndex((item) => item.id === snippet.id);
440
+ const next = index === -1 ? [...current, snippet] : current.map((item, itemIndex) => itemIndex === index ? snippet : item);
441
+ saveEventSnippets(next, storage);
442
+ return next;
443
+ }
444
+ function deleteEventSnippet(id, storage = defaultStorage()) {
445
+ const next = loadEventSnippets(storage).filter((item) => item.id !== id);
446
+ saveEventSnippets(next, storage);
447
+ return next;
448
+ }
449
+ function exportEventSnippetsJson(snippets) {
450
+ return JSON.stringify(snippets, null, 2);
451
+ }
452
+ function importEventSnippets(raw, storage = defaultStorage()) {
453
+ let parsed;
454
+ try {
455
+ parsed = JSON.parse(raw);
456
+ } catch {
457
+ throw new Error("Import JSON is invalid.");
458
+ }
459
+ const incoming = Array.isArray(parsed) ? parsed : [parsed];
460
+ const imported = [];
461
+ for (const item of incoming) {
462
+ const snippet = parseStoredSnippet(item);
463
+ if (!snippet) throw new Error("Import JSON is not a valid snippet list.");
464
+ imported.push({
465
+ ...snippet,
466
+ id: createSnippetId(),
467
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
468
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
469
+ });
470
+ }
471
+ if (imported.length === 0) throw new Error("Import JSON is not a valid snippet list.");
472
+ const next = [...loadEventSnippets(storage), ...imported];
473
+ saveEventSnippets(next, storage);
474
+ return next;
475
+ }
476
+ function snippetLabelFromText(text) {
477
+ const compact = text.trim().replace(/\s+/g, " ");
478
+ if (compact.length <= 40) return compact;
479
+ return `${compact.slice(0, 37)}...`;
480
+ }
481
+ function parseObjectJson(raw, label) {
482
+ try {
483
+ return JSON.parse(raw);
484
+ } catch {
485
+ throw new Error(`${label} JSON is invalid.`);
486
+ }
487
+ }
488
+ function readEventString(event, key) {
489
+ const value = event[key];
490
+ return typeof value === "string" && value.length > 0 ? value : null;
491
+ }
492
+ function prettyJson(value) {
493
+ if (typeof value === "string") try {
494
+ return JSON.stringify(JSON.parse(value), null, 2);
495
+ } catch {
496
+ return value;
497
+ }
498
+ try {
499
+ return JSON.stringify(value ?? {}, null, 2);
500
+ } catch {
501
+ return "{}";
502
+ }
503
+ }
504
+ function parseStoredSnippet(value) {
505
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
506
+ const record = value;
507
+ if (typeof record.id !== "string" || record.id.length === 0) return null;
508
+ if (typeof record.name !== "string") return null;
509
+ if (!isSnippetRecipe(record.recipe)) return null;
510
+ if (!Array.isArray(record.events)) return null;
511
+ const events = [];
512
+ for (const event of record.events) {
513
+ if (!event || typeof event !== "object" || Array.isArray(event)) return null;
514
+ if (typeof event.type !== "string") return null;
515
+ events.push(event);
516
+ }
517
+ return {
518
+ id: record.id,
519
+ name: record.name,
520
+ recipe: record.recipe,
521
+ events,
522
+ createdAt: typeof record.createdAt === "string" ? record.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
523
+ updatedAt: typeof record.updatedAt === "string" ? record.updatedAt : (/* @__PURE__ */ new Date()).toISOString()
524
+ };
525
+ }
526
+ function defaultStorage() {
527
+ if (typeof window === "undefined") return null;
528
+ try {
529
+ return window.localStorage;
530
+ } catch {
531
+ return null;
532
+ }
533
+ }
534
+
535
+ //#endregion
536
+ export { ACTIVITY_STARTERS, compileActivityRecipe, compileChatSnippet, compileFromActivityMessage, compileReasoningRecipe, compileTextRecipe, compileToolCallRecipe, createSnippetId, deleteEventSnippet, editorStateFromSnippet, expandSnippetEventsForRun, exportEventSnippetsJson, groupEventSnippets, importEventSnippets, loadEventSnippets, parseSnippetEvents, recipeIconName, recipeIconWrapClass, recipeLabel, snippetContainsToolCall, snippetJsonIsRunnable, upsertEventSnippet };
537
+ //# sourceMappingURL=event-snippets.mjs.map