@copilotkit/runtime-client-gql
Version:
<img src="https://github.com/user-attachments/assets/0a6b64d9-e193-4940-a3f6-60334ac34084" alt="banner" style="border-radius: 12px; border: 2px solid #d6d4fa;" />
1,106 lines (1,105 loc) • 38.9 kB
JavaScript
import {
aguiMessageWithImageToGQLMessage,
aguiMessageWithRenderToGQL,
aguiTextMessageToGQLMessage,
aguiToGQL,
aguiToolCallToGQLActionExecution,
aguiToolMessageToGQLResultMessage
} from "../chunk-SCACOKQX.mjs";
import {
describe,
globalExpect,
test,
vi
} from "../chunk-2R7M2FWR.mjs";
import "../chunk-7ECCT6PK.mjs";
import "../chunk-FXYV7IUL.mjs";
import "../chunk-X2UAP3QY.mjs";
import "../chunk-HEODM5TW.mjs";
import "../chunk-4KTMZMM2.mjs";
import "../chunk-P2AUSQOK.mjs";
import {
ActionExecutionMessage,
AgentStateMessage,
ImageMessage,
ResultMessage,
Role,
TextMessage
} from "../chunk-ROUIRR4B.mjs";
import "../chunk-WM3ARNBD.mjs";
import "../chunk-DELDZXUX.mjs";
// src/message-conversion/agui-to-gql.test.ts
describe("agui-to-gql", () => {
describe("aguiTextMessageToGQLMessage", () => {
test("should convert developer message", () => {
const aguiMessage = {
id: "dev-message-id",
role: "developer",
content: "Hello from developer"
};
const result = aguiTextMessageToGQLMessage(aguiMessage);
globalExpect(result).toBeInstanceOf(TextMessage);
globalExpect(result.id).toBe("dev-message-id");
globalExpect(result.content).toBe("Hello from developer");
globalExpect(result.role).toBe(Role.Developer);
});
test("should convert system message", () => {
const aguiMessage = {
id: "system-message-id",
role: "system",
content: "System instruction"
};
const result = aguiTextMessageToGQLMessage(aguiMessage);
globalExpect(result).toBeInstanceOf(TextMessage);
globalExpect(result.id).toBe("system-message-id");
globalExpect(result.content).toBe("System instruction");
globalExpect(result.role).toBe(Role.System);
});
test("should convert assistant message", () => {
const aguiMessage = {
id: "assistant-message-id",
role: "assistant",
content: "Assistant response"
};
const result = aguiTextMessageToGQLMessage(aguiMessage);
globalExpect(result).toBeInstanceOf(TextMessage);
globalExpect(result.id).toBe("assistant-message-id");
globalExpect(result.content).toBe("Assistant response");
globalExpect(result.role).toBe(Role.Assistant);
});
test("should convert user message", () => {
const aguiMessage = {
id: "user-message-id",
role: "user",
content: "User input"
};
const result = aguiTextMessageToGQLMessage(aguiMessage);
globalExpect(result).toBeInstanceOf(TextMessage);
globalExpect(result.id).toBe("user-message-id");
globalExpect(result.content).toBe("User input");
globalExpect(result.role).toBe(Role.User);
});
test("should throw error for unsupported role", () => {
const aguiMessage = {
id: "tool-message-id",
role: "tool",
content: "Tool response",
toolCallId: "tool-call-id"
};
globalExpect(() => aguiTextMessageToGQLMessage(aguiMessage)).toThrow(
"Cannot convert message with role tool to TextMessage"
);
});
test("should handle undefined content", () => {
const aguiMessage = {
id: "assistant-message-id",
role: "assistant",
content: void 0
};
const result = aguiTextMessageToGQLMessage(aguiMessage);
globalExpect(result.content).toBe("");
});
});
describe("aguiToolCallToGQLActionExecution", () => {
test("should convert function tool call to action execution message", () => {
const toolCall = {
id: "tool-call-id",
type: "function",
function: {
name: "testFunction",
arguments: JSON.stringify({ param: "value" })
}
};
const result = aguiToolCallToGQLActionExecution(toolCall, "parent-message-id");
globalExpect(result).toBeInstanceOf(ActionExecutionMessage);
globalExpect(result.id).toBe("tool-call-id");
globalExpect(result.name).toBe("testFunction");
globalExpect(result.arguments).toEqual({ param: "value" });
globalExpect(result.parentMessageId).toBe("parent-message-id");
});
test("should throw error for unsupported tool call type", () => {
const toolCall = {
id: "tool-call-id",
type: "unsupported-type",
function: {
name: "testFunction",
arguments: "{}"
}
};
globalExpect(() => aguiToolCallToGQLActionExecution(toolCall, "parent-id")).toThrow(
"Unsupported tool call type"
);
});
});
describe("aguiToolMessageToGQLResultMessage", () => {
test("should convert tool message to result message", () => {
const aguiMessage = {
id: "tool-message-id",
role: "tool",
content: "Tool execution result",
toolCallId: "tool-call-id"
};
const toolCallNames = { "tool-call-id": "testFunction" };
const result = aguiToolMessageToGQLResultMessage(aguiMessage, toolCallNames);
globalExpect(result).toBeInstanceOf(ResultMessage);
globalExpect(result.id).toBe("tool-message-id");
globalExpect(result.result).toBe("Tool execution result");
globalExpect(result.actionExecutionId).toBe("tool-call-id");
globalExpect(result.actionName).toBe("testFunction");
});
test("should throw error for non-tool message", () => {
const aguiMessage = {
id: "assistant-message-id",
role: "assistant",
content: "Assistant response"
};
globalExpect(() => aguiToolMessageToGQLResultMessage(aguiMessage, {})).toThrow(
"Cannot convert message with role assistant to ResultMessage"
);
});
test("should throw error for tool message without toolCallId", () => {
const aguiMessage = {
id: "tool-message-id",
role: "tool",
content: "Tool execution result"
};
globalExpect(() => aguiToolMessageToGQLResultMessage(aguiMessage, {})).toThrow(
"Tool message must have a toolCallId"
);
});
test("should handle undefined content", () => {
const aguiMessage = {
id: "tool-message-id",
role: "tool",
content: void 0,
toolCallId: "tool-call-id"
};
const toolCallNames = { "tool-call-id": "testFunction" };
const result = aguiToolMessageToGQLResultMessage(aguiMessage, toolCallNames);
globalExpect(result.result).toBe("");
globalExpect(result.actionName).toBe("testFunction");
});
});
describe("aguiToGQL", () => {
test("should convert an array of text messages", () => {
const aguiMessages = [
{
id: "dev-1",
role: "developer",
content: "Hello"
},
{
id: "assistant-1",
role: "assistant",
content: "Hi there"
}
];
const result = aguiToGQL(aguiMessages);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[0].id).toBe("dev-1");
globalExpect(result[0].content).toBe("Hello");
globalExpect(result[0].role).toBe(Role.Developer);
globalExpect(result[1]).toBeInstanceOf(TextMessage);
globalExpect(result[1].id).toBe("assistant-1");
globalExpect(result[1].content).toBe("Hi there");
globalExpect(result[1].role).toBe(Role.Assistant);
});
test("should convert an array of text messages including user messages", () => {
const aguiMessages = [
{
id: "user-1",
role: "user",
content: "Hello from user"
},
{
id: "assistant-1",
role: "assistant",
content: "Hi there"
},
{
id: "user-2",
role: "user",
content: "Another user message"
}
];
const result = aguiToGQL(aguiMessages);
globalExpect(result).toHaveLength(3);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[0].id).toBe("user-1");
globalExpect(result[0].content).toBe("Hello from user");
globalExpect(result[0].role).toBe(Role.User);
globalExpect(result[1]).toBeInstanceOf(TextMessage);
globalExpect(result[1].id).toBe("assistant-1");
globalExpect(result[1].content).toBe("Hi there");
globalExpect(result[1].role).toBe(Role.Assistant);
globalExpect(result[2]).toBeInstanceOf(TextMessage);
globalExpect(result[2].id).toBe("user-2");
globalExpect(result[2].content).toBe("Another user message");
globalExpect(result[2].role).toBe(Role.User);
});
test("should handle assistant messages with tool calls", () => {
const aguiMessages = [
{
id: "assistant-1",
role: "assistant",
content: "I'll execute a function",
toolCalls: [
{
id: "tool-call-1",
type: "function",
function: {
name: "testFunction",
arguments: JSON.stringify({ param: "value" })
}
}
]
}
];
const result = aguiToGQL(aguiMessages);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[0].id).toBe("assistant-1");
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(result[1].id).toBe("tool-call-1");
globalExpect(result[1].name).toBe("testFunction");
globalExpect(result[1].arguments).toEqual({ param: "value" });
globalExpect(result[1].parentMessageId).toBe("assistant-1");
});
test("should handle multiple tool calls in assistant message", () => {
const aguiMessages = [
{
id: "assistant-1",
role: "assistant",
content: "I'll execute multiple functions",
toolCalls: [
{
id: "tool-call-1",
type: "function",
function: {
name: "firstFunction",
arguments: JSON.stringify({ param: "value1" })
}
},
{
id: "tool-call-2",
type: "function",
function: {
name: "secondFunction",
arguments: JSON.stringify({ param: "value2" })
}
}
]
}
];
const result = aguiToGQL(aguiMessages);
globalExpect(result).toHaveLength(3);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(result[1].id).toBe("tool-call-1");
globalExpect(result[1].name).toBe("firstFunction");
globalExpect(result[2]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(result[2].id).toBe("tool-call-2");
globalExpect(result[2].name).toBe("secondFunction");
});
test("should convert tool messages to result messages", () => {
const aguiMessages = [
{
id: "tool-1",
role: "tool",
content: "Tool result",
toolCallId: "tool-call-1"
}
];
const result = aguiToGQL(aguiMessages);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toBeInstanceOf(ResultMessage);
globalExpect(result[0].id).toBe("tool-1");
globalExpect(result[0].result).toBe("Tool result");
globalExpect(result[0].actionExecutionId).toBe("tool-call-1");
});
test("should handle a mix of message types", () => {
const aguiMessages = [
{
id: "dev-1",
role: "developer",
content: "Can you run a function?"
},
{
id: "assistant-1",
role: "assistant",
content: "Yes, I'll run it",
toolCalls: [
{
id: "tool-call-1",
type: "function",
function: {
name: "testFunction",
arguments: JSON.stringify({ param: "value" })
}
}
]
},
{
id: "tool-1",
role: "tool",
content: "Function result",
toolCallId: "tool-call-1"
}
];
const result = aguiToGQL(aguiMessages);
globalExpect(result).toHaveLength(4);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[0].id).toBe("dev-1");
globalExpect(result[1]).toBeInstanceOf(TextMessage);
globalExpect(result[1].id).toBe("assistant-1");
globalExpect(result[2]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(result[2].id).toBe("tool-call-1");
globalExpect(result[3]).toBeInstanceOf(ResultMessage);
globalExpect(result[3].id).toBe("tool-1");
});
test("should handle a mix of message types including user messages", () => {
const aguiMessages = [
{
id: "user-1",
role: "user",
content: "Can you help me?"
},
{
id: "assistant-1",
role: "assistant",
content: "Yes, I'll help you",
toolCalls: [
{
id: "tool-call-1",
type: "function",
function: {
name: "helpFunction",
arguments: JSON.stringify({ query: "help" })
}
}
]
},
{
id: "tool-1",
role: "tool",
content: "Help result",
toolCallId: "tool-call-1"
},
{
id: "user-2",
role: "user",
content: "Thank you!"
}
];
const result = aguiToGQL(aguiMessages);
globalExpect(result).toHaveLength(5);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[0].id).toBe("user-1");
globalExpect(result[0].role).toBe(Role.User);
globalExpect(result[1]).toBeInstanceOf(TextMessage);
globalExpect(result[1].id).toBe("assistant-1");
globalExpect(result[1].role).toBe(Role.Assistant);
globalExpect(result[2]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(result[2].id).toBe("tool-call-1");
globalExpect(result[3]).toBeInstanceOf(ResultMessage);
globalExpect(result[3].id).toBe("tool-1");
globalExpect(result[4]).toBeInstanceOf(TextMessage);
globalExpect(result[4].id).toBe("user-2");
globalExpect(result[4].role).toBe(Role.User);
});
});
describe("aguiMessageWithRenderToGQL", () => {
test("should handle assistant message with tool calls and render function", () => {
const mockRender = () => "Test Render";
const aguiMessage = {
id: "assistant-1",
role: "assistant",
content: "I'll execute a function",
toolCalls: [
{
id: "tool-call-1",
type: "function",
function: {
name: "testFunction",
arguments: JSON.stringify({ param: "value" })
}
}
],
generativeUI: mockRender
};
const actions = {
testFunction: {
name: "testFunction"
}
};
const result = aguiMessageWithRenderToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(actions.testFunction.render).toBe(mockRender);
});
test("should handle assistant message with render function but no tool calls", () => {
const mockRender = () => "Agent State Render";
const aguiMessage = {
id: "agent-state-1",
role: "assistant",
generativeUI: mockRender
};
const coAgentStateRenders = {};
const result = aguiMessageWithRenderToGQL(aguiMessage, void 0, coAgentStateRenders);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toBeInstanceOf(AgentStateMessage);
globalExpect(result[0].agentName).toBe("unknown");
globalExpect(coAgentStateRenders.unknown.render).toBe(mockRender);
});
test("should handle regular assistant message without render function", () => {
const aguiMessage = {
id: "assistant-1",
role: "assistant",
content: "Regular assistant message"
};
const result = aguiMessageWithRenderToGQL(aguiMessage);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[0].content).toBe("Regular assistant message");
});
test("should handle non-assistant messages normally", () => {
const aguiMessage = {
id: "user-1",
role: "user",
content: "User message"
};
const result = aguiMessageWithRenderToGQL(aguiMessage);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[0].role).toBe(Role.User);
});
test("should handle multiple tool calls with render functions", () => {
const mockRender1 = () => "Render 1";
const mockRender2 = () => "Render 2";
const aguiMessage = {
id: "assistant-1",
role: "assistant",
content: "I'll execute multiple functions",
toolCalls: [
{
id: "tool-call-1",
type: "function",
function: {
name: "firstFunction",
arguments: JSON.stringify({ param: "value1" })
}
},
{
id: "tool-call-2",
type: "function",
function: {
name: "secondFunction",
arguments: JSON.stringify({ param: "value2" })
}
}
],
generativeUI: mockRender1
};
const actions = {
firstFunction: { name: "firstFunction" },
secondFunction: { name: "secondFunction" }
};
const result = aguiMessageWithRenderToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(3);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(result[2]).toBeInstanceOf(ActionExecutionMessage);
Object.values(actions).forEach((action) => {
globalExpect(action.render).toBe(mockRender1);
});
});
test("should verify render function receives correct props including name", () => {
const mockRender = vi.fn(
(props) => `Rendered: ${props.name} with args: ${JSON.stringify(props.args)}`
);
const aguiMessage = {
id: "assistant-render-props",
role: "assistant",
content: "I'll execute a function",
toolCalls: [
{
id: "tool-call-render-props",
type: "function",
function: {
name: "testFunction",
arguments: JSON.stringify({ param: "value" })
}
}
],
generativeUI: mockRender
};
const actions = {
testFunction: { name: "testFunction" }
};
const result = aguiMessageWithRenderToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(actions.testFunction.render).toBe(mockRender);
if (actions.testFunction.render) {
actions.testFunction.render({
status: "inProgress",
args: { param: "value" },
result: void 0,
respond: () => {
},
messageId: "tool-call-render-props",
name: "testFunction"
});
globalExpect(mockRender).toHaveBeenCalledWith({
status: "inProgress",
args: { param: "value" },
result: void 0,
respond: globalExpect.any(Function),
messageId: "tool-call-render-props",
name: "testFunction"
});
}
});
});
describe("aguiImageMessageToGQLMessage", () => {
test("should throw error for missing format or bytes in image message", () => {
const aguiMessage = {
id: "image-1",
role: "assistant",
content: "Image message"
};
globalExpect(() => aguiMessageWithImageToGQLMessage(aguiMessage)).toThrow(
"Cannot convert message to ImageMessage: missing format or bytes"
);
});
test("should convert valid assistant image message", () => {
const aguiMessage = {
id: "image-2",
role: "assistant",
image: {
format: "jpeg",
bytes: "base64stringdata"
}
};
const result = aguiMessageWithImageToGQLMessage(aguiMessage);
globalExpect(result).toBeInstanceOf(ImageMessage);
globalExpect(result.id).toBe("image-2");
globalExpect(result.format).toBe("jpeg");
globalExpect(result.bytes).toBe("base64stringdata");
globalExpect(result.role).toBe(Role.Assistant);
});
test("should convert valid user image message", () => {
const aguiMessage = {
id: "image-3",
role: "user",
content: "",
image: {
format: "png",
bytes: "anotherbase64string"
}
};
const result = aguiMessageWithImageToGQLMessage(aguiMessage);
globalExpect(result).toBeInstanceOf(ImageMessage);
globalExpect(result.id).toBe("image-3");
globalExpect(result.format).toBe("png");
globalExpect(result.bytes).toBe("anotherbase64string");
globalExpect(result.role).toBe(Role.User);
});
});
describe("Wild Card Actions", () => {
test("should preserve render function for specific action", () => {
const mockRender = () => "Specific Action Render";
const aguiMessage = {
id: "assistant-1",
role: "assistant",
content: "I'll execute a function",
toolCalls: [
{
id: "tool-call-1",
type: "function",
function: {
name: "specificAction",
arguments: JSON.stringify({ param: "value" })
}
}
],
generativeUI: mockRender
};
const actions = {
specificAction: { name: "specificAction" }
};
const result = aguiToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(actions.specificAction.render).toBe(mockRender);
});
test("should preserve render function for wild card action", () => {
const mockRender = () => "Wild Card Action Render";
const aguiMessage = {
id: "assistant-2",
role: "assistant",
content: "I'll execute an unknown function",
toolCalls: [
{
id: "tool-call-2",
type: "function",
function: {
name: "unknownAction",
arguments: JSON.stringify({ param: "value" })
}
}
],
generativeUI: mockRender
};
const actions = {
"*": { name: "*" }
};
const result = aguiToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(actions["*"].render).toBe(mockRender);
});
test("should prioritize specific action over wild card action", () => {
const mockRender = () => "Prioritized Render";
const aguiMessage = {
id: "assistant-3",
role: "assistant",
content: "I'll execute a function",
toolCalls: [
{
id: "tool-call-3",
type: "function",
function: {
name: "specificAction",
arguments: JSON.stringify({ param: "value" })
}
}
],
generativeUI: mockRender
};
const actions = {
specificAction: { name: "specificAction" },
"*": { name: "*" }
};
const result = aguiToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(actions.specificAction.render).toBe(mockRender);
globalExpect(actions["*"].render).toBeUndefined();
});
test("should not preserve render function when no matching action", () => {
const mockRender = () => "Unmatched Render";
const aguiMessage = {
id: "assistant-4",
role: "assistant",
content: "I'll execute an unmatched function",
toolCalls: [
{
id: "tool-call-4",
type: "function",
function: {
name: "unmatchedAction",
arguments: JSON.stringify({ param: "value" })
}
}
],
generativeUI: mockRender
};
const actions = {
otherAction: { name: "otherAction" }
};
const result = aguiToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(actions.otherAction.render).toBeUndefined();
});
test("should handle multiple tool calls with wild card action", () => {
const mockRender = () => "Wild Card Render";
const aguiMessage = {
id: "assistant-5",
role: "assistant",
content: "I'll execute multiple functions",
toolCalls: [
{
id: "tool-call-5",
type: "function",
function: {
name: "firstFunction",
arguments: JSON.stringify({ param: "value1" })
}
},
{
id: "tool-call-6",
type: "function",
function: {
name: "secondFunction",
arguments: JSON.stringify({ param: "value2" })
}
}
],
generativeUI: mockRender
};
const actions = {
"*": { name: "*" }
};
const result = aguiToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(3);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(result[2]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(actions["*"].render).toBe(mockRender);
});
test("should handle mixed specific and wild card actions", () => {
const mockRender = () => "Mixed Render";
const aguiMessage = {
id: "assistant-6",
role: "assistant",
content: "I'll execute mixed functions",
toolCalls: [
{
id: "tool-call-7",
type: "function",
function: {
name: "specificAction",
arguments: JSON.stringify({ param: "value1" })
}
},
{
id: "tool-call-8",
type: "function",
function: {
name: "unknownAction",
arguments: JSON.stringify({ param: "value2" })
}
}
],
generativeUI: mockRender
};
const actions = {
specificAction: { name: "specificAction" },
"*": { name: "*" }
};
const result = aguiToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(3);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(result[2]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(actions.specificAction.render).toBe(mockRender);
globalExpect(actions["*"].render).toBe(mockRender);
});
test("should handle no actions provided", () => {
const mockRender = () => "No Actions Render";
const aguiMessage = {
id: "assistant-7",
role: "assistant",
content: "I'll execute a function",
toolCalls: [
{
id: "tool-call-9",
type: "function",
function: {
name: "anyAction",
arguments: JSON.stringify({ param: "value" })
}
}
],
generativeUI: mockRender
};
const result = aguiToGQL(aguiMessage);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
});
test("should handle empty actions object", () => {
const mockRender = () => "Empty Actions Render";
const aguiMessage = {
id: "assistant-8",
role: "assistant",
content: "I'll execute a function",
toolCalls: [
{
id: "tool-call-10",
type: "function",
function: {
name: "anyAction",
arguments: JSON.stringify({ param: "value" })
}
}
],
generativeUI: mockRender
};
const actions = {};
const result = aguiToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
});
test("should handle actions with null render functions", () => {
const mockRender = () => "Null Render Test";
const aguiMessage = {
id: "assistant-9",
role: "assistant",
content: "I'll execute a function",
toolCalls: [
{
id: "tool-call-11",
type: "function",
function: {
name: "specificAction",
arguments: JSON.stringify({ param: "value" })
}
}
],
generativeUI: mockRender
};
const actions = {
specificAction: { name: "specificAction", render: null },
"*": { name: "*", render: null }
};
const result = aguiToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(actions.specificAction.render).toBe(mockRender);
});
test("should handle actions with undefined render functions", () => {
const mockRender = () => "Undefined Render Test";
const aguiMessage = {
id: "assistant-10",
role: "assistant",
content: "I'll execute a function",
toolCalls: [
{
id: "tool-call-12",
type: "function",
function: {
name: "wildcardAction",
arguments: JSON.stringify({ param: "value" })
}
}
],
generativeUI: mockRender
};
const actions = {
"*": { name: "*", render: void 0 }
};
const result = aguiToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(actions["*"].render).toBe(mockRender);
});
test("should handle tool calls with malformed arguments", () => {
const mockRender = () => "Malformed Args Test";
const aguiMessage = {
id: "assistant-11",
role: "assistant",
content: "I'll execute a function",
toolCalls: [
{
id: "tool-call-13",
type: "function",
function: {
name: "wildcardAction",
arguments: "invalid json {"
// Malformed JSON
}
}
],
generativeUI: mockRender
};
const actions = {
"*": { name: "*" }
};
const result = aguiToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(actions["*"].render).toBe(mockRender);
});
test("should handle tool calls with empty arguments string", () => {
const mockRender = () => "Empty Args Test";
const aguiMessage = {
id: "assistant-12",
role: "assistant",
content: "I'll execute a function",
toolCalls: [
{
id: "tool-call-14",
type: "function",
function: {
name: "wildcardAction",
arguments: ""
}
}
],
generativeUI: mockRender
};
const actions = {
"*": { name: "*" }
};
const result = aguiToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(actions["*"].render).toBe(mockRender);
});
test("should handle multiple wild card actions in same object", () => {
const mockRender = () => "Multiple Wildcards Test";
const aguiMessage = {
id: "assistant-13",
role: "assistant",
content: "I'll execute a function",
toolCalls: [
{
id: "tool-call-15",
type: "function",
function: {
name: "unknownAction",
arguments: JSON.stringify({ param: "value" })
}
}
],
generativeUI: mockRender
};
const actions = {
wildcard1: { name: "*" },
wildcard2: { name: "*" }
};
const result = aguiToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(actions.wildcard1.render).toBe(mockRender);
globalExpect(actions.wildcard2.render).toBeUndefined();
});
test("should handle tool calls with object arguments (backward compatibility)", () => {
const mockRender = () => "Object Args Test";
const aguiMessage = {
id: "assistant-14",
role: "assistant",
content: "I'll execute a function",
toolCalls: [
{
id: "tool-call-16",
type: "function",
function: {
name: "objectArgsAction",
arguments: { param: "value" }
// Object instead of string
}
}
],
generativeUI: mockRender
};
const actions = {
"*": { name: "*" }
};
const result = aguiToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(result[1].arguments).toEqual({ param: "value" });
globalExpect(actions["*"].render).toBe(mockRender);
});
test("should handle tool calls with null/undefined arguments", () => {
const mockRender = () => "Null Args Test";
const aguiMessage = {
id: "assistant-15",
role: "assistant",
content: "I'll execute a function",
toolCalls: [
{
id: "tool-call-17",
type: "function",
function: {
name: "nullArgsAction",
arguments: null
}
}
],
generativeUI: mockRender
};
const actions = {
"*": { name: "*" }
};
const result = aguiToGQL(aguiMessage, actions);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toBeInstanceOf(TextMessage);
globalExpect(result[1]).toBeInstanceOf(ActionExecutionMessage);
globalExpect(result[1].arguments).toEqual({});
globalExpect(actions["*"].render).toBe(mockRender);
});
test("should handle tool result messages with object content", () => {
const aguiMessage = {
id: "tool-result-1",
role: "tool",
content: { status: "success", data: { value: 42 } },
toolCallId: "tool-call-1",
toolName: "testAction"
};
const toolCallNames = { "tool-call-1": "testAction" };
const result = aguiToGQL(aguiMessage);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toBeInstanceOf(ResultMessage);
globalExpect(result[0].result).toBe('{"status":"success","data":{"value":42}}');
globalExpect(result[0].actionExecutionId).toBe("tool-call-1");
globalExpect(result[0].actionName).toBe("testAction");
});
test("should handle tool result messages with non-string content types", () => {
const aguiMessage = {
id: "tool-result-2",
role: "tool",
content: 42,
toolCallId: "tool-call-2",
toolName: "numberAction"
};
const result = aguiToGQL(aguiMessage);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toBeInstanceOf(ResultMessage);
globalExpect(result[0].result).toBe("42");
globalExpect(result[0].actionExecutionId).toBe("tool-call-2");
globalExpect(result[0].actionName).toBe("numberAction");
});
test("should handle tool result messages with circular reference content", () => {
const circularObj = { status: "success" };
circularObj.self = circularObj;
const aguiMessage = {
id: "tool-result-3",
role: "tool",
content: circularObj,
toolCallId: "tool-call-3",
toolName: "circularAction"
};
const result = aguiToGQL(aguiMessage);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toBeInstanceOf(ResultMessage);
globalExpect(result[0].result).toBe("[object Object]");
globalExpect(result[0].actionExecutionId).toBe("tool-call-3");
globalExpect(result[0].actionName).toBe("circularAction");
});
test("should handle tool result messages with boolean content", () => {
const aguiMessage = {
id: "tool-result-4",
role: "tool",
content: true,
toolCallId: "tool-call-4",
toolName: "booleanAction"
};
const result = aguiToGQL(aguiMessage);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toBeInstanceOf(ResultMessage);
globalExpect(result[0].result).toBe("true");
globalExpect(result[0].actionExecutionId).toBe("tool-call-4");
globalExpect(result[0].actionName).toBe("booleanAction");
});
});
});
//# sourceMappingURL=agui-to-gql.test.mjs.map