@assistant-ui/react-ag-ui 0.0.10 → 0.0.12
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.
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { type Tool } from "assistant-stream";
|
|
1
2
|
type ThreadMessageLike = {
|
|
2
3
|
id: string;
|
|
3
4
|
role: string;
|
|
4
|
-
content:
|
|
5
|
+
content: unknown;
|
|
5
6
|
name?: string;
|
|
7
|
+
toolCallId?: string;
|
|
8
|
+
error?: string;
|
|
6
9
|
};
|
|
7
10
|
type AgUiToolCall = {
|
|
8
11
|
id: string;
|
|
@@ -25,11 +28,12 @@ export type AgUiMessage = {
|
|
|
25
28
|
toolCallId: string;
|
|
26
29
|
error?: string;
|
|
27
30
|
};
|
|
28
|
-
export declare
|
|
29
|
-
|
|
31
|
+
export declare function toAgUiMessages(messages: readonly ThreadMessageLike[]): AgUiMessage[];
|
|
32
|
+
type AgUiTool = {
|
|
30
33
|
name: string;
|
|
31
|
-
description:
|
|
32
|
-
parameters:
|
|
33
|
-
}
|
|
34
|
+
description: string | undefined;
|
|
35
|
+
parameters: unknown;
|
|
36
|
+
};
|
|
37
|
+
export declare function toAgUiTools(tools: Record<string, Tool> | undefined): AgUiTool[];
|
|
34
38
|
export {};
|
|
35
39
|
//# sourceMappingURL=conversions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversions.d.ts","sourceRoot":"","sources":["../../../src/runtime/adapter/conversions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"conversions.d.ts","sourceRoot":"","sources":["../../../src/runtime/adapter/conversions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,IAAI,EAAqB,MAAM,kBAAkB,CAAC;AAEhE,KAAK,iBAAiB,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,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,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC;CAC5B,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;AA4HN,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,iBAAiB,EAAE,GACrC,WAAW,EAAE,CA0Bf;AAED,KAAK,QAAQ,GAAG;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS,GACtC,QAAQ,EAAE,CASZ"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import { toToolsJSONSchema } from "assistant-stream";
|
|
3
|
+
function generateId() {
|
|
4
|
+
return (globalThis.crypto?.randomUUID?.() ??
|
|
5
|
+
Math.random().toString(36).slice(2));
|
|
6
|
+
}
|
|
7
|
+
function normalizeToolCall(part) {
|
|
6
8
|
const id = part.toolCallId ?? generateId();
|
|
7
9
|
const argsText = typeof part.argsText === "string"
|
|
8
10
|
? part.argsText
|
|
@@ -18,91 +20,100 @@ const normaliseToolCall = (part) => {
|
|
|
18
20
|
},
|
|
19
21
|
},
|
|
20
22
|
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
+
}
|
|
24
|
+
function extractText(content) {
|
|
25
|
+
if (typeof content === "string")
|
|
26
|
+
return content;
|
|
27
|
+
if (!Array.isArray(content))
|
|
28
|
+
return "";
|
|
29
|
+
return content
|
|
30
|
+
.filter((part) => part?.type === "text" && typeof part?.text === "string")
|
|
31
|
+
.map((part) => part.text)
|
|
32
|
+
.join("\n");
|
|
33
|
+
}
|
|
34
|
+
function convertAssistantMessage(message, converted) {
|
|
35
|
+
const content = extractText(message.content);
|
|
36
|
+
const contentArray = Array.isArray(message.content) ? message.content : [];
|
|
37
|
+
const toolCallParts = contentArray.filter((part) => part?.type === "tool-call");
|
|
38
|
+
const toolCalls = toolCallParts.map((part) => ({
|
|
39
|
+
...normalizeToolCall(part),
|
|
40
|
+
part,
|
|
41
|
+
}));
|
|
42
|
+
const assistantMessage = {
|
|
43
|
+
id: message.id,
|
|
44
|
+
role: "assistant",
|
|
45
|
+
content,
|
|
46
|
+
};
|
|
47
|
+
if (message.name) {
|
|
48
|
+
assistantMessage.name = message.name;
|
|
49
|
+
}
|
|
50
|
+
if (toolCalls.length > 0) {
|
|
51
|
+
assistantMessage.toolCalls = toolCalls.map((entry) => entry.call);
|
|
52
|
+
}
|
|
53
|
+
converted.push(assistantMessage);
|
|
54
|
+
for (const { id: toolCallId, part } of toolCalls) {
|
|
55
|
+
if (part.result === undefined)
|
|
56
|
+
continue;
|
|
57
|
+
const resultContent = typeof part.result === "string"
|
|
58
|
+
? part.result
|
|
59
|
+
: JSON.stringify(part.result);
|
|
60
|
+
const toolMessage = {
|
|
61
|
+
id: `${toolCallId}:tool`,
|
|
62
|
+
role: "tool",
|
|
63
|
+
content: resultContent,
|
|
64
|
+
toolCallId,
|
|
65
|
+
};
|
|
66
|
+
if (part.isError) {
|
|
67
|
+
toolMessage.error = resultContent;
|
|
68
|
+
}
|
|
69
|
+
converted.push(toolMessage);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function convertToolMessage(message, converted) {
|
|
73
|
+
const content = extractText(message.content);
|
|
74
|
+
const toolCallId = message.toolCallId ?? generateId();
|
|
75
|
+
const toolMessage = {
|
|
76
|
+
id: message.id,
|
|
77
|
+
role: "tool",
|
|
78
|
+
content,
|
|
79
|
+
toolCallId,
|
|
80
|
+
};
|
|
81
|
+
if (typeof message.error === "string") {
|
|
82
|
+
toolMessage.error = message.error;
|
|
83
|
+
}
|
|
84
|
+
converted.push(toolMessage);
|
|
85
|
+
}
|
|
86
|
+
export function toAgUiMessages(messages) {
|
|
23
87
|
const converted = [];
|
|
24
88
|
for (const message of messages) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (role === "assistant" && Array.isArray(message.content)) {
|
|
28
|
-
const toolCallParts = message.content.filter((part) => part?.type === "tool-call");
|
|
29
|
-
const toolCalls = toolCallParts.map((part) => {
|
|
30
|
-
const { id, call } = normaliseToolCall(part);
|
|
31
|
-
return { id, call, part };
|
|
32
|
-
});
|
|
33
|
-
converted.push({
|
|
34
|
-
id: message.id,
|
|
35
|
-
role: "assistant",
|
|
36
|
-
content,
|
|
37
|
-
...(message.name ? { name: message.name } : {}),
|
|
38
|
-
...(toolCalls.length > 0
|
|
39
|
-
? { toolCalls: toolCalls.map((entry) => entry.call) }
|
|
40
|
-
: {}),
|
|
41
|
-
});
|
|
42
|
-
for (const { id: toolCallId, part } of toolCalls) {
|
|
43
|
-
if (part.result === undefined)
|
|
44
|
-
continue;
|
|
45
|
-
const resultContent = typeof part.result === "string"
|
|
46
|
-
? part.result
|
|
47
|
-
: JSON.stringify(part.result);
|
|
48
|
-
converted.push({
|
|
49
|
-
id: `${toolCallId}:tool`,
|
|
50
|
-
role: "tool",
|
|
51
|
-
content: resultContent,
|
|
52
|
-
toolCallId,
|
|
53
|
-
...(part.isError ? { error: resultContent } : {}),
|
|
54
|
-
});
|
|
55
|
-
}
|
|
89
|
+
if (message.role === "assistant") {
|
|
90
|
+
convertAssistantMessage(message, converted);
|
|
56
91
|
continue;
|
|
57
92
|
}
|
|
58
|
-
if (role === "tool") {
|
|
59
|
-
|
|
60
|
-
converted.push({
|
|
61
|
-
id: message.id,
|
|
62
|
-
role: "tool",
|
|
63
|
-
content,
|
|
64
|
-
toolCallId,
|
|
65
|
-
...(typeof message.error === "string"
|
|
66
|
-
? { error: message.error }
|
|
67
|
-
: undefined),
|
|
68
|
-
});
|
|
93
|
+
if (message.role === "tool") {
|
|
94
|
+
convertToolMessage(message, converted);
|
|
69
95
|
continue;
|
|
70
96
|
}
|
|
71
|
-
|
|
97
|
+
const genericMessage = {
|
|
72
98
|
id: message.id,
|
|
73
|
-
role,
|
|
74
|
-
content,
|
|
75
|
-
|
|
76
|
-
|
|
99
|
+
role: message.role,
|
|
100
|
+
content: extractText(message.content),
|
|
101
|
+
};
|
|
102
|
+
if (message.name) {
|
|
103
|
+
genericMessage.name = message.name;
|
|
104
|
+
}
|
|
105
|
+
converted.push(genericMessage);
|
|
77
106
|
}
|
|
78
107
|
return converted;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (!Array.isArray(content)) {
|
|
82
|
-
if (typeof content === "string")
|
|
83
|
-
return content;
|
|
84
|
-
return "";
|
|
85
|
-
}
|
|
86
|
-
return content
|
|
87
|
-
.filter((part) => part?.type === "text" && typeof part?.text === "string")
|
|
88
|
-
.map((part) => part.text)
|
|
89
|
-
.join("\n");
|
|
90
|
-
};
|
|
91
|
-
export const toAgUiTools = (tools) => {
|
|
108
|
+
}
|
|
109
|
+
export function toAgUiTools(tools) {
|
|
92
110
|
if (!tools)
|
|
93
111
|
return [];
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
.map(([name, tool]) => ({
|
|
112
|
+
const toolsSchema = toToolsJSONSchema(tools);
|
|
113
|
+
return Object.entries(toolsSchema).map(([name, tool]) => ({
|
|
97
114
|
name,
|
|
98
|
-
description: tool
|
|
99
|
-
parameters: tool
|
|
100
|
-
? z.toJSONSchema(tool.parameters)
|
|
101
|
-
: typeof tool?.parameters?.toJSON === "function"
|
|
102
|
-
? tool.parameters.toJSON()
|
|
103
|
-
: typeof tool?.parameters?.toJSONSchema === "function"
|
|
104
|
-
? tool.parameters.toJSONSchema()
|
|
105
|
-
: tool?.parameters,
|
|
115
|
+
description: tool.description,
|
|
116
|
+
parameters: tool.parameters,
|
|
106
117
|
}));
|
|
107
|
-
}
|
|
118
|
+
}
|
|
108
119
|
//# sourceMappingURL=conversions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversions.js","sourceRoot":"","sources":["../../../src/runtime/adapter/conversions.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,
|
|
1
|
+
{"version":3,"file":"conversions.js","sourceRoot":"","sources":["../../../src/runtime/adapter/conversions.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAa,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AA2ChE,SAAS,UAAU;IACjB,OAAO,CACJ,UAAU,CAAC,MAAwC,EAAE,UAAU,EAAE,EAAE;QACpE,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CACpC,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAkB;IAI3C,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,IAAI,UAAU,EAAE,CAAC;IAC3C,MAAM,QAAQ,GACZ,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ;QAC/B,CAAC,CAAC,IAAI,CAAC,QAAQ;QACf,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAEtC,OAAO;QACL,EAAE;QACF,IAAI,EAAE;YACJ,EAAE;YACF,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE;gBACR,IAAI,EAAE,IAAI,CAAC,QAAQ,IAAI,MAAM;gBAC7B,SAAS,EAAE,QAAQ;aACpB;SACF;KACF,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,OAAgB;IACnC,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IAEvC,OAAO,OAAO;SACX,MAAM,CACL,CAAC,IAAI,EAA0C,EAAE,CAC/C,IAAI,EAAE,IAAI,KAAK,MAAM,IAAI,OAAO,IAAI,EAAE,IAAI,KAAK,QAAQ,CAC1D;SACA,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;SACxB,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,SAAS,uBAAuB,CAC9B,OAA0B,EAC1B,SAAwB;IAExB,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAE3E,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CACvC,CAAC,IAAI,EAAwB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,WAAW,CAC3D,CAAC;IAEF,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7C,GAAG,iBAAiB,CAAC,IAAI,CAAC;QAC1B,IAAI;KACL,CAAC,CAAC,CAAC;IAEJ,MAAM,gBAAgB,GAAgB;QACpC,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,IAAI,EAAE,WAAW;QACjB,OAAO;KACR,CAAC;IACF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,gBAAgB,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IACvC,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,gBAAgB,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpE,CAAC;IACD,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAEjC,KAAK,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,SAAS,EAAE,CAAC;QACjD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;YAAE,SAAS;QAExC,MAAM,aAAa,GACjB,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ;YAC7B,CAAC,CAAC,IAAI,CAAC,MAAM;YACb,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAElC,MAAM,WAAW,GAAgB;YAC/B,EAAE,EAAE,GAAG,UAAU,OAAO;YACxB,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,aAAa;YACtB,UAAU;SACX,CAAC;QACF,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,WAAW,CAAC,KAAK,GAAG,aAAa,CAAC;QACpC,CAAC;QACD,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CACzB,OAA0B,EAC1B,SAAwB;IAExB,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,UAAU,EAAE,CAAC;IAEtD,MAAM,WAAW,GAAgB;QAC/B,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,IAAI,EAAE,MAAM;QACZ,OAAO;QACP,UAAU;KACX,CAAC;IACF,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACtC,WAAW,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IACpC,CAAC;IACD,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,QAAsC;IAEtC,MAAM,SAAS,GAAkB,EAAE,CAAC;IAEpC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACjC,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAC5C,SAAS;QACX,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,kBAAkB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YACvC,SAAS;QACX,CAAC;QAED,MAAM,cAAc,GAAgB;YAClC,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC;SACtC,CAAC;QACF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,cAAc,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACrC,CAAC;QACD,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAQD,MAAM,UAAU,WAAW,CACzB,KAAuC;IAEvC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IAEtB,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI;QACJ,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;KAC5B,CAAC,CAAC,CAAC;AACN,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/react-ag-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "AG-UI protocol adapter for assistant-ui",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ag-ui",
|
|
@@ -31,11 +31,11 @@
|
|
|
31
31
|
"sideEffects": false,
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@ag-ui/client": "^0.0.43",
|
|
34
|
-
"assistant-stream": "^0.
|
|
35
|
-
"zod": "^4.3.
|
|
34
|
+
"assistant-stream": "^0.3.0",
|
|
35
|
+
"zod": "^4.3.6"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@assistant-ui/react": "^0.12.
|
|
38
|
+
"@assistant-ui/react": "^0.12.3",
|
|
39
39
|
"@types/react": "*",
|
|
40
40
|
"react": "^18 || ^19"
|
|
41
41
|
},
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/react": "^19.2.9",
|
|
49
|
-
"react": "^19.2.
|
|
50
|
-
"vitest": "^4.0.
|
|
51
|
-
"@assistant-ui/react": "0.12.
|
|
49
|
+
"react": "^19.2.4",
|
|
50
|
+
"vitest": "^4.0.18",
|
|
51
|
+
"@assistant-ui/react": "0.12.3",
|
|
52
52
|
"@assistant-ui/x-buildutils": "0.0.1"
|
|
53
53
|
},
|
|
54
54
|
"publishConfig": {
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { type Tool, toToolsJSONSchema } from "assistant-stream";
|
|
4
4
|
|
|
5
5
|
type ThreadMessageLike = {
|
|
6
6
|
id: string;
|
|
7
7
|
role: string;
|
|
8
|
-
content:
|
|
8
|
+
content: unknown;
|
|
9
9
|
name?: string;
|
|
10
|
+
toolCallId?: string;
|
|
11
|
+
error?: string;
|
|
10
12
|
};
|
|
11
13
|
|
|
12
|
-
const generateId = () =>
|
|
13
|
-
(globalThis.crypto as any)?.randomUUID?.() ??
|
|
14
|
-
Math.random().toString(36).slice(2);
|
|
15
|
-
|
|
16
14
|
type AgUiToolCall = {
|
|
17
15
|
id: string;
|
|
18
16
|
type: "function";
|
|
@@ -45,125 +43,163 @@ type ToolCallPart = {
|
|
|
45
43
|
isError?: boolean;
|
|
46
44
|
};
|
|
47
45
|
|
|
48
|
-
|
|
46
|
+
function generateId(): string {
|
|
47
|
+
return (
|
|
48
|
+
(globalThis.crypto as { randomUUID?: () => string })?.randomUUID?.() ??
|
|
49
|
+
Math.random().toString(36).slice(2)
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function normalizeToolCall(part: ToolCallPart): {
|
|
54
|
+
id: string;
|
|
55
|
+
call: AgUiToolCall;
|
|
56
|
+
} {
|
|
49
57
|
const id = part.toolCallId ?? generateId();
|
|
50
58
|
const argsText =
|
|
51
59
|
typeof part.argsText === "string"
|
|
52
60
|
? part.argsText
|
|
53
61
|
: JSON.stringify(part.args ?? {});
|
|
62
|
+
|
|
54
63
|
return {
|
|
55
64
|
id,
|
|
56
65
|
call: {
|
|
57
66
|
id,
|
|
58
|
-
type: "function"
|
|
67
|
+
type: "function",
|
|
59
68
|
function: {
|
|
60
69
|
name: part.toolName ?? "tool",
|
|
61
70
|
arguments: argsText,
|
|
62
71
|
},
|
|
63
72
|
},
|
|
64
73
|
};
|
|
65
|
-
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function extractText(content: unknown): string {
|
|
77
|
+
if (typeof content === "string") return content;
|
|
78
|
+
if (!Array.isArray(content)) return "";
|
|
79
|
+
|
|
80
|
+
return content
|
|
81
|
+
.filter(
|
|
82
|
+
(part): part is { type: "text"; text: string } =>
|
|
83
|
+
part?.type === "text" && typeof part?.text === "string",
|
|
84
|
+
)
|
|
85
|
+
.map((part) => part.text)
|
|
86
|
+
.join("\n");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function convertAssistantMessage(
|
|
90
|
+
message: ThreadMessageLike,
|
|
91
|
+
converted: AgUiMessage[],
|
|
92
|
+
): void {
|
|
93
|
+
const content = extractText(message.content);
|
|
94
|
+
const contentArray = Array.isArray(message.content) ? message.content : [];
|
|
95
|
+
|
|
96
|
+
const toolCallParts = contentArray.filter(
|
|
97
|
+
(part): part is ToolCallPart => part?.type === "tool-call",
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
const toolCalls = toolCallParts.map((part) => ({
|
|
101
|
+
...normalizeToolCall(part),
|
|
102
|
+
part,
|
|
103
|
+
}));
|
|
104
|
+
|
|
105
|
+
const assistantMessage: AgUiMessage = {
|
|
106
|
+
id: message.id,
|
|
107
|
+
role: "assistant",
|
|
108
|
+
content,
|
|
109
|
+
};
|
|
110
|
+
if (message.name) {
|
|
111
|
+
assistantMessage.name = message.name;
|
|
112
|
+
}
|
|
113
|
+
if (toolCalls.length > 0) {
|
|
114
|
+
assistantMessage.toolCalls = toolCalls.map((entry) => entry.call);
|
|
115
|
+
}
|
|
116
|
+
converted.push(assistantMessage);
|
|
117
|
+
|
|
118
|
+
for (const { id: toolCallId, part } of toolCalls) {
|
|
119
|
+
if (part.result === undefined) continue;
|
|
120
|
+
|
|
121
|
+
const resultContent =
|
|
122
|
+
typeof part.result === "string"
|
|
123
|
+
? part.result
|
|
124
|
+
: JSON.stringify(part.result);
|
|
66
125
|
|
|
67
|
-
|
|
126
|
+
const toolMessage: AgUiMessage = {
|
|
127
|
+
id: `${toolCallId}:tool`,
|
|
128
|
+
role: "tool",
|
|
129
|
+
content: resultContent,
|
|
130
|
+
toolCallId,
|
|
131
|
+
};
|
|
132
|
+
if (part.isError) {
|
|
133
|
+
toolMessage.error = resultContent;
|
|
134
|
+
}
|
|
135
|
+
converted.push(toolMessage);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function convertToolMessage(
|
|
140
|
+
message: ThreadMessageLike,
|
|
141
|
+
converted: AgUiMessage[],
|
|
142
|
+
): void {
|
|
143
|
+
const content = extractText(message.content);
|
|
144
|
+
const toolCallId = message.toolCallId ?? generateId();
|
|
145
|
+
|
|
146
|
+
const toolMessage: AgUiMessage = {
|
|
147
|
+
id: message.id,
|
|
148
|
+
role: "tool",
|
|
149
|
+
content,
|
|
150
|
+
toolCallId,
|
|
151
|
+
};
|
|
152
|
+
if (typeof message.error === "string") {
|
|
153
|
+
toolMessage.error = message.error;
|
|
154
|
+
}
|
|
155
|
+
converted.push(toolMessage);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function toAgUiMessages(
|
|
68
159
|
messages: readonly ThreadMessageLike[],
|
|
69
|
-
): AgUiMessage[]
|
|
160
|
+
): AgUiMessage[] {
|
|
70
161
|
const converted: AgUiMessage[] = [];
|
|
71
162
|
|
|
72
163
|
for (const message of messages) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (role === "assistant" && Array.isArray(message.content)) {
|
|
77
|
-
const toolCallParts = message.content.filter(
|
|
78
|
-
(part): part is ToolCallPart => part?.type === "tool-call",
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
const toolCalls = toolCallParts.map((part) => {
|
|
82
|
-
const { id, call } = normaliseToolCall(part);
|
|
83
|
-
return { id, call, part };
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
converted.push({
|
|
87
|
-
id: message.id,
|
|
88
|
-
role: "assistant",
|
|
89
|
-
content,
|
|
90
|
-
...(message.name ? { name: message.name } : {}),
|
|
91
|
-
...(toolCalls.length > 0
|
|
92
|
-
? { toolCalls: toolCalls.map((entry) => entry.call) }
|
|
93
|
-
: {}),
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
for (const { id: toolCallId, part } of toolCalls) {
|
|
97
|
-
if (part.result === undefined) continue;
|
|
98
|
-
|
|
99
|
-
const resultContent =
|
|
100
|
-
typeof part.result === "string"
|
|
101
|
-
? part.result
|
|
102
|
-
: JSON.stringify(part.result);
|
|
103
|
-
converted.push({
|
|
104
|
-
id: `${toolCallId}:tool`,
|
|
105
|
-
role: "tool",
|
|
106
|
-
content: resultContent,
|
|
107
|
-
toolCallId,
|
|
108
|
-
...(part.isError ? { error: resultContent } : {}),
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
164
|
+
if (message.role === "assistant") {
|
|
165
|
+
convertAssistantMessage(message, converted);
|
|
112
166
|
continue;
|
|
113
167
|
}
|
|
114
168
|
|
|
115
|
-
if (role === "tool") {
|
|
116
|
-
|
|
117
|
-
converted.push({
|
|
118
|
-
id: message.id,
|
|
119
|
-
role: "tool",
|
|
120
|
-
content,
|
|
121
|
-
toolCallId,
|
|
122
|
-
...(typeof (message as any).error === "string"
|
|
123
|
-
? { error: (message as any).error }
|
|
124
|
-
: undefined),
|
|
125
|
-
});
|
|
169
|
+
if (message.role === "tool") {
|
|
170
|
+
convertToolMessage(message, converted);
|
|
126
171
|
continue;
|
|
127
172
|
}
|
|
128
173
|
|
|
129
|
-
|
|
174
|
+
const genericMessage: AgUiMessage = {
|
|
130
175
|
id: message.id,
|
|
131
|
-
role,
|
|
132
|
-
content,
|
|
133
|
-
|
|
134
|
-
|
|
176
|
+
role: message.role,
|
|
177
|
+
content: extractText(message.content),
|
|
178
|
+
};
|
|
179
|
+
if (message.name) {
|
|
180
|
+
genericMessage.name = message.name;
|
|
181
|
+
}
|
|
182
|
+
converted.push(genericMessage);
|
|
135
183
|
}
|
|
136
184
|
|
|
137
185
|
return converted;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const extractText = (content: any): string => {
|
|
141
|
-
if (!Array.isArray(content)) {
|
|
142
|
-
if (typeof content === "string") return content;
|
|
143
|
-
return "";
|
|
144
|
-
}
|
|
186
|
+
}
|
|
145
187
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
188
|
+
type AgUiTool = {
|
|
189
|
+
name: string;
|
|
190
|
+
description: string | undefined;
|
|
191
|
+
parameters: unknown;
|
|
150
192
|
};
|
|
151
193
|
|
|
152
|
-
export
|
|
194
|
+
export function toAgUiTools(
|
|
195
|
+
tools: Record<string, Tool> | undefined,
|
|
196
|
+
): AgUiTool[] {
|
|
153
197
|
if (!tools) return [];
|
|
154
198
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
? z.toJSONSchema(tool.parameters)
|
|
163
|
-
: typeof tool?.parameters?.toJSON === "function"
|
|
164
|
-
? tool.parameters.toJSON()
|
|
165
|
-
: typeof tool?.parameters?.toJSONSchema === "function"
|
|
166
|
-
? tool.parameters.toJSONSchema()
|
|
167
|
-
: tool?.parameters,
|
|
168
|
-
}));
|
|
169
|
-
};
|
|
199
|
+
const toolsSchema = toToolsJSONSchema(tools);
|
|
200
|
+
return Object.entries(toolsSchema).map(([name, tool]) => ({
|
|
201
|
+
name,
|
|
202
|
+
description: tool.description,
|
|
203
|
+
parameters: tool.parameters,
|
|
204
|
+
}));
|
|
205
|
+
}
|