@assistant-ui/react-ag-ui 0.0.59 → 0.0.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agUiExtras.d.ts +2 -5
- package/dist/agUiExtras.d.ts.map +1 -1
- package/dist/hooks.d.ts +9 -12
- package/dist/hooks.d.ts.map +1 -1
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/runtime/AgUiThreadRuntimeCore.d.ts +153 -146
- package/dist/runtime/AgUiThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtime/AgUiThreadRuntimeCore.js +146 -26
- package/dist/runtime/AgUiThreadRuntimeCore.js.map +1 -1
- package/dist/runtime/adapter/conversions.d.ts +54 -56
- package/dist/runtime/adapter/conversions.d.ts.map +1 -1
- package/dist/runtime/adapter/conversions.js +164 -23
- package/dist/runtime/adapter/conversions.js.map +1 -1
- package/dist/runtime/adapter/run-aggregator.d.ts +98 -98
- package/dist/runtime/adapter/run-aggregator.d.ts.map +1 -1
- package/dist/runtime/adapter/run-aggregator.js +35 -2
- package/dist/runtime/adapter/run-aggregator.js.map +1 -1
- package/dist/runtime/adapter/subscriber.d.ts +109 -111
- package/dist/runtime/adapter/subscriber.d.ts.map +1 -1
- package/dist/runtime/adapter/tool-approval.d.ts +7 -9
- package/dist/runtime/adapter/tool-approval.d.ts.map +1 -1
- package/dist/runtime/event-parser.d.ts +5 -8
- package/dist/runtime/event-parser.d.ts.map +1 -1
- package/dist/runtime/interrupt-internals.d.ts +4 -7
- package/dist/runtime/interrupt-internals.d.ts.map +1 -1
- package/dist/runtime/logger.d.ts +4 -7
- package/dist/runtime/logger.d.ts.map +1 -1
- package/dist/runtime/mcp-tool-result.d.ts +7 -10
- package/dist/runtime/mcp-tool-result.d.ts.map +1 -1
- package/dist/runtime/types.d.ts +248 -250
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/useAgUiRuntime.d.ts +15 -18
- package/dist/useAgUiRuntime.d.ts.map +1 -1
- package/dist/useAgUiRuntime.js +9 -2
- package/dist/useAgUiRuntime.js.map +1 -1
- package/package.json +12 -11
- package/src/runtime/AgUiThreadRuntimeCore.ts +246 -30
- package/src/runtime/adapter/conversions.content.test.ts +56 -0
- package/src/runtime/adapter/conversions.ts +278 -36
- package/src/runtime/adapter/run-aggregator.ts +53 -2
- package/src/useAgUiRuntime.history.test.tsx +93 -2
- package/src/useAgUiRuntime.thread-switch.test.tsx +84 -4
- package/src/useAgUiRuntime.ts +12 -3
- package/src/useAgUiRuntime.voice.test.tsx +402 -0
|
@@ -1,69 +1,67 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { Tool } from "assistant-stream";
|
|
4
|
-
|
|
1
|
+
import type { InputContent, RunAgentParameters } from "@ag-ui/client";
|
|
2
|
+
import type { ThreadMessageLike as CoreThreadMessageLike } from "@assistant-ui/core";
|
|
3
|
+
import { type Tool } from "assistant-stream";
|
|
4
|
+
export type { InputContent };
|
|
5
5
|
type AttachmentLike = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
name?: string | undefined;
|
|
7
|
+
contentType?: string | undefined;
|
|
8
|
+
content?: readonly unknown[] | undefined;
|
|
9
9
|
};
|
|
10
|
-
type ThreadMessageLike
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
type ThreadMessageLike = {
|
|
11
|
+
id?: string | undefined;
|
|
12
|
+
role: string;
|
|
13
|
+
content: unknown;
|
|
14
|
+
metadata?: unknown;
|
|
15
|
+
name?: string | undefined;
|
|
16
|
+
toolCallId?: string | undefined;
|
|
17
|
+
error?: string | undefined;
|
|
18
|
+
attachments?: readonly AttachmentLike[] | undefined;
|
|
19
19
|
};
|
|
20
20
|
type AgUiToolCall = {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
id: string;
|
|
22
|
+
type: "function";
|
|
23
|
+
function: {
|
|
24
|
+
name: string;
|
|
25
|
+
arguments: string;
|
|
26
|
+
};
|
|
27
27
|
};
|
|
28
|
-
type AgUiMessage = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
export type AgUiMessage = {
|
|
29
|
+
id: string;
|
|
30
|
+
role: "user";
|
|
31
|
+
content: string | InputContent[];
|
|
32
|
+
name?: string;
|
|
33
33
|
} | {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
id: string;
|
|
35
|
+
role: "assistant";
|
|
36
|
+
content: string;
|
|
37
|
+
name?: string;
|
|
38
|
+
toolCalls?: AgUiToolCall[];
|
|
39
39
|
} | {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
id: string;
|
|
41
|
+
role: "system" | "developer";
|
|
42
|
+
content: string;
|
|
43
|
+
name?: string;
|
|
44
44
|
} | {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
id: string;
|
|
46
|
+
role: "reasoning";
|
|
47
|
+
content: string;
|
|
48
|
+
encryptedValue?: string;
|
|
49
49
|
} | {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
id: string;
|
|
51
|
+
role: "tool";
|
|
52
|
+
content: string;
|
|
53
|
+
toolCallId: string;
|
|
54
|
+
error?: string;
|
|
55
55
|
};
|
|
56
|
-
type FromAgUiMessagesOptions = {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
export type FromAgUiMessagesOptions = {
|
|
57
|
+
/**
|
|
58
|
+
* Whether to convert `reasoning` messages into visible reasoning parts.
|
|
59
|
+
* Matches the `showThinking` option of `useAgUiRuntime`. Defaults to `true`.
|
|
60
|
+
*/
|
|
61
|
+
showThinking?: boolean;
|
|
62
62
|
};
|
|
63
|
-
declare function fromAgUiMessages(messages: readonly unknown[], options?: FromAgUiMessagesOptions):
|
|
64
|
-
declare function toAgUiMessages(messages: readonly ThreadMessageLike
|
|
63
|
+
export declare function fromAgUiMessages(messages: readonly unknown[], options?: FromAgUiMessagesOptions): CoreThreadMessageLike[];
|
|
64
|
+
export declare function toAgUiMessages(messages: readonly ThreadMessageLike[]): AgUiMessage[];
|
|
65
65
|
type AgUiTool = NonNullable<RunAgentParameters["tools"]>[number];
|
|
66
|
-
declare function toAgUiTools(tools: Record<string, Tool> | undefined): AgUiTool[];
|
|
67
|
-
//#endregion
|
|
68
|
-
export { AgUiMessage, FromAgUiMessagesOptions, type InputContent, fromAgUiMessages, toAgUiMessages, toAgUiTools };
|
|
66
|
+
export declare function toAgUiTools(tools: Record<string, Tool> | undefined): AgUiTool[];
|
|
69
67
|
//# sourceMappingURL=conversions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversions.d.ts","
|
|
1
|
+
{"version":3,"file":"conversions.d.ts","sourceRoot":"","sources":["../../../src/runtime/adapter/conversions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEtE,OAAO,KAAK,EACV,iBAAiB,IAAI,qBAAqB,EAM3C,MAAM,oBAAoB,CAAC;AAM5B,OAAO,EAAE,KAAK,IAAI,EAAqB,MAAM,kBAAkB,CAAC;AAuBhE,YAAY,EAAE,YAAY,EAAE,CAAC;AAE7B,KAAK,cAAc,GAAG;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,OAAO,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,CAAC;CAC1C,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,WAAW,CAAC,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,CAAC;CACrD,CAAC;AAIF,KAAK,YAAY,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,WAAW,GACnB;IACE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACD;IACE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC;CAC5B,GACD;IACE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,WAAW,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACD;IACE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GACD;IACE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA8vBN,MAAM,MAAM,uBAAuB,GAAG;IACpC;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,OAAO,CAAC,EAAE,uBAAuB,GAChC,qBAAqB,EAAE,CAsXzB;AAiKD,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,iBAAiB,EAAE,GACrC,WAAW,EAAE,CAoFf;AAED,KAAK,QAAQ,GAAG,WAAW,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS,GACtC,QAAQ,EAAE,CASZ"}
|
|
@@ -4,7 +4,7 @@ import { projectAgUiToolApprovals } from "./tool-approval.js";
|
|
|
4
4
|
import { AG_UI_METADATA_NAMESPACE } from "./run-aggregator.js";
|
|
5
5
|
import { generateId } from "@assistant-ui/core";
|
|
6
6
|
import { getAutoStatus, parseDataUrl, resolveFilePartSource } from "@assistant-ui/core/internal";
|
|
7
|
-
import { applyA2uiOperations, convertSurfaceToUISpec } from "@assistant-ui/react-generative-ui/a2ui";
|
|
7
|
+
import { applyA2uiOperations, convertSurfaceToUISpec, surfaceToOperations } from "@assistant-ui/react-generative-ui/a2ui";
|
|
8
8
|
import { toToolsJSONSchema } from "assistant-stream";
|
|
9
9
|
//#region src/runtime/adapter/conversions.ts
|
|
10
10
|
const isObject = (value) => typeof value === "object" && value !== null;
|
|
@@ -79,7 +79,7 @@ function buildInputSource(value, declaredMimeType, sourceType) {
|
|
|
79
79
|
const source = resolveFilePartSource({
|
|
80
80
|
data: value,
|
|
81
81
|
mimeType: declaredMimeType ?? "application/octet-stream",
|
|
82
|
-
sourceType
|
|
82
|
+
sourceType: /^data:/i.test(value) && !parseDataUrl(value) ? "url" : sourceType
|
|
83
83
|
});
|
|
84
84
|
if (source.kind === "url") return declaredMimeType !== void 0 ? {
|
|
85
85
|
type: "url",
|
|
@@ -424,7 +424,8 @@ function attachA2uiSurfaces(message, state) {
|
|
|
424
424
|
toolName: "present",
|
|
425
425
|
args: spec,
|
|
426
426
|
argsText: JSON.stringify(spec),
|
|
427
|
-
result: {}
|
|
427
|
+
result: {},
|
|
428
|
+
artifact: { a2ui: surfaceToOperations(surface) }
|
|
428
429
|
});
|
|
429
430
|
}
|
|
430
431
|
const preserved = (Array.isArray(message.content) ? message.content : []).filter((part) => !(isObject(part) && part.type === "tool-call" && typeof part.toolCallId === "string" && part.toolCallId.startsWith("a2ui:")));
|
|
@@ -433,17 +434,100 @@ function attachA2uiSurfaces(message, state) {
|
|
|
433
434
|
content: [...preserved, ...a2uiParts]
|
|
434
435
|
};
|
|
435
436
|
}
|
|
437
|
+
function isSyntheticToolCallContainer(message) {
|
|
438
|
+
if (message.role !== "assistant" || !Array.isArray(message.content)) return false;
|
|
439
|
+
let carriesOwnId = false;
|
|
440
|
+
for (const part of message.content) {
|
|
441
|
+
if (!isObject(part)) continue;
|
|
442
|
+
if (part.type === "text") return false;
|
|
443
|
+
if (part.type === "tool-call" && getString(part, "toolCallId") === message.id) carriesOwnId = true;
|
|
444
|
+
}
|
|
445
|
+
return carriesOwnId;
|
|
446
|
+
}
|
|
447
|
+
function carriesPart(message, type) {
|
|
448
|
+
return Array.isArray(message.content) && message.content.some((part) => isObject(part) && part.type === type);
|
|
449
|
+
}
|
|
450
|
+
function carriesText(message) {
|
|
451
|
+
return carriesPart(message, "text");
|
|
452
|
+
}
|
|
453
|
+
function opensTurn(message) {
|
|
454
|
+
return message.role === "assistant" && (carriesText(message) || carriesPart(message, "tool-call"));
|
|
455
|
+
}
|
|
456
|
+
function answersToolCallContainer(message) {
|
|
457
|
+
if (message.role !== "assistant" || !Array.isArray(message.content)) return false;
|
|
458
|
+
if (message.content.length === 0) return false;
|
|
459
|
+
return !message.content.some((part) => isObject(part) && part.type === "tool-call");
|
|
460
|
+
}
|
|
461
|
+
function readCustomMetadata(metadata) {
|
|
462
|
+
if (!isObject(metadata) || !isObject(metadata.custom)) return {};
|
|
463
|
+
return metadata.custom;
|
|
464
|
+
}
|
|
465
|
+
function readNamespacedMetadata(metadata) {
|
|
466
|
+
const namespaced = readCustomMetadata(metadata)[AG_UI_METADATA_NAMESPACE];
|
|
467
|
+
return isObject(namespaced) ? namespaced : {};
|
|
468
|
+
}
|
|
469
|
+
function foldTurnRecords(previous, message) {
|
|
470
|
+
const interrupts = [...readPersistedInterrupts(previous.metadata) ?? [], ...readPersistedInterrupts(message.metadata) ?? []];
|
|
471
|
+
const trailsCalls = carriesPart(previous, "tool-call");
|
|
472
|
+
const opaqueReasoning = [...readOpaqueReasoning(previous.metadata), ...readOpaqueReasoning(message.metadata).map((entry) => trailsCalls ? {
|
|
473
|
+
...entry,
|
|
474
|
+
after: true
|
|
475
|
+
} : entry)];
|
|
476
|
+
const namespaced = {
|
|
477
|
+
...readNamespacedMetadata(previous.metadata),
|
|
478
|
+
...readNamespacedMetadata(message.metadata),
|
|
479
|
+
...interrupts.length > 0 ? { interrupts } : {},
|
|
480
|
+
...opaqueReasoning.length > 0 ? { opaqueReasoning } : {}
|
|
481
|
+
};
|
|
482
|
+
const custom = {
|
|
483
|
+
...readCustomMetadata(previous.metadata),
|
|
484
|
+
...readCustomMetadata(message.metadata),
|
|
485
|
+
...Object.keys(namespaced).length > 0 ? { [AG_UI_METADATA_NAMESPACE]: namespaced } : {}
|
|
486
|
+
};
|
|
487
|
+
const metadata = {
|
|
488
|
+
...isObject(previous.metadata) ? previous.metadata : {},
|
|
489
|
+
...isObject(message.metadata) ? message.metadata : {},
|
|
490
|
+
...Object.keys(custom).length > 0 ? { custom } : {}
|
|
491
|
+
};
|
|
492
|
+
return {
|
|
493
|
+
...previous,
|
|
494
|
+
...message,
|
|
495
|
+
id: carriesText(message) ? message.id : previous.id,
|
|
496
|
+
content: [...Array.isArray(previous.content) ? previous.content : [], ...Array.isArray(message.content) ? message.content : []],
|
|
497
|
+
...Object.keys(metadata).length > 0 ? { metadata } : {}
|
|
498
|
+
};
|
|
499
|
+
}
|
|
436
500
|
function fromAgUiMessages(messages, options) {
|
|
437
501
|
const showThinking = options?.showThinking ?? true;
|
|
438
502
|
const converted = [];
|
|
439
503
|
const a2uiBuckets = /* @__PURE__ */ new Map();
|
|
440
504
|
const a2uiBucketOwnerIndices = /* @__PURE__ */ new Map();
|
|
505
|
+
const activityParts = /* @__PURE__ */ new Map();
|
|
441
506
|
const opaqueReasoning = [];
|
|
507
|
+
const pendingReasoning = [];
|
|
508
|
+
const flushPendingReasoning = () => {
|
|
509
|
+
for (const { id, part } of pendingReasoning) converted.push({
|
|
510
|
+
id: id ?? generateId(),
|
|
511
|
+
role: "assistant",
|
|
512
|
+
content: [part]
|
|
513
|
+
});
|
|
514
|
+
pendingReasoning.length = 0;
|
|
515
|
+
};
|
|
516
|
+
const withPendingReasoning = (message) => {
|
|
517
|
+
if (pendingReasoning.length === 0) return message;
|
|
518
|
+
const parts = pendingReasoning.map(({ part }) => part);
|
|
519
|
+
pendingReasoning.length = 0;
|
|
520
|
+
return {
|
|
521
|
+
...message,
|
|
522
|
+
content: [...parts, ...Array.isArray(message.content) ? message.content : []]
|
|
523
|
+
};
|
|
524
|
+
};
|
|
442
525
|
for (const rawMessage of messages) {
|
|
443
526
|
if (!isObject(rawMessage)) continue;
|
|
444
527
|
const role = getString(rawMessage, "role");
|
|
445
528
|
if (!role) continue;
|
|
446
529
|
if (role === "tool") {
|
|
530
|
+
flushPendingReasoning();
|
|
447
531
|
const toolCallId = getToolCallId(rawMessage) ?? `tool-${generateId()}`;
|
|
448
532
|
const toolMessageId = getString(rawMessage, "id");
|
|
449
533
|
const modelContent = extractText(rawMessage.content);
|
|
@@ -503,9 +587,9 @@ function fromAgUiMessages(messages, options) {
|
|
|
503
587
|
continue;
|
|
504
588
|
}
|
|
505
589
|
if (role === "activity") {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
590
|
+
const activityType = getString(rawMessage, "activityType");
|
|
591
|
+
if (activityType === void 0 || activityType === "mcp-apps") continue;
|
|
592
|
+
flushPendingReasoning();
|
|
509
593
|
let ownerIndex = -1;
|
|
510
594
|
for (let i = converted.length - 1; i >= 0; i--) {
|
|
511
595
|
const candidate = converted[i];
|
|
@@ -516,6 +600,42 @@ function fromAgUiMessages(messages, options) {
|
|
|
516
600
|
}
|
|
517
601
|
if (ownerIndex === -1) continue;
|
|
518
602
|
const owner = converted[ownerIndex];
|
|
603
|
+
if (activityType !== "a2ui-surface") {
|
|
604
|
+
const bucketKey = getString(rawMessage, "id") ?? `agui-activity:${activityType}`;
|
|
605
|
+
const part = {
|
|
606
|
+
type: "data",
|
|
607
|
+
name: `agui-activity/${activityType}`,
|
|
608
|
+
data: rawMessage.content
|
|
609
|
+
};
|
|
610
|
+
const existing = activityParts.get(bucketKey);
|
|
611
|
+
const existingOwner = existing && converted[existing.ownerIndex];
|
|
612
|
+
const existingIndex = existingOwner && Array.isArray(existingOwner.content) ? existingOwner.content.indexOf(existing.part) : -1;
|
|
613
|
+
if (existing && existingOwner && existingIndex !== -1) {
|
|
614
|
+
const content = [...existingOwner.content];
|
|
615
|
+
content[existingIndex] = part;
|
|
616
|
+
converted[existing.ownerIndex] = {
|
|
617
|
+
...existingOwner,
|
|
618
|
+
content
|
|
619
|
+
};
|
|
620
|
+
activityParts.set(bucketKey, {
|
|
621
|
+
ownerIndex: existing.ownerIndex,
|
|
622
|
+
part
|
|
623
|
+
});
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
626
|
+
const content = Array.isArray(owner.content) ? owner.content : [];
|
|
627
|
+
activityParts.set(bucketKey, {
|
|
628
|
+
ownerIndex,
|
|
629
|
+
part
|
|
630
|
+
});
|
|
631
|
+
converted[ownerIndex] = {
|
|
632
|
+
...owner,
|
|
633
|
+
content: [...content, part]
|
|
634
|
+
};
|
|
635
|
+
continue;
|
|
636
|
+
}
|
|
637
|
+
const operations = (isObject(rawMessage.content) ? rawMessage.content : null)?.["a2ui_operations"];
|
|
638
|
+
if (!Array.isArray(operations)) continue;
|
|
519
639
|
const bucketKey = getString(rawMessage, "id") ?? "a2ui:anonymous";
|
|
520
640
|
const { state } = applyA2uiOperations(/* @__PURE__ */ new Map(), operations);
|
|
521
641
|
a2uiBuckets.delete(bucketKey);
|
|
@@ -531,7 +651,7 @@ function fromAgUiMessages(messages, options) {
|
|
|
531
651
|
continue;
|
|
532
652
|
}
|
|
533
653
|
if (role === "assistant") {
|
|
534
|
-
converted.push(toAssistantSnapshotMessage(rawMessage));
|
|
654
|
+
converted.push(withPendingReasoning(toAssistantSnapshotMessage(rawMessage)));
|
|
535
655
|
continue;
|
|
536
656
|
}
|
|
537
657
|
if (role === "reasoning") {
|
|
@@ -539,11 +659,14 @@ function fromAgUiMessages(messages, options) {
|
|
|
539
659
|
const encryptedValue = getString(rawMessage, "encryptedValue");
|
|
540
660
|
if (text.trim().length === 0) {
|
|
541
661
|
const opaqueId = getString(rawMessage, "id");
|
|
542
|
-
if (opaqueId?.trim() && encryptedValue?.trim())
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
662
|
+
if (opaqueId?.trim() && encryptedValue?.trim()) {
|
|
663
|
+
flushPendingReasoning();
|
|
664
|
+
opaqueReasoning.push({
|
|
665
|
+
id: opaqueId,
|
|
666
|
+
encryptedValue,
|
|
667
|
+
anchor: converted.length
|
|
668
|
+
});
|
|
669
|
+
}
|
|
547
670
|
continue;
|
|
548
671
|
}
|
|
549
672
|
if (!showThinking) {
|
|
@@ -555,19 +678,28 @@ function fromAgUiMessages(messages, options) {
|
|
|
555
678
|
});
|
|
556
679
|
continue;
|
|
557
680
|
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
681
|
+
const rawReasoningId = getString(rawMessage, "id");
|
|
682
|
+
const reasoningId = rawReasoningId?.trim() ? rawReasoningId : void 0;
|
|
683
|
+
const meta = {
|
|
684
|
+
...reasoningId !== void 0 ? { reasoningId } : {},
|
|
685
|
+
...encryptedValue !== void 0 ? { encryptedValue } : {}
|
|
686
|
+
};
|
|
687
|
+
pendingReasoning.push({
|
|
688
|
+
id: reasoningId,
|
|
689
|
+
part: {
|
|
562
690
|
type: "reasoning",
|
|
563
691
|
text,
|
|
564
|
-
...
|
|
565
|
-
}
|
|
692
|
+
...Object.keys(meta).length > 0 ? { providerMetadata: { [AG_UI_METADATA_NAMESPACE]: meta } } : {}
|
|
693
|
+
}
|
|
566
694
|
});
|
|
567
695
|
continue;
|
|
568
696
|
}
|
|
569
|
-
if (role === "user" || role === "system" || role === "developer")
|
|
697
|
+
if (role === "user" || role === "system" || role === "developer") {
|
|
698
|
+
flushPendingReasoning();
|
|
699
|
+
converted.push(toUserOrSystemSnapshotMessage(role, rawMessage));
|
|
700
|
+
}
|
|
570
701
|
}
|
|
702
|
+
flushPendingReasoning();
|
|
571
703
|
for (const { anchor, ...entry } of opaqueReasoning) {
|
|
572
704
|
const trailing = anchor >= converted.length;
|
|
573
705
|
const index = trailing ? converted.length - 1 : anchor;
|
|
@@ -578,17 +710,26 @@ function fromAgUiMessages(messages, options) {
|
|
|
578
710
|
after: true
|
|
579
711
|
}] : [entry]]);
|
|
580
712
|
}
|
|
581
|
-
|
|
582
|
-
|
|
713
|
+
const folded = [];
|
|
714
|
+
for (const message of converted) {
|
|
715
|
+
const previous = folded[folded.length - 1];
|
|
716
|
+
if (previous !== void 0 && (isSyntheticToolCallContainer(message) ? opensTurn(previous) : isSyntheticToolCallContainer(previous) && answersToolCallContainer(message))) {
|
|
717
|
+
folded[folded.length - 1] = foldTurnRecords(previous, message);
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
folded.push(message);
|
|
721
|
+
}
|
|
722
|
+
for (let i = 0; i < folded.length; i++) {
|
|
723
|
+
const message = folded[i];
|
|
583
724
|
if (message.role !== "assistant") continue;
|
|
584
725
|
const hasInterrupt = readPersistedInterrupts(message.metadata) !== void 0;
|
|
585
726
|
const hasPendingToolCall = Array.isArray(message.content) && message.content.some((part) => isObject(part) && part.type === "tool-call" && part.result === void 0);
|
|
586
|
-
if (hasInterrupt || hasPendingToolCall)
|
|
727
|
+
if (hasInterrupt || hasPendingToolCall) folded[i] = {
|
|
587
728
|
...message,
|
|
588
729
|
status: getAutoStatus(false, false, hasInterrupt, hasPendingToolCall, void 0)
|
|
589
730
|
};
|
|
590
731
|
}
|
|
591
|
-
return
|
|
732
|
+
return folded;
|
|
592
733
|
}
|
|
593
734
|
function convertAssistantMessage(message, converted) {
|
|
594
735
|
const content = extractText(message.content);
|