@copilotkit/runtime-client-gql 1.51.4-next.7 → 1.51.4
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/CHANGELOG.md +16 -0
- package/codegen.ts +4 -1
- package/dist/{chunk-FTOMK35N.mjs → chunk-2XWNDVTL.mjs} +18 -7
- package/dist/chunk-2XWNDVTL.mjs.map +1 -0
- package/dist/{chunk-L6PM6AT3.mjs → chunk-A4INSSNE.mjs} +55 -55
- package/dist/chunk-A4INSSNE.mjs.map +1 -0
- package/dist/{chunk-KTA7QTTU.mjs → chunk-E5FOLXLN.mjs} +6 -3
- package/dist/chunk-E5FOLXLN.mjs.map +1 -0
- package/dist/{chunk-RNENVFJ3.mjs → chunk-LTVE64IE.mjs} +31 -11
- package/dist/chunk-LTVE64IE.mjs.map +1 -0
- package/dist/{chunk-AMFKR5ST.mjs → chunk-M4CK5HDR.mjs} +2 -2
- package/dist/chunk-M4CK5HDR.mjs.map +1 -0
- package/dist/{chunk-3ETRQN2E.mjs → chunk-QUH7QWUA.mjs} +2 -2
- package/dist/chunk-SDQPJXLL.mjs +20 -0
- package/dist/chunk-SDQPJXLL.mjs.map +1 -0
- package/dist/{chunk-NHOKFX55.mjs → chunk-UOAPP5IN.mjs} +6 -2
- package/dist/chunk-UOAPP5IN.mjs.map +1 -0
- package/dist/{chunk-EIPAWDCN.mjs → chunk-VIHKTLUA.mjs} +14 -6
- package/dist/chunk-VIHKTLUA.mjs.map +1 -0
- package/dist/client/CopilotRuntimeClient.js +20 -6
- package/dist/client/CopilotRuntimeClient.js.map +1 -1
- package/dist/client/CopilotRuntimeClient.mjs +4 -4
- package/dist/client/conversion.js.map +1 -1
- package/dist/client/conversion.mjs +2 -2
- package/dist/client/index.js +25 -7
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +6 -6
- package/dist/client/types.js +5 -1
- package/dist/client/types.js.map +1 -1
- package/dist/client/types.mjs +1 -1
- package/dist/graphql/@generated/gql.d.ts +2 -2
- package/dist/graphql/@generated/gql.js +1 -1
- package/dist/graphql/@generated/gql.js.map +1 -1
- package/dist/graphql/@generated/gql.mjs +1 -1
- package/dist/graphql/@generated/index.js +1 -1
- package/dist/graphql/@generated/index.js.map +1 -1
- package/dist/graphql/@generated/index.mjs +1 -1
- package/dist/graphql/definitions/mutations.js +5 -2
- package/dist/graphql/definitions/mutations.js.map +1 -1
- package/dist/graphql/definitions/mutations.mjs +2 -2
- package/dist/graphql/definitions/queries.js +1 -1
- package/dist/graphql/definitions/queries.js.map +1 -1
- package/dist/graphql/definitions/queries.mjs +2 -2
- package/dist/index.js +66 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8 -8
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/{magic-string.es-26DP735G.mjs → magic-string.es-XBKSJO3K.mjs} +3 -3
- package/dist/magic-string.es-XBKSJO3K.mjs.map +1 -0
- package/dist/message-conversion/agui-to-gql.js +29 -9
- package/dist/message-conversion/agui-to-gql.js.map +1 -1
- package/dist/message-conversion/agui-to-gql.mjs +7 -7
- package/dist/message-conversion/agui-to-gql.test.js +133 -82
- package/dist/message-conversion/agui-to-gql.test.js.map +1 -1
- package/dist/message-conversion/agui-to-gql.test.mjs +55 -24
- package/dist/message-conversion/agui-to-gql.test.mjs.map +1 -1
- package/dist/message-conversion/gql-to-agui.js +12 -4
- package/dist/message-conversion/gql-to-agui.js.map +1 -1
- package/dist/message-conversion/gql-to-agui.mjs +7 -7
- package/dist/message-conversion/gql-to-agui.test.js +166 -85
- package/dist/message-conversion/gql-to-agui.test.js.map +1 -1
- package/dist/message-conversion/gql-to-agui.test.mjs +105 -32
- package/dist/message-conversion/gql-to-agui.test.mjs.map +1 -1
- package/dist/message-conversion/index.js +41 -13
- package/dist/message-conversion/index.js.map +1 -1
- package/dist/message-conversion/index.mjs +8 -8
- package/dist/message-conversion/roundtrip-conversion.test.js +149 -87
- package/dist/message-conversion/roundtrip-conversion.test.js.map +1 -1
- package/dist/message-conversion/roundtrip-conversion.test.mjs +60 -26
- package/dist/message-conversion/roundtrip-conversion.test.mjs.map +1 -1
- package/package.json +3 -4
- package/src/client/CopilotRuntimeClient.ts +21 -5
- package/src/client/conversion.ts +3 -1
- package/src/client/types.ts +34 -12
- package/src/graphql/@generated/gql.ts +3 -3
- package/src/graphql/definitions/mutations.ts +4 -1
- package/src/message-conversion/agui-to-gql.test.ts +49 -17
- package/src/message-conversion/agui-to-gql.ts +47 -15
- package/src/message-conversion/gql-to-agui.test.ts +101 -26
- package/src/message-conversion/gql-to-agui.ts +30 -11
- package/src/message-conversion/roundtrip-conversion.test.ts +53 -18
- package/tsconfig.json +1 -1
- package/dist/chunk-AMFKR5ST.mjs.map +0 -1
- package/dist/chunk-EIPAWDCN.mjs.map +0 -1
- package/dist/chunk-FTOMK35N.mjs.map +0 -1
- package/dist/chunk-KTA7QTTU.mjs.map +0 -1
- package/dist/chunk-L6PM6AT3.mjs.map +0 -1
- package/dist/chunk-M5LBGBWO.mjs +0 -20
- package/dist/chunk-M5LBGBWO.mjs.map +0 -1
- package/dist/chunk-NHOKFX55.mjs.map +0 -1
- package/dist/chunk-RNENVFJ3.mjs.map +0 -1
- package/dist/magic-string.es-26DP735G.mjs.map +0 -1
- /package/dist/{chunk-3ETRQN2E.mjs.map → chunk-QUH7QWUA.mjs.map} +0 -0
|
@@ -109,7 +109,10 @@ describe("agui-to-gql", () => {
|
|
|
109
109
|
},
|
|
110
110
|
};
|
|
111
111
|
|
|
112
|
-
const result = aguiToolCallToGQLActionExecution(
|
|
112
|
+
const result = aguiToolCallToGQLActionExecution(
|
|
113
|
+
toolCall,
|
|
114
|
+
"parent-message-id",
|
|
115
|
+
);
|
|
113
116
|
|
|
114
117
|
expect(result).toBeInstanceOf(gql.ActionExecutionMessage);
|
|
115
118
|
expect(result.id).toBe("tool-call-id");
|
|
@@ -128,9 +131,9 @@ describe("agui-to-gql", () => {
|
|
|
128
131
|
},
|
|
129
132
|
} as any;
|
|
130
133
|
|
|
131
|
-
expect(() =>
|
|
132
|
-
|
|
133
|
-
);
|
|
134
|
+
expect(() =>
|
|
135
|
+
aguiToolCallToGQLActionExecution(toolCall, "parent-id"),
|
|
136
|
+
).toThrow("Unsupported tool call type");
|
|
134
137
|
});
|
|
135
138
|
});
|
|
136
139
|
|
|
@@ -144,7 +147,10 @@ describe("agui-to-gql", () => {
|
|
|
144
147
|
};
|
|
145
148
|
|
|
146
149
|
const toolCallNames = { "tool-call-id": "testFunction" };
|
|
147
|
-
const result = aguiToolMessageToGQLResultMessage(
|
|
150
|
+
const result = aguiToolMessageToGQLResultMessage(
|
|
151
|
+
aguiMessage,
|
|
152
|
+
toolCallNames,
|
|
153
|
+
);
|
|
148
154
|
|
|
149
155
|
expect(result).toBeInstanceOf(gql.ResultMessage);
|
|
150
156
|
expect(result.id).toBe("tool-message-id");
|
|
@@ -186,7 +192,10 @@ describe("agui-to-gql", () => {
|
|
|
186
192
|
} as any;
|
|
187
193
|
|
|
188
194
|
const toolCallNames = { "tool-call-id": "testFunction" };
|
|
189
|
-
const result = aguiToolMessageToGQLResultMessage(
|
|
195
|
+
const result = aguiToolMessageToGQLResultMessage(
|
|
196
|
+
aguiMessage,
|
|
197
|
+
toolCallNames,
|
|
198
|
+
);
|
|
190
199
|
|
|
191
200
|
expect(result.result).toBe("");
|
|
192
201
|
expect(result.actionName).toBe("testFunction");
|
|
@@ -256,7 +265,9 @@ describe("agui-to-gql", () => {
|
|
|
256
265
|
|
|
257
266
|
expect(result[2]).toBeInstanceOf(gql.TextMessage);
|
|
258
267
|
expect(result[2].id).toBe("user-2");
|
|
259
|
-
expect((result[2] as gql.TextMessage).content).toBe(
|
|
268
|
+
expect((result[2] as gql.TextMessage).content).toBe(
|
|
269
|
+
"Another user message",
|
|
270
|
+
);
|
|
260
271
|
expect((result[2] as gql.TextMessage).role).toBe(gql.Role.User);
|
|
261
272
|
});
|
|
262
273
|
|
|
@@ -287,9 +298,15 @@ describe("agui-to-gql", () => {
|
|
|
287
298
|
|
|
288
299
|
expect(result[1]).toBeInstanceOf(gql.ActionExecutionMessage);
|
|
289
300
|
expect(result[1].id).toBe("tool-call-1");
|
|
290
|
-
expect((result[1] as gql.ActionExecutionMessage).name).toBe(
|
|
291
|
-
|
|
292
|
-
|
|
301
|
+
expect((result[1] as gql.ActionExecutionMessage).name).toBe(
|
|
302
|
+
"testFunction",
|
|
303
|
+
);
|
|
304
|
+
expect((result[1] as gql.ActionExecutionMessage).arguments).toEqual({
|
|
305
|
+
param: "value",
|
|
306
|
+
});
|
|
307
|
+
expect((result[1] as gql.ActionExecutionMessage).parentMessageId).toBe(
|
|
308
|
+
"assistant-1",
|
|
309
|
+
);
|
|
293
310
|
});
|
|
294
311
|
|
|
295
312
|
test("should handle multiple tool calls in assistant message", () => {
|
|
@@ -326,11 +343,15 @@ describe("agui-to-gql", () => {
|
|
|
326
343
|
|
|
327
344
|
expect(result[1]).toBeInstanceOf(gql.ActionExecutionMessage);
|
|
328
345
|
expect(result[1].id).toBe("tool-call-1");
|
|
329
|
-
expect((result[1] as gql.ActionExecutionMessage).name).toBe(
|
|
346
|
+
expect((result[1] as gql.ActionExecutionMessage).name).toBe(
|
|
347
|
+
"firstFunction",
|
|
348
|
+
);
|
|
330
349
|
|
|
331
350
|
expect(result[2]).toBeInstanceOf(gql.ActionExecutionMessage);
|
|
332
351
|
expect(result[2].id).toBe("tool-call-2");
|
|
333
|
-
expect((result[2] as gql.ActionExecutionMessage).name).toBe(
|
|
352
|
+
expect((result[2] as gql.ActionExecutionMessage).name).toBe(
|
|
353
|
+
"secondFunction",
|
|
354
|
+
);
|
|
334
355
|
});
|
|
335
356
|
|
|
336
357
|
test("should convert tool messages to result messages", () => {
|
|
@@ -349,7 +370,9 @@ describe("agui-to-gql", () => {
|
|
|
349
370
|
expect(result[0]).toBeInstanceOf(gql.ResultMessage);
|
|
350
371
|
expect(result[0].id).toBe("tool-1");
|
|
351
372
|
expect((result[0] as gql.ResultMessage).result).toBe("Tool result");
|
|
352
|
-
expect((result[0] as gql.ResultMessage).actionExecutionId).toBe(
|
|
373
|
+
expect((result[0] as gql.ResultMessage).actionExecutionId).toBe(
|
|
374
|
+
"tool-call-1",
|
|
375
|
+
);
|
|
353
376
|
});
|
|
354
377
|
|
|
355
378
|
test("should handle a mix of message types", () => {
|
|
@@ -502,7 +525,11 @@ describe("agui-to-gql", () => {
|
|
|
502
525
|
|
|
503
526
|
const coAgentStateRenders: Record<string, any> = {};
|
|
504
527
|
|
|
505
|
-
const result = aguiMessageWithRenderToGQL(
|
|
528
|
+
const result = aguiMessageWithRenderToGQL(
|
|
529
|
+
aguiMessage,
|
|
530
|
+
undefined,
|
|
531
|
+
coAgentStateRenders,
|
|
532
|
+
);
|
|
506
533
|
|
|
507
534
|
expect(result).toHaveLength(1);
|
|
508
535
|
expect(result[0]).toBeInstanceOf(gql.AgentStateMessage);
|
|
@@ -523,7 +550,9 @@ describe("agui-to-gql", () => {
|
|
|
523
550
|
|
|
524
551
|
expect(result).toHaveLength(1);
|
|
525
552
|
expect(result[0]).toBeInstanceOf(gql.TextMessage);
|
|
526
|
-
expect((result[0] as gql.TextMessage).content).toBe(
|
|
553
|
+
expect((result[0] as gql.TextMessage).content).toBe(
|
|
554
|
+
"Regular assistant message",
|
|
555
|
+
);
|
|
527
556
|
});
|
|
528
557
|
|
|
529
558
|
test("should handle non-assistant messages normally", () => {
|
|
@@ -588,7 +617,8 @@ describe("agui-to-gql", () => {
|
|
|
588
617
|
|
|
589
618
|
test("should verify render function receives correct props including name", () => {
|
|
590
619
|
const mockRender = vi.fn(
|
|
591
|
-
(props) =>
|
|
620
|
+
(props) =>
|
|
621
|
+
`Rendered: ${props.name} with args: ${JSON.stringify(props.args)}`,
|
|
592
622
|
);
|
|
593
623
|
const aguiMessage: agui.Message = {
|
|
594
624
|
id: "assistant-render-props",
|
|
@@ -1198,7 +1228,9 @@ describe("agui-to-gql", () => {
|
|
|
1198
1228
|
|
|
1199
1229
|
expect(result).toHaveLength(1);
|
|
1200
1230
|
expect(result[0]).toBeInstanceOf(gql.ResultMessage);
|
|
1201
|
-
expect((result[0] as any).result).toBe(
|
|
1231
|
+
expect((result[0] as any).result).toBe(
|
|
1232
|
+
'{"status":"success","data":{"value":42}}',
|
|
1233
|
+
);
|
|
1202
1234
|
expect((result[0] as any).actionExecutionId).toBe("tool-call-1");
|
|
1203
1235
|
expect((result[0] as any).actionName).toBe("testAction");
|
|
1204
1236
|
});
|
|
@@ -5,7 +5,9 @@ import agui from "@copilotkit/shared"; // named agui for clarity, but this only
|
|
|
5
5
|
// Helper function to extract agent name from message
|
|
6
6
|
function extractAgentName(message: agui.Message): string {
|
|
7
7
|
if (message.role !== "assistant") {
|
|
8
|
-
throw new Error(
|
|
8
|
+
throw new Error(
|
|
9
|
+
`Cannot extract agent name from message with role ${message.role}`,
|
|
10
|
+
);
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
return message.agentName || "unknown";
|
|
@@ -13,17 +15,21 @@ function extractAgentName(message: agui.Message): string {
|
|
|
13
15
|
|
|
14
16
|
// Type guard for agent state message
|
|
15
17
|
function isAgentStateMessage(message: agui.Message): boolean {
|
|
16
|
-
return
|
|
18
|
+
return (
|
|
19
|
+
message.role === "assistant" && "agentName" in message && "state" in message
|
|
20
|
+
);
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
// Type guard for messages with image property
|
|
20
24
|
function hasImageProperty(message: agui.Message): boolean {
|
|
21
|
-
const canContainImage =
|
|
25
|
+
const canContainImage =
|
|
26
|
+
message.role === "assistant" || message.role === "user";
|
|
22
27
|
if (!canContainImage || message.image === undefined) {
|
|
23
28
|
return false;
|
|
24
29
|
}
|
|
25
30
|
|
|
26
|
-
const isMalformed =
|
|
31
|
+
const isMalformed =
|
|
32
|
+
message.image.format === undefined || message.image.bytes === undefined;
|
|
27
33
|
if (isMalformed) {
|
|
28
34
|
return false;
|
|
29
35
|
}
|
|
@@ -61,7 +67,11 @@ export function aguiToGQL(
|
|
|
61
67
|
}),
|
|
62
68
|
);
|
|
63
69
|
// Optionally preserve render function
|
|
64
|
-
if (
|
|
70
|
+
if (
|
|
71
|
+
"generativeUI" in message &&
|
|
72
|
+
message.generativeUI &&
|
|
73
|
+
coAgentStateRenders
|
|
74
|
+
) {
|
|
65
75
|
coAgentStateRenders[agentName] = {
|
|
66
76
|
name: agentName,
|
|
67
77
|
render: message.generativeUI,
|
|
@@ -82,7 +92,10 @@ export function aguiToGQL(
|
|
|
82
92
|
// Track the tool call name by its ID
|
|
83
93
|
toolCallNames[toolCall.id] = toolCall.function.name;
|
|
84
94
|
|
|
85
|
-
const actionExecMsg = aguiToolCallToGQLActionExecution(
|
|
95
|
+
const actionExecMsg = aguiToolCallToGQLActionExecution(
|
|
96
|
+
toolCall,
|
|
97
|
+
message.id,
|
|
98
|
+
);
|
|
86
99
|
// Preserve render function in actions context
|
|
87
100
|
if ("generativeUI" in message && message.generativeUI && actions) {
|
|
88
101
|
const actionName = toolCall.function.name;
|
|
@@ -90,7 +103,9 @@ export function aguiToGQL(
|
|
|
90
103
|
const specificAction = Object.values(actions).find(
|
|
91
104
|
(action: any) => action.name === actionName,
|
|
92
105
|
);
|
|
93
|
-
const wildcardAction = Object.values(actions).find(
|
|
106
|
+
const wildcardAction = Object.values(actions).find(
|
|
107
|
+
(action: any) => action.name === "*",
|
|
108
|
+
);
|
|
94
109
|
|
|
95
110
|
// Assign render function to the matching action (specific takes priority)
|
|
96
111
|
if (specificAction) {
|
|
@@ -115,7 +130,9 @@ export function aguiToGQL(
|
|
|
115
130
|
}
|
|
116
131
|
// Tool result message
|
|
117
132
|
if (message.role === "tool") {
|
|
118
|
-
gqlMessages.push(
|
|
133
|
+
gqlMessages.push(
|
|
134
|
+
aguiToolMessageToGQLResultMessage(message, toolCallNames),
|
|
135
|
+
);
|
|
119
136
|
continue;
|
|
120
137
|
}
|
|
121
138
|
throw new Error(
|
|
@@ -126,14 +143,18 @@ export function aguiToGQL(
|
|
|
126
143
|
return gqlMessages;
|
|
127
144
|
}
|
|
128
145
|
|
|
129
|
-
export function aguiTextMessageToGQLMessage(
|
|
146
|
+
export function aguiTextMessageToGQLMessage(
|
|
147
|
+
message: agui.Message,
|
|
148
|
+
): gql.TextMessage {
|
|
130
149
|
if (
|
|
131
150
|
message.role !== "developer" &&
|
|
132
151
|
message.role !== "system" &&
|
|
133
152
|
message.role !== "assistant" &&
|
|
134
153
|
message.role !== "user"
|
|
135
154
|
) {
|
|
136
|
-
throw new Error(
|
|
155
|
+
throw new Error(
|
|
156
|
+
`Cannot convert message with role ${message.role} to TextMessage`,
|
|
157
|
+
);
|
|
137
158
|
}
|
|
138
159
|
|
|
139
160
|
let roleValue: MessageRole;
|
|
@@ -172,7 +193,10 @@ export function aguiToolCallToGQLActionExecution(
|
|
|
172
193
|
try {
|
|
173
194
|
argumentsObj = JSON.parse(toolCall.function.arguments);
|
|
174
195
|
} catch (error) {
|
|
175
|
-
console.warn(
|
|
196
|
+
console.warn(
|
|
197
|
+
`Failed to parse tool call arguments for ${toolCall.function.name}:`,
|
|
198
|
+
error,
|
|
199
|
+
);
|
|
176
200
|
// Provide fallback empty object to prevent application crash
|
|
177
201
|
argumentsObj = {};
|
|
178
202
|
}
|
|
@@ -205,7 +229,9 @@ export function aguiToolMessageToGQLResultMessage(
|
|
|
205
229
|
toolCallNames: Record<string, string>,
|
|
206
230
|
): gql.ResultMessage {
|
|
207
231
|
if (message.role !== "tool") {
|
|
208
|
-
throw new Error(
|
|
232
|
+
throw new Error(
|
|
233
|
+
`Cannot convert message with role ${message.role} to ResultMessage`,
|
|
234
|
+
);
|
|
209
235
|
}
|
|
210
236
|
|
|
211
237
|
if (!message.toolCallId) {
|
|
@@ -277,9 +303,13 @@ export function aguiMessageWithRenderToGQL(
|
|
|
277
303
|
return aguiToGQL([message], actions, coAgentStateRenders);
|
|
278
304
|
}
|
|
279
305
|
|
|
280
|
-
export function aguiMessageWithImageToGQLMessage(
|
|
306
|
+
export function aguiMessageWithImageToGQLMessage(
|
|
307
|
+
message: agui.Message,
|
|
308
|
+
): gql.ImageMessage {
|
|
281
309
|
if (!hasImageProperty(message)) {
|
|
282
|
-
throw new Error(
|
|
310
|
+
throw new Error(
|
|
311
|
+
`Cannot convert message to ImageMessage: missing format or bytes`,
|
|
312
|
+
);
|
|
283
313
|
}
|
|
284
314
|
|
|
285
315
|
let roleValue: MessageRole;
|
|
@@ -290,7 +320,9 @@ export function aguiMessageWithImageToGQLMessage(message: agui.Message): gql.Ima
|
|
|
290
320
|
}
|
|
291
321
|
|
|
292
322
|
if (message.role !== "assistant" && message.role !== "user") {
|
|
293
|
-
throw new Error(
|
|
323
|
+
throw new Error(
|
|
324
|
+
`Cannot convert message with role ${message.role} to ImageMessage`,
|
|
325
|
+
);
|
|
294
326
|
}
|
|
295
327
|
|
|
296
328
|
return new gql.ImageMessage({
|
|
@@ -67,7 +67,9 @@ describe("message-conversion", () => {
|
|
|
67
67
|
role: "unknown" as any,
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
-
expect(() => gqlTextMessageToAGUIMessage(gqlMessage)).toThrow(
|
|
70
|
+
expect(() => gqlTextMessageToAGUIMessage(gqlMessage)).toThrow(
|
|
71
|
+
"Unknown message role",
|
|
72
|
+
);
|
|
71
73
|
});
|
|
72
74
|
});
|
|
73
75
|
|
|
@@ -371,7 +373,8 @@ describe("message-conversion", () => {
|
|
|
371
373
|
});
|
|
372
374
|
|
|
373
375
|
const mockRender = vi.fn();
|
|
374
|
-
const mockRenderAndWaitForResponse = (props: any) =>
|
|
376
|
+
const mockRenderAndWaitForResponse = (props: any) =>
|
|
377
|
+
"Test Render With Response";
|
|
375
378
|
|
|
376
379
|
const actions = {
|
|
377
380
|
testAction: {
|
|
@@ -494,7 +497,9 @@ describe("message-conversion", () => {
|
|
|
494
497
|
const result = gqlToAGUI([actionExecMsg, resultMsg], actions);
|
|
495
498
|
|
|
496
499
|
// Find the action execution message result (not the tool result)
|
|
497
|
-
const actionMessage = result.find(
|
|
500
|
+
const actionMessage = result.find(
|
|
501
|
+
(msg) => msg.role === "assistant" && "toolCalls" in msg,
|
|
502
|
+
);
|
|
498
503
|
|
|
499
504
|
// Call the generativeUI function
|
|
500
505
|
(actionMessage as any)?.generativeUI?.();
|
|
@@ -748,7 +753,11 @@ describe("message-conversion", () => {
|
|
|
748
753
|
},
|
|
749
754
|
};
|
|
750
755
|
|
|
751
|
-
const result = gqlToAGUI(
|
|
756
|
+
const result = gqlToAGUI(
|
|
757
|
+
[textMsg, agentStateMsg],
|
|
758
|
+
undefined,
|
|
759
|
+
coAgentStateRenders,
|
|
760
|
+
);
|
|
752
761
|
|
|
753
762
|
expect(result).toHaveLength(2);
|
|
754
763
|
expect(result[0]).toEqual({
|
|
@@ -775,7 +784,9 @@ describe("message-conversion", () => {
|
|
|
775
784
|
bytes: "somebase64string",
|
|
776
785
|
role: gql.Role.User,
|
|
777
786
|
});
|
|
778
|
-
expect(() => gqlImageMessageToAGUIMessage(invalidImageMsg)).toThrow(
|
|
787
|
+
expect(() => gqlImageMessageToAGUIMessage(invalidImageMsg)).toThrow(
|
|
788
|
+
"Invalid image format",
|
|
789
|
+
);
|
|
779
790
|
});
|
|
780
791
|
|
|
781
792
|
test("should throw error for empty image bytes", () => {
|
|
@@ -864,7 +875,10 @@ describe("message-conversion", () => {
|
|
|
864
875
|
parentMessageId: "parent-1",
|
|
865
876
|
});
|
|
866
877
|
|
|
867
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
878
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
879
|
+
actionExecMsg,
|
|
880
|
+
actions,
|
|
881
|
+
);
|
|
868
882
|
|
|
869
883
|
expect(result).toMatchObject({
|
|
870
884
|
id: "action-1",
|
|
@@ -900,7 +914,10 @@ describe("message-conversion", () => {
|
|
|
900
914
|
parentMessageId: "parent-2",
|
|
901
915
|
});
|
|
902
916
|
|
|
903
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
917
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
918
|
+
actionExecMsg,
|
|
919
|
+
actions,
|
|
920
|
+
);
|
|
904
921
|
|
|
905
922
|
expect(result).toMatchObject({
|
|
906
923
|
id: "action-2",
|
|
@@ -923,7 +940,8 @@ describe("message-conversion", () => {
|
|
|
923
940
|
|
|
924
941
|
test("should pass tool name to wildcard action render function", () => {
|
|
925
942
|
const mockRender = vi.fn(
|
|
926
|
-
(props) =>
|
|
943
|
+
(props) =>
|
|
944
|
+
`Wildcard rendered: ${props.name} with args: ${JSON.stringify(props.args)}`,
|
|
927
945
|
);
|
|
928
946
|
const actions = {
|
|
929
947
|
"*": {
|
|
@@ -939,7 +957,10 @@ describe("message-conversion", () => {
|
|
|
939
957
|
parentMessageId: "parent-wildcard-name",
|
|
940
958
|
});
|
|
941
959
|
|
|
942
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
960
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
961
|
+
actionExecMsg,
|
|
962
|
+
actions,
|
|
963
|
+
);
|
|
943
964
|
|
|
944
965
|
// Call the generativeUI function to trigger the render
|
|
945
966
|
(result as any).generativeUI?.();
|
|
@@ -954,7 +975,9 @@ describe("message-conversion", () => {
|
|
|
954
975
|
});
|
|
955
976
|
|
|
956
977
|
test("should pass tool name to regular action render function", () => {
|
|
957
|
-
const mockRender = vi.fn(
|
|
978
|
+
const mockRender = vi.fn(
|
|
979
|
+
(props) => `Regular action rendered: ${JSON.stringify(props.args)}`,
|
|
980
|
+
);
|
|
958
981
|
const actions = {
|
|
959
982
|
testAction: {
|
|
960
983
|
name: "testAction",
|
|
@@ -969,7 +992,10 @@ describe("message-conversion", () => {
|
|
|
969
992
|
parentMessageId: "parent-regular-name",
|
|
970
993
|
});
|
|
971
994
|
|
|
972
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
995
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
996
|
+
actionExecMsg,
|
|
997
|
+
actions,
|
|
998
|
+
);
|
|
973
999
|
|
|
974
1000
|
// Call the generativeUI function to trigger the render
|
|
975
1001
|
(result as any).generativeUI?.();
|
|
@@ -1007,7 +1033,10 @@ describe("message-conversion", () => {
|
|
|
1007
1033
|
parentMessageId: "parent-3",
|
|
1008
1034
|
});
|
|
1009
1035
|
|
|
1010
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1036
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1037
|
+
actionExecMsg,
|
|
1038
|
+
actions,
|
|
1039
|
+
);
|
|
1011
1040
|
|
|
1012
1041
|
expect(result).toMatchObject({
|
|
1013
1042
|
id: "action-3",
|
|
@@ -1043,7 +1072,10 @@ describe("message-conversion", () => {
|
|
|
1043
1072
|
parentMessageId: "parent-4",
|
|
1044
1073
|
});
|
|
1045
1074
|
|
|
1046
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1075
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1076
|
+
actionExecMsg,
|
|
1077
|
+
actions,
|
|
1078
|
+
);
|
|
1047
1079
|
|
|
1048
1080
|
expect(result).toMatchObject({
|
|
1049
1081
|
id: "action-4",
|
|
@@ -1108,7 +1140,11 @@ describe("message-conversion", () => {
|
|
|
1108
1140
|
|
|
1109
1141
|
const actionResults = new Map([["action-6", "completed result"]]);
|
|
1110
1142
|
|
|
1111
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1143
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1144
|
+
actionExecMsg,
|
|
1145
|
+
actions,
|
|
1146
|
+
actionResults,
|
|
1147
|
+
);
|
|
1112
1148
|
|
|
1113
1149
|
expect(result).toMatchObject({
|
|
1114
1150
|
id: "action-6",
|
|
@@ -1145,7 +1181,10 @@ describe("message-conversion", () => {
|
|
|
1145
1181
|
status: { code: MessageStatusCode.Success },
|
|
1146
1182
|
});
|
|
1147
1183
|
|
|
1148
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1184
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1185
|
+
actionExecMsg,
|
|
1186
|
+
actions,
|
|
1187
|
+
);
|
|
1149
1188
|
|
|
1150
1189
|
expect(result).toMatchObject({
|
|
1151
1190
|
id: "action-7",
|
|
@@ -1182,7 +1221,10 @@ describe("message-conversion", () => {
|
|
|
1182
1221
|
status: { code: MessageStatusCode.Pending },
|
|
1183
1222
|
});
|
|
1184
1223
|
|
|
1185
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1224
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1225
|
+
actionExecMsg,
|
|
1226
|
+
actions,
|
|
1227
|
+
);
|
|
1186
1228
|
|
|
1187
1229
|
expect(result).toMatchObject({
|
|
1188
1230
|
id: "action-8",
|
|
@@ -1219,7 +1261,10 @@ describe("message-conversion", () => {
|
|
|
1219
1261
|
status: { code: MessageStatusCode.Failed },
|
|
1220
1262
|
});
|
|
1221
1263
|
|
|
1222
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1264
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1265
|
+
actionExecMsg,
|
|
1266
|
+
actions,
|
|
1267
|
+
);
|
|
1223
1268
|
|
|
1224
1269
|
expect(result).toMatchObject({
|
|
1225
1270
|
id: "action-9",
|
|
@@ -1256,7 +1301,10 @@ describe("message-conversion", () => {
|
|
|
1256
1301
|
// No status field
|
|
1257
1302
|
});
|
|
1258
1303
|
|
|
1259
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1304
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1305
|
+
actionExecMsg,
|
|
1306
|
+
actions,
|
|
1307
|
+
);
|
|
1260
1308
|
|
|
1261
1309
|
expect(result).toMatchObject({
|
|
1262
1310
|
id: "action-10",
|
|
@@ -1292,7 +1340,10 @@ describe("message-conversion", () => {
|
|
|
1292
1340
|
parentMessageId: "parent-11",
|
|
1293
1341
|
});
|
|
1294
1342
|
|
|
1295
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1343
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1344
|
+
actionExecMsg,
|
|
1345
|
+
actions,
|
|
1346
|
+
);
|
|
1296
1347
|
|
|
1297
1348
|
expect(result).toMatchObject({
|
|
1298
1349
|
id: "action-11",
|
|
@@ -1328,7 +1379,10 @@ describe("message-conversion", () => {
|
|
|
1328
1379
|
parentMessageId: "parent-12",
|
|
1329
1380
|
});
|
|
1330
1381
|
|
|
1331
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1382
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1383
|
+
actionExecMsg,
|
|
1384
|
+
actions,
|
|
1385
|
+
);
|
|
1332
1386
|
|
|
1333
1387
|
expect(result).toMatchObject({
|
|
1334
1388
|
id: "action-12",
|
|
@@ -1376,7 +1430,10 @@ describe("message-conversion", () => {
|
|
|
1376
1430
|
parentMessageId: "parent-13",
|
|
1377
1431
|
});
|
|
1378
1432
|
|
|
1379
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1433
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1434
|
+
actionExecMsg,
|
|
1435
|
+
actions,
|
|
1436
|
+
);
|
|
1380
1437
|
|
|
1381
1438
|
expect(result).toMatchObject({
|
|
1382
1439
|
id: "action-13",
|
|
@@ -1416,7 +1473,10 @@ describe("message-conversion", () => {
|
|
|
1416
1473
|
parentMessageId: "parent-14",
|
|
1417
1474
|
});
|
|
1418
1475
|
|
|
1419
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1476
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1477
|
+
actionExecMsg,
|
|
1478
|
+
actions,
|
|
1479
|
+
);
|
|
1420
1480
|
|
|
1421
1481
|
expect(result).toMatchObject({
|
|
1422
1482
|
id: "action-14",
|
|
@@ -1453,9 +1513,16 @@ describe("message-conversion", () => {
|
|
|
1453
1513
|
});
|
|
1454
1514
|
|
|
1455
1515
|
const actionResults = new Map<string, string>();
|
|
1456
|
-
actionResults.set(
|
|
1516
|
+
actionResults.set(
|
|
1517
|
+
"action-string-result",
|
|
1518
|
+
'{"parsed": true, "value": 42}',
|
|
1519
|
+
);
|
|
1457
1520
|
|
|
1458
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1521
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1522
|
+
actionExecMsg,
|
|
1523
|
+
actions,
|
|
1524
|
+
actionResults,
|
|
1525
|
+
);
|
|
1459
1526
|
|
|
1460
1527
|
expect((result as AIMessage).generativeUI).toBeDefined();
|
|
1461
1528
|
// Call the render function to test the result parsing
|
|
@@ -1492,7 +1559,11 @@ describe("message-conversion", () => {
|
|
|
1492
1559
|
const actionResults = new Map<string, string>();
|
|
1493
1560
|
actionResults.set("action-malformed", "invalid json {");
|
|
1494
1561
|
|
|
1495
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1562
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1563
|
+
actionExecMsg,
|
|
1564
|
+
actions,
|
|
1565
|
+
actionResults,
|
|
1566
|
+
);
|
|
1496
1567
|
|
|
1497
1568
|
expect((result as AIMessage).generativeUI).toBeDefined();
|
|
1498
1569
|
// Call the render function to test malformed JSON handling
|
|
@@ -1529,7 +1600,11 @@ describe("message-conversion", () => {
|
|
|
1529
1600
|
const actionResults = new Map<string, string>();
|
|
1530
1601
|
actionResults.set("action-object-result", '{"already": "parsed"}');
|
|
1531
1602
|
|
|
1532
|
-
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1603
|
+
const result = gqlActionExecutionMessageToAGUIMessage(
|
|
1604
|
+
actionExecMsg,
|
|
1605
|
+
actions,
|
|
1606
|
+
actionResults,
|
|
1607
|
+
);
|
|
1533
1608
|
|
|
1534
1609
|
expect((result as AIMessage).generativeUI).toBeDefined();
|
|
1535
1610
|
// Call the render function with an object result
|
|
@@ -38,9 +38,13 @@ export function gqlToAGUI(
|
|
|
38
38
|
} else if (message.isResultMessage()) {
|
|
39
39
|
aguiMessages.push(gqlResultMessageToAGUIMessage(message));
|
|
40
40
|
} else if (message.isActionExecutionMessage()) {
|
|
41
|
-
aguiMessages.push(
|
|
41
|
+
aguiMessages.push(
|
|
42
|
+
gqlActionExecutionMessageToAGUIMessage(message, actions, actionResults),
|
|
43
|
+
);
|
|
42
44
|
} else if (message.isAgentStateMessage()) {
|
|
43
|
-
aguiMessages.push(
|
|
45
|
+
aguiMessages.push(
|
|
46
|
+
gqlAgentStateMessageToAGUIMessage(message, coAgentStateRenders),
|
|
47
|
+
);
|
|
44
48
|
} else if (message.isImageMessage()) {
|
|
45
49
|
aguiMessages.push(gqlImageMessageToAGUIMessage(message));
|
|
46
50
|
} else {
|
|
@@ -58,9 +62,11 @@ export function gqlActionExecutionMessageToAGUIMessage(
|
|
|
58
62
|
): agui.Message {
|
|
59
63
|
// Check if we have actions and if there's a specific action or wild card action
|
|
60
64
|
const hasSpecificAction =
|
|
61
|
-
actions &&
|
|
65
|
+
actions &&
|
|
66
|
+
Object.values(actions).some((action: any) => action.name === message.name);
|
|
62
67
|
const hasWildcardAction =
|
|
63
|
-
actions &&
|
|
68
|
+
actions &&
|
|
69
|
+
Object.values(actions).some((action: any) => action.name === "*");
|
|
64
70
|
|
|
65
71
|
if (!actions || (!hasSpecificAction && !hasWildcardAction)) {
|
|
66
72
|
return {
|
|
@@ -73,8 +79,9 @@ export function gqlActionExecutionMessageToAGUIMessage(
|
|
|
73
79
|
|
|
74
80
|
// Find the specific action first, then fall back to wild card action
|
|
75
81
|
const action =
|
|
76
|
-
Object.values(actions).find(
|
|
77
|
-
|
|
82
|
+
Object.values(actions).find(
|
|
83
|
+
(action: any) => action.name === message.name,
|
|
84
|
+
) || Object.values(actions).find((action: any) => action.name === "*");
|
|
78
85
|
|
|
79
86
|
// Create render function wrapper that provides proper props
|
|
80
87
|
const createRenderWrapper = (originalRender: any) => {
|
|
@@ -153,7 +160,9 @@ function gqlAgentStateMessageToAGUIMessage(
|
|
|
153
160
|
): agui.Message {
|
|
154
161
|
if (
|
|
155
162
|
coAgentStateRenders &&
|
|
156
|
-
Object.values(coAgentStateRenders).some(
|
|
163
|
+
Object.values(coAgentStateRenders).some(
|
|
164
|
+
(render: any) => render.name === message.agentName,
|
|
165
|
+
)
|
|
157
166
|
) {
|
|
158
167
|
const render = Object.values(coAgentStateRenders).find(
|
|
159
168
|
(render: any) => render.name === message.agentName,
|
|
@@ -206,7 +215,9 @@ function actionExecutionMessageToAGUIMessage(
|
|
|
206
215
|
};
|
|
207
216
|
}
|
|
208
217
|
|
|
209
|
-
export function gqlTextMessageToAGUIMessage(
|
|
218
|
+
export function gqlTextMessageToAGUIMessage(
|
|
219
|
+
message: gql.TextMessage,
|
|
220
|
+
): agui.Message {
|
|
210
221
|
switch (message.role) {
|
|
211
222
|
case gql.Role.Developer:
|
|
212
223
|
return {
|
|
@@ -237,7 +248,9 @@ export function gqlTextMessageToAGUIMessage(message: gql.TextMessage): agui.Mess
|
|
|
237
248
|
}
|
|
238
249
|
}
|
|
239
250
|
|
|
240
|
-
export function gqlResultMessageToAGUIMessage(
|
|
251
|
+
export function gqlResultMessageToAGUIMessage(
|
|
252
|
+
message: gql.ResultMessage,
|
|
253
|
+
): agui.Message {
|
|
241
254
|
return {
|
|
242
255
|
id: message.id,
|
|
243
256
|
role: "tool",
|
|
@@ -247,7 +260,9 @@ export function gqlResultMessageToAGUIMessage(message: gql.ResultMessage): agui.
|
|
|
247
260
|
};
|
|
248
261
|
}
|
|
249
262
|
|
|
250
|
-
export function gqlImageMessageToAGUIMessage(
|
|
263
|
+
export function gqlImageMessageToAGUIMessage(
|
|
264
|
+
message: gql.ImageMessage,
|
|
265
|
+
): agui.Message {
|
|
251
266
|
// Validate image format
|
|
252
267
|
if (!validateImageFormat(message.format)) {
|
|
253
268
|
throw new Error(
|
|
@@ -256,7 +271,11 @@ export function gqlImageMessageToAGUIMessage(message: gql.ImageMessage): agui.Me
|
|
|
256
271
|
}
|
|
257
272
|
|
|
258
273
|
// Validate that bytes is a non-empty string
|
|
259
|
-
if (
|
|
274
|
+
if (
|
|
275
|
+
!message.bytes ||
|
|
276
|
+
typeof message.bytes !== "string" ||
|
|
277
|
+
message.bytes.trim() === ""
|
|
278
|
+
) {
|
|
260
279
|
throw new Error("Image bytes must be a non-empty string");
|
|
261
280
|
}
|
|
262
281
|
|