@anvia/client 1.0.0-rc.6 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/index.d.ts +28 -19
- package/dist/index.js +163 -53
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -38,6 +38,10 @@ subpath; importing Client does not load the Agent runtime or its infrastructure
|
|
|
38
38
|
- `parseUIMessage` and `parseUIMessages` validate externally loaded UI state.
|
|
39
39
|
|
|
40
40
|
Tool-call start, delta, and end events are automatic when the provider exposes streamed arguments.
|
|
41
|
+
`UIToolMessagePart` states are exact: `input-streaming` carries raw partial text,
|
|
42
|
+
`input-available` carries parsed JSON input, and terminal `output-available` or `error` parts retain
|
|
43
|
+
that input with their result. `uiMessagesToMessages()` rejects partial calls instead of replaying
|
|
44
|
+
incomplete JSON or inventing empty arguments.
|
|
41
45
|
Errors are masked by default. Use `mapError` only at the server adapter boundary when an application
|
|
42
46
|
intentionally exposes a safe error shape. Non-JSON outputs require an explicit `mapOutput`; returning
|
|
43
47
|
`undefined` intentionally omits the output, while returning `null` exposes JSON `null`.
|
package/dist/index.d.ts
CHANGED
|
@@ -72,6 +72,32 @@ type UIDataPart<Data extends ClientDataMap> = {
|
|
|
72
72
|
data: Data[Name];
|
|
73
73
|
};
|
|
74
74
|
}[keyof Data & string];
|
|
75
|
+
type UIToolMessagePartBase = {
|
|
76
|
+
id: string;
|
|
77
|
+
type: "tool";
|
|
78
|
+
toolName: string;
|
|
79
|
+
toolCallId: string;
|
|
80
|
+
callId?: string;
|
|
81
|
+
internalCallId?: string;
|
|
82
|
+
turn?: number;
|
|
83
|
+
signature?: string;
|
|
84
|
+
};
|
|
85
|
+
type UIToolMessagePart = (UIToolMessagePartBase & {
|
|
86
|
+
state: "input-streaming";
|
|
87
|
+
input: string;
|
|
88
|
+
}) | (UIToolMessagePartBase & {
|
|
89
|
+
state: "input-available";
|
|
90
|
+
input: JsonValue;
|
|
91
|
+
}) | (UIToolMessagePartBase & {
|
|
92
|
+
state: "output-available";
|
|
93
|
+
input: JsonValue;
|
|
94
|
+
output: JsonValue;
|
|
95
|
+
resultContent?: readonly ToolResultContentPart[];
|
|
96
|
+
}) | (UIToolMessagePartBase & {
|
|
97
|
+
state: "error";
|
|
98
|
+
input: JsonValue;
|
|
99
|
+
error: UIError;
|
|
100
|
+
});
|
|
75
101
|
type UIMessagePart<Data extends ClientDataMap = ClientDataMap> = {
|
|
76
102
|
id: string;
|
|
77
103
|
type: "text";
|
|
@@ -83,21 +109,7 @@ type UIMessagePart<Data extends ClientDataMap = ClientDataMap> = {
|
|
|
83
109
|
text: string;
|
|
84
110
|
reasoningId?: string;
|
|
85
111
|
content?: readonly ReasoningDetail[];
|
|
86
|
-
} | {
|
|
87
|
-
id: string;
|
|
88
|
-
type: "tool";
|
|
89
|
-
toolName: string;
|
|
90
|
-
toolCallId: string;
|
|
91
|
-
callId?: string;
|
|
92
|
-
internalCallId?: string;
|
|
93
|
-
turn?: number;
|
|
94
|
-
state: "input-streaming" | "input-available" | "output-available" | "error";
|
|
95
|
-
input?: JsonValue;
|
|
96
|
-
output?: JsonValue;
|
|
97
|
-
resultContent?: readonly ToolResultContentPart[];
|
|
98
|
-
signature?: string;
|
|
99
|
-
error?: UIError;
|
|
100
|
-
} | {
|
|
112
|
+
} | UIToolMessagePart | {
|
|
101
113
|
id: string;
|
|
102
114
|
type: "source";
|
|
103
115
|
source: CompletionSource;
|
|
@@ -110,9 +122,6 @@ type UIMessagePart<Data extends ClientDataMap = ClientDataMap> = {
|
|
|
110
122
|
type: "error";
|
|
111
123
|
error: UIError;
|
|
112
124
|
};
|
|
113
|
-
type UIToolMessagePart = Extract<UIMessagePart, {
|
|
114
|
-
type: "tool";
|
|
115
|
-
}>;
|
|
116
125
|
type ClientStreamCursor = {
|
|
117
126
|
streamId: string;
|
|
118
127
|
after: number;
|
|
@@ -243,7 +252,7 @@ type ClientStandardStreamEvent<Metadata extends JsonObject, Data extends ClientD
|
|
|
243
252
|
callId?: string;
|
|
244
253
|
internalCallId?: string;
|
|
245
254
|
toolName: string;
|
|
246
|
-
input
|
|
255
|
+
input: JsonValue;
|
|
247
256
|
result: {
|
|
248
257
|
status: "success";
|
|
249
258
|
output: JsonValue;
|
package/dist/index.js
CHANGED
|
@@ -59,11 +59,12 @@ function uiMessagesToMessages(messages) {
|
|
|
59
59
|
if (part.content !== void 0) reasoning = { ...reasoning, details: part.content };
|
|
60
60
|
content2.push(reasoning);
|
|
61
61
|
} else if (part.type === "tool") {
|
|
62
|
+
assertReplayableToolPart(part);
|
|
62
63
|
let toolCall = {
|
|
63
64
|
type: "tool-call",
|
|
64
65
|
toolCallId: part.toolCallId,
|
|
65
66
|
toolName: part.toolName,
|
|
66
|
-
input: part.input
|
|
67
|
+
input: part.input
|
|
67
68
|
};
|
|
68
69
|
if (part.callId !== void 0) toolCall = { ...toolCall, callId: part.callId };
|
|
69
70
|
if (part.signature !== void 0) toolCall = { ...toolCall, signature: part.signature };
|
|
@@ -90,9 +91,12 @@ function uiMessagesToMessages(messages) {
|
|
|
90
91
|
continue;
|
|
91
92
|
}
|
|
92
93
|
assertOnlyParts(message, ["tool", "data", "error"]);
|
|
93
|
-
const content =
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
const content = [];
|
|
95
|
+
for (const part of message.parts) {
|
|
96
|
+
if (part.type !== "tool") continue;
|
|
97
|
+
assertToolResultPart(part);
|
|
98
|
+
content.push(toolResultFromPart(part));
|
|
99
|
+
}
|
|
96
100
|
result.push({ role: "tool", content, ...metadataField(message.metadata) });
|
|
97
101
|
}
|
|
98
102
|
return result;
|
|
@@ -147,7 +151,13 @@ function messagesToUIMessages(messages) {
|
|
|
147
151
|
for (const content of message.content) {
|
|
148
152
|
if (content.type !== "tool-result") continue;
|
|
149
153
|
const location = (content.callId === void 0 ? void 0 : byCallId.get(content.callId)) ?? byToolCallId.get(content.toolCallId);
|
|
150
|
-
const
|
|
154
|
+
const ownerPart = toolPartAt(result, location);
|
|
155
|
+
if (ownerPart === void 0 || ownerPart.state === "input-streaming") {
|
|
156
|
+
throw new TypeError(
|
|
157
|
+
`Tool result "${content.toolCallId}" requires a matching completed tool call.`
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
const part = toolResultToUIMessagePart(content, ownerPart.toolName, ownerPart.input);
|
|
151
161
|
if (message.metadata === void 0 && location !== void 0) {
|
|
152
162
|
const owner = result[location.messageIndex];
|
|
153
163
|
const existing = owner?.parts[location.partIndex];
|
|
@@ -233,12 +243,12 @@ function toolResultFromPart(part) {
|
|
|
233
243
|
}
|
|
234
244
|
function toolOutputFromPart(part) {
|
|
235
245
|
if (part.state === "error") {
|
|
236
|
-
return { type: "error-text", value: part.error
|
|
246
|
+
return { type: "error-text", value: part.error.message };
|
|
237
247
|
}
|
|
238
248
|
if (part.resultContent !== void 0) {
|
|
239
249
|
return { type: "content", value: part.resultContent };
|
|
240
250
|
}
|
|
241
|
-
const output = part.output
|
|
251
|
+
const output = part.output;
|
|
242
252
|
return typeof output === "string" ? { type: "text", value: output } : { type: "json", value: output };
|
|
243
253
|
}
|
|
244
254
|
function attachmentToUserContent(attachment) {
|
|
@@ -293,13 +303,14 @@ function contentToAttachment(content) {
|
|
|
293
303
|
else attachment.text = content.data.text;
|
|
294
304
|
return attachment;
|
|
295
305
|
}
|
|
296
|
-
function toolResultToUIMessagePart(content, fallbackToolName) {
|
|
306
|
+
function toolResultToUIMessagePart(content, fallbackToolName, input) {
|
|
297
307
|
const output = content.output;
|
|
298
308
|
const common = {
|
|
299
309
|
id: toolPartId(content.toolCallId),
|
|
300
310
|
type: "tool",
|
|
301
|
-
toolName: content.toolName || fallbackToolName
|
|
302
|
-
toolCallId: content.toolCallId
|
|
311
|
+
toolName: content.toolName || fallbackToolName,
|
|
312
|
+
toolCallId: content.toolCallId,
|
|
313
|
+
input
|
|
303
314
|
};
|
|
304
315
|
if (content.callId !== void 0) Object.assign(common, { callId: content.callId });
|
|
305
316
|
if (output.type === "error-text" || output.type === "error-json") {
|
|
@@ -334,10 +345,28 @@ function toolResultOutput(output) {
|
|
|
334
345
|
(part) => part.type === "text" ? { ...part } : { ...part, data: { ...part.data } }
|
|
335
346
|
);
|
|
336
347
|
}
|
|
337
|
-
function
|
|
348
|
+
function toolPartAt(messages, location) {
|
|
338
349
|
if (location === void 0) return void 0;
|
|
339
350
|
const part = messages[location.messageIndex]?.parts[location.partIndex];
|
|
340
|
-
return part?.type === "tool" ? part
|
|
351
|
+
return part?.type === "tool" ? part : void 0;
|
|
352
|
+
}
|
|
353
|
+
function assertReplayableToolPart(part) {
|
|
354
|
+
if (part.state === "input-streaming") {
|
|
355
|
+
throw new TypeError(
|
|
356
|
+
`Tool call "${part.toolCallId}" is still streaming and cannot be converted to a model message.`
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
if (!isJsonValue(part.input)) {
|
|
360
|
+
throw new TypeError(`Tool call "${part.toolCallId}" input must be a strict JSON value.`);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
function assertToolResultPart(part) {
|
|
364
|
+
assertReplayableToolPart(part);
|
|
365
|
+
if (part.state === "input-available") {
|
|
366
|
+
throw new TypeError(
|
|
367
|
+
`Tool message part "${part.toolCallId}" requires an output or execution error.`
|
|
368
|
+
);
|
|
369
|
+
}
|
|
341
370
|
}
|
|
342
371
|
function textFromParts(parts) {
|
|
343
372
|
return parts.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
|
|
@@ -612,6 +641,7 @@ function parseClientStreamEvent(value, options = {}) {
|
|
|
612
641
|
]);
|
|
613
642
|
requireStrings(event, ["messageId", "partId", "toolCallId", "toolName"], value);
|
|
614
643
|
requireOptionalStrings(event, ["callId", "internalCallId"], value);
|
|
644
|
+
if (!isJsonValue2(event.input)) invalid("tool_result.input", value);
|
|
615
645
|
if (!isRecord(event.result)) invalid("tool_result.result", value);
|
|
616
646
|
if (event.result.status === "success") {
|
|
617
647
|
if (!hasOnlyKeys(event.result, ["status", "output", "content"]) || !isJsonValue2(event.result.output) || event.result.content !== void 0 && (!Array.isArray(event.result.content) || !event.result.content.every(isToolResultContent))) {
|
|
@@ -700,6 +730,10 @@ function parseClientStreamEvent(value, options = {}) {
|
|
|
700
730
|
"originalMessageCount",
|
|
701
731
|
"compactedMessageCount",
|
|
702
732
|
"retainedMessageCount",
|
|
733
|
+
"originalTokenCount",
|
|
734
|
+
"compactedTokenCount",
|
|
735
|
+
"retainedTokenCount",
|
|
736
|
+
"resultTokenCount",
|
|
703
737
|
"attempts",
|
|
704
738
|
"usage"
|
|
705
739
|
]);
|
|
@@ -733,6 +767,10 @@ function parseClientStreamEvent(value, options = {}) {
|
|
|
733
767
|
"originalMessageCount",
|
|
734
768
|
"compactedMessageCount",
|
|
735
769
|
"retainedMessageCount",
|
|
770
|
+
"originalTokenCount",
|
|
771
|
+
"compactedTokenCount",
|
|
772
|
+
"retainedTokenCount",
|
|
773
|
+
"resultTokenCount",
|
|
736
774
|
"attempts",
|
|
737
775
|
"usage"
|
|
738
776
|
],
|
|
@@ -864,6 +902,10 @@ function validateMemoryCompactionForGuard(value) {
|
|
|
864
902
|
"originalMessageCount",
|
|
865
903
|
"compactedMessageCount",
|
|
866
904
|
"retainedMessageCount",
|
|
905
|
+
"originalTokenCount",
|
|
906
|
+
"compactedTokenCount",
|
|
907
|
+
"retainedTokenCount",
|
|
908
|
+
"resultTokenCount",
|
|
867
909
|
"attempts",
|
|
868
910
|
"usage"
|
|
869
911
|
],
|
|
@@ -930,7 +972,7 @@ function isUIMessagePart(value) {
|
|
|
930
972
|
if (value.type === "error") {
|
|
931
973
|
return hasOnlyKeys(value, ["id", "type", "error"]) && isClientStreamError(value.error);
|
|
932
974
|
}
|
|
933
|
-
|
|
975
|
+
if (value.type !== "tool" || !hasOnlyKeys(value, [
|
|
934
976
|
"id",
|
|
935
977
|
"type",
|
|
936
978
|
"toolName",
|
|
@@ -944,9 +986,19 @@ function isUIMessagePart(value) {
|
|
|
944
986
|
"resultContent",
|
|
945
987
|
"signature",
|
|
946
988
|
"error"
|
|
947
|
-
])
|
|
948
|
-
|
|
949
|
-
|
|
989
|
+
]) || typeof value.toolName !== "string" || typeof value.toolCallId !== "string" || value.callId !== void 0 && typeof value.callId !== "string" || value.internalCallId !== void 0 && typeof value.internalCallId !== "string" || value.turn !== void 0 && !isPositiveEventId(value.turn) || value.signature !== void 0 && typeof value.signature !== "string") {
|
|
990
|
+
return false;
|
|
991
|
+
}
|
|
992
|
+
if (value.state === "input-streaming") {
|
|
993
|
+
return typeof value.input === "string" && value.output === void 0 && value.resultContent === void 0 && value.error === void 0;
|
|
994
|
+
}
|
|
995
|
+
if (value.state === "input-available") {
|
|
996
|
+
return isJsonValue2(value.input) && value.output === void 0 && value.resultContent === void 0 && value.error === void 0;
|
|
997
|
+
}
|
|
998
|
+
if (value.state === "output-available") {
|
|
999
|
+
return isJsonValue2(value.input) && isJsonValue2(value.output) && (value.resultContent === void 0 || Array.isArray(value.resultContent) && value.resultContent.every(isToolResultContent)) && value.error === void 0;
|
|
1000
|
+
}
|
|
1001
|
+
return value.state === "error" && isJsonValue2(value.input) && value.output === void 0 && value.resultContent === void 0 && isClientStreamError(value.error);
|
|
950
1002
|
}
|
|
951
1003
|
function isReasoningContent(value) {
|
|
952
1004
|
if (!isRecord(value) || typeof value.type !== "string") return false;
|
|
@@ -1037,7 +1089,15 @@ function validateUsageAndContext(event, original) {
|
|
|
1037
1089
|
}
|
|
1038
1090
|
}
|
|
1039
1091
|
function validateMemoryCompactionInfo(value, original) {
|
|
1040
|
-
for (const field of [
|
|
1092
|
+
for (const field of [
|
|
1093
|
+
"originalMessageCount",
|
|
1094
|
+
"compactedMessageCount",
|
|
1095
|
+
"retainedMessageCount",
|
|
1096
|
+
"originalTokenCount",
|
|
1097
|
+
"compactedTokenCount",
|
|
1098
|
+
"retainedTokenCount",
|
|
1099
|
+
"resultTokenCount"
|
|
1100
|
+
]) {
|
|
1041
1101
|
if (!isEventId(value[field])) invalid(`memory_compaction.${field}`, original);
|
|
1042
1102
|
}
|
|
1043
1103
|
if (!isPositiveEventId(value.attempts)) invalid("memory_compaction.attempts", original);
|
|
@@ -1261,6 +1321,10 @@ async function* translateAgentEvent(runtime, event, scope) {
|
|
|
1261
1321
|
originalMessageCount: event.originalMessageCount,
|
|
1262
1322
|
compactedMessageCount: event.compactedMessageCount,
|
|
1263
1323
|
retainedMessageCount: event.retainedMessageCount,
|
|
1324
|
+
originalTokenCount: event.originalTokenCount,
|
|
1325
|
+
compactedTokenCount: event.compactedTokenCount,
|
|
1326
|
+
retainedTokenCount: event.retainedTokenCount,
|
|
1327
|
+
resultTokenCount: event.resultTokenCount,
|
|
1264
1328
|
attempts: event.attempts,
|
|
1265
1329
|
usage: event.usage
|
|
1266
1330
|
});
|
|
@@ -1372,18 +1436,20 @@ async function* translateAgentEvent(runtime, event, scope) {
|
|
|
1372
1436
|
decision: event.decision
|
|
1373
1437
|
});
|
|
1374
1438
|
return;
|
|
1375
|
-
case "
|
|
1376
|
-
|
|
1377
|
-
|
|
1439
|
+
case "response":
|
|
1440
|
+
case "interaction":
|
|
1441
|
+
case "blocked": {
|
|
1442
|
+
const result = event;
|
|
1443
|
+
if (result.type === "interaction" && scope === void 0) {
|
|
1378
1444
|
yield scopedEvent(runtime.runId, turn, scope, {
|
|
1379
1445
|
type: "interaction",
|
|
1380
1446
|
interaction: result.interaction
|
|
1381
1447
|
});
|
|
1382
1448
|
}
|
|
1383
|
-
const output = result.
|
|
1449
|
+
const output = result.type === "response" ? clientOutput(result.output, runtime.options.mapOutput) : void 0;
|
|
1384
1450
|
const runEnd = {
|
|
1385
1451
|
type: "run_end",
|
|
1386
|
-
status: result.
|
|
1452
|
+
status: agentOutcomeStatus(result.type),
|
|
1387
1453
|
text: result.text,
|
|
1388
1454
|
usage: result.usage
|
|
1389
1455
|
};
|
|
@@ -1759,25 +1825,43 @@ function contentToUIMessageParts(content, state) {
|
|
|
1759
1825
|
}
|
|
1760
1826
|
if (contentPart.type === "tool-call") {
|
|
1761
1827
|
const tool = getToolState(state, contentPart.toolCallId, contentPart.toolName);
|
|
1762
|
-
const
|
|
1828
|
+
const partBase = {
|
|
1763
1829
|
id: tool.partId,
|
|
1764
1830
|
type: "tool",
|
|
1765
1831
|
toolName: contentPart.toolName,
|
|
1766
|
-
toolCallId: contentPart.toolCallId
|
|
1767
|
-
state: tool.result?.status === "error" ? "error" : tool.result ? "output-available" : "input-available",
|
|
1768
|
-
input: contentPart.input
|
|
1832
|
+
toolCallId: contentPart.toolCallId
|
|
1769
1833
|
};
|
|
1770
|
-
if (contentPart.callId !== void 0)
|
|
1771
|
-
if (tool.internalCallId !== void 0)
|
|
1772
|
-
|
|
1773
|
-
|
|
1834
|
+
if (contentPart.callId !== void 0) Object.assign(partBase, { callId: contentPart.callId });
|
|
1835
|
+
if (tool.internalCallId !== void 0) {
|
|
1836
|
+
Object.assign(partBase, { internalCallId: tool.internalCallId });
|
|
1837
|
+
}
|
|
1838
|
+
if (state.turn !== void 0) Object.assign(partBase, { turn: state.turn });
|
|
1839
|
+
if (contentPart.signature !== void 0) {
|
|
1840
|
+
Object.assign(partBase, { signature: contentPart.signature });
|
|
1841
|
+
}
|
|
1774
1842
|
if (tool.result?.status === "success") {
|
|
1775
|
-
part
|
|
1843
|
+
const part = {
|
|
1844
|
+
...partBase,
|
|
1845
|
+
state: "output-available",
|
|
1846
|
+
input: contentPart.input,
|
|
1847
|
+
output: tool.result.output
|
|
1848
|
+
};
|
|
1776
1849
|
if (tool.result.content !== void 0) part.resultContent = tool.result.content;
|
|
1777
|
-
|
|
1778
|
-
part.error = tool.result.error;
|
|
1850
|
+
return part;
|
|
1779
1851
|
}
|
|
1780
|
-
|
|
1852
|
+
if (tool.result?.status === "error") {
|
|
1853
|
+
return {
|
|
1854
|
+
...partBase,
|
|
1855
|
+
state: "error",
|
|
1856
|
+
input: contentPart.input,
|
|
1857
|
+
error: tool.result.error
|
|
1858
|
+
};
|
|
1859
|
+
}
|
|
1860
|
+
return {
|
|
1861
|
+
...partBase,
|
|
1862
|
+
state: "input-available",
|
|
1863
|
+
input: contentPart.input
|
|
1864
|
+
};
|
|
1781
1865
|
}
|
|
1782
1866
|
const attachment = contentAttachment(contentPart);
|
|
1783
1867
|
return {
|
|
@@ -1939,7 +2023,12 @@ function scopeKey(scope) {
|
|
|
1939
2023
|
].join(":");
|
|
1940
2024
|
}
|
|
1941
2025
|
function isRootTerminalAgentEvent(event) {
|
|
1942
|
-
return event.type === "
|
|
2026
|
+
return event.type === "response" || event.type === "interaction" || event.type === "blocked" || event.type === "error";
|
|
2027
|
+
}
|
|
2028
|
+
function agentOutcomeStatus(type) {
|
|
2029
|
+
if (type === "response") return "completed";
|
|
2030
|
+
if (type === "interaction") return "suspended";
|
|
2031
|
+
return "blocked";
|
|
1943
2032
|
}
|
|
1944
2033
|
function propagateCancellation(source, transform) {
|
|
1945
2034
|
return {
|
|
@@ -2193,21 +2282,22 @@ function applyClientStreamEvent(messages, event) {
|
|
|
2193
2282
|
}
|
|
2194
2283
|
case "tool_call_delta":
|
|
2195
2284
|
return updatePart(messages, event.messageId, event.partId, (current) => {
|
|
2196
|
-
const part = current?.type === "tool" ?
|
|
2285
|
+
const part = current?.type === "tool" ? toolPartBase(current) : {
|
|
2197
2286
|
id: event.partId,
|
|
2198
2287
|
type: "tool",
|
|
2199
2288
|
toolName: event.toolName ?? "",
|
|
2200
|
-
toolCallId: event.toolCallId
|
|
2201
|
-
state: "input-streaming"
|
|
2289
|
+
toolCallId: event.toolCallId
|
|
2202
2290
|
};
|
|
2203
|
-
const previous = typeof
|
|
2204
|
-
part.input = event.mode === "replace" ? event.delta : `${previous}${event.delta}`;
|
|
2205
|
-
part.state = "input-streaming";
|
|
2291
|
+
const previous = current?.type === "tool" && typeof current.input === "string" ? current.input : "";
|
|
2206
2292
|
if (event.toolName !== void 0) part.toolName = event.toolName;
|
|
2207
2293
|
if (event.callId !== void 0) part.callId = event.callId;
|
|
2208
2294
|
if (event.signature !== void 0) part.signature = event.signature;
|
|
2209
2295
|
if (event.turn !== void 0) part.turn = event.turn;
|
|
2210
|
-
return
|
|
2296
|
+
return {
|
|
2297
|
+
...part,
|
|
2298
|
+
state: "input-streaming",
|
|
2299
|
+
input: event.mode === "replace" ? event.delta : `${previous}${event.delta}`
|
|
2300
|
+
};
|
|
2211
2301
|
});
|
|
2212
2302
|
case "tool_call_end": {
|
|
2213
2303
|
const part = {
|
|
@@ -2225,26 +2315,31 @@ function applyClientStreamEvent(messages, event) {
|
|
|
2225
2315
|
}
|
|
2226
2316
|
case "tool_result":
|
|
2227
2317
|
return updatePart(messages, event.messageId, event.partId, (current) => {
|
|
2228
|
-
const part = current?.type === "tool" ?
|
|
2318
|
+
const part = current?.type === "tool" ? toolPartBase(current) : {
|
|
2229
2319
|
id: event.partId,
|
|
2230
2320
|
type: "tool",
|
|
2231
2321
|
toolName: event.toolName,
|
|
2232
|
-
toolCallId: event.toolCallId
|
|
2233
|
-
state: "input-available"
|
|
2322
|
+
toolCallId: event.toolCallId
|
|
2234
2323
|
};
|
|
2235
2324
|
if (event.callId !== void 0) part.callId = event.callId;
|
|
2236
2325
|
if (event.internalCallId !== void 0) part.internalCallId = event.internalCallId;
|
|
2237
|
-
if (event.input !== void 0) part.input = event.input;
|
|
2238
2326
|
if (event.turn !== void 0) part.turn = event.turn;
|
|
2239
2327
|
if (event.result.status === "error") {
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2328
|
+
return {
|
|
2329
|
+
...part,
|
|
2330
|
+
state: "error",
|
|
2331
|
+
input: event.input,
|
|
2332
|
+
error: event.result.error
|
|
2333
|
+
};
|
|
2246
2334
|
}
|
|
2247
|
-
|
|
2335
|
+
const completed = {
|
|
2336
|
+
...part,
|
|
2337
|
+
state: "output-available",
|
|
2338
|
+
input: event.input,
|
|
2339
|
+
output: event.result.output
|
|
2340
|
+
};
|
|
2341
|
+
if (event.result.content !== void 0) completed.resultContent = event.result.content;
|
|
2342
|
+
return completed;
|
|
2248
2343
|
});
|
|
2249
2344
|
case "source":
|
|
2250
2345
|
return upsertPart(messages, event.messageId, {
|
|
@@ -2314,6 +2409,21 @@ function applyClientStreamEvent(messages, event) {
|
|
|
2314
2409
|
return messages;
|
|
2315
2410
|
}
|
|
2316
2411
|
}
|
|
2412
|
+
function toolPartBase(part) {
|
|
2413
|
+
const base = {
|
|
2414
|
+
id: part.id,
|
|
2415
|
+
type: part.type,
|
|
2416
|
+
toolName: part.toolName,
|
|
2417
|
+
toolCallId: part.toolCallId
|
|
2418
|
+
};
|
|
2419
|
+
if (part.callId !== void 0) Object.assign(base, { callId: part.callId });
|
|
2420
|
+
if (part.internalCallId !== void 0) {
|
|
2421
|
+
Object.assign(base, { internalCallId: part.internalCallId });
|
|
2422
|
+
}
|
|
2423
|
+
if (part.turn !== void 0) Object.assign(base, { turn: part.turn });
|
|
2424
|
+
if (part.signature !== void 0) Object.assign(base, { signature: part.signature });
|
|
2425
|
+
return base;
|
|
2426
|
+
}
|
|
2317
2427
|
function reconcileFinalParts(current, final) {
|
|
2318
2428
|
const clientOnly = current.filter(
|
|
2319
2429
|
(part) => part.type === "source" || part.type === "data" || part.type === "error"
|