@compose-market/core 0.1.0 → 0.1.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.
@@ -0,0 +1,1225 @@
1
+ const EOL = /\r\n|\r|\n/;
2
+ function lines(buffer) {
3
+ const parts = buffer.split(EOL);
4
+ const rest = parts.pop() ?? "";
5
+ return { lines: parts, rest };
6
+ }
7
+ export async function* parseSSEStream(stream, options = {}) {
8
+ const reader = stream.getReader();
9
+ const decoder = new TextDecoder("utf-8");
10
+ let buffer = "";
11
+ let event = "message";
12
+ let data = [];
13
+ let id;
14
+ const abort = () => {
15
+ try {
16
+ reader.cancel();
17
+ }
18
+ catch { /* best effort */ }
19
+ };
20
+ options.signal?.addEventListener("abort", abort);
21
+ try {
22
+ while (true) {
23
+ const { value, done } = await reader.read();
24
+ if (done)
25
+ break;
26
+ buffer += decoder.decode(value, { stream: true });
27
+ const split = lines(buffer);
28
+ buffer = split.rest;
29
+ for (const line of split.lines) {
30
+ if (line === "") {
31
+ if (data.length > 0) {
32
+ yield { event, data: data.join("\n"), ...(id ? { id } : {}) };
33
+ }
34
+ event = "message";
35
+ data = [];
36
+ id = undefined;
37
+ continue;
38
+ }
39
+ if (line.startsWith(":"))
40
+ continue;
41
+ const colon = line.indexOf(":");
42
+ const field = colon === -1 ? line : line.slice(0, colon);
43
+ let value = colon === -1 ? "" : line.slice(colon + 1);
44
+ if (value.startsWith(" "))
45
+ value = value.slice(1);
46
+ if (field === "event")
47
+ event = value || "message";
48
+ else if (field === "data")
49
+ data.push(value);
50
+ else if (field === "id")
51
+ id = value;
52
+ }
53
+ }
54
+ buffer += decoder.decode();
55
+ if (buffer.length > 0) {
56
+ const split = lines(`${buffer}\n`);
57
+ for (const line of split.lines) {
58
+ if (line === "")
59
+ break;
60
+ if (line.startsWith(":"))
61
+ continue;
62
+ const colon = line.indexOf(":");
63
+ const field = colon === -1 ? line : line.slice(0, colon);
64
+ let value = colon === -1 ? "" : line.slice(colon + 1);
65
+ if (value.startsWith(" "))
66
+ value = value.slice(1);
67
+ if (field === "event")
68
+ event = value || "message";
69
+ else if (field === "data")
70
+ data.push(value);
71
+ else if (field === "id")
72
+ id = value;
73
+ }
74
+ }
75
+ if (data.length > 0) {
76
+ yield { event, data: data.join("\n"), ...(id ? { id } : {}) };
77
+ }
78
+ }
79
+ finally {
80
+ options.signal?.removeEventListener("abort", abort);
81
+ try {
82
+ reader.releaseLock();
83
+ }
84
+ catch { /* best effort */ }
85
+ }
86
+ }
87
+ export function encode(event) {
88
+ return `data: ${JSON.stringify(event)}\n\n`;
89
+ }
90
+ export function createStreamTree() {
91
+ return {
92
+ roots: [],
93
+ nodes: {},
94
+ seen: {},
95
+ text: "",
96
+ reasoning: "",
97
+ artifacts: [],
98
+ receipts: [],
99
+ errors: [],
100
+ };
101
+ }
102
+ export function reduce(tree, event) {
103
+ const next = {
104
+ roots: tree.roots.slice(),
105
+ nodes: { ...tree.nodes },
106
+ seen: { ...tree.seen },
107
+ text: tree.text,
108
+ reasoning: tree.reasoning,
109
+ artifacts: tree.artifacts.slice(),
110
+ receipts: tree.receipts.slice(),
111
+ errors: tree.errors.slice(),
112
+ };
113
+ if (!event.delta) {
114
+ const serial = stable(event);
115
+ if (next.seen[event.id] !== undefined && next.seen[event.id] === serial) {
116
+ return next;
117
+ }
118
+ next.seen[event.id] = serial;
119
+ }
120
+ const current = next.nodes[event.id];
121
+ const node = {
122
+ id: event.id,
123
+ kind: event.kind,
124
+ source: event.source,
125
+ ...(event.parentId ? { parentId: event.parentId } : current?.parentId ? { parentId: current.parentId } : {}),
126
+ ...(event.rootId ? { rootId: event.rootId } : current?.rootId ? { rootId: current.rootId } : {}),
127
+ ...(event.runId ? { runId: event.runId } : current?.runId ? { runId: current.runId } : {}),
128
+ status: event.status ?? current?.status ?? "running",
129
+ path: event.path ?? current?.path ?? [],
130
+ display: { ...(current?.display ?? {}), ...(event.display ?? {}) },
131
+ payload: merge(current?.payload, event.payload),
132
+ ...(event.raw !== undefined ? { raw: event.raw } : current?.raw !== undefined ? { raw: current.raw } : {}),
133
+ text: current?.text ?? "",
134
+ children: current?.children.slice() ?? [],
135
+ updatedAt: event.ts ?? Date.now(),
136
+ events: (current?.events ?? 0) + 1,
137
+ };
138
+ if (event.delta) {
139
+ node.text += event.delta;
140
+ if (event.kind === "text")
141
+ next.text += event.delta;
142
+ if (event.kind === "reasoning")
143
+ next.reasoning += event.delta;
144
+ }
145
+ next.nodes[event.id] = node;
146
+ if (node.parentId) {
147
+ const parent = next.nodes[node.parentId] ?? placeholder(node.parentId, event);
148
+ if (!parent.children.includes(node.id))
149
+ parent.children.push(node.id);
150
+ next.nodes[parent.id] = parent;
151
+ }
152
+ else if (!next.roots.includes(node.id)) {
153
+ next.roots.push(node.id);
154
+ }
155
+ if (event.kind === "artifact" && !next.artifacts.some((item) => item.id === event.id)) {
156
+ next.artifacts.push(event);
157
+ }
158
+ if ((event.kind === "receipt" || event.kind === "payment") && !next.receipts.some((item) => item.id === event.id)) {
159
+ next.receipts.push(event);
160
+ }
161
+ if (event.kind === "error" && !next.errors.some((item) => item.id === event.id)) {
162
+ next.errors.push(event);
163
+ }
164
+ return next;
165
+ }
166
+ export function decode(input, options = {}) {
167
+ const raw = framePayload(input);
168
+ if (raw === "[DONE]") {
169
+ return event({
170
+ id: id("done", options.runId),
171
+ kind: "run",
172
+ source: options.source ?? "stream",
173
+ status: "completed",
174
+ display: { title: "Done" },
175
+ raw,
176
+ }, options);
177
+ }
178
+ if (!raw)
179
+ return null;
180
+ if (isRecord(raw) && raw.type === "stream") {
181
+ const decoded = raw;
182
+ if (!decoded.id || !decoded.kind || !decoded.source)
183
+ return null;
184
+ return decoded;
185
+ }
186
+ if (typeof raw === "string") {
187
+ return event({
188
+ id: id("text", options.runId),
189
+ kind: "text",
190
+ source: options.source ?? "stream",
191
+ status: "running",
192
+ delta: raw,
193
+ raw,
194
+ }, options);
195
+ }
196
+ if (!isRecord(raw))
197
+ return null;
198
+ return decodeRecord(raw, options);
199
+ }
200
+ function decodeRecord(raw, options) {
201
+ const type = string(raw.type) ?? string(raw.eventName) ?? string(raw.event) ?? "";
202
+ const runId = string(raw.composeRunId) ?? string(raw.runId) ?? options.runId;
203
+ const rootId = string(raw.rootComposeRunId) ?? options.rootId ?? runId;
204
+ const source = options.source ?? sourceOf(type, raw);
205
+ const base = { ...options, runId, rootId, source };
206
+ if (type === "text-delta") {
207
+ const delta = string(raw.delta) ?? string(raw.text) ?? string(raw.content) ?? "";
208
+ return delta ? event({
209
+ id: id("text", runId),
210
+ kind: "text",
211
+ source,
212
+ status: "running",
213
+ delta,
214
+ display: { title: "Response" },
215
+ raw,
216
+ }, base) : null;
217
+ }
218
+ if (type === "reasoning-delta" || type === "reasoning_delta" || type === "thinking" || type === "thinking-delta" || type === "thinking_delta") {
219
+ const delta = string(raw.delta) ?? string(raw.text) ?? string(raw.thinking) ?? string(raw.content) ?? "";
220
+ return delta ? event({
221
+ id: id("reasoning", runId),
222
+ kind: "reasoning",
223
+ source,
224
+ status: "running",
225
+ delta,
226
+ display: { title: "Reasoning" },
227
+ raw,
228
+ }, base) : null;
229
+ }
230
+ if (type === "warning" || type === "response.warning") {
231
+ const warning = isRecord(raw.warning) ? raw.warning : raw;
232
+ return event({
233
+ id: id("warning", string(warning.code), string(warning.message), runId),
234
+ kind: "debug",
235
+ source,
236
+ status: "info",
237
+ display: { title: "Warning", summary: string(warning.message) ?? string(raw.message) },
238
+ payload: { warning },
239
+ raw,
240
+ }, base);
241
+ }
242
+ if (type === "citation" || type === "response.citation") {
243
+ const citation = isRecord(raw.citation) ? raw.citation : raw;
244
+ return event({
245
+ id: id("citation", string(citation.url), string(citation.title), string(citation.marker), runId),
246
+ kind: "catalog",
247
+ source,
248
+ parentId: modelParent(base, string(raw.response_id)),
249
+ status: "completed",
250
+ display: {
251
+ title: string(citation.title) ?? "Citation",
252
+ summary: string(citation.snippet),
253
+ target: string(citation.url) ?? string(citation.marker),
254
+ },
255
+ payload: { citation },
256
+ raw,
257
+ }, base);
258
+ }
259
+ if (type === "thinking-start" || type === "thinking_start" || type === "thinking-end" || type === "thinking_end") {
260
+ return event({
261
+ id: id("debug", type, runId),
262
+ kind: "debug",
263
+ source,
264
+ status: type.endsWith("end") ? "completed" : "running",
265
+ display: { title: "Runtime status", summary: string(raw.message) ?? type },
266
+ payload: raw,
267
+ raw,
268
+ }, base);
269
+ }
270
+ if (type === "stopped") {
271
+ return event({
272
+ id: id("stopped", runId),
273
+ kind: "run",
274
+ source,
275
+ status: "cancelled",
276
+ display: { title: "Stopped", summary: string(raw.reason) },
277
+ payload: raw,
278
+ raw,
279
+ }, base);
280
+ }
281
+ if (type === "tool-args-delta") {
282
+ return event({
283
+ id: id("tool", string(raw.id) ?? string(raw.toolName), runId),
284
+ kind: "tool",
285
+ source,
286
+ status: "running",
287
+ display: { title: string(raw.toolName) ?? "Tool" },
288
+ payload: { arguments: string(raw.argsDelta) },
289
+ raw,
290
+ }, base);
291
+ }
292
+ if (type === "tool-start")
293
+ raw.type = "tool_start";
294
+ if (type === "tool-end")
295
+ raw.type = "tool_end";
296
+ if (Array.isArray(raw.choices)) {
297
+ const choice = raw.choices[0];
298
+ const delta = isRecord(choice) && isRecord(choice.delta) ? choice.delta : null;
299
+ const reasoning = string(delta?.reasoning_content);
300
+ if (reasoning) {
301
+ return event({
302
+ id: id("reasoning", runId),
303
+ kind: "reasoning",
304
+ source,
305
+ parentId: modelParent(base, string(raw.id)),
306
+ status: "running",
307
+ delta: reasoning,
308
+ display: { title: "Reasoning" },
309
+ raw,
310
+ }, base);
311
+ }
312
+ const text = string(delta?.content);
313
+ if (text) {
314
+ return event({
315
+ id: id("text", runId),
316
+ kind: "text",
317
+ source,
318
+ parentId: modelParent(base, string(raw.id)),
319
+ status: "running",
320
+ delta: text,
321
+ display: { title: "Response" },
322
+ raw,
323
+ }, base);
324
+ }
325
+ if (raw.usage) {
326
+ return event({
327
+ id: id("model", string(raw.id) ?? runId),
328
+ kind: "model",
329
+ source,
330
+ status: "completed",
331
+ display: { title: string(raw.model) ?? "Model", summary: "Usage", target: string(raw.id) },
332
+ payload: { usage: raw.usage },
333
+ raw,
334
+ }, base);
335
+ }
336
+ const finish = isRecord(choice) ? string(choice.finish_reason) : undefined;
337
+ if (finish) {
338
+ return event({
339
+ id: id("model", string(raw.id) ?? runId),
340
+ kind: "model",
341
+ source,
342
+ status: "completed",
343
+ display: { title: string(raw.model) ?? "Model", summary: finish, target: string(raw.id) },
344
+ payload: { finishReason: finish, usage: raw.usage },
345
+ raw,
346
+ }, base);
347
+ }
348
+ return null;
349
+ }
350
+ if (Array.isArray(raw.candidates)) {
351
+ const candidate = isRecord(raw.candidates[0]) ? raw.candidates[0] : null;
352
+ const content = isRecord(candidate?.content) ? candidate.content : {};
353
+ const parts = Array.isArray(content.parts) ? content.parts : [];
354
+ const part = parts.find(isRecord);
355
+ if (part) {
356
+ const text = string(part.text);
357
+ if (text) {
358
+ const reasoning = part.thought === true;
359
+ return event({
360
+ id: id(reasoning ? "reasoning" : "text", runId),
361
+ kind: reasoning ? "reasoning" : "text",
362
+ source,
363
+ parentId: modelParent(base, string(raw.response_id)),
364
+ status: "running",
365
+ delta: text,
366
+ display: { title: reasoning ? "Reasoning" : "Response" },
367
+ raw,
368
+ }, base);
369
+ }
370
+ const inline = isRecord(part.inlineData) ? part.inlineData : isRecord(part.inline_data) ? part.inline_data : null;
371
+ const data = string(inline?.data);
372
+ if (data) {
373
+ return event({
374
+ id: id("artifact", string(raw.response_id) ?? runId, number(raw.index), data),
375
+ kind: "artifact",
376
+ source,
377
+ parentId: modelParent(base, string(raw.response_id)),
378
+ status: "running",
379
+ display: { title: "Media", target: string(raw.model) },
380
+ payload: {
381
+ artifactType: mediaKind(string(inline?.mimeType) ?? string(inline?.mime_type)),
382
+ responseId: string(raw.response_id),
383
+ mimeType: string(inline?.mimeType) ?? string(inline?.mime_type),
384
+ inline: true,
385
+ base64: data,
386
+ },
387
+ raw,
388
+ }, base);
389
+ }
390
+ const call = isRecord(part.functionCall) ? part.functionCall : isRecord(part.function_call) ? part.function_call : null;
391
+ if (call) {
392
+ return event({
393
+ id: id("tool", string(call.id) ?? string(call.name), runId),
394
+ kind: "tool",
395
+ source,
396
+ parentId: modelParent(base, string(raw.response_id)),
397
+ status: "completed",
398
+ display: { title: string(call.name) ?? "Tool" },
399
+ payload: {
400
+ name: string(call.name),
401
+ arguments: JSON.stringify(call.args ?? {}),
402
+ },
403
+ raw,
404
+ }, base);
405
+ }
406
+ }
407
+ if (raw.usageMetadata) {
408
+ return event({
409
+ id: id("model", string(raw.response_id) ?? runId),
410
+ kind: "model",
411
+ source,
412
+ parentId: modelParent(base, string(raw.response_id)),
413
+ status: "info",
414
+ display: { title: string(raw.model) ?? "Model", summary: "Usage" },
415
+ payload: { usage: raw.usageMetadata },
416
+ raw,
417
+ }, base);
418
+ }
419
+ }
420
+ if (type === "response.created") {
421
+ const response = isRecord(raw.response) ? raw.response : {};
422
+ const responseId = string(response.id) ?? string(raw.response_id) ?? runId;
423
+ return event({
424
+ id: id("model", responseId),
425
+ kind: "model",
426
+ source,
427
+ status: "running",
428
+ display: { title: string(response.model) ?? string(raw.model) ?? "Model", target: responseId },
429
+ payload: { response },
430
+ raw,
431
+ }, base);
432
+ }
433
+ if (type === "response.output_text.delta") {
434
+ const delta = string(raw.delta) ?? "";
435
+ return delta ? event({
436
+ id: id("text", string(raw.response_id) ?? runId),
437
+ kind: "text",
438
+ source,
439
+ parentId: modelParent(base, string(raw.response_id)),
440
+ status: "running",
441
+ delta,
442
+ display: { title: "Response", target: string(raw.model) },
443
+ raw,
444
+ }, base) : null;
445
+ }
446
+ if (type === "response.reasoning.delta" || type === "response.reasoning_text.delta" || type === "response.reasoning_summary_text.delta") {
447
+ const delta = string(raw.delta) ?? "";
448
+ return delta ? event({
449
+ id: id("reasoning", string(raw.response_id) ?? runId),
450
+ kind: "reasoning",
451
+ source,
452
+ parentId: modelParent(base, string(raw.response_id)),
453
+ status: "running",
454
+ delta,
455
+ display: { title: "Reasoning", target: string(raw.model) },
456
+ raw,
457
+ }, base) : null;
458
+ }
459
+ if (type === "content_block_start") {
460
+ const block = isRecord(raw.content_block) ? raw.content_block : {};
461
+ if (string(block.type) === "tool_use") {
462
+ return event({
463
+ id: id("tool", string(block.id), string(block.name), runId),
464
+ kind: "tool",
465
+ source,
466
+ parentId: modelParent(base, string(raw.message_id)),
467
+ status: "running",
468
+ display: { title: string(block.name) ?? "Tool" },
469
+ payload: { name: string(block.name), input: block.input, index: number(raw.index) },
470
+ raw,
471
+ }, base);
472
+ }
473
+ }
474
+ if (type === "message_delta") {
475
+ const delta = isRecord(raw.delta) ? raw.delta : {};
476
+ return event({
477
+ id: id("model", string(raw.message_id) ?? runId),
478
+ kind: "model",
479
+ source,
480
+ status: "info",
481
+ display: { title: string(raw.model) ?? "Model", summary: string(delta.stop_reason) },
482
+ payload: { usage: raw.usage, stopReason: string(delta.stop_reason) },
483
+ raw,
484
+ }, base);
485
+ }
486
+ if (type === "content_block_delta") {
487
+ const delta = isRecord(raw.delta) ? raw.delta : {};
488
+ const deltaType = string(delta.type);
489
+ const text = string(delta.text) ?? string(delta.thinking);
490
+ if (!text)
491
+ return null;
492
+ const reasoning = deltaType === "thinking_delta" || string(delta.thinking) !== undefined;
493
+ return event({
494
+ id: id(reasoning ? "reasoning" : "text", string(raw.message_id) ?? runId),
495
+ kind: reasoning ? "reasoning" : "text",
496
+ source,
497
+ parentId: modelParent(base, string(raw.message_id)),
498
+ status: "running",
499
+ delta: text,
500
+ display: { title: reasoning ? "Reasoning" : "Response" },
501
+ raw,
502
+ }, base);
503
+ }
504
+ if (type === "response.audio.delta" || type === "response.output_audio.delta") {
505
+ const delta = string(raw.delta) ?? "";
506
+ return event({
507
+ id: id("audio", string(raw.response_id) ?? runId),
508
+ kind: "artifact",
509
+ source,
510
+ parentId: modelParent(base, string(raw.response_id)),
511
+ status: "running",
512
+ display: { title: "Audio", target: string(raw.model) },
513
+ payload: {
514
+ artifactType: "audio",
515
+ responseId: string(raw.response_id),
516
+ mimeType: string(raw.mime_type),
517
+ inline: true,
518
+ base64: delta,
519
+ },
520
+ raw,
521
+ }, base);
522
+ }
523
+ if (type === "audio-chunk") {
524
+ const chunk = raw.chunk;
525
+ const base64 = typeof chunk === "string"
526
+ ? chunk
527
+ : isRecord(chunk) && typeof chunk.base64 === "string"
528
+ ? chunk.base64
529
+ : undefined;
530
+ return event({
531
+ id: id("audio", string(raw.response_id) ?? runId, number(raw.sequenceIndex)),
532
+ kind: "artifact",
533
+ source,
534
+ parentId: modelParent(base, string(raw.response_id)),
535
+ status: "running",
536
+ display: { title: "Audio", target: string(raw.model) },
537
+ payload: {
538
+ artifactType: "audio",
539
+ responseId: string(raw.response_id),
540
+ sequenceIndex: number(raw.sequenceIndex),
541
+ mimeType: string(raw.mime_type) ?? string(raw.mimeType),
542
+ inline: true,
543
+ base64,
544
+ },
545
+ raw,
546
+ }, base);
547
+ }
548
+ if (type === "subtitle" || type === "response.output_audio.subtitle") {
549
+ const subtitle = isRecord(raw.subtitle) ? raw.subtitle : raw;
550
+ return event({
551
+ id: id("subtitle", string(raw.response_id), number(subtitle.start), number(subtitle.end), runId),
552
+ kind: "artifact",
553
+ source,
554
+ parentId: modelParent(base, string(raw.response_id)),
555
+ status: "running",
556
+ display: { title: "Subtitle", summary: string(subtitle.text), target: string(raw.model) },
557
+ payload: {
558
+ artifactType: "text",
559
+ responseId: string(raw.response_id),
560
+ subtitle,
561
+ },
562
+ raw,
563
+ }, base);
564
+ }
565
+ if (type === "response.text.delta") {
566
+ const delta = string(raw.delta) ?? "";
567
+ return delta ? event({
568
+ id: id("text", string(raw.response_id) ?? runId),
569
+ kind: "text",
570
+ source,
571
+ parentId: modelParent(base, string(raw.response_id)),
572
+ status: "running",
573
+ delta,
574
+ display: { title: "Response", target: string(raw.model) },
575
+ raw,
576
+ }, base) : null;
577
+ }
578
+ if (type === "response.image_generation_call.partial_image" || type === "response.image_generation_call.completed") {
579
+ const complete = type.endsWith(".completed");
580
+ return event({
581
+ id: id("artifact", string(raw.response_id), number(raw.partial_image_index)),
582
+ kind: "artifact",
583
+ source,
584
+ parentId: modelParent(base, string(raw.response_id)),
585
+ status: complete ? "completed" : "running",
586
+ display: {
587
+ title: complete ? "Image complete" : "Image partial",
588
+ target: string(raw.model),
589
+ summary: string(raw.revised_prompt),
590
+ },
591
+ payload: {
592
+ artifactType: "image",
593
+ responseId: string(raw.response_id),
594
+ mimeType: string(raw.mime_type) ?? "image/png",
595
+ inline: true,
596
+ partial: !complete,
597
+ base64: string(raw.partial_image_b64) ?? string(raw.image_b64),
598
+ usage: raw.usage,
599
+ },
600
+ raw,
601
+ }, base);
602
+ }
603
+ if (type === "image-partial" || type === "image-complete") {
604
+ const image = isRecord(raw.image) ? raw.image : raw;
605
+ const complete = type === "image-complete";
606
+ return event({
607
+ id: id("artifact", string(raw.response_id) ?? runId, number(image.index), string(image.url), string(image.base64)),
608
+ kind: "artifact",
609
+ source,
610
+ parentId: modelParent(base, string(raw.response_id)),
611
+ status: complete ? "completed" : "running",
612
+ display: {
613
+ title: complete ? "Image complete" : "Image partial",
614
+ target: string(raw.model),
615
+ summary: string(image.revisedPrompt),
616
+ },
617
+ payload: {
618
+ artifactType: "image",
619
+ responseId: string(raw.response_id),
620
+ mimeType: string(image.mediaType) ?? string(image.mimeType) ?? "image/png",
621
+ url: string(image.url),
622
+ inline: string(image.base64) !== undefined,
623
+ partial: !complete,
624
+ base64: string(image.base64),
625
+ usage: raw.usage,
626
+ },
627
+ raw,
628
+ }, base);
629
+ }
630
+ if (type === "response.output_item.completed") {
631
+ const item = isRecord(raw.item) ? raw.item : {};
632
+ const itemType = string(item.type);
633
+ if (itemType === "output_text") {
634
+ const text = string(item.text) ?? "";
635
+ return text ? event({
636
+ id: id("text", string(raw.response_id) ?? runId),
637
+ kind: "text",
638
+ source,
639
+ parentId: modelParent(base, string(raw.response_id)),
640
+ status: "completed",
641
+ delta: text,
642
+ display: { title: "Response", target: string(raw.model) },
643
+ raw,
644
+ }, base) : null;
645
+ }
646
+ const asset = media(item);
647
+ if (asset) {
648
+ return event({
649
+ id: id("artifact", string(raw.response_id), number(raw.output_index), asset.url ?? asset.base64),
650
+ kind: "artifact",
651
+ source,
652
+ parentId: modelParent(base, string(raw.response_id)),
653
+ status: "completed",
654
+ display: {
655
+ title: asset.kind,
656
+ target: string(raw.model),
657
+ summary: string(item.text) ?? string(item.status),
658
+ },
659
+ payload: {
660
+ artifactType: asset.kind,
661
+ responseId: string(raw.response_id),
662
+ mimeType: string(item.mime_type),
663
+ url: asset.url,
664
+ inline: asset.base64 !== undefined,
665
+ base64: asset.base64,
666
+ status: string(item.status),
667
+ jobId: string(item.job_id),
668
+ },
669
+ raw,
670
+ }, base);
671
+ }
672
+ }
673
+ if (type === "response.output_video.status" || type === "compose.video.status" || type === "status") {
674
+ return event({
675
+ id: id("video", string(raw.job_id) ?? string(raw.jobId) ?? string(raw.response_id)),
676
+ kind: "artifact",
677
+ source,
678
+ parentId: modelParent(base, string(raw.response_id)),
679
+ status: raw.status === "failed" ? "failed" : raw.status === "completed" ? "completed" : "running",
680
+ display: {
681
+ title: "Video",
682
+ target: string(raw.model),
683
+ summary: string(raw.status),
684
+ },
685
+ payload: {
686
+ artifactType: "video",
687
+ responseId: string(raw.response_id),
688
+ jobId: string(raw.job_id) ?? string(raw.jobId),
689
+ status: string(raw.status),
690
+ progress: number(raw.progress),
691
+ url: string(raw.url),
692
+ error: string(raw.error),
693
+ },
694
+ raw,
695
+ }, base);
696
+ }
697
+ if (type === "video-complete") {
698
+ const video = isRecord(raw.video) ? raw.video : raw;
699
+ return event({
700
+ id: id("video", string(video.jobId), string(video.url), string(raw.response_id), runId),
701
+ kind: "artifact",
702
+ source,
703
+ parentId: modelParent(base, string(raw.response_id)),
704
+ status: "completed",
705
+ display: { title: "Video", target: string(raw.model), summary: string(video.status) },
706
+ payload: {
707
+ artifactType: "video",
708
+ responseId: string(raw.response_id),
709
+ jobId: string(video.jobId),
710
+ status: string(video.status) ?? "completed",
711
+ progress: number(video.progress),
712
+ url: string(video.url),
713
+ mimeType: string(video.mediaType) ?? string(video.mimeType),
714
+ inline: string(video.base64) !== undefined,
715
+ base64: string(video.base64),
716
+ },
717
+ raw,
718
+ }, base);
719
+ }
720
+ if (type === "start" || type === "step" || type === "agent" || type === "progress" || type === "complete") {
721
+ const kind = type === "agent" ? "agent" : type === "progress" || type === "step" ? "action" : "run";
722
+ return event({
723
+ id: id(kind, string(raw.stepName) ?? string(raw.agentName) ?? type, runId),
724
+ kind,
725
+ source,
726
+ status: type === "complete" ? "completed" : "running",
727
+ display: {
728
+ title: string(raw.agentName) ?? string(raw.stepName) ?? type,
729
+ summary: string(raw.message),
730
+ },
731
+ payload: raw,
732
+ raw,
733
+ }, base);
734
+ }
735
+ if (type === "result") {
736
+ const output = raw.output;
737
+ const outputRecord = isRecord(output) ? output : {};
738
+ const mediaOutput = media(outputRecord);
739
+ if (mediaOutput) {
740
+ return event({
741
+ id: id("artifact", mediaOutput.url ?? mediaOutput.base64, runId),
742
+ kind: "artifact",
743
+ source,
744
+ status: "completed",
745
+ display: { title: mediaOutput.kind, summary: string(outputRecord.status) },
746
+ payload: {
747
+ artifactType: mediaOutput.kind,
748
+ url: mediaOutput.url,
749
+ inline: mediaOutput.base64 !== undefined,
750
+ base64: mediaOutput.base64,
751
+ mimeType: string(outputRecord.mimeType) ?? string(outputRecord.mime_type),
752
+ },
753
+ raw,
754
+ }, base);
755
+ }
756
+ const text = string(output) ?? (isRecord(output) ? JSON.stringify(output) : undefined);
757
+ return text ? event({
758
+ id: id("text", runId),
759
+ kind: "text",
760
+ source,
761
+ status: "completed",
762
+ delta: text,
763
+ display: { title: "Result" },
764
+ payload: raw,
765
+ raw,
766
+ }, base) : null;
767
+ }
768
+ if (type === "tool-call-start" || type === "tool-call" || type === "tool-call-delta" || type === "response.tool_call" || type === "response.tool_call.delta" || type === "tool_args_delta") {
769
+ const call = isRecord(raw.tool_call) ? raw.tool_call : raw;
770
+ const delta = isRecord(raw.delta) ? raw.delta : raw;
771
+ return event({
772
+ id: id("tool", string(call.id) ?? string(delta.id) ?? string(call.name) ?? string(raw.toolName), runId),
773
+ kind: "tool",
774
+ source,
775
+ parentId: modelParent(base, string(raw.response_id)),
776
+ status: type.endsWith(".delta") || type === "tool_args_delta" || type === "tool-call-delta" || type === "tool-call-start" ? "running" : "completed",
777
+ display: { title: string(call.name) ?? string(delta.name) ?? string(raw.toolName) ?? "Tool" },
778
+ payload: {
779
+ name: string(call.name) ?? string(delta.name) ?? string(raw.toolName),
780
+ arguments: string(call.arguments) ?? string(delta.arguments) ?? string(raw.argumentsDelta) ?? string(raw.argsDelta),
781
+ index: number(raw.index),
782
+ },
783
+ raw,
784
+ }, base);
785
+ }
786
+ if (type === "tool_start" || type === "tool-start") {
787
+ const display = displayOf(raw);
788
+ return event({
789
+ id: id("tool", string(raw.toolName) ?? display.target, runId),
790
+ kind: displayKind(display, "tool"),
791
+ source,
792
+ parentId: agentParent(base),
793
+ status: "running",
794
+ display: { title: display.title ?? string(raw.toolName) ?? "Tool", summary: string(raw.content) ?? display.summary, target: display.target, kind: display.kind, metadata: display.metadata },
795
+ raw,
796
+ }, base);
797
+ }
798
+ if (type === "tool_end" || type === "tool-end") {
799
+ const display = displayOf(raw);
800
+ const failed = Boolean(raw.failed) || Boolean(string(raw.error));
801
+ return event({
802
+ id: id("tool", string(raw.toolName) ?? display.target, runId),
803
+ kind: displayKind(display, "tool"),
804
+ source,
805
+ parentId: agentParent(base),
806
+ status: failed ? "failed" : "completed",
807
+ display: { title: display.title ?? string(raw.toolName) ?? "Tool", summary: string(raw.message) ?? display.summary, target: display.target, kind: display.kind, metadata: display.metadata },
808
+ payload: { output: raw.output, error: string(raw.error) },
809
+ raw,
810
+ }, base);
811
+ }
812
+ if (type === "harness_plan_proposed" || type === "harness_plan_decided") {
813
+ const decided = type === "harness_plan_decided";
814
+ return event({
815
+ id: id("approval", string(raw.proposalId), string(raw.version)),
816
+ kind: "approval",
817
+ source,
818
+ parentId: agentParent(base),
819
+ status: decided ? "completed" : "pending",
820
+ display: {
821
+ title: decided ? "Plan decision" : "Plan review",
822
+ summary: string(raw.state),
823
+ target: string(raw.composeRunId),
824
+ },
825
+ payload: {
826
+ proposalId: string(raw.proposalId),
827
+ version: number(raw.version),
828
+ state: string(raw.state),
829
+ decision: string(raw.decision),
830
+ proposal: raw.proposal,
831
+ markdown: string(raw.markdown),
832
+ approver: string(raw.approver),
833
+ reason: string(raw.reason),
834
+ feedback: string(raw.feedback),
835
+ },
836
+ raw,
837
+ }, base);
838
+ }
839
+ if (type.startsWith("swarm_child_") || type === "child") {
840
+ return childEvent(raw, type, base);
841
+ }
842
+ if (type === "artifact") {
843
+ const runKey = string(raw.runKey);
844
+ const parentRunId = string(raw.parentRunId) ?? runId;
845
+ return event({
846
+ id: id("artifact", string(raw.responseId), string(raw.jobId), string(raw.runKey)),
847
+ kind: "artifact",
848
+ source,
849
+ parentId: runKey ? id("agent", runKey, parentRunId) : agentParent(base),
850
+ status: raw.status === "failed" ? "failed" : raw.status === "completed" ? "completed" : "running",
851
+ display: { title: string(raw.artifactType) ?? "Artifact", summary: string(raw.status) },
852
+ payload: raw,
853
+ raw,
854
+ }, base);
855
+ }
856
+ if (type === "trace") {
857
+ const display = displayOf(raw);
858
+ return event({
859
+ id: id("debug", string(raw.source), string(raw.stage), string(raw.action), display.target ?? display.summary ?? display.title),
860
+ kind: "debug",
861
+ source,
862
+ parentId: agentParent(base),
863
+ status: "info",
864
+ display,
865
+ payload: { stage: string(raw.stage), action: string(raw.action), message: string(raw.message), details: raw.details },
866
+ raw,
867
+ }, base);
868
+ }
869
+ if (type === "conclave") {
870
+ const key = string(raw.key);
871
+ return event({
872
+ id: id("conclave", string(raw.action), key, runId),
873
+ kind: "conclave",
874
+ source,
875
+ parentId: agentParent(base),
876
+ status: raw.success === false ? "failed" : "completed",
877
+ display: { title: "Conclave", summary: string(raw.action), target: key },
878
+ payload: raw,
879
+ raw,
880
+ }, base);
881
+ }
882
+ if (type === "compose.receipt") {
883
+ return receipt(raw, base);
884
+ }
885
+ if (type === "session-active" || type === "session-expired" || type === "session-lease") {
886
+ return event({
887
+ id: id("session", type, string(raw.userAddress), string(raw.chainId)),
888
+ kind: "session",
889
+ source,
890
+ status: type === "session-active" ? "running" : "info",
891
+ display: { title: "Session", summary: type },
892
+ payload: raw,
893
+ raw,
894
+ }, base);
895
+ }
896
+ if (type === "error" || type === "compose.error" || type === "response.error") {
897
+ const err = isRecord(raw.error) ? raw.error : raw;
898
+ return event({
899
+ id: id("error", string(err.code), string(err.message) ?? string(raw.message), runId),
900
+ kind: "error",
901
+ source,
902
+ status: "failed",
903
+ display: { title: "Error", summary: string(err.message) ?? string(raw.message) ?? string(raw.content) },
904
+ payload: { ...raw, error: err },
905
+ raw,
906
+ }, base);
907
+ }
908
+ if (type === "done" || type === "finish" || type === "message-stop" || type === "message_stop" || type === "response.completed") {
909
+ if (type === "response.completed") {
910
+ const responseId = string(raw.response_id) ?? runId;
911
+ return event({
912
+ id: id("model", responseId),
913
+ kind: "model",
914
+ source,
915
+ status: "completed",
916
+ display: { title: string(raw.model) ?? "Model", summary: string(raw.finish_reason), target: responseId },
917
+ payload: raw,
918
+ raw,
919
+ }, base);
920
+ }
921
+ return event({
922
+ id: id("done", string(raw.response_id) ?? runId),
923
+ kind: "run",
924
+ source,
925
+ status: "completed",
926
+ display: { title: "Done", summary: string(raw.finish_reason) ?? string(raw.finishReason) },
927
+ payload: raw,
928
+ raw,
929
+ }, base);
930
+ }
931
+ const content = string(raw.content) ?? string(raw.text);
932
+ if (content) {
933
+ return event({
934
+ id: id("text", runId),
935
+ kind: "text",
936
+ source,
937
+ status: "running",
938
+ delta: content,
939
+ display: { title: "Response" },
940
+ raw,
941
+ }, base);
942
+ }
943
+ return null;
944
+ }
945
+ function childEvent(raw, type, options) {
946
+ const eventType = type === "child" ? string(raw.event) ?? "" : type.replace(/^swarm_child_/, "");
947
+ const runKey = string(raw.runKey);
948
+ const parentRunId = string(raw.parentRunId) ?? options.runId;
949
+ const agentId = id("agent", runKey ?? string(raw.agentWallet), parentRunId);
950
+ const parentRun = parentRunId ? id("agent", parentRunId) : options.parentId;
951
+ if (eventType === "start") {
952
+ return event({
953
+ id: agentId,
954
+ kind: "agent",
955
+ source: options.source ?? "agent",
956
+ parentId: parentRun,
957
+ status: "running",
958
+ path: array(raw.runKeyChain),
959
+ display: { title: string(raw.agentWallet) ?? "Agent", target: runKey },
960
+ payload: raw,
961
+ raw,
962
+ }, options);
963
+ }
964
+ if (eventType === "delta") {
965
+ const delta = string(raw.delta) ?? "";
966
+ return delta ? event({
967
+ id: id("text", runKey),
968
+ kind: "text",
969
+ source: options.source ?? "agent",
970
+ parentId: agentId,
971
+ status: "running",
972
+ path: array(raw.runKeyChain),
973
+ delta,
974
+ display: { title: "Agent response" },
975
+ raw,
976
+ }, options) : null;
977
+ }
978
+ if (eventType === "tool-start" || eventType === "tool_start") {
979
+ return event({
980
+ id: id("tool", runKey, string(raw.toolName)),
981
+ kind: "tool",
982
+ source: options.source ?? "agent",
983
+ parentId: agentId,
984
+ status: "running",
985
+ path: array(raw.runKeyChain),
986
+ display: { title: string(raw.toolName) ?? "Tool" },
987
+ payload: { input: raw.input },
988
+ raw,
989
+ }, options);
990
+ }
991
+ if (eventType === "tool-end" || eventType === "tool_end") {
992
+ return event({
993
+ id: id("tool", runKey, string(raw.toolName)),
994
+ kind: "tool",
995
+ source: options.source ?? "agent",
996
+ parentId: agentId,
997
+ status: raw.failed === true ? "failed" : "completed",
998
+ path: array(raw.runKeyChain),
999
+ display: { title: string(raw.toolName) ?? "Tool" },
1000
+ payload: { output: raw.output, error: string(raw.error) },
1001
+ raw,
1002
+ }, options);
1003
+ }
1004
+ if (eventType === "done" || eventType === "error") {
1005
+ return event({
1006
+ id: agentId,
1007
+ kind: "agent",
1008
+ source: options.source ?? "agent",
1009
+ parentId: parentRun,
1010
+ status: eventType === "error" ? "failed" : "completed",
1011
+ path: array(raw.runKeyChain),
1012
+ display: { title: string(raw.agentWallet) ?? "Agent", summary: string(raw.stopReason) ?? string(raw.error), target: runKey },
1013
+ payload: raw,
1014
+ raw,
1015
+ }, options);
1016
+ }
1017
+ return null;
1018
+ }
1019
+ function receipt(raw, options) {
1020
+ return event({
1021
+ id: id("receipt", string(raw.id), string(raw.runId), string(raw.txHash), string(raw.settleTxHash)),
1022
+ kind: "receipt",
1023
+ source: options.source ?? "payment",
1024
+ status: "completed",
1025
+ display: { title: "Receipt", summary: string(raw.settlementStatus), target: string(raw.txHash) ?? string(raw.settleTxHash) },
1026
+ payload: raw,
1027
+ raw,
1028
+ }, options);
1029
+ }
1030
+ function event(input, options) {
1031
+ return {
1032
+ type: "stream",
1033
+ ...input,
1034
+ ...(input.rootId || options.rootId ? { rootId: input.rootId ?? options.rootId } : {}),
1035
+ ...(input.runId || options.runId ? { runId: input.runId ?? options.runId } : {}),
1036
+ ...(input.parentId || options.parentId ? { parentId: input.parentId ?? options.parentId } : {}),
1037
+ ts: input.ts ?? Date.now(),
1038
+ };
1039
+ }
1040
+ function framePayload(input) {
1041
+ if (isRecord(input) && typeof input.data === "string" && typeof input.event === "string") {
1042
+ if (input.data === "[DONE]")
1043
+ return "[DONE]";
1044
+ if (input.event !== "message") {
1045
+ try {
1046
+ const parsed = JSON.parse(input.data);
1047
+ return isRecord(parsed) ? { ...parsed, type: input.event } : parsed;
1048
+ }
1049
+ catch {
1050
+ return { type: input.event, message: input.data };
1051
+ }
1052
+ }
1053
+ try {
1054
+ return JSON.parse(input.data);
1055
+ }
1056
+ catch {
1057
+ return input.data;
1058
+ }
1059
+ }
1060
+ return input;
1061
+ }
1062
+ function displayOf(raw) {
1063
+ const display = isRecord(raw.display) ? raw.display : {};
1064
+ const kind = streamKind(string(display.kind));
1065
+ const details = isRecord(display.details) ? display.details : isRecord(raw.details) ? raw.details : undefined;
1066
+ const metadata = kind || details ? { ...(details ?? {}), ...(kind ? { kind } : {}) } : undefined;
1067
+ return {
1068
+ title: string(display.name) ?? string(raw.source) ?? string(raw.toolName),
1069
+ label: string(display.label),
1070
+ summary: string(display.summary) ?? string(raw.message),
1071
+ target: string(display.target) ?? string(display.id),
1072
+ ...(kind ? { kind } : {}),
1073
+ ...(metadata ? { metadata } : {}),
1074
+ };
1075
+ }
1076
+ function displayKind(display, fallback) {
1077
+ const kind = display.kind ?? (display.metadata && typeof display.metadata.kind === "string" ? streamKind(display.metadata.kind) : undefined);
1078
+ if (kind === "model" || kind === "connector" || kind === "agent" || kind === "harness" || kind === "conclave" || kind === "catalog")
1079
+ return kind;
1080
+ return fallback;
1081
+ }
1082
+ function streamKind(value) {
1083
+ switch (value) {
1084
+ case "run":
1085
+ case "agent":
1086
+ case "text":
1087
+ case "reasoning":
1088
+ case "action":
1089
+ case "tool":
1090
+ case "catalog":
1091
+ case "model":
1092
+ case "connector":
1093
+ case "harness":
1094
+ case "conclave":
1095
+ case "approval":
1096
+ case "artifact":
1097
+ case "receipt":
1098
+ case "payment":
1099
+ case "session":
1100
+ case "error":
1101
+ case "debug":
1102
+ return value;
1103
+ case "search":
1104
+ return "catalog";
1105
+ default:
1106
+ return undefined;
1107
+ }
1108
+ }
1109
+ function agentParent(options) {
1110
+ return options.runId ? id("agent", options.runId) : options.parentId;
1111
+ }
1112
+ function modelParent(options, responseId) {
1113
+ const value = responseId ?? options.runId;
1114
+ return value ? id("model", value) : options.parentId;
1115
+ }
1116
+ function sourceOf(type, raw) {
1117
+ const source = string(raw.source);
1118
+ if (source)
1119
+ return source;
1120
+ if (type.startsWith("response."))
1121
+ return "inference";
1122
+ if (type.startsWith("swarm_child_"))
1123
+ return "agent";
1124
+ if (type.startsWith("harness_"))
1125
+ return "harness";
1126
+ if (type.startsWith("session-"))
1127
+ return "session";
1128
+ return "stream";
1129
+ }
1130
+ function id(...parts) {
1131
+ const clean = parts
1132
+ .filter((part) => part !== undefined && part !== null && String(part).trim().length > 0)
1133
+ .map((part) => String(part).trim().replace(/\s+/g, "_"));
1134
+ return clean.length > 0 ? clean.join(":") : "stream";
1135
+ }
1136
+ function placeholder(idValue, eventValue) {
1137
+ const kind = idValue.startsWith("agent:")
1138
+ ? "agent"
1139
+ : idValue.startsWith("model:")
1140
+ ? "model"
1141
+ : "run";
1142
+ return {
1143
+ id: idValue,
1144
+ kind,
1145
+ source: eventValue.source,
1146
+ status: "running",
1147
+ path: [],
1148
+ display: { title: kind === "agent" ? "Agent" : kind === "model" ? "Model" : idValue, target: idValue },
1149
+ text: "",
1150
+ children: [],
1151
+ updatedAt: eventValue.ts ?? Date.now(),
1152
+ events: 0,
1153
+ };
1154
+ }
1155
+ function stable(eventValue) {
1156
+ let hash = 5381;
1157
+ const text = JSON.stringify({
1158
+ id: eventValue.id,
1159
+ kind: eventValue.kind,
1160
+ status: eventValue.status,
1161
+ delta: eventValue.delta,
1162
+ display: eventValue.display,
1163
+ payload: eventValue.payload,
1164
+ });
1165
+ for (let i = 0; i < text.length; i += 1) {
1166
+ hash = ((hash << 5) + hash) ^ text.charCodeAt(i);
1167
+ }
1168
+ return hash >>> 0;
1169
+ }
1170
+ function merge(a, b) {
1171
+ if (!a && !b)
1172
+ return undefined;
1173
+ return { ...(a ?? {}), ...(b ?? {}) };
1174
+ }
1175
+ function isRecord(value) {
1176
+ return value !== null && typeof value === "object" && !Array.isArray(value);
1177
+ }
1178
+ function string(value) {
1179
+ return typeof value === "string" && value.length > 0 ? value : undefined;
1180
+ }
1181
+ function number(value) {
1182
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
1183
+ }
1184
+ function array(value) {
1185
+ return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : undefined;
1186
+ }
1187
+ function media(value) {
1188
+ const type = string(value.type) ?? string(value.kind);
1189
+ const normalized = type === "output_image" || type === "image"
1190
+ ? "image"
1191
+ : type === "output_audio" || type === "audio"
1192
+ ? "audio"
1193
+ : type === "output_video" || type === "video"
1194
+ ? "video"
1195
+ : type === "output_embedding" || type === "embedding"
1196
+ ? "embedding"
1197
+ : type === "file" || type === "artifact"
1198
+ ? "file"
1199
+ : undefined;
1200
+ if (!normalized)
1201
+ return null;
1202
+ const url = string(value.url)
1203
+ ?? string(value.image_url)
1204
+ ?? string(value.imageUrl)
1205
+ ?? string(value.audio_url)
1206
+ ?? string(value.audioUrl)
1207
+ ?? string(value.video_url)
1208
+ ?? string(value.videoUrl);
1209
+ const base64 = string(value.base64)
1210
+ ?? string(value.b64_json)
1211
+ ?? string(value.data);
1212
+ return { kind: normalized, ...(url ? { url } : {}), ...(base64 ? { base64 } : {}) };
1213
+ }
1214
+ function mediaKind(mimeType) {
1215
+ if (!mimeType)
1216
+ return "file";
1217
+ if (mimeType.startsWith("image/"))
1218
+ return "image";
1219
+ if (mimeType.startsWith("audio/"))
1220
+ return "audio";
1221
+ if (mimeType.startsWith("video/"))
1222
+ return "video";
1223
+ return "file";
1224
+ }
1225
+ //# sourceMappingURL=index.js.map