@copilotkit/runtime-client-gql 1.10.0 → 1.10.1-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/{chunk-PAQ6AHHC.mjs → chunk-5V6B3OXS.mjs} +2 -2
- package/dist/{chunk-PAQ6AHHC.mjs.map → chunk-5V6B3OXS.mjs.map} +1 -1
- package/dist/{chunk-YNQMTL2P.mjs → chunk-SCACOKQX.mjs} +38 -8
- package/dist/chunk-SCACOKQX.mjs.map +1 -0
- package/dist/{chunk-MTD2RJDJ.mjs → chunk-ZYA32QXZ.mjs} +44 -29
- package/dist/chunk-ZYA32QXZ.mjs.map +1 -0
- package/dist/client/CopilotRuntimeClient.js +1 -1
- package/dist/client/CopilotRuntimeClient.js.map +1 -1
- package/dist/client/CopilotRuntimeClient.mjs +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +82 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -3
- package/dist/message-conversion/agui-to-gql.js +37 -7
- package/dist/message-conversion/agui-to-gql.js.map +1 -1
- package/dist/message-conversion/agui-to-gql.mjs +2 -2
- package/dist/message-conversion/agui-to-gql.test.js +529 -7
- package/dist/message-conversion/agui-to-gql.test.js.map +1 -1
- package/dist/message-conversion/agui-to-gql.test.mjs +494 -2
- package/dist/message-conversion/agui-to-gql.test.mjs.map +1 -1
- package/dist/message-conversion/gql-to-agui.d.ts +3 -2
- package/dist/message-conversion/gql-to-agui.js +44 -28
- package/dist/message-conversion/gql-to-agui.js.map +1 -1
- package/dist/message-conversion/gql-to-agui.mjs +4 -2
- package/dist/message-conversion/gql-to-agui.test.js +622 -28
- package/dist/message-conversion/gql-to-agui.test.js.map +1 -1
- package/dist/message-conversion/gql-to-agui.test.mjs +583 -2
- package/dist/message-conversion/gql-to-agui.test.mjs.map +1 -1
- package/dist/message-conversion/index.d.ts +1 -1
- package/dist/message-conversion/index.js +81 -35
- package/dist/message-conversion/index.js.map +1 -1
- package/dist/message-conversion/index.mjs +5 -3
- package/dist/message-conversion/roundtrip-conversion.test.js +250 -35
- package/dist/message-conversion/roundtrip-conversion.test.js.map +1 -1
- package/dist/message-conversion/roundtrip-conversion.test.mjs +174 -3
- package/dist/message-conversion/roundtrip-conversion.test.mjs.map +1 -1
- package/package.json +3 -3
- package/src/message-conversion/agui-to-gql.test.ts +566 -0
- package/src/message-conversion/agui-to-gql.ts +56 -9
- package/src/message-conversion/gql-to-agui.test.ts +663 -0
- package/src/message-conversion/gql-to-agui.ts +62 -35
- package/src/message-conversion/roundtrip-conversion.test.ts +228 -0
- package/dist/chunk-MTD2RJDJ.mjs.map +0 -1
- package/dist/chunk-YNQMTL2P.mjs.map +0 -1
|
@@ -51,59 +51,86 @@ export function gqlToAGUI(
|
|
|
51
51
|
return aguiMessages;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
function gqlActionExecutionMessageToAGUIMessage(
|
|
54
|
+
export function gqlActionExecutionMessageToAGUIMessage(
|
|
55
55
|
message: gql.ActionExecutionMessage,
|
|
56
56
|
actions?: Record<string, any>,
|
|
57
57
|
actionResults?: Map<string, string>,
|
|
58
58
|
): agui.Message {
|
|
59
|
-
if
|
|
60
|
-
|
|
59
|
+
// Check if we have actions and if there's a specific action or wild card action
|
|
60
|
+
const hasSpecificAction =
|
|
61
|
+
actions && Object.values(actions).some((action: any) => action.name === message.name);
|
|
62
|
+
const hasWildcardAction =
|
|
63
|
+
actions && Object.values(actions).some((action: any) => action.name === "*");
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
if (!actions || (!hasSpecificAction && !hasWildcardAction)) {
|
|
66
|
+
return {
|
|
67
|
+
id: message.id,
|
|
68
|
+
role: "assistant",
|
|
69
|
+
toolCalls: [actionExecutionMessageToAGUIMessage(message)],
|
|
70
|
+
name: message.name,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
65
73
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
// Find the specific action first, then fall back to wild card action
|
|
75
|
+
const action =
|
|
76
|
+
Object.values(actions).find((action: any) => action.name === message.name) ||
|
|
77
|
+
Object.values(actions).find((action: any) => action.name === "*");
|
|
70
78
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
79
|
+
// Create render function wrapper that provides proper props
|
|
80
|
+
const createRenderWrapper = (originalRender: any) => {
|
|
81
|
+
if (!originalRender) return undefined;
|
|
82
|
+
|
|
83
|
+
return (props?: any) => {
|
|
84
|
+
// Determine the correct status based on the same logic as RenderActionExecutionMessage
|
|
85
|
+
let actionResult: any = actionResults?.get(message.id);
|
|
86
|
+
let status: "inProgress" | "executing" | "complete" = "inProgress";
|
|
87
|
+
|
|
88
|
+
if (actionResult !== undefined) {
|
|
89
|
+
status = "complete";
|
|
90
|
+
} else if (message.status?.code !== MessageStatusCode.Pending) {
|
|
91
|
+
status = "executing";
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// if props.result is a string, parse it as JSON but don't throw an error if it's not valid JSON
|
|
95
|
+
if (typeof props?.result === "string") {
|
|
96
|
+
try {
|
|
97
|
+
props.result = JSON.parse(props.result);
|
|
98
|
+
} catch (e) {
|
|
99
|
+
/* do nothing */
|
|
75
100
|
}
|
|
101
|
+
}
|
|
76
102
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
};
|
|
103
|
+
// if actionResult is a string, parse it as JSON but don't throw an error if it's not valid JSON
|
|
104
|
+
if (typeof actionResult === "string") {
|
|
105
|
+
try {
|
|
106
|
+
actionResult = JSON.parse(actionResult);
|
|
107
|
+
} catch (e) {
|
|
108
|
+
/* do nothing */
|
|
109
|
+
}
|
|
110
|
+
}
|
|
86
111
|
|
|
87
|
-
|
|
112
|
+
// Provide the full props structure that the render function expects
|
|
113
|
+
const renderProps = {
|
|
114
|
+
status: props?.status || status,
|
|
115
|
+
args: message.arguments || {},
|
|
116
|
+
result: props?.result || actionResult || undefined,
|
|
117
|
+
respond: props?.respond || (() => {}),
|
|
118
|
+
messageId: message.id,
|
|
119
|
+
...props,
|
|
88
120
|
};
|
|
89
|
-
};
|
|
90
121
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
content: "",
|
|
95
|
-
toolCalls: [actionExecutionMessageToAGUIMessage(message)],
|
|
96
|
-
generativeUI: createRenderWrapper(action.render),
|
|
97
|
-
name: message.name,
|
|
98
|
-
} as agui.AIMessage;
|
|
99
|
-
}
|
|
122
|
+
return originalRender(renderProps);
|
|
123
|
+
};
|
|
124
|
+
};
|
|
100
125
|
|
|
101
126
|
return {
|
|
102
127
|
id: message.id,
|
|
103
128
|
role: "assistant",
|
|
129
|
+
content: "",
|
|
104
130
|
toolCalls: [actionExecutionMessageToAGUIMessage(message)],
|
|
131
|
+
generativeUI: createRenderWrapper(action.render),
|
|
105
132
|
name: message.name,
|
|
106
|
-
};
|
|
133
|
+
} as agui.AIMessage;
|
|
107
134
|
}
|
|
108
135
|
|
|
109
136
|
function gqlAgentStateMessageToAGUIMessage(
|
|
@@ -209,4 +209,232 @@ describe("roundtrip message conversion", () => {
|
|
|
209
209
|
expect((aguiUserMsgs2[0] as any).image.format).toBe("png");
|
|
210
210
|
expect((aguiUserMsgs2[0] as any).image.bytes).toBe("userbase64data");
|
|
211
211
|
});
|
|
212
|
+
|
|
213
|
+
test("wild card action roundtrip conversion", () => {
|
|
214
|
+
const mockRender = vi.fn((props) => `Wildcard rendered: ${props.args.test}`);
|
|
215
|
+
const aguiMsg: agui.Message = {
|
|
216
|
+
id: "assistant-wildcard-1",
|
|
217
|
+
role: "assistant",
|
|
218
|
+
content: "Running wild card action",
|
|
219
|
+
toolCalls: [
|
|
220
|
+
{
|
|
221
|
+
id: "tool-call-wildcard-1",
|
|
222
|
+
type: "function",
|
|
223
|
+
function: {
|
|
224
|
+
name: "unknownAction",
|
|
225
|
+
arguments: JSON.stringify({ test: "wildcard-value" }),
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
],
|
|
229
|
+
generativeUI: mockRender,
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const actions: Record<string, any> = {
|
|
233
|
+
"*": { name: "*" },
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
// AGUI -> GQL -> AGUI roundtrip
|
|
237
|
+
const gqlMsgs = aguiToGQL(aguiMsg, actions);
|
|
238
|
+
const aguiMsgs2 = gqlToAGUI(gqlMsgs, actions);
|
|
239
|
+
|
|
240
|
+
// Verify the wild card action preserved the render function
|
|
241
|
+
expect(typeof actions["*"].render).toBe("function");
|
|
242
|
+
expect(actions["*"].render).toBe(mockRender);
|
|
243
|
+
|
|
244
|
+
// Verify the roundtripped message structure
|
|
245
|
+
expect(aguiMsgs2).toHaveLength(2);
|
|
246
|
+
expect(aguiMsgs2[0].role).toBe("assistant");
|
|
247
|
+
expect(aguiMsgs2[1].role).toBe("assistant");
|
|
248
|
+
|
|
249
|
+
// Check that the tool call is preserved
|
|
250
|
+
if ("toolCalls" in aguiMsgs2[1]) {
|
|
251
|
+
expect((aguiMsgs2[1] as any).toolCalls[0].function.name).toBe("unknownAction");
|
|
252
|
+
expect((aguiMsgs2[1] as any).toolCalls[0].function.arguments).toBe(
|
|
253
|
+
'{"test":"wildcard-value"}',
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
test("wild card action with specific action priority roundtrip", () => {
|
|
259
|
+
const mockRender = vi.fn((props) => `Specific action rendered: ${props.args.test}`);
|
|
260
|
+
const aguiMsg: agui.Message = {
|
|
261
|
+
id: "assistant-priority-1",
|
|
262
|
+
role: "assistant",
|
|
263
|
+
content: "Running specific action",
|
|
264
|
+
toolCalls: [
|
|
265
|
+
{
|
|
266
|
+
id: "tool-call-priority-1",
|
|
267
|
+
type: "function",
|
|
268
|
+
function: {
|
|
269
|
+
name: "specificAction",
|
|
270
|
+
arguments: JSON.stringify({ test: "specific-value" }),
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
generativeUI: mockRender,
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const actions: Record<string, any> = {
|
|
278
|
+
specificAction: { name: "specificAction" },
|
|
279
|
+
"*": { name: "*" },
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
// AGUI -> GQL -> AGUI roundtrip
|
|
283
|
+
const gqlMsgs = aguiToGQL(aguiMsg, actions);
|
|
284
|
+
const aguiMsgs2 = gqlToAGUI(gqlMsgs, actions);
|
|
285
|
+
|
|
286
|
+
// Verify the specific action preserved the render function (not wild card)
|
|
287
|
+
expect(typeof actions.specificAction.render).toBe("function");
|
|
288
|
+
expect(actions.specificAction.render).toBe(mockRender);
|
|
289
|
+
expect(actions["*"].render).toBeUndefined();
|
|
290
|
+
|
|
291
|
+
// Verify the roundtripped message structure
|
|
292
|
+
expect(aguiMsgs2).toHaveLength(2);
|
|
293
|
+
expect(aguiMsgs2[0].role).toBe("assistant");
|
|
294
|
+
expect(aguiMsgs2[1].role).toBe("assistant");
|
|
295
|
+
|
|
296
|
+
// Check that the tool call is preserved
|
|
297
|
+
if ("toolCalls" in aguiMsgs2[1]) {
|
|
298
|
+
expect((aguiMsgs2[1] as any).toolCalls[0].function.name).toBe("specificAction");
|
|
299
|
+
expect((aguiMsgs2[1] as any).toolCalls[0].function.arguments).toBe(
|
|
300
|
+
'{"test":"specific-value"}',
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
test("wild card action GQL -> AGUI -> GQL roundtrip", () => {
|
|
306
|
+
const actionExecMsg = new gql.ActionExecutionMessage({
|
|
307
|
+
id: "wildcard-action-1",
|
|
308
|
+
name: "unknownAction",
|
|
309
|
+
arguments: { test: "wildcard-gql-value" },
|
|
310
|
+
parentMessageId: "assistant-1",
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
const actions: Record<string, any> = {
|
|
314
|
+
"*": {
|
|
315
|
+
name: "*",
|
|
316
|
+
render: vi.fn((props) => `GQL wildcard rendered: ${props.args.test}`),
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
// GQL -> AGUI -> GQL roundtrip
|
|
321
|
+
const aguiMsgs = gqlToAGUI([actionExecMsg], actions);
|
|
322
|
+
const gqlMsgs2 = aguiToGQL(aguiMsgs, actions);
|
|
323
|
+
|
|
324
|
+
// When converting ActionExecutionMessage to AGUI and back, we get:
|
|
325
|
+
// 1. A TextMessage (assistant message with toolCalls)
|
|
326
|
+
// 2. An ActionExecutionMessage (the tool call itself)
|
|
327
|
+
expect(gqlMsgs2).toHaveLength(2);
|
|
328
|
+
expect(gqlMsgs2[0].id).toBe("wildcard-action-1");
|
|
329
|
+
expect((gqlMsgs2[0] as any).role).toBe(gql.Role.Assistant);
|
|
330
|
+
expect(gqlMsgs2[1].id).toBe("wildcard-action-1");
|
|
331
|
+
expect((gqlMsgs2[1] as any).name).toBe("unknownAction");
|
|
332
|
+
expect((gqlMsgs2[1] as any).arguments).toEqual({ test: "wildcard-gql-value" });
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
test("roundtrip conversion with result parsing edge cases", () => {
|
|
336
|
+
// Test with a tool result that contains a JSON string
|
|
337
|
+
const toolResultMsg: agui.Message = {
|
|
338
|
+
id: "tool-result-json",
|
|
339
|
+
role: "tool",
|
|
340
|
+
content: '{"status": "success", "data": {"value": 42}}',
|
|
341
|
+
toolCallId: "tool-call-json",
|
|
342
|
+
toolName: "jsonAction",
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
// Convert AGUI -> GQL -> AGUI
|
|
346
|
+
const gqlMsgs = aguiToGQL(toolResultMsg);
|
|
347
|
+
const aguiMsgs = gqlToAGUI(gqlMsgs);
|
|
348
|
+
|
|
349
|
+
expect(gqlMsgs).toHaveLength(1);
|
|
350
|
+
expect(gqlMsgs[0]).toBeInstanceOf(gql.ResultMessage);
|
|
351
|
+
expect((gqlMsgs[0] as any).result).toBe('{"status": "success", "data": {"value": 42}}');
|
|
352
|
+
|
|
353
|
+
expect(aguiMsgs).toHaveLength(1);
|
|
354
|
+
expect(aguiMsgs[0].role).toBe("tool");
|
|
355
|
+
expect(aguiMsgs[0].content).toBe('{"status": "success", "data": {"value": 42}}');
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
test("roundtrip conversion with object content in tool results", () => {
|
|
359
|
+
// Test with a tool result that has object content (edge case)
|
|
360
|
+
const toolResultMsg: agui.Message = {
|
|
361
|
+
id: "tool-result-object",
|
|
362
|
+
role: "tool",
|
|
363
|
+
content: { status: "success", data: { value: 42 } } as any,
|
|
364
|
+
toolCallId: "tool-call-object",
|
|
365
|
+
toolName: "objectAction",
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
// Convert AGUI -> GQL -> AGUI
|
|
369
|
+
const gqlMsgs = aguiToGQL(toolResultMsg);
|
|
370
|
+
const aguiMsgs = gqlToAGUI(gqlMsgs);
|
|
371
|
+
|
|
372
|
+
expect(gqlMsgs).toHaveLength(1);
|
|
373
|
+
expect(gqlMsgs[0]).toBeInstanceOf(gql.ResultMessage);
|
|
374
|
+
expect((gqlMsgs[0] as any).result).toBe('{"status":"success","data":{"value":42}}');
|
|
375
|
+
|
|
376
|
+
expect(aguiMsgs).toHaveLength(1);
|
|
377
|
+
expect(aguiMsgs[0].role).toBe("tool");
|
|
378
|
+
expect(aguiMsgs[0].content).toBe('{"status":"success","data":{"value":42}}');
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
test("roundtrip conversion with action execution and result parsing", () => {
|
|
382
|
+
const mockRender = vi.fn((props) => `Rendered: ${JSON.stringify(props.result)}`);
|
|
383
|
+
|
|
384
|
+
// Create action execution message
|
|
385
|
+
const actionExecMsg = new gql.ActionExecutionMessage({
|
|
386
|
+
id: "action-with-result",
|
|
387
|
+
name: "testAction",
|
|
388
|
+
arguments: { input: "test-value" },
|
|
389
|
+
parentMessageId: "parent-result",
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
// Create result message
|
|
393
|
+
const resultMsg = new gql.ResultMessage({
|
|
394
|
+
id: "result-with-json",
|
|
395
|
+
result: '{"output": "processed", "count": 5}',
|
|
396
|
+
actionExecutionId: "action-with-result",
|
|
397
|
+
actionName: "testAction",
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
const actions = {
|
|
401
|
+
testAction: {
|
|
402
|
+
name: "testAction",
|
|
403
|
+
render: mockRender,
|
|
404
|
+
},
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
// Convert GQL -> AGUI
|
|
408
|
+
const aguiMsgs = gqlToAGUI([actionExecMsg, resultMsg], actions);
|
|
409
|
+
|
|
410
|
+
// The action execution should have a generativeUI function that parses string results
|
|
411
|
+
expect(aguiMsgs).toHaveLength(2);
|
|
412
|
+
expect(aguiMsgs[0].role).toBe("assistant");
|
|
413
|
+
expect("generativeUI" in aguiMsgs[0]).toBe(true);
|
|
414
|
+
expect(aguiMsgs[1].role).toBe("tool");
|
|
415
|
+
expect(aguiMsgs[1].content).toBe('{"output": "processed", "count": 5}');
|
|
416
|
+
|
|
417
|
+
// Test that the render function receives parsed results
|
|
418
|
+
if ("generativeUI" in aguiMsgs[0] && aguiMsgs[0].generativeUI) {
|
|
419
|
+
aguiMsgs[0].generativeUI({ result: '{"parsed": true}' });
|
|
420
|
+
expect(mockRender).toHaveBeenCalledWith(
|
|
421
|
+
expect.objectContaining({
|
|
422
|
+
result: { parsed: true }, // Should be parsed from string
|
|
423
|
+
}),
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// Convert back AGUI -> GQL
|
|
428
|
+
const gqlMsgs2 = aguiToGQL(aguiMsgs, actions);
|
|
429
|
+
|
|
430
|
+
// Should have 3 messages: TextMessage, ActionExecutionMessage, ResultMessage
|
|
431
|
+
expect(gqlMsgs2).toHaveLength(3);
|
|
432
|
+
expect(gqlMsgs2[0]).toBeInstanceOf(gql.TextMessage);
|
|
433
|
+
expect(gqlMsgs2[1]).toBeInstanceOf(gql.ActionExecutionMessage);
|
|
434
|
+
expect(gqlMsgs2[2]).toBeInstanceOf(gql.ResultMessage);
|
|
435
|
+
|
|
436
|
+
// Check that arguments roundtripped correctly
|
|
437
|
+
expect((gqlMsgs2[1] as any).arguments).toEqual({ input: "test-value" });
|
|
438
|
+
expect((gqlMsgs2[2] as any).result).toBe('{"output": "processed", "count": 5}');
|
|
439
|
+
});
|
|
212
440
|
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/message-conversion/gql-to-agui.ts"],"sourcesContent":["import * as gql from \"../client\";\nimport agui from \"@copilotkit/shared\";\nimport { MessageStatusCode } from \"../graphql/@generated/graphql\";\n\n// Define valid image formats based on the supported formats in the codebase\nconst VALID_IMAGE_FORMATS = [\"jpeg\", \"png\", \"webp\", \"gif\"] as const;\ntype ValidImageFormat = (typeof VALID_IMAGE_FORMATS)[number];\n\n// Validation function for image format\nfunction validateImageFormat(format: string): format is ValidImageFormat {\n return VALID_IMAGE_FORMATS.includes(format as ValidImageFormat);\n}\n\n/*\n ----------------------------\n GQL Message -> AGUI Message\n ----------------------------\n*/\nexport function gqlToAGUI(\n messages: gql.Message[] | gql.Message,\n actions?: Record<string, any>,\n coAgentStateRenders?: Record<string, any>,\n): agui.Message[] {\n let aguiMessages: agui.Message[] = [];\n messages = Array.isArray(messages) ? messages : [messages];\n\n // Create a map of action execution ID to result for completed actions\n const actionResults = new Map<string, string>();\n for (const message of messages) {\n if (message.isResultMessage()) {\n actionResults.set(message.actionExecutionId, message.result);\n }\n }\n\n for (const message of messages) {\n if (message.isTextMessage()) {\n aguiMessages.push(gqlTextMessageToAGUIMessage(message));\n } else if (message.isResultMessage()) {\n aguiMessages.push(gqlResultMessageToAGUIMessage(message));\n } else if (message.isActionExecutionMessage()) {\n aguiMessages.push(gqlActionExecutionMessageToAGUIMessage(message, actions, actionResults));\n } else if (message.isAgentStateMessage()) {\n aguiMessages.push(gqlAgentStateMessageToAGUIMessage(message, coAgentStateRenders));\n } else if (message.isImageMessage()) {\n aguiMessages.push(gqlImageMessageToAGUIMessage(message));\n } else {\n throw new Error(\"Unknown message type\");\n }\n }\n\n return aguiMessages;\n}\n\nfunction gqlActionExecutionMessageToAGUIMessage(\n message: gql.ActionExecutionMessage,\n actions?: Record<string, any>,\n actionResults?: Map<string, string>,\n): agui.Message {\n if (actions && Object.values(actions).some((action: any) => action.name === message.name)) {\n const action = Object.values(actions).find((action: any) => action.name === message.name);\n\n // Create render function wrapper that provides proper props\n const createRenderWrapper = (originalRender: any) => {\n if (!originalRender) return undefined;\n\n return (props?: any) => {\n // Determine the correct status based on the same logic as RenderActionExecutionMessage\n const actionResult = actionResults?.get(message.id);\n let status: \"inProgress\" | \"executing\" | \"complete\" = \"inProgress\";\n\n if (actionResult !== undefined) {\n status = \"complete\";\n } else if (message.status?.code !== MessageStatusCode.Pending) {\n status = \"executing\";\n }\n\n // Provide the full props structure that the render function expects\n const renderProps = {\n status: props?.status || status,\n args: message.arguments || {},\n result: props?.result || actionResult || undefined,\n respond: props?.respond || (() => {}),\n messageId: message.id,\n ...props,\n };\n\n return originalRender(renderProps);\n };\n };\n\n return {\n id: message.id,\n role: \"assistant\",\n content: \"\",\n toolCalls: [actionExecutionMessageToAGUIMessage(message)],\n generativeUI: createRenderWrapper(action.render),\n name: message.name,\n } as agui.AIMessage;\n }\n\n return {\n id: message.id,\n role: \"assistant\",\n toolCalls: [actionExecutionMessageToAGUIMessage(message)],\n name: message.name,\n };\n}\n\nfunction gqlAgentStateMessageToAGUIMessage(\n message: gql.AgentStateMessage,\n coAgentStateRenders?: Record<string, any>,\n): agui.Message {\n if (\n coAgentStateRenders &&\n Object.values(coAgentStateRenders).some((render: any) => render.name === message.agentName)\n ) {\n const render = Object.values(coAgentStateRenders).find(\n (render: any) => render.name === message.agentName,\n );\n\n // Create render function wrapper that provides proper props\n const createRenderWrapper = (originalRender: any) => {\n if (!originalRender) return undefined;\n\n return (props?: any) => {\n // Determine the correct status based on the same logic as RenderActionExecutionMessage\n const state = message.state;\n\n // Provide the full props structure that the render function expects\n const renderProps = {\n state: state,\n };\n\n return originalRender(renderProps);\n };\n };\n\n return {\n id: message.id,\n role: \"assistant\",\n generativeUI: createRenderWrapper(render.render),\n agentName: message.agentName,\n state: message.state,\n };\n }\n\n return {\n id: message.id,\n role: \"assistant\",\n agentName: message.agentName,\n state: message.state,\n };\n}\n\nfunction actionExecutionMessageToAGUIMessage(\n actionExecutionMessage: gql.ActionExecutionMessage,\n): agui.ToolCall {\n return {\n id: actionExecutionMessage.id,\n function: {\n name: actionExecutionMessage.name,\n arguments: JSON.stringify(actionExecutionMessage.arguments),\n },\n type: \"function\",\n };\n}\n\nexport function gqlTextMessageToAGUIMessage(message: gql.TextMessage): agui.Message {\n switch (message.role) {\n case gql.Role.Developer:\n return {\n id: message.id,\n role: \"developer\",\n content: message.content,\n };\n case gql.Role.System:\n return {\n id: message.id,\n role: \"system\",\n content: message.content,\n };\n case gql.Role.Assistant:\n return {\n id: message.id,\n role: \"assistant\",\n content: message.content,\n };\n case gql.Role.User:\n return {\n id: message.id,\n role: \"user\",\n content: message.content,\n };\n default:\n throw new Error(\"Unknown message role\");\n }\n}\n\nexport function gqlResultMessageToAGUIMessage(message: gql.ResultMessage): agui.Message {\n return {\n id: message.id,\n role: \"tool\",\n content: message.result,\n toolCallId: message.actionExecutionId,\n toolName: message.actionName,\n };\n}\n\nexport function gqlImageMessageToAGUIMessage(message: gql.ImageMessage): agui.Message {\n // Validate image format\n if (!validateImageFormat(message.format)) {\n throw new Error(\n `Invalid image format: ${message.format}. Supported formats are: ${VALID_IMAGE_FORMATS.join(\", \")}`,\n );\n }\n\n // Validate that bytes is a non-empty string\n if (!message.bytes || typeof message.bytes !== \"string\" || message.bytes.trim() === \"\") {\n throw new Error(\"Image bytes must be a non-empty string\");\n }\n\n // Determine the role based on the message role\n const role = message.role === gql.Role.Assistant ? \"assistant\" : \"user\";\n\n // Create the image message with proper typing\n const imageMessage: agui.Message = {\n id: message.id,\n role,\n content: \"\",\n image: {\n format: message.format,\n bytes: message.bytes,\n },\n };\n\n return imageMessage;\n}\n"],"mappings":"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","names":["action","render"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/message-conversion/agui-to-gql.ts"],"sourcesContent":["import * as gql from \"../client\";\nimport { MessageRole } from \"../graphql/@generated/graphql\";\nimport agui from \"@copilotkit/shared\"; // named agui for clarity, but this only includes agui message types\n\n// Helper function to extract agent name from message\nfunction extractAgentName(message: agui.Message): string {\n if (message.role !== \"assistant\") {\n throw new Error(`Cannot extract agent name from message with role ${message.role}`);\n }\n\n return message.agentName || \"unknown\";\n}\n\n// Type guard for agent state message\nfunction isAgentStateMessage(message: agui.Message): boolean {\n return message.role === \"assistant\" && \"agentName\" in message && \"state\" in message;\n}\n\n// Type guard for messages with image property\nfunction hasImageProperty(message: agui.Message): boolean {\n const canContainImage = message.role === \"assistant\" || message.role === \"user\";\n if (!canContainImage || message.image === undefined) {\n return false;\n }\n\n const isMalformed = message.image.format === undefined || message.image.bytes === undefined;\n if (isMalformed) {\n return false;\n }\n\n return true;\n}\n\n/*\n ----------------------------\n AGUI Message -> GQL Message\n ----------------------------\n*/\nexport function aguiToGQL(\n messages: agui.Message[] | agui.Message,\n actions?: Record<string, any>,\n coAgentStateRenders?: Record<string, any>,\n): gql.Message[] {\n const gqlMessages: gql.Message[] = [];\n messages = Array.isArray(messages) ? messages : [messages];\n\n // Track tool call names by their IDs for use in result messages\n const toolCallNames: Record<string, string> = {};\n\n for (const message of messages) {\n // Agent state message support\n if (isAgentStateMessage(message)) {\n const agentName = extractAgentName(message);\n const state = \"state\" in message && message.state ? message.state : {};\n gqlMessages.push(\n new gql.AgentStateMessage({\n id: message.id,\n agentName,\n state,\n role: gql.Role.Assistant,\n }),\n );\n // Optionally preserve render function\n if (\"generativeUI\" in message && message.generativeUI && coAgentStateRenders) {\n coAgentStateRenders[agentName] = {\n name: agentName,\n render: message.generativeUI,\n };\n }\n continue;\n }\n\n if (hasImageProperty(message)) {\n gqlMessages.push(aguiMessageWithImageToGQLMessage(message));\n continue;\n }\n\n // Action execution message support\n if (message.role === \"assistant\" && message.toolCalls) {\n gqlMessages.push(aguiTextMessageToGQLMessage(message));\n for (const toolCall of message.toolCalls) {\n // Track the tool call name by its ID\n toolCallNames[toolCall.id] = toolCall.function.name;\n\n const actionExecMsg = aguiToolCallToGQLActionExecution(toolCall, message.id);\n // Preserve render function in actions context\n if (\"generativeUI\" in message && message.generativeUI && actions) {\n const actionName = toolCall.function.name;\n if (actions[actionName]) {\n actions[actionName].render = message.generativeUI;\n }\n }\n gqlMessages.push(actionExecMsg);\n }\n continue;\n }\n // Regular text messages\n if (\n message.role === \"developer\" ||\n message.role === \"system\" ||\n message.role === \"assistant\" ||\n message.role === \"user\"\n ) {\n gqlMessages.push(aguiTextMessageToGQLMessage(message));\n continue;\n }\n // Tool result message\n if (message.role === \"tool\") {\n gqlMessages.push(aguiToolMessageToGQLResultMessage(message, toolCallNames));\n continue;\n }\n throw new Error(\n `Unknown message role: \"${(message as any).role}\" in message with id: ${(message as any).id}`,\n );\n }\n\n return gqlMessages;\n}\n\nexport function aguiTextMessageToGQLMessage(message: agui.Message): gql.TextMessage {\n if (\n message.role !== \"developer\" &&\n message.role !== \"system\" &&\n message.role !== \"assistant\" &&\n message.role !== \"user\"\n ) {\n throw new Error(`Cannot convert message with role ${message.role} to TextMessage`);\n }\n\n let roleValue: MessageRole;\n\n if (message.role === \"developer\") {\n roleValue = gql.Role.Developer;\n } else if (message.role === \"system\") {\n roleValue = gql.Role.System;\n } else if (message.role === \"assistant\") {\n roleValue = gql.Role.Assistant;\n } else {\n roleValue = gql.Role.User;\n }\n\n return new gql.TextMessage({\n id: message.id,\n content: message.content || \"\",\n role: roleValue,\n });\n}\n\nexport function aguiToolCallToGQLActionExecution(\n toolCall: agui.ToolCall,\n parentMessageId: string,\n): gql.ActionExecutionMessage {\n if (toolCall.type !== \"function\") {\n throw new Error(`Unsupported tool call type: ${toolCall.type}`);\n }\n\n // Parse arguments with error handling\n let argumentsObj: any;\n try {\n argumentsObj = JSON.parse(toolCall.function.arguments);\n } catch (error) {\n console.warn(`Failed to parse tool call arguments for ${toolCall.function.name}:`, error);\n // Provide fallback empty object to prevent application crash\n argumentsObj = {};\n }\n\n // Always include name and arguments\n return new gql.ActionExecutionMessage({\n id: toolCall.id,\n name: toolCall.function.name,\n arguments: argumentsObj,\n parentMessageId: parentMessageId,\n });\n}\n\nexport function aguiToolMessageToGQLResultMessage(\n message: agui.Message,\n toolCallNames: Record<string, string>,\n): gql.ResultMessage {\n if (message.role !== \"tool\") {\n throw new Error(`Cannot convert message with role ${message.role} to ResultMessage`);\n }\n\n if (!message.toolCallId) {\n throw new Error(\"Tool message must have a toolCallId\");\n }\n\n const actionName = toolCallNames[message.toolCallId] || \"unknown\";\n\n return new gql.ResultMessage({\n id: message.id,\n result: message.content || \"\",\n actionExecutionId: message.toolCallId,\n actionName: message.toolName || actionName,\n });\n}\n\n// New function to handle AGUI messages with render functions\nexport function aguiMessageWithRenderToGQL(\n message: agui.Message,\n actions?: Record<string, any>,\n coAgentStateRenders?: Record<string, any>,\n): gql.Message[] {\n // Handle the special case: assistant messages with render function but no tool calls\n if (\n message.role === \"assistant\" &&\n \"generativeUI\" in message &&\n message.generativeUI &&\n !message.toolCalls\n ) {\n const gqlMessages: gql.Message[] = [];\n gqlMessages.push(\n new gql.AgentStateMessage({\n id: message.id,\n agentName: \"unknown\",\n state: {},\n role: gql.Role.Assistant,\n }),\n );\n if (coAgentStateRenders) {\n coAgentStateRenders.unknown = {\n name: \"unknown\",\n render: message.generativeUI,\n };\n }\n return gqlMessages;\n }\n\n // For all other cases, delegate to aguiToGQL\n return aguiToGQL([message], actions, coAgentStateRenders);\n}\n\nexport function aguiMessageWithImageToGQLMessage(message: agui.Message): gql.ImageMessage {\n if (!hasImageProperty(message)) {\n throw new Error(`Cannot convert message to ImageMessage: missing format or bytes`);\n }\n\n let roleValue: MessageRole;\n if (message.role === \"assistant\") {\n roleValue = gql.Role.Assistant;\n } else {\n roleValue = gql.Role.User;\n }\n\n if (message.role !== \"assistant\" && message.role !== \"user\") {\n throw new Error(`Cannot convert message with role ${message.role} to ImageMessage`);\n }\n\n return new gql.ImageMessage({\n id: message.id,\n format: message.image!.format,\n bytes: message.image!.bytes,\n role: roleValue,\n });\n}\n"],"mappings":";;;;;;;;;;AAKA,SAAS,iBAAiB,SAA+B;AACvD,MAAI,QAAQ,SAAS,aAAa;AAChC,UAAM,IAAI,MAAM,oDAAoD,QAAQ,MAAM;AAAA,EACpF;AAEA,SAAO,QAAQ,aAAa;AAC9B;AAGA,SAAS,oBAAoB,SAAgC;AAC3D,SAAO,QAAQ,SAAS,eAAe,eAAe,WAAW,WAAW;AAC9E;AAGA,SAAS,iBAAiB,SAAgC;AACxD,QAAM,kBAAkB,QAAQ,SAAS,eAAe,QAAQ,SAAS;AACzE,MAAI,CAAC,mBAAmB,QAAQ,UAAU,QAAW;AACnD,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,QAAQ,MAAM,WAAW,UAAa,QAAQ,MAAM,UAAU;AAClF,MAAI,aAAa;AACf,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAOO,SAAS,UACd,UACA,SACA,qBACe;AACf,QAAM,cAA6B,CAAC;AACpC,aAAW,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAQ;AAGzD,QAAM,gBAAwC,CAAC;AAE/C,aAAW,WAAW,UAAU;AAE9B,QAAI,oBAAoB,OAAO,GAAG;AAChC,YAAM,YAAY,iBAAiB,OAAO;AAC1C,YAAM,QAAQ,WAAW,WAAW,QAAQ,QAAQ,QAAQ,QAAQ,CAAC;AACrE,kBAAY;AAAA,QACV,IAAQ,kBAAkB;AAAA,UACxB,IAAI,QAAQ;AAAA,UACZ;AAAA,UACA;AAAA,UACA,MAAU,KAAK;AAAA,QACjB,CAAC;AAAA,MACH;AAEA,UAAI,kBAAkB,WAAW,QAAQ,gBAAgB,qBAAqB;AAC5E,4BAAoB,SAAS,IAAI;AAAA,UAC/B,MAAM;AAAA,UACN,QAAQ,QAAQ;AAAA,QAClB;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,iBAAiB,OAAO,GAAG;AAC7B,kBAAY,KAAK,iCAAiC,OAAO,CAAC;AAC1D;AAAA,IACF;AAGA,QAAI,QAAQ,SAAS,eAAe,QAAQ,WAAW;AACrD,kBAAY,KAAK,4BAA4B,OAAO,CAAC;AACrD,iBAAW,YAAY,QAAQ,WAAW;AAExC,sBAAc,SAAS,EAAE,IAAI,SAAS,SAAS;AAE/C,cAAM,gBAAgB,iCAAiC,UAAU,QAAQ,EAAE;AAE3E,YAAI,kBAAkB,WAAW,QAAQ,gBAAgB,SAAS;AAChE,gBAAM,aAAa,SAAS,SAAS;AACrC,cAAI,QAAQ,UAAU,GAAG;AACvB,oBAAQ,UAAU,EAAE,SAAS,QAAQ;AAAA,UACvC;AAAA,QACF;AACA,oBAAY,KAAK,aAAa;AAAA,MAChC;AACA;AAAA,IACF;AAEA,QACE,QAAQ,SAAS,eACjB,QAAQ,SAAS,YACjB,QAAQ,SAAS,eACjB,QAAQ,SAAS,QACjB;AACA,kBAAY,KAAK,4BAA4B,OAAO,CAAC;AACrD;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS,QAAQ;AAC3B,kBAAY,KAAK,kCAAkC,SAAS,aAAa,CAAC;AAC1E;AAAA,IACF;AACA,UAAM,IAAI;AAAA,MACR,0BAA2B,QAAgB,6BAA8B,QAAgB;AAAA,IAC3F;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,4BAA4B,SAAwC;AAClF,MACE,QAAQ,SAAS,eACjB,QAAQ,SAAS,YACjB,QAAQ,SAAS,eACjB,QAAQ,SAAS,QACjB;AACA,UAAM,IAAI,MAAM,oCAAoC,QAAQ,qBAAqB;AAAA,EACnF;AAEA,MAAI;AAEJ,MAAI,QAAQ,SAAS,aAAa;AAChC,gBAAgB,KAAK;AAAA,EACvB,WAAW,QAAQ,SAAS,UAAU;AACpC,gBAAgB,KAAK;AAAA,EACvB,WAAW,QAAQ,SAAS,aAAa;AACvC,gBAAgB,KAAK;AAAA,EACvB,OAAO;AACL,gBAAgB,KAAK;AAAA,EACvB;AAEA,SAAO,IAAQ,YAAY;AAAA,IACzB,IAAI,QAAQ;AAAA,IACZ,SAAS,QAAQ,WAAW;AAAA,IAC5B,MAAM;AAAA,EACR,CAAC;AACH;AAEO,SAAS,iCACd,UACA,iBAC4B;AAC5B,MAAI,SAAS,SAAS,YAAY;AAChC,UAAM,IAAI,MAAM,+BAA+B,SAAS,MAAM;AAAA,EAChE;AAGA,MAAI;AACJ,MAAI;AACF,mBAAe,KAAK,MAAM,SAAS,SAAS,SAAS;AAAA,EACvD,SAAS,OAAP;AACA,YAAQ,KAAK,2CAA2C,SAAS,SAAS,SAAS,KAAK;AAExF,mBAAe,CAAC;AAAA,EAClB;AAGA,SAAO,IAAQ,uBAAuB;AAAA,IACpC,IAAI,SAAS;AAAA,IACb,MAAM,SAAS,SAAS;AAAA,IACxB,WAAW;AAAA,IACX;AAAA,EACF,CAAC;AACH;AAEO,SAAS,kCACd,SACA,eACmB;AACnB,MAAI,QAAQ,SAAS,QAAQ;AAC3B,UAAM,IAAI,MAAM,oCAAoC,QAAQ,uBAAuB;AAAA,EACrF;AAEA,MAAI,CAAC,QAAQ,YAAY;AACvB,UAAM,IAAI,MAAM,qCAAqC;AAAA,EACvD;AAEA,QAAM,aAAa,cAAc,QAAQ,UAAU,KAAK;AAExD,SAAO,IAAQ,cAAc;AAAA,IAC3B,IAAI,QAAQ;AAAA,IACZ,QAAQ,QAAQ,WAAW;AAAA,IAC3B,mBAAmB,QAAQ;AAAA,IAC3B,YAAY,QAAQ,YAAY;AAAA,EAClC,CAAC;AACH;AAGO,SAAS,2BACd,SACA,SACA,qBACe;AAEf,MACE,QAAQ,SAAS,eACjB,kBAAkB,WAClB,QAAQ,gBACR,CAAC,QAAQ,WACT;AACA,UAAM,cAA6B,CAAC;AACpC,gBAAY;AAAA,MACV,IAAQ,kBAAkB;AAAA,QACxB,IAAI,QAAQ;AAAA,QACZ,WAAW;AAAA,QACX,OAAO,CAAC;AAAA,QACR,MAAU,KAAK;AAAA,MACjB,CAAC;AAAA,IACH;AACA,QAAI,qBAAqB;AACvB,0BAAoB,UAAU;AAAA,QAC5B,MAAM;AAAA,QACN,QAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGA,SAAO,UAAU,CAAC,OAAO,GAAG,SAAS,mBAAmB;AAC1D;AAEO,SAAS,iCAAiC,SAAyC;AACxF,MAAI,CAAC,iBAAiB,OAAO,GAAG;AAC9B,UAAM,IAAI,MAAM,iEAAiE;AAAA,EACnF;AAEA,MAAI;AACJ,MAAI,QAAQ,SAAS,aAAa;AAChC,gBAAgB,KAAK;AAAA,EACvB,OAAO;AACL,gBAAgB,KAAK;AAAA,EACvB;AAEA,MAAI,QAAQ,SAAS,eAAe,QAAQ,SAAS,QAAQ;AAC3D,UAAM,IAAI,MAAM,oCAAoC,QAAQ,sBAAsB;AAAA,EACpF;AAEA,SAAO,IAAQ,aAAa;AAAA,IAC1B,IAAI,QAAQ;AAAA,IACZ,QAAQ,QAAQ,MAAO;AAAA,IACvB,OAAO,QAAQ,MAAO;AAAA,IACtB,MAAM;AAAA,EACR,CAAC;AACH;","names":[]}
|