@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,374 lines (1,373 loc) • 43.6 kB
JavaScript
import {
gqlActionExecutionMessageToAGUIMessage,
gqlImageMessageToAGUIMessage,
gqlResultMessageToAGUIMessage,
gqlTextMessageToAGUIMessage,
gqlToAGUI
} from "../chunk-EIPAWDCN.mjs";
import {
describe,
globalExpect,
test,
vi
} from "../chunk-SVJN2STA.mjs";
import "../chunk-7ECCT6PK.mjs";
import "../chunk-WVBWDNR6.mjs";
import "../chunk-WUF3XSW5.mjs";
import "../chunk-EWRHYLZE.mjs";
import "../chunk-AQ2Y6PF5.mjs";
import "../chunk-AMFKR5ST.mjs";
import {
ActionExecutionMessage,
AgentStateMessage,
ImageMessage,
ResultMessage,
Role,
TextMessage
} from "../chunk-NHOKFX55.mjs";
import "../chunk-OBDQ5BWD.mjs";
import "../chunk-DELDZXUX.mjs";
// src/message-conversion/gql-to-agui.test.ts
describe("message-conversion", () => {
describe("gqlTextMessageToAGUIMessage", () => {
test("should convert developer message", () => {
const gqlMessage = new TextMessage({
id: "dev-message-id",
content: "Hello from developer",
role: Role.Developer
});
const result = gqlTextMessageToAGUIMessage(gqlMessage);
globalExpect(result).toEqual({
id: "dev-message-id",
role: "developer",
content: "Hello from developer"
});
});
test("should convert system message", () => {
const gqlMessage = new TextMessage({
id: "system-message-id",
content: "System instruction",
role: Role.System
});
const result = gqlTextMessageToAGUIMessage(gqlMessage);
globalExpect(result).toEqual({
id: "system-message-id",
role: "system",
content: "System instruction"
});
});
test("should convert assistant message", () => {
const gqlMessage = new TextMessage({
id: "assistant-message-id",
content: "Assistant response",
role: Role.Assistant
});
const result = gqlTextMessageToAGUIMessage(gqlMessage);
globalExpect(result).toEqual({
id: "assistant-message-id",
role: "assistant",
content: "Assistant response"
});
});
test("should throw error for unknown role", () => {
const gqlMessage = new TextMessage({
id: "unknown-message-id",
content: "Unknown message",
role: "unknown"
});
globalExpect(() => gqlTextMessageToAGUIMessage(gqlMessage)).toThrow("Unknown message role");
});
});
describe("gqlResultMessageToAGUIMessage", () => {
test("should convert result message to tool message", () => {
const gqlMessage = new ResultMessage({
id: "result-id",
result: "Function result data",
actionExecutionId: "action-exec-123",
actionName: "testAction"
});
const result = gqlResultMessageToAGUIMessage(gqlMessage);
globalExpect(result).toEqual({
id: "result-id",
role: "tool",
content: "Function result data",
toolCallId: "action-exec-123",
toolName: "testAction"
});
});
});
describe("gqlToAGUI", () => {
test("should convert an array of text messages", () => {
const gqlMessages = [
new TextMessage({
id: "dev-1",
content: "Hello",
role: Role.Developer
}),
new TextMessage({
id: "assistant-1",
content: "Hi there",
role: Role.Assistant
})
];
const result = gqlToAGUI(gqlMessages);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toEqual({
id: "dev-1",
role: "developer",
content: "Hello"
});
globalExpect(result[1]).toEqual({
id: "assistant-1",
role: "assistant",
content: "Hi there"
});
});
test("should handle agent state messages", () => {
const gqlMessages = [new AgentStateMessage({ id: "agent-state-1" })];
const result = gqlToAGUI(gqlMessages);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toEqual({
id: "agent-state-1",
role: "assistant"
});
});
test("should handle a mix of message types", () => {
const gqlMessages = [
new TextMessage({
id: "dev-1",
content: "Run action",
role: Role.Developer
}),
new TextMessage({
id: "assistant-1",
content: "I'll run the action",
role: Role.Assistant
}),
new ResultMessage({
id: "result-1",
result: "Action result",
actionExecutionId: "action-exec-1",
actionName: "testAction"
})
];
const result = gqlToAGUI(gqlMessages);
globalExpect(result).toHaveLength(3);
globalExpect(result[0]).toEqual({
id: "dev-1",
role: "developer",
content: "Run action"
});
globalExpect(result[1]).toEqual({
id: "assistant-1",
role: "assistant",
content: "I'll run the action"
});
globalExpect(result[2]).toEqual({
id: "result-1",
role: "tool",
content: "Action result",
toolCallId: "action-exec-1",
toolName: "testAction"
});
});
test("should handle action execution messages with parent messages", () => {
const assistantMsg = new TextMessage({
id: "assistant-1",
content: "I'll execute an action",
role: Role.Assistant
});
const actionExecMsg = new ActionExecutionMessage({
id: "action-1",
name: "testAction",
arguments: { param: "value" },
parentMessageId: "assistant-1"
});
const result = gqlToAGUI([assistantMsg, actionExecMsg]);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toEqual({
id: "assistant-1",
role: "assistant",
content: "I'll execute an action"
});
globalExpect(result[1]).toEqual({
id: "action-1",
role: "assistant",
name: "testAction",
toolCalls: [
{
id: "action-1",
function: {
name: "testAction",
arguments: JSON.stringify({ param: "value" })
},
type: "function"
}
]
});
});
test("should handle multiple action execution messages for the same parent", () => {
const assistantMsg = new TextMessage({
id: "assistant-1",
content: "I'll execute multiple actions",
role: Role.Assistant
});
const action1 = new ActionExecutionMessage({
id: "action-1",
name: "firstAction",
arguments: { param: "value1" },
parentMessageId: "assistant-1"
});
const action2 = new ActionExecutionMessage({
id: "action-2",
name: "secondAction",
arguments: { param: "value2" },
parentMessageId: "assistant-1"
});
const result = gqlToAGUI([assistantMsg, action1, action2]);
globalExpect(result).toHaveLength(3);
globalExpect(result[0]).toEqual({
id: "assistant-1",
role: "assistant",
content: "I'll execute multiple actions"
});
globalExpect(result[1]).toEqual({
id: "action-1",
role: "assistant",
name: "firstAction",
toolCalls: [
{
id: "action-1",
function: {
name: "firstAction",
arguments: JSON.stringify({ param: "value1" })
},
type: "function"
}
]
});
globalExpect(result[2]).toEqual({
id: "action-2",
role: "assistant",
name: "secondAction",
toolCalls: [
{
id: "action-2",
function: {
name: "secondAction",
arguments: JSON.stringify({ param: "value2" })
},
type: "function"
}
]
});
});
test("should not add toolCalls to non-assistant messages", () => {
const developerMsg = new TextMessage({
id: "dev-1",
content: "Developer message",
role: Role.Developer
});
const actionExecMsg = new ActionExecutionMessage({
id: "action-1",
name: "testAction",
arguments: { param: "value" },
parentMessageId: "dev-1"
// This should be ignored since parent is not assistant
});
const result = gqlToAGUI([developerMsg, actionExecMsg]);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toEqual({
id: "dev-1",
role: "developer",
content: "Developer message"
});
globalExpect(result[1]).toEqual({
id: "action-1",
role: "assistant",
name: "testAction",
toolCalls: [
{
id: "action-1",
function: {
name: "testAction",
arguments: JSON.stringify({ param: "value" })
},
type: "function"
}
]
});
});
test("should handle action execution messages without actions context", () => {
const actionExecMsg = new ActionExecutionMessage({
id: "action-1",
name: "testAction",
arguments: { param: "value" }
});
const result = gqlToAGUI([actionExecMsg]);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toEqual({
id: "action-1",
role: "assistant",
name: "testAction",
toolCalls: [
{
id: "action-1",
function: {
name: "testAction",
arguments: JSON.stringify({ param: "value" })
},
type: "function"
}
]
});
globalExpect(result[0]).not.toHaveProperty("render");
globalExpect(result[0]).not.toHaveProperty("renderAndWaitForResponse");
});
test("should handle action execution messages with actions context and render functions", () => {
const actionExecMsg = new ActionExecutionMessage({
id: "action-1",
name: "testAction",
arguments: { param: "value" },
status: { code: "Pending" /* Pending */ }
});
const mockRender = vi.fn();
const mockRenderAndWaitForResponse = (props) => "Test Render With Response";
const actions = {
testAction: {
name: "testAction",
render: mockRender,
renderAndWaitForResponse: mockRenderAndWaitForResponse
}
};
const result = gqlToAGUI([actionExecMsg], actions);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toMatchObject({
id: "action-1",
role: "assistant",
name: "testAction",
content: "",
toolCalls: [
{
id: "action-1",
function: {
name: "testAction",
arguments: JSON.stringify({ param: "value" })
},
type: "function"
}
]
});
globalExpect(result[0]).toHaveProperty("generativeUI");
globalExpect(typeof result[0].generativeUI).toBe("function");
});
test("should provide correct status in generativeUI function props", () => {
var _a, _b;
const actionExecMsg = new ActionExecutionMessage({
id: "action-1",
name: "testAction",
arguments: { param: "value" },
status: { code: "Pending" /* Pending */ }
});
const mockRender = vi.fn();
const actions = {
testAction: {
name: "testAction",
render: mockRender
}
};
const result = gqlToAGUI([actionExecMsg], actions);
(_b = (_a = result[0]).generativeUI) == null ? void 0 : _b.call(_a);
globalExpect(mockRender).toHaveBeenCalledWith({
status: "inProgress",
args: { param: "value" },
result: void 0,
respond: globalExpect.any(Function),
messageId: "action-1"
// Regular actions should NOT have the name property
});
});
test("should provide executing status when not pending", () => {
var _a, _b;
const actionExecMsg = new ActionExecutionMessage({
id: "action-1",
name: "testAction",
arguments: { param: "value" },
status: { code: "Success" /* Success */ }
});
const mockRender = vi.fn();
const actions = {
testAction: {
name: "testAction",
render: mockRender
}
};
const result = gqlToAGUI([actionExecMsg], actions);
(_b = (_a = result[0]).generativeUI) == null ? void 0 : _b.call(_a);
globalExpect(mockRender).toHaveBeenCalledWith({
status: "executing",
args: { param: "value" },
result: void 0,
respond: globalExpect.any(Function),
messageId: "action-1"
// Regular actions should NOT have the name property
});
});
test("should provide complete status when result is available", () => {
var _a;
const actionExecMsg = new ActionExecutionMessage({
id: "action-1",
name: "testAction",
arguments: { param: "value" },
status: { code: "Success" /* Success */ }
});
const resultMsg = new ResultMessage({
id: "result-1",
result: "Action completed successfully",
actionExecutionId: "action-1",
actionName: "testAction"
});
const mockRender = vi.fn();
const actions = {
testAction: {
name: "testAction",
render: mockRender
}
};
const result = gqlToAGUI([actionExecMsg, resultMsg], actions);
const actionMessage = result.find((msg) => msg.role === "assistant" && "toolCalls" in msg);
(_a = actionMessage == null ? void 0 : actionMessage.generativeUI) == null ? void 0 : _a.call(actionMessage);
globalExpect(mockRender).toHaveBeenCalledWith({
status: "complete",
args: { param: "value" },
result: "Action completed successfully",
respond: globalExpect.any(Function),
messageId: "action-1"
// Regular actions should NOT have the name property
});
});
test("should handle generativeUI function props override", () => {
var _a, _b;
const actionExecMsg = new ActionExecutionMessage({
id: "action-1",
name: "testAction",
arguments: { param: "value" },
status: { code: "Pending" /* Pending */ }
});
const mockRender = vi.fn();
const actions = {
testAction: {
name: "testAction",
render: mockRender
}
};
const result = gqlToAGUI([actionExecMsg], actions);
(_b = (_a = result[0]).generativeUI) == null ? void 0 : _b.call(_a, {
status: "custom",
customProp: "test",
respond: () => "custom respond"
});
globalExpect(mockRender).toHaveBeenCalledWith({
status: "custom",
args: { param: "value" },
result: void 0,
respond: globalExpect.any(Function),
customProp: "test",
messageId: "action-1"
// Regular actions should NOT have the name property
});
});
test("should handle missing render functions gracefully", () => {
const actionExecMsg = new ActionExecutionMessage({
id: "action-1",
name: "testAction",
arguments: { param: "value" }
});
const actions = {
testAction: {
name: "testAction"
// No render functions provided
}
};
const result = gqlToAGUI([actionExecMsg], actions);
globalExpect(result[0]).toMatchObject({
id: "action-1",
role: "assistant",
name: "testAction",
content: "",
toolCalls: [
{
id: "action-1",
function: {
name: "testAction",
arguments: JSON.stringify({ param: "value" })
},
type: "function"
}
]
});
globalExpect(result[0].generativeUI).toBeUndefined();
});
test("should handle action not found in actions context", () => {
const actionExecMsg = new ActionExecutionMessage({
id: "action-1",
name: "unknownAction",
arguments: { param: "value" }
});
const actions = {
testAction: {
name: "testAction",
render: () => "Test"
}
};
const result = gqlToAGUI([actionExecMsg], actions);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toEqual({
id: "action-1",
role: "assistant",
name: "unknownAction",
toolCalls: [
{
id: "action-1",
function: {
name: "unknownAction",
arguments: JSON.stringify({ param: "value" })
},
type: "function"
}
]
});
globalExpect(result[0]).not.toHaveProperty("generativeUI");
});
test("should handle agent state messages with coAgentStateRenders", () => {
var _a, _b;
const agentStateMsg = new AgentStateMessage({
id: "agent-state-1",
agentName: "testAgent",
state: { status: "running", data: "test data" },
role: Role.Assistant
});
const mockRender = vi.fn();
const coAgentStateRenders = {
testAgent: {
name: "testAgent",
render: mockRender
}
};
const result = gqlToAGUI([agentStateMsg], void 0, coAgentStateRenders);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toEqual({
id: "agent-state-1",
role: "assistant",
agentName: "testAgent",
state: { status: "running", data: "test data" },
generativeUI: globalExpect.any(Function)
});
globalExpect(result[0]).toHaveProperty("generativeUI");
globalExpect(typeof result[0].generativeUI).toBe("function");
(_b = (_a = result[0]).generativeUI) == null ? void 0 : _b.call(_a);
globalExpect(mockRender).toHaveBeenCalledWith({
state: { status: "running", data: "test data" }
});
});
test("should handle agent state messages without coAgentStateRenders", () => {
const agentStateMsg = new AgentStateMessage({
id: "agent-state-1",
agentName: "testAgent",
state: { status: "running", data: "test data" },
role: Role.Assistant
});
const result = gqlToAGUI([agentStateMsg]);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toEqual({
id: "agent-state-1",
role: "assistant",
agentName: "testAgent",
state: { status: "running", data: "test data" }
});
globalExpect(result[0]).not.toHaveProperty("generativeUI");
});
test("should handle agent state messages with agent not found in coAgentStateRenders", () => {
const agentStateMsg = new AgentStateMessage({
id: "agent-state-1",
agentName: "unknownAgent",
state: { status: "running", data: "test data" },
role: Role.Assistant
});
const coAgentStateRenders = {
testAgent: {
name: "testAgent",
render: () => "Test"
}
};
const result = gqlToAGUI([agentStateMsg], void 0, coAgentStateRenders);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toEqual({
id: "agent-state-1",
role: "assistant",
agentName: "unknownAgent",
state: { status: "running", data: "test data" }
});
globalExpect(result[0]).not.toHaveProperty("generativeUI");
});
test("should handle user role messages", () => {
const userMsg = new TextMessage({
id: "user-1",
content: "Hello from user",
role: Role.User
});
const result = gqlToAGUI([userMsg]);
globalExpect(result).toHaveLength(1);
globalExpect(result[0]).toEqual({
id: "user-1",
role: "user",
content: "Hello from user"
});
});
test("should handle mixed message types including agent state messages", () => {
const textMsg = new TextMessage({
id: "text-1",
content: "Hello",
role: Role.Assistant
});
const agentStateMsg = new AgentStateMessage({
id: "agent-state-1",
agentName: "testAgent",
state: { status: "running" },
role: Role.Assistant
});
const mockRender = vi.fn();
const coAgentStateRenders = {
testAgent: {
name: "testAgent",
render: mockRender
}
};
const result = gqlToAGUI([textMsg, agentStateMsg], void 0, coAgentStateRenders);
globalExpect(result).toHaveLength(2);
globalExpect(result[0]).toEqual({
id: "text-1",
role: "assistant",
content: "Hello"
});
globalExpect(result[1]).toMatchObject({
id: "agent-state-1",
role: "assistant",
agentName: "testAgent",
state: { status: "running" },
generativeUI: globalExpect.any(Function)
});
globalExpect(result[1]).toHaveProperty("generativeUI");
});
});
describe("gqlImageMessageToAGUIMessage", () => {
test("should throw error for invalid image format", () => {
const invalidImageMsg = new ImageMessage({
id: "img-1",
format: "bmp",
// not in VALID_IMAGE_FORMATS
bytes: "somebase64string",
role: Role.User
});
globalExpect(() => gqlImageMessageToAGUIMessage(invalidImageMsg)).toThrow("Invalid image format");
});
test("should throw error for empty image bytes", () => {
const invalidImageMsg = new ImageMessage({
id: "img-2",
format: "jpeg",
bytes: "",
role: Role.User
});
globalExpect(() => gqlImageMessageToAGUIMessage(invalidImageMsg)).toThrow(
"Image bytes must be a non-empty string"
);
});
test("should convert valid image message", () => {
const validImageMsg = new ImageMessage({
id: "img-3",
format: "jpeg",
bytes: "somebase64string",
role: Role.User
});
const result = gqlImageMessageToAGUIMessage(validImageMsg);
globalExpect(result).toMatchObject({
id: "img-3",
role: "user",
content: "",
image: {
format: "jpeg",
bytes: "somebase64string"
}
});
});
test("should convert valid user image message", () => {
const validImageMsg = new ImageMessage({
id: "img-user-1",
format: "jpeg",
bytes: "userbase64string",
role: Role.User
});
const result = gqlImageMessageToAGUIMessage(validImageMsg);
globalExpect(result).toMatchObject({
id: "img-user-1",
role: "user",
content: "",
image: {
format: "jpeg",
bytes: "userbase64string"
}
});
});
test("should convert valid assistant image message", () => {
const validImageMsg = new ImageMessage({
id: "img-assistant-1",
format: "png",
bytes: "assistantbase64string",
role: Role.Assistant
});
const result = gqlImageMessageToAGUIMessage(validImageMsg);
globalExpect(result).toMatchObject({
id: "img-assistant-1",
role: "assistant",
content: "",
image: {
format: "png",
bytes: "assistantbase64string"
}
});
});
});
describe("Wild Card Actions", () => {
test("should handle action execution with specific action", () => {
const actions = {
testAction: {
name: "testAction",
render: vi.fn((props) => `Rendered: ${props.args.test}`)
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-1",
name: "testAction",
arguments: { test: "value" },
parentMessageId: "parent-1"
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions);
globalExpect(result).toMatchObject({
id: "action-1",
role: "assistant",
content: "",
toolCalls: [
{
id: "action-1",
function: {
name: "testAction",
arguments: '{"test":"value"}'
},
type: "function"
}
],
generativeUI: globalExpect.any(Function),
name: "testAction"
});
});
test("should handle action execution with wild card action", () => {
const actions = {
"*": {
name: "*",
render: vi.fn((props) => `Wildcard rendered: ${props.args.test}`)
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-2",
name: "unknownAction",
arguments: { test: "wildcard-value" },
parentMessageId: "parent-2"
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions);
globalExpect(result).toMatchObject({
id: "action-2",
role: "assistant",
content: "",
toolCalls: [
{
id: "action-2",
function: {
name: "unknownAction",
arguments: '{"test":"wildcard-value"}'
},
type: "function"
}
],
generativeUI: globalExpect.any(Function),
name: "unknownAction"
});
});
test("should pass tool name to wildcard action render function", () => {
var _a;
const mockRender = vi.fn(
(props) => `Wildcard rendered: ${props.name} with args: ${JSON.stringify(props.args)}`
);
const actions = {
"*": {
name: "*",
render: mockRender
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-wildcard-name",
name: "testTool",
arguments: { param: "value" },
parentMessageId: "parent-wildcard-name"
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions);
(_a = result.generativeUI) == null ? void 0 : _a.call(result);
globalExpect(mockRender).toHaveBeenCalledWith(
globalExpect.objectContaining({
name: "testTool",
args: { param: "value" }
})
);
});
test("should pass tool name to regular action render function", () => {
var _a;
const mockRender = vi.fn((props) => `Regular action rendered: ${JSON.stringify(props.args)}`);
const actions = {
testAction: {
name: "testAction",
render: mockRender
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-regular-name",
name: "testAction",
arguments: { param: "value" },
parentMessageId: "parent-regular-name"
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions);
(_a = result.generativeUI) == null ? void 0 : _a.call(result);
globalExpect(mockRender).toHaveBeenCalledWith(
globalExpect.objectContaining({
args: { param: "value" }
// name property should NOT be present for regular actions
})
);
const callArgs = mockRender.mock.calls[0][0];
globalExpect(callArgs).not.toHaveProperty("name");
});
test("should prioritize specific action over wild card action", () => {
const actions = {
specificAction: {
name: "specificAction",
render: vi.fn((props) => "Specific action rendered")
},
"*": {
name: "*",
render: vi.fn((props) => "Wildcard action rendered")
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-3",
name: "specificAction",
arguments: { test: "value" },
parentMessageId: "parent-3"
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions);
globalExpect(result).toMatchObject({
id: "action-3",
role: "assistant",
content: "",
toolCalls: [
{
id: "action-3",
function: {
name: "specificAction",
arguments: '{"test":"value"}'
},
type: "function"
}
],
generativeUI: globalExpect.any(Function),
name: "specificAction"
});
});
test("should handle action execution without any matching actions", () => {
const actions = {
otherAction: {
name: "otherAction",
render: vi.fn()
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-4",
name: "unmatchedAction",
arguments: { test: "value" },
parentMessageId: "parent-4"
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions);
globalExpect(result).toMatchObject({
id: "action-4",
role: "assistant",
toolCalls: [
{
id: "action-4",
function: {
name: "unmatchedAction",
arguments: '{"test":"value"}'
},
type: "function"
}
],
name: "unmatchedAction"
});
globalExpect(result).not.toHaveProperty("generativeUI");
});
test("should handle action execution with no actions provided", () => {
const actionExecMsg = new ActionExecutionMessage({
id: "action-5",
name: "anyAction",
arguments: { test: "value" },
parentMessageId: "parent-5"
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg);
globalExpect(result).toMatchObject({
id: "action-5",
role: "assistant",
toolCalls: [
{
id: "action-5",
function: {
name: "anyAction",
arguments: '{"test":"value"}'
},
type: "function"
}
],
name: "anyAction"
});
globalExpect(result).not.toHaveProperty("generativeUI");
});
test("should handle action execution with completed result", () => {
const actions = {
"*": {
name: "*",
render: vi.fn((props) => `Result: ${props.result}`)
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-6",
name: "testAction",
arguments: { test: "value" },
parentMessageId: "parent-6"
});
const actionResults = /* @__PURE__ */ new Map([["action-6", "completed result"]]);
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions, actionResults);
globalExpect(result).toMatchObject({
id: "action-6",
role: "assistant",
content: "",
toolCalls: [
{
id: "action-6",
function: {
name: "testAction",
arguments: '{"test":"value"}'
},
type: "function"
}
],
generativeUI: globalExpect.any(Function),
name: "testAction"
});
});
test("should handle action execution with executing status", () => {
const actions = {
"*": {
name: "*",
render: vi.fn((props) => `Status: ${props.status}`)
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-7",
name: "testAction",
arguments: { test: "value" },
parentMessageId: "parent-7",
status: { code: "Success" /* Success */ }
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions);
globalExpect(result).toMatchObject({
id: "action-7",
role: "assistant",
content: "",
toolCalls: [
{
id: "action-7",
function: {
name: "testAction",
arguments: '{"test":"value"}'
},
type: "function"
}
],
generativeUI: globalExpect.any(Function),
name: "testAction"
});
});
test("should handle action execution with pending status", () => {
const actions = {
"*": {
name: "*",
render: vi.fn((props) => `Status: ${props.status}`)
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-8",
name: "testAction",
arguments: { test: "value" },
parentMessageId: "parent-8",
status: { code: "Pending" /* Pending */ }
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions);
globalExpect(result).toMatchObject({
id: "action-8",
role: "assistant",
content: "",
toolCalls: [
{
id: "action-8",
function: {
name: "testAction",
arguments: '{"test":"value"}'
},
type: "function"
}
],
generativeUI: globalExpect.any(Function),
name: "testAction"
});
});
test("should handle action execution with failed status", () => {
const actions = {
"*": {
name: "*",
render: vi.fn((props) => `Status: ${props.status}`)
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-9",
name: "testAction",
arguments: { test: "value" },
parentMessageId: "parent-9",
status: { code: "Failed" /* Failed */ }
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions);
globalExpect(result).toMatchObject({
id: "action-9",
role: "assistant",
content: "",
toolCalls: [
{
id: "action-9",
function: {
name: "testAction",
arguments: '{"test":"value"}'
},
type: "function"
}
],
generativeUI: globalExpect.any(Function),
name: "testAction"
});
});
test("should handle action execution with undefined status", () => {
const actions = {
"*": {
name: "*",
render: vi.fn((props) => `Status: ${props.status}`)
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-10",
name: "testAction",
arguments: { test: "value" },
parentMessageId: "parent-10"
// No status field
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions);
globalExpect(result).toMatchObject({
id: "action-10",
role: "assistant",
content: "",
toolCalls: [
{
id: "action-10",
function: {
name: "testAction",
arguments: '{"test":"value"}'
},
type: "function"
}
],
generativeUI: globalExpect.any(Function),
name: "testAction"
});
});
test("should handle action execution with empty arguments", () => {
const actions = {
"*": {
name: "*",
render: vi.fn((props) => `Args: ${JSON.stringify(props.args)}`)
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-11",
name: "testAction",
arguments: {},
parentMessageId: "parent-11"
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions);
globalExpect(result).toMatchObject({
id: "action-11",
role: "assistant",
content: "",
toolCalls: [
{
id: "action-11",
function: {
name: "testAction",
arguments: "{}"
},
type: "function"
}
],
generativeUI: globalExpect.any(Function),
name: "testAction"
});
});
test("should handle action execution with null arguments", () => {
const actions = {
"*": {
name: "*",
render: vi.fn((props) => `Args: ${JSON.stringify(props.args)}`)
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-12",
name: "testAction",
arguments: null,
parentMessageId: "parent-12"
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions);
globalExpect(result).toMatchObject({
id: "action-12",
role: "assistant",
content: "",
toolCalls: [
{
id: "action-12",
function: {
name: "testAction",
arguments: "null"
},
type: "function"
}
],
generativeUI: globalExpect.any(Function),
name: "testAction"
});
});
test("should handle action execution with complex nested arguments", () => {
const actions = {
"*": {
name: "*",
render: vi.fn((props) => `Complex: ${JSON.stringify(props.args)}`)
}
};
const complexArgs = {
nested: {
array: [1, 2, 3],
object: { key: "value" },
nullValue: null,
undefinedValue: void 0
},
string: "test",
number: 42,
boolean: true
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-13",
name: "testAction",
arguments: complexArgs,
parentMessageId: "parent-13"
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions);
globalExpect(result).toMatchObject({
id: "action-13",
role: "assistant",
content: "",
toolCalls: [
{
id: "action-13",
function: {
name: "testAction",
arguments: JSON.stringify(complexArgs)
},
type: "function"
}
],
generativeUI: globalExpect.any(Function),
name: "testAction"
});
});
test("should handle multiple wild card actions (should use first one)", () => {
const actions = {
wildcard1: {
name: "*",
render: vi.fn((props) => "First wildcard")
},
wildcard2: {
name: "*",
render: vi.fn((props) => "Second wildcard")
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-14",
name: "unknownAction",
arguments: { test: "value" },
parentMessageId: "parent-14"
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions);
globalExpect(result).toMatchObject({
id: "action-14",
role: "assistant",
content: "",
toolCalls: [
{
id: "action-14",
function: {
name: "unknownAction",
arguments: '{"test":"value"}'
},
type: "function"
}
],
generativeUI: globalExpect.any(Function),
name: "unknownAction"
});
});
test("should parse string results in generativeUI props", () => {
const actions = {
"*": {
name: "*",
render: vi.fn((props) => `Result: ${JSON.stringify(props.result)}`)
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-string-result",
name: "stringResultAction",
arguments: { test: "value" },
parentMessageId: "parent-string"
});
const actionResults = /* @__PURE__ */ new Map();
actionResults.set("action-string-result", '{"parsed": true, "value": 42}');
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions, actionResults);
globalExpect(result.generativeUI).toBeDefined();
const renderResult = result.generativeUI({
result: '{"from": "props", "data": "test"}'
});
globalExpect(actions["*"].render).toHaveBeenCalledWith(
globalExpect.objectContaining({
result: { from: "props", data: "test" },
// Should be parsed from string
args: { test: "value" },
status: "complete",
messageId: "action-string-result"
})
);
});
test("should handle malformed JSON strings gracefully in results", () => {
const actions = {
"*": {
name: "*",
render: vi.fn((props) => `Result: ${JSON.stringify(props.result)}`)
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-malformed",
name: "malformedAction",
arguments: { test: "value" },
parentMessageId: "parent-malformed"
});
const actionResults = /* @__PURE__ */ new Map();
actionResults.set("action-malformed", "invalid json {");
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions, actionResults);
globalExpect(result.generativeUI).toBeDefined();
const renderResult = result.generativeUI({
result: "invalid json {"
});
globalExpect(actions["*"].render).toHaveBeenCalledWith(
globalExpect.objectContaining({
result: "invalid json {",
// Should remain as string due to parse error
args: { test: "value" },
status: "complete",
messageId: "action-malformed"
})
);
});
test("should handle non-string results without parsing", () => {
const actions = {
"*": {
name: "*",
render: vi.fn((props) => `Result: ${JSON.stringify(props.result)}`)
}
};
const actionExecMsg = new ActionExecutionMessage({
id: "action-object-result",
name: "objectResultAction",
arguments: { test: "value" },
parentMessageId: "parent-object"
});
const actionResults = /* @__PURE__ */ new Map();
actionResults.set("action-object-result", '{"already": "parsed"}');
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg, actions, actionResults);
globalExpect(result.generativeUI).toBeDefined();
const renderResult = result.generativeUI({
result: { from: "props", data: "object" }
});
globalExpect(actions["*"].render).toHaveBeenCalledWith(
globalExpect.objectContaining({
result: { from: "props", data: "object" },
// Should remain as object
args: { test: "value" },
status: "complete",
messageId: "action-object-result"
})
);
});
test("should handle action execution arguments correctly with simplified conversion", () => {
const actionExecMsg = new ActionExecutionMessage({
id: "action-simplified",
name: "simplifiedAction",
arguments: { complex: { nested: "value" }, array: [1, 2, 3] },
parentMessageId: "parent-simplified"
});
const result = gqlActionExecutionMessageToAGUIMessage(actionExecMsg);
globalExpect(result).toMatchObject({
id: "action-simplified",
role: "assistant",
toolCalls: [
{
id: "action-simplified",
function: {
name: "simplifiedAction",
arguments: '{"complex":{"nested":"value"},"array":[1,2,3]}'
},
type: "function"
}
],
name: "simplifiedAction"
});
});
});
});
//# sourceMappingURL=gql-to-agui.test.mjs.map