@agent-native/core 0.57.0 → 0.58.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,992 @@
1
+ import { createHttpAgentChatRuntime, } from "./runtime.js";
2
+ function runtimeConnectorId(prefix) {
3
+ if (typeof crypto !== "undefined" &&
4
+ typeof crypto.randomUUID === "function") {
5
+ return `${prefix}-${crypto.randomUUID()}`;
6
+ }
7
+ return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
8
+ }
9
+ function turnKey(context) {
10
+ return `${context.sessionId}:${context.turnId ?? context.runId ?? "turn"}`;
11
+ }
12
+ function baseEvent(context) {
13
+ return {
14
+ sessionId: context.sessionId,
15
+ turnId: context.turnId,
16
+ };
17
+ }
18
+ function asRecord(value) {
19
+ return value && typeof value === "object" && !Array.isArray(value)
20
+ ? value
21
+ : null;
22
+ }
23
+ function stringValue(value) {
24
+ return typeof value === "string" ? value : undefined;
25
+ }
26
+ function numberValue(value) {
27
+ return typeof value === "number" && Number.isFinite(value)
28
+ ? value
29
+ : undefined;
30
+ }
31
+ function recordString(record, ...keys) {
32
+ if (!record)
33
+ return undefined;
34
+ for (const key of keys) {
35
+ const value = record[key];
36
+ if (typeof value === "string" && value.trim())
37
+ return value;
38
+ }
39
+ return undefined;
40
+ }
41
+ function recordKey(record, ...keys) {
42
+ if (!record)
43
+ return undefined;
44
+ for (const key of keys) {
45
+ const value = record[key];
46
+ if (typeof value === "string" && value.trim())
47
+ return value;
48
+ if (typeof value === "number" && Number.isFinite(value))
49
+ return String(value);
50
+ }
51
+ return undefined;
52
+ }
53
+ function nestedRecord(record, ...keys) {
54
+ if (!record)
55
+ return null;
56
+ for (const key of keys) {
57
+ const value = asRecord(record[key]);
58
+ if (value)
59
+ return value;
60
+ }
61
+ return null;
62
+ }
63
+ function normalizeEventType(type) {
64
+ return (type ?? "")
65
+ .replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2")
66
+ .replace(/([a-z0-9])([A-Z])/g, "$1_$2")
67
+ .replace(/[.-]/g, "_")
68
+ .toUpperCase();
69
+ }
70
+ function ensureMessage(state, id, role = "assistant") {
71
+ const messageId = id || state.fallbackMessageId;
72
+ let message = state.messages.get(messageId);
73
+ if (!message) {
74
+ message = {
75
+ id: messageId,
76
+ role,
77
+ text: "",
78
+ started: false,
79
+ done: false,
80
+ };
81
+ state.messages.set(messageId, message);
82
+ }
83
+ return message;
84
+ }
85
+ function messageFromState(message) {
86
+ return {
87
+ id: message.id,
88
+ role: message.role,
89
+ content: message.text ? [{ type: "text", text: message.text }] : [],
90
+ };
91
+ }
92
+ function appendTextEvents(context, state, input) {
93
+ if (!input.text)
94
+ return [];
95
+ const message = ensureMessage(state, input.messageId, input.role);
96
+ const events = [];
97
+ if (!message.started) {
98
+ message.started = true;
99
+ events.push({
100
+ type: "message-start",
101
+ ...baseEvent(context),
102
+ message: messageFromState(message),
103
+ });
104
+ }
105
+ message.text += input.text;
106
+ events.push({
107
+ type: "message-delta",
108
+ ...baseEvent(context),
109
+ messageId: message.id,
110
+ delta: { type: "text", text: input.text },
111
+ });
112
+ return events;
113
+ }
114
+ function finishMessageEvents(context, state, messageId) {
115
+ const messages = messageId
116
+ ? [ensureMessage(state, messageId)]
117
+ : [...state.messages.values()];
118
+ const events = [];
119
+ for (const message of messages) {
120
+ if (!message.started || message.done)
121
+ continue;
122
+ message.done = true;
123
+ events.push({
124
+ type: "message-done",
125
+ ...baseEvent(context),
126
+ message: messageFromState(message),
127
+ });
128
+ }
129
+ return events;
130
+ }
131
+ function ensureTool(state, id, name) {
132
+ const toolId = id || runtimeConnectorId("tool");
133
+ let tool = state.tools.get(toolId);
134
+ if (!tool) {
135
+ tool = {
136
+ id: toolId,
137
+ name: name || "tool",
138
+ argsText: "",
139
+ started: false,
140
+ done: false,
141
+ };
142
+ state.tools.set(toolId, tool);
143
+ }
144
+ if (name)
145
+ tool.name = name;
146
+ return tool;
147
+ }
148
+ function startToolEvents(context, state, input) {
149
+ const tool = ensureTool(state, input.id, input.name);
150
+ if (tool.started)
151
+ return [];
152
+ tool.started = true;
153
+ return [
154
+ {
155
+ type: "tool-start",
156
+ ...baseEvent(context),
157
+ toolCall: {
158
+ id: tool.id,
159
+ name: tool.name,
160
+ input: input.input,
161
+ inputText: input.input === undefined
162
+ ? undefined
163
+ : stringifyToolValue(input.input),
164
+ },
165
+ },
166
+ ];
167
+ }
168
+ function appendToolArgsEvents(context, state, input) {
169
+ if (!input.delta)
170
+ return [];
171
+ const tool = ensureTool(state, input.id, input.name);
172
+ tool.argsText += input.delta;
173
+ const events = startToolEvents(context, state, {
174
+ id: tool.id,
175
+ name: tool.name,
176
+ });
177
+ events.push({
178
+ type: "tool-delta",
179
+ ...baseEvent(context),
180
+ toolCallId: tool.id,
181
+ inputTextDelta: input.delta,
182
+ });
183
+ return events;
184
+ }
185
+ function finishToolEvents(context, state, input) {
186
+ const tool = ensureTool(state, input.id, input.name);
187
+ const events = startToolEvents(context, state, {
188
+ id: tool.id,
189
+ name: tool.name,
190
+ });
191
+ if (tool.done &&
192
+ input.result === undefined &&
193
+ !input.resultText &&
194
+ !input.error) {
195
+ return events;
196
+ }
197
+ tool.done = true;
198
+ events.push({
199
+ type: "tool-done",
200
+ ...baseEvent(context),
201
+ toolCallId: tool.id,
202
+ toolName: tool.name,
203
+ status: input.error ? "failed" : "completed",
204
+ result: input.result,
205
+ resultText: input.resultText ??
206
+ (input.result === undefined
207
+ ? tool.argsText
208
+ : stringifyToolValue(input.result)),
209
+ error: input.error,
210
+ });
211
+ return events;
212
+ }
213
+ function stringifyToolValue(value) {
214
+ if (typeof value === "string")
215
+ return value;
216
+ if (value === undefined)
217
+ return "";
218
+ try {
219
+ return JSON.stringify(value);
220
+ }
221
+ catch {
222
+ return String(value);
223
+ }
224
+ }
225
+ function extractText(value) {
226
+ if (typeof value === "string")
227
+ return value;
228
+ const record = asRecord(value);
229
+ if (!record)
230
+ return undefined;
231
+ const direct = recordString(record, "text", "content", "output");
232
+ if (direct)
233
+ return direct;
234
+ const content = record.content;
235
+ if (Array.isArray(content)) {
236
+ return content
237
+ .map((part) => {
238
+ const partRecord = asRecord(part);
239
+ return (recordString(partRecord, "text", "content", "value") ??
240
+ recordString(nestedRecord(partRecord, "text"), "value"));
241
+ })
242
+ .filter(Boolean)
243
+ .join("");
244
+ }
245
+ return undefined;
246
+ }
247
+ function extractToolId(record) {
248
+ return recordString(record, "toolCallId", "tool_call_id", "callId", "call_id", "toolUseId", "tool_use_id", "itemId", "item_id", "id");
249
+ }
250
+ function extractToolName(record) {
251
+ return recordString(record, "toolCallName", "tool_call_name", "toolName", "tool_name", "name");
252
+ }
253
+ function extractMessageId(event, state) {
254
+ return (recordString(event, "messageId", "message_id", "itemId", "item_id", "id") ??
255
+ recordString(nestedRecord(event, "message"), "id") ??
256
+ state.activeMessageId ??
257
+ state.fallbackMessageId);
258
+ }
259
+ function extractUsage(record) {
260
+ const usage = nestedRecord(record, "usage");
261
+ const inputTokens = numberValue(usage?.input_tokens) ?? numberValue(usage?.inputTokens);
262
+ const outputTokens = numberValue(usage?.output_tokens) ?? numberValue(usage?.outputTokens);
263
+ const totalTokens = numberValue(usage?.total_tokens) ??
264
+ numberValue(usage?.totalTokens) ??
265
+ (inputTokens !== undefined || outputTokens !== undefined
266
+ ? (inputTokens ?? 0) + (outputTokens ?? 0)
267
+ : undefined);
268
+ const costUsd = numberValue(record?.total_cost_usd) ?? numberValue(record?.cost_usd);
269
+ const costCents = costUsd === undefined ? undefined : costUsd * 100;
270
+ if (inputTokens === undefined &&
271
+ outputTokens === undefined &&
272
+ totalTokens === undefined &&
273
+ costCents === undefined) {
274
+ return null;
275
+ }
276
+ return {
277
+ inputTokens,
278
+ outputTokens,
279
+ totalTokens,
280
+ costCents,
281
+ };
282
+ }
283
+ function normalizeContentBlockType(block) {
284
+ return normalizeEventType(recordString(block, "type"));
285
+ }
286
+ function mapClaudeContentBlocks(context, state, message) {
287
+ const messageId = extractMessageId(message, state);
288
+ state.activeMessageId = messageId;
289
+ const content = message.content;
290
+ const events = [];
291
+ if (!Array.isArray(content))
292
+ return events;
293
+ for (const value of content) {
294
+ const block = asRecord(value);
295
+ const blockType = normalizeContentBlockType(block);
296
+ if (blockType === "TEXT") {
297
+ const text = recordString(block, "text");
298
+ const existing = state.messages.get(messageId);
299
+ if (text && !existing?.text) {
300
+ events.push(...appendTextEvents(context, state, { messageId, text }));
301
+ }
302
+ continue;
303
+ }
304
+ if (blockType === "TOOL_USE") {
305
+ const toolId = extractToolId(block);
306
+ const toolName = extractToolName(block);
307
+ events.push(...startToolEvents(context, state, {
308
+ id: toolId,
309
+ name: toolName,
310
+ input: block?.input,
311
+ }));
312
+ events.push(...finishToolEvents(context, state, {
313
+ id: toolId,
314
+ name: toolName,
315
+ result: block?.input,
316
+ }));
317
+ continue;
318
+ }
319
+ if (blockType === "TOOL_RESULT") {
320
+ const isError = block?.is_error === true || block?.isError === true;
321
+ events.push(...finishToolEvents(context, state, {
322
+ id: extractToolId(block),
323
+ name: extractToolName(block),
324
+ result: block?.content ?? block?.result,
325
+ resultText: extractText(block),
326
+ error: isError ? (extractText(block) ?? "Tool failed.") : undefined,
327
+ }));
328
+ }
329
+ }
330
+ events.push(...finishMessageEvents(context, state, messageId));
331
+ return events;
332
+ }
333
+ function unwrapClaudeAgentEvent(raw) {
334
+ const record = asRecord(raw);
335
+ const type = normalizeEventType(recordString(record, "type"));
336
+ const event = nestedRecord(record, "event");
337
+ if (event && (type === "STREAM_EVENT" || recordString(event, "type"))) {
338
+ return event;
339
+ }
340
+ return raw;
341
+ }
342
+ function mapClaudeAgentEvent(raw, context, state) {
343
+ const event = asRecord(unwrapClaudeAgentEvent(raw));
344
+ const type = normalizeEventType(recordString(event, "type"));
345
+ const base = baseEvent(context);
346
+ if (!event || !type)
347
+ return [];
348
+ if (type === "MESSAGE_START") {
349
+ const message = nestedRecord(event, "message");
350
+ const messageId = extractMessageId(message ?? event, state);
351
+ state.activeMessageId = messageId;
352
+ const stateMessage = ensureMessage(state, messageId);
353
+ if (stateMessage.started)
354
+ return [];
355
+ stateMessage.started = true;
356
+ return [
357
+ {
358
+ type: "message-start",
359
+ ...base,
360
+ message: messageFromState(stateMessage),
361
+ },
362
+ ];
363
+ }
364
+ if (type === "CONTENT_BLOCK_START") {
365
+ const block = nestedRecord(event, "content_block", "contentBlock");
366
+ const blockKey = recordKey(event, "index") ?? extractToolId(block);
367
+ const blockType = normalizeContentBlockType(block);
368
+ const toolId = blockType === "TOOL_USE"
369
+ ? (extractToolId(block) ?? (blockKey ? `tool-${blockKey}` : undefined))
370
+ : undefined;
371
+ if (blockKey) {
372
+ state.contentBlocks.set(blockKey, {
373
+ messageId: state.activeMessageId,
374
+ toolId,
375
+ type: blockType,
376
+ });
377
+ }
378
+ if (blockType === "TOOL_USE") {
379
+ return startToolEvents(context, state, {
380
+ id: toolId,
381
+ name: extractToolName(block),
382
+ input: block?.input,
383
+ });
384
+ }
385
+ return [];
386
+ }
387
+ if (type === "CONTENT_BLOCK_DELTA") {
388
+ const delta = nestedRecord(event, "delta");
389
+ const deltaType = normalizeEventType(recordString(delta, "type"));
390
+ const blockRef = state.contentBlocks.get(recordKey(event, "index") ?? "");
391
+ if (deltaType === "TEXT_DELTA") {
392
+ return appendTextEvents(context, state, {
393
+ messageId: blockRef?.messageId ?? state.activeMessageId,
394
+ text: recordString(delta, "text") ?? "",
395
+ });
396
+ }
397
+ if (deltaType === "INPUT_JSON_DELTA") {
398
+ return appendToolArgsEvents(context, state, {
399
+ id: blockRef?.toolId ?? extractToolId(event),
400
+ name: extractToolName(event),
401
+ delta: recordString(delta, "partial_json", "partialJson", "text"),
402
+ });
403
+ }
404
+ return [];
405
+ }
406
+ if (type === "CONTENT_BLOCK_STOP") {
407
+ const blockKey = recordKey(event, "index");
408
+ const blockRef = blockKey ? state.contentBlocks.get(blockKey) : undefined;
409
+ if (blockKey)
410
+ state.contentBlocks.delete(blockKey);
411
+ if (blockRef?.toolId || blockRef?.type === "TOOL_USE") {
412
+ return finishToolEvents(context, state, {
413
+ id: blockRef.toolId,
414
+ });
415
+ }
416
+ return [];
417
+ }
418
+ if (type === "MESSAGE_STOP") {
419
+ return finishMessageEvents(context, state, state.activeMessageId);
420
+ }
421
+ if (type === "ASSISTANT" || type === "ASSISTANT_MESSAGE") {
422
+ return mapClaudeContentBlocks(context, state, event);
423
+ }
424
+ if (type === "USER" || type === "USER_MESSAGE") {
425
+ return mapClaudeContentBlocks(context, state, event);
426
+ }
427
+ if (type === "SYSTEM" || type === "SYSTEM_MESSAGE") {
428
+ return [
429
+ {
430
+ type: "status",
431
+ ...base,
432
+ message: recordString(event, "message", "subtype") ?? "Claude agent update",
433
+ metadata: event,
434
+ },
435
+ ];
436
+ }
437
+ if (type === "RESULT" || type === "RESULT_MESSAGE") {
438
+ const usage = extractUsage(event);
439
+ return [
440
+ ...(usage ? [{ type: "usage", ...base, usage }] : []),
441
+ ...finishMessageEvents(context, state),
442
+ {
443
+ type: "done",
444
+ ...base,
445
+ reason: recordString(event, "subtype") === "error" ? "error" : "complete",
446
+ },
447
+ ];
448
+ }
449
+ if (type === "ERROR") {
450
+ return [
451
+ {
452
+ type: "error",
453
+ ...base,
454
+ error: recordString(event, "message", "error") ??
455
+ "Claude agent stream failed.",
456
+ code: recordString(event, "code", "name"),
457
+ },
458
+ { type: "done", ...base, reason: "error" },
459
+ ];
460
+ }
461
+ return [];
462
+ }
463
+ function unwrapOpenAIResponsesEvent(raw) {
464
+ const record = asRecord(raw);
465
+ const data = asRecord(record?.data);
466
+ return data?.event ?? data ?? raw;
467
+ }
468
+ function mapOpenAIResponsesEvent(raw, context, state) {
469
+ const event = asRecord(raw);
470
+ const type = normalizeEventType(recordString(event, "type"));
471
+ const base = baseEvent(context);
472
+ if (!event || !type)
473
+ return [];
474
+ if (type === "RESPONSE_OUTPUT_TEXT_DELTA" || type === "OUTPUT_TEXT_DELTA") {
475
+ return appendTextEvents(context, state, {
476
+ messageId: recordString(event, "item_id", "itemId", "messageId"),
477
+ text: stringValue(event.delta) ?? "",
478
+ });
479
+ }
480
+ if (type === "RESPONSE_OUTPUT_TEXT_DONE" || type === "OUTPUT_TEXT_DONE") {
481
+ const text = stringValue(event.text);
482
+ return [
483
+ ...(text && ![...state.messages.values()].some((message) => message.text)
484
+ ? appendTextEvents(context, state, {
485
+ messageId: recordString(event, "item_id", "itemId", "messageId"),
486
+ text,
487
+ })
488
+ : []),
489
+ ...finishMessageEvents(context, state, recordString(event, "item_id", "itemId", "messageId")),
490
+ ];
491
+ }
492
+ if (type === "RESPONSE_OUTPUT_ITEM_ADDED") {
493
+ const item = nestedRecord(event, "item");
494
+ const itemType = normalizeEventType(recordString(item, "type"));
495
+ if (itemType.includes("FUNCTION_CALL") || extractToolName(item)) {
496
+ return startToolEvents(context, state, {
497
+ id: extractToolId(item),
498
+ name: extractToolName(item),
499
+ input: item?.arguments,
500
+ });
501
+ }
502
+ }
503
+ if (type === "RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA") {
504
+ return appendToolArgsEvents(context, state, {
505
+ id: extractToolId(event),
506
+ name: extractToolName(event),
507
+ delta: stringValue(event.delta),
508
+ });
509
+ }
510
+ if (type === "RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE") {
511
+ return finishToolEvents(context, state, {
512
+ id: extractToolId(event),
513
+ name: extractToolName(event),
514
+ resultText: recordString(event, "arguments", "text"),
515
+ });
516
+ }
517
+ if (type === "RESPONSE_OUTPUT_ITEM_DONE") {
518
+ const item = nestedRecord(event, "item");
519
+ const itemType = normalizeEventType(recordString(item, "type"));
520
+ if (itemType.includes("FUNCTION_CALL") || extractToolName(item)) {
521
+ return finishToolEvents(context, state, {
522
+ id: extractToolId(item),
523
+ name: extractToolName(item),
524
+ resultText: recordString(item, "arguments", "output"),
525
+ });
526
+ }
527
+ const text = extractText(item);
528
+ if (text && ![...state.messages.values()].some((message) => message.text)) {
529
+ return [
530
+ ...appendTextEvents(context, state, {
531
+ messageId: recordString(item, "id"),
532
+ text,
533
+ }),
534
+ ...finishMessageEvents(context, state, recordString(item, "id")),
535
+ ];
536
+ }
537
+ }
538
+ if (type === "RESPONSE_COMPLETED" || type === "RESPONSE_DONE") {
539
+ return [
540
+ ...finishMessageEvents(context, state),
541
+ { type: "done", ...base, reason: "complete" },
542
+ ];
543
+ }
544
+ if (type === "RESPONSE_FAILED" || type === "RESPONSE_ERROR") {
545
+ const error = nestedRecord(event, "error");
546
+ return [
547
+ {
548
+ type: "error",
549
+ ...base,
550
+ error: recordString(error, "message", "error") ??
551
+ recordString(event, "message", "error") ??
552
+ "OpenAI agent stream failed.",
553
+ code: recordString(error, "code", "type"),
554
+ },
555
+ { type: "done", ...base, reason: "error" },
556
+ ];
557
+ }
558
+ if (type === "RESPONSE_INCOMPLETE") {
559
+ return [
560
+ ...finishMessageEvents(context, state),
561
+ { type: "done", ...base, reason: "interrupted" },
562
+ ];
563
+ }
564
+ return [];
565
+ }
566
+ function mapOpenAIAgentsEvent(raw, context, state) {
567
+ const event = asRecord(raw);
568
+ const type = normalizeEventType(recordString(event, "type"));
569
+ const base = baseEvent(context);
570
+ if (!event || !type)
571
+ return [];
572
+ if (type === "RAW_MODEL_STREAM_EVENT" || type === "RAW_RESPONSE_EVENT") {
573
+ return mapOpenAIResponsesEvent(unwrapOpenAIResponsesEvent(raw), context, state);
574
+ }
575
+ if (type === "RUN_ITEM_STREAM_EVENT") {
576
+ const name = normalizeEventType(recordString(event, "name"));
577
+ const item = nestedRecord(event, "item");
578
+ if (name === "MESSAGE_OUTPUT_CREATED") {
579
+ const text = extractText(item);
580
+ if (!text ||
581
+ [...state.messages.values()].some((message) => message.text)) {
582
+ return [];
583
+ }
584
+ const messageId = recordString(item, "id") ?? state.fallbackMessageId;
585
+ return [
586
+ ...appendTextEvents(context, state, { messageId, text }),
587
+ ...finishMessageEvents(context, state, messageId),
588
+ ];
589
+ }
590
+ if (name === "TOOL_CALLED" ||
591
+ name === "TOOL_SEARCH_CALLED" ||
592
+ name === "MCP_LIST_TOOLS") {
593
+ return startToolEvents(context, state, {
594
+ id: extractToolId(item) ?? extractToolId(event),
595
+ name: extractToolName(item) ?? extractToolName(event) ?? name.toLowerCase(),
596
+ input: item?.arguments ?? item?.input,
597
+ });
598
+ }
599
+ if (name === "TOOL_OUTPUT" || name === "TOOL_SEARCH_OUTPUT_CREATED") {
600
+ return finishToolEvents(context, state, {
601
+ id: extractToolId(item) ?? extractToolId(event),
602
+ name: extractToolName(item) ?? extractToolName(event),
603
+ result: item?.output ?? item?.result ?? item?.content ?? item,
604
+ });
605
+ }
606
+ if (name === "MCP_APPROVAL_REQUESTED") {
607
+ const approvalId = recordString(item, "approvalKey", "approval_key", "id") ??
608
+ runtimeConnectorId("approval");
609
+ return [
610
+ {
611
+ type: "approval-request",
612
+ ...base,
613
+ approvalId,
614
+ toolCallId: extractToolId(item),
615
+ toolName: extractToolName(item),
616
+ message: recordString(item, "message", "label") ?? "Approve this tool call?",
617
+ input: item?.input ?? item?.arguments,
618
+ },
619
+ ];
620
+ }
621
+ if (name === "HANDOFF_REQUESTED" ||
622
+ name === "HANDOFF_OCCURRED" ||
623
+ name === "HANDOFF_OCCURED") {
624
+ return [
625
+ {
626
+ type: "status",
627
+ ...base,
628
+ message: name === "HANDOFF_REQUESTED"
629
+ ? "Agent handoff requested"
630
+ : "Agent handoff completed",
631
+ metadata: item ?? undefined,
632
+ },
633
+ ];
634
+ }
635
+ }
636
+ if (type === "AGENT_UPDATED_STREAM_EVENT") {
637
+ const agent = nestedRecord(event, "new_agent", "newAgent");
638
+ return [
639
+ {
640
+ type: "status",
641
+ ...base,
642
+ message: `Switched to ${recordString(agent, "name") ?? "another agent"}`,
643
+ metadata: agent ?? undefined,
644
+ },
645
+ ];
646
+ }
647
+ return mapOpenAIResponsesEvent(raw, context, state);
648
+ }
649
+ function mapVercelAiEvent(raw, context, state) {
650
+ const event = asRecord(raw);
651
+ const type = normalizeEventType(recordString(event, "type"));
652
+ const base = baseEvent(context);
653
+ if (!event || !type)
654
+ return [];
655
+ const vercelMessageId = recordString(event, "messageId", "message_id") ??
656
+ state.activeMessageId ??
657
+ state.fallbackMessageId;
658
+ if (type === "START") {
659
+ const messageId = vercelMessageId;
660
+ state.activeMessageId = messageId;
661
+ const message = ensureMessage(state, messageId);
662
+ if (message.started)
663
+ return [];
664
+ message.started = true;
665
+ return [
666
+ {
667
+ type: "message-start",
668
+ ...base,
669
+ message: messageFromState(message),
670
+ },
671
+ ];
672
+ }
673
+ if (type === "TEXT_START") {
674
+ const messageId = vercelMessageId;
675
+ state.activeMessageId = messageId;
676
+ const message = ensureMessage(state, messageId);
677
+ if (message.started)
678
+ return [];
679
+ message.started = true;
680
+ return [
681
+ {
682
+ type: "message-start",
683
+ ...base,
684
+ message: messageFromState(message),
685
+ },
686
+ ];
687
+ }
688
+ if (type === "TEXT_DELTA") {
689
+ return appendTextEvents(context, state, {
690
+ messageId: vercelMessageId,
691
+ text: recordString(event, "delta", "text") ?? "",
692
+ });
693
+ }
694
+ if (type === "TEXT_END") {
695
+ return [];
696
+ }
697
+ if (type === "REASONING_DELTA") {
698
+ return [
699
+ {
700
+ type: "status",
701
+ ...base,
702
+ message: recordString(event, "delta", "text") ?? "Reasoning",
703
+ },
704
+ ];
705
+ }
706
+ if (type === "TOOL_INPUT_START") {
707
+ return startToolEvents(context, state, {
708
+ id: extractToolId(event),
709
+ name: extractToolName(event),
710
+ });
711
+ }
712
+ if (type === "TOOL_INPUT_DELTA") {
713
+ return appendToolArgsEvents(context, state, {
714
+ id: extractToolId(event),
715
+ name: extractToolName(event),
716
+ delta: recordString(event, "inputTextDelta", "delta", "text"),
717
+ });
718
+ }
719
+ if (type === "TOOL_INPUT_AVAILABLE") {
720
+ return startToolEvents(context, state, {
721
+ id: extractToolId(event),
722
+ name: extractToolName(event),
723
+ input: event.input,
724
+ });
725
+ }
726
+ if (type === "TOOL_OUTPUT_AVAILABLE") {
727
+ return finishToolEvents(context, state, {
728
+ id: extractToolId(event),
729
+ name: extractToolName(event),
730
+ result: event.output,
731
+ resultText: recordString(event, "outputText", "resultText", "text") ??
732
+ (event.output === undefined
733
+ ? undefined
734
+ : stringifyToolValue(event.output)),
735
+ });
736
+ }
737
+ if (type === "SOURCE_URL" || type === "SOURCE_DOCUMENT") {
738
+ return [
739
+ {
740
+ type: "artifact",
741
+ ...base,
742
+ artifact: {
743
+ id: recordString(event, "sourceId", "source_id", "id"),
744
+ kind: type === "SOURCE_URL" ? "source-url" : "source-document",
745
+ title: recordString(event, "title"),
746
+ url: recordString(event, "url"),
747
+ data: event,
748
+ },
749
+ },
750
+ ];
751
+ }
752
+ if (type === "FILE") {
753
+ return [
754
+ {
755
+ type: "artifact",
756
+ ...base,
757
+ artifact: {
758
+ id: recordString(event, "id", "fileId", "file_id"),
759
+ kind: "file",
760
+ title: recordString(event, "filename", "title"),
761
+ url: recordString(event, "url"),
762
+ data: event,
763
+ },
764
+ },
765
+ ];
766
+ }
767
+ if (type.startsWith("DATA_")) {
768
+ return [
769
+ {
770
+ type: "message-delta",
771
+ ...base,
772
+ messageId: vercelMessageId,
773
+ delta: {
774
+ type: "data",
775
+ data: event.data ?? event,
776
+ partId: recordString(event, "id"),
777
+ },
778
+ },
779
+ ];
780
+ }
781
+ if (type === "ERROR") {
782
+ return [
783
+ {
784
+ type: "error",
785
+ ...base,
786
+ error: recordString(event, "errorText", "message", "error") ??
787
+ "AI SDK stream failed.",
788
+ code: recordString(event, "code"),
789
+ },
790
+ { type: "done", ...base, reason: "error" },
791
+ ];
792
+ }
793
+ if (type === "ABORT") {
794
+ return [
795
+ ...finishMessageEvents(context, state),
796
+ { type: "done", ...base, reason: "cancelled" },
797
+ ];
798
+ }
799
+ if (type === "FINISH") {
800
+ const usage = extractUsage(event);
801
+ return [
802
+ ...(usage ? [{ type: "usage", ...base, usage }] : []),
803
+ ...finishMessageEvents(context, state),
804
+ { type: "done", ...base, reason: "complete" },
805
+ ];
806
+ }
807
+ if (type === "START_STEP" || type === "FINISH_STEP") {
808
+ return [
809
+ {
810
+ type: "status",
811
+ ...base,
812
+ message: type === "START_STEP" ? "Step started" : "Step finished",
813
+ },
814
+ ];
815
+ }
816
+ return [];
817
+ }
818
+ function mapAgUiEvent(raw, context, state) {
819
+ const event = asRecord(raw);
820
+ const type = normalizeEventType(recordString(event, "type"));
821
+ const base = baseEvent(context);
822
+ if (!event || !type)
823
+ return [];
824
+ if (type === "RUN_STARTED") {
825
+ return [
826
+ {
827
+ type: "status",
828
+ ...base,
829
+ message: "Agent run started",
830
+ },
831
+ ];
832
+ }
833
+ if (type === "RUN_FINISHED") {
834
+ return [
835
+ ...finishMessageEvents(context, state),
836
+ { type: "done", ...base, reason: "complete" },
837
+ ];
838
+ }
839
+ if (type === "RUN_ERROR") {
840
+ return [
841
+ {
842
+ type: "error",
843
+ ...base,
844
+ error: recordString(event, "message", "error") ??
845
+ "AG-UI agent stream failed.",
846
+ code: recordString(event, "code"),
847
+ },
848
+ { type: "done", ...base, reason: "error" },
849
+ ];
850
+ }
851
+ if (type === "STEP_STARTED" || type === "STEP_FINISHED") {
852
+ return [
853
+ {
854
+ type: "status",
855
+ ...base,
856
+ message: recordString(event, "stepName", "step_name") ??
857
+ (type === "STEP_STARTED" ? "Step started" : "Step finished"),
858
+ },
859
+ ];
860
+ }
861
+ if (type === "TEXT_MESSAGE_START") {
862
+ const message = ensureMessage(state, recordString(event, "messageId", "message_id"), recordString(event, "role") ?? "assistant");
863
+ if (message.started)
864
+ return [];
865
+ message.started = true;
866
+ return [
867
+ {
868
+ type: "message-start",
869
+ ...base,
870
+ message: messageFromState(message),
871
+ },
872
+ ];
873
+ }
874
+ if (type === "TEXT_MESSAGE_CONTENT" || type === "TEXT_MESSAGE_CHUNK") {
875
+ return appendTextEvents(context, state, {
876
+ messageId: recordString(event, "messageId", "message_id"),
877
+ role: recordString(event, "role") ?? "assistant",
878
+ text: stringValue(event.delta) ?? "",
879
+ });
880
+ }
881
+ if (type === "TEXT_MESSAGE_END") {
882
+ return finishMessageEvents(context, state, recordString(event, "messageId", "message_id"));
883
+ }
884
+ if (type === "TOOL_CALL_START") {
885
+ return startToolEvents(context, state, {
886
+ id: extractToolId(event),
887
+ name: extractToolName(event),
888
+ });
889
+ }
890
+ if (type === "TOOL_CALL_ARGS") {
891
+ return appendToolArgsEvents(context, state, {
892
+ id: extractToolId(event),
893
+ name: extractToolName(event),
894
+ delta: stringValue(event.delta),
895
+ });
896
+ }
897
+ if (type === "TOOL_CALL_END") {
898
+ return finishToolEvents(context, state, {
899
+ id: extractToolId(event),
900
+ name: extractToolName(event),
901
+ });
902
+ }
903
+ if (type === "TOOL_CALL_RESULT") {
904
+ return finishToolEvents(context, state, {
905
+ id: extractToolId(event),
906
+ name: extractToolName(event),
907
+ resultText: recordString(event, "content", "result", "text"),
908
+ });
909
+ }
910
+ if (type === "REASONING_MESSAGE_CONTENT") {
911
+ return [
912
+ {
913
+ type: "status",
914
+ ...base,
915
+ message: stringValue(event.delta) ?? "Reasoning",
916
+ },
917
+ ];
918
+ }
919
+ return [];
920
+ }
921
+ function createConnectorMapEvent(mapper) {
922
+ const states = new Map();
923
+ return (event, context) => {
924
+ const key = turnKey(context);
925
+ let state = states.get(key);
926
+ if (!state) {
927
+ state = {
928
+ fallbackMessageId: runtimeConnectorId("message"),
929
+ messages: new Map(),
930
+ tools: new Map(),
931
+ contentBlocks: new Map(),
932
+ };
933
+ states.set(key, state);
934
+ }
935
+ const mapped = mapper(event, context, state);
936
+ const mappedEvents = Array.isArray(mapped)
937
+ ? mapped
938
+ : mapped
939
+ ? [mapped]
940
+ : [];
941
+ if (mappedEvents.some((runtimeEvent) => runtimeEvent.type === "done" || runtimeEvent.type === "error")) {
942
+ states.delete(key);
943
+ }
944
+ return mapped;
945
+ };
946
+ }
947
+ export function createOpenAIResponsesChatRuntime(options) {
948
+ return createHttpAgentChatRuntime({
949
+ id: "external:openai-responses",
950
+ kind: "external-agent",
951
+ label: "OpenAI Responses",
952
+ ...options,
953
+ mapEvent: createConnectorMapEvent(mapOpenAIResponsesEvent),
954
+ });
955
+ }
956
+ export function createOpenAIAgentsChatRuntime(options) {
957
+ return createHttpAgentChatRuntime({
958
+ id: "external:openai-agents",
959
+ kind: "external-agent",
960
+ label: "OpenAI Agents",
961
+ ...options,
962
+ mapEvent: createConnectorMapEvent(mapOpenAIAgentsEvent),
963
+ });
964
+ }
965
+ export function createAgUiChatRuntime(options) {
966
+ return createHttpAgentChatRuntime({
967
+ id: "external:ag-ui",
968
+ kind: "external-agent",
969
+ label: "AG-UI",
970
+ ...options,
971
+ mapEvent: createConnectorMapEvent(mapAgUiEvent),
972
+ });
973
+ }
974
+ export function createClaudeAgentChatRuntime(options) {
975
+ return createHttpAgentChatRuntime({
976
+ id: "external:claude-agent",
977
+ kind: "external-agent",
978
+ label: "Claude Agent SDK",
979
+ ...options,
980
+ mapEvent: createConnectorMapEvent(mapClaudeAgentEvent),
981
+ });
982
+ }
983
+ export function createVercelAiChatRuntime(options) {
984
+ return createHttpAgentChatRuntime({
985
+ id: "external:vercel-ai",
986
+ kind: "external-agent",
987
+ label: "Vercel AI SDK",
988
+ ...options,
989
+ mapEvent: createConnectorMapEvent(mapVercelAiEvent),
990
+ });
991
+ }
992
+ //# sourceMappingURL=connectors.js.map