UNPKG

@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
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