@copilotkit/runtime 1.53.1-next.1 → 1.54.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @copilotkit/runtime
2
2
 
3
+ ## 1.54.0-next.3
4
+
5
+ ### Minor Changes
6
+
7
+ - fa0d1cd: Add support for Standard Schema (instead of just Zod)
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [fa0d1cd]
12
+ - @copilotkitnext/agent@1.54.0-next.3
13
+ - @copilotkit/shared@1.54.0-next.3
14
+ - @copilotkitnext/runtime@1.54.0-next.3
15
+
16
+ ## 1.53.1-next.2
17
+
18
+ ### Patch Changes
19
+
20
+ - @copilotkit/shared@1.53.1-next.2
21
+ - @copilotkitnext/agent@1.53.1-next.2
22
+ - @copilotkitnext/runtime@1.53.1-next.2
23
+
3
24
  ## 1.53.1-next.1
4
25
 
5
26
  ### Patch Changes
@@ -100,12 +100,16 @@ function aguiToolCallToGQLActionExecution(toolCall, parentMessageId) {
100
100
  if (typeof toolCall.function.arguments === "string") try {
101
101
  argumentsObj = JSON.parse(toolCall.function.arguments);
102
102
  } catch (error) {
103
- console.warn(`Failed to parse tool call arguments for ${toolCall.function.name}:`, error);
103
+ console.warn(`[CopilotKit] Failed to parse tool arguments, falling back to empty object`);
104
104
  argumentsObj = {};
105
105
  }
106
106
  else if (typeof toolCall.function.arguments === "object" && toolCall.function.arguments !== null) argumentsObj = toolCall.function.arguments;
107
107
  else {
108
- console.warn(`Invalid tool call arguments type for ${toolCall.function.name}:`, typeof toolCall.function.arguments);
108
+ console.warn(`[CopilotKit] Tool arguments parsed to non-object (${typeof toolCall.function.arguments}), falling back to empty object`);
109
+ argumentsObj = {};
110
+ }
111
+ if (typeof argumentsObj !== "object" || argumentsObj === null || Array.isArray(argumentsObj)) {
112
+ console.warn(`[CopilotKit] Tool arguments parsed to non-object (${typeof argumentsObj}), falling back to empty object`);
109
113
  argumentsObj = {};
110
114
  }
111
115
  return new require_index.ActionExecutionMessage({
@@ -1 +1 @@
1
- {"version":3,"file":"agui-to-gql.cjs","names":[],"sources":["../../../src/graphql/message-conversion/agui-to-gql.ts"],"sourcesContent":["import * as gql from \"../types/converted/index\";\nimport { MessageRole } from \"../types/enums\";\nimport agui from \"@copilotkit/shared\"; // named agui for clarity, but this only includes agui message types\n\n// Helper function to extract agent name from message\nfunction extractAgentName(message: agui.Message): string {\n if (message.role !== \"assistant\") {\n throw new Error(\n `Cannot extract agent name from message with role ${message.role}`,\n );\n }\n\n return message.agentName || \"unknown\";\n}\n\n// Type guard for agent state message\nfunction isAgentStateMessage(message: agui.Message): boolean {\n return (\n message.role === \"assistant\" && \"agentName\" in message && \"state\" in message\n );\n}\n\n// Type guard for messages with image property\nfunction hasImageProperty(message: agui.Message): boolean {\n const canContainImage =\n message.role === \"assistant\" || message.role === \"user\";\n if (!canContainImage || message.image === undefined) {\n return false;\n }\n\n const isMalformed =\n message.image.format === undefined || message.image.bytes === undefined;\n if (isMalformed) {\n return false;\n }\n\n return true;\n}\n\nfunction normalizeMessageContent(content: agui.Message[\"content\"]): string {\n if (typeof content === \"string\" || typeof content === \"undefined\") {\n return content || \"\";\n }\n\n if (Array.isArray(content)) {\n return content\n .map((part) => {\n if (part?.type === \"text\") {\n return part.text;\n }\n if (part?.type === \"binary\") {\n return (\n part.data ||\n part.url ||\n part.filename ||\n `[binary:${part.mimeType}]`\n );\n }\n return \"\";\n })\n .filter(Boolean)\n .join(\"\\n\");\n }\n\n if (content && typeof content === \"object\") {\n try {\n return JSON.stringify(content);\n } catch (error) {\n console.warn(\"Failed to serialize message content\", error);\n }\n }\n\n return String(content ?? \"\");\n}\n\n/*\n ----------------------------\n AGUI Message -> GQL Message\n ----------------------------\n*/\nexport function aguiToGQL(\n messages: agui.Message[] | agui.Message,\n actions?: Record<string, any>,\n coAgentStateRenders?: Record<string, any>,\n): gql.Message[] {\n const gqlMessages: gql.Message[] = [];\n messages = Array.isArray(messages) ? messages : [messages];\n\n // Track tool call names by their IDs for use in result messages\n const toolCallNames: Record<string, string> = {};\n\n for (const message of messages) {\n // Agent state message support\n if (isAgentStateMessage(message)) {\n const agentName = extractAgentName(message);\n const state = \"state\" in message && message.state ? message.state : {};\n gqlMessages.push(\n new gql.AgentStateMessage({\n id: message.id,\n agentName,\n state,\n role: gql.Role.assistant,\n }),\n );\n // Optionally preserve render function\n if (\n \"generativeUI\" in message &&\n message.generativeUI &&\n coAgentStateRenders\n ) {\n coAgentStateRenders[agentName] = {\n name: agentName,\n render: message.generativeUI,\n };\n }\n continue;\n }\n\n if (hasImageProperty(message)) {\n gqlMessages.push(aguiMessageWithImageToGQLMessage(message));\n continue;\n }\n\n // Action execution message support\n if (message.role === \"assistant\" && message.toolCalls) {\n gqlMessages.push(aguiTextMessageToGQLMessage(message));\n for (const toolCall of message.toolCalls) {\n // Track the tool call name by its ID\n toolCallNames[toolCall.id] = toolCall.function.name;\n\n const actionExecMsg = aguiToolCallToGQLActionExecution(\n toolCall,\n message.id,\n );\n // Preserve render function in actions context\n if (\"generativeUI\" in message && message.generativeUI && actions) {\n const actionName = toolCall.function.name;\n // Check for specific action first, then wild card action\n const specificAction = Object.values(actions).find(\n (action: any) => action.name === actionName,\n );\n const wildcardAction = Object.values(actions).find(\n (action: any) => action.name === \"*\",\n );\n\n // Assign render function to the matching action (specific takes priority)\n if (specificAction) {\n specificAction.render = message.generativeUI;\n } else if (wildcardAction) {\n wildcardAction.render = message.generativeUI;\n }\n }\n gqlMessages.push(actionExecMsg);\n }\n continue;\n }\n // Reasoning messages are ephemeral display-only content with no GQL equivalent — skip them\n if (message.role === \"reasoning\") {\n continue;\n }\n // Regular text messages\n if (\n message.role === \"developer\" ||\n message.role === \"system\" ||\n message.role === \"assistant\" ||\n message.role === \"user\"\n ) {\n gqlMessages.push(aguiTextMessageToGQLMessage(message));\n continue;\n }\n // Tool result message\n if (message.role === \"tool\") {\n gqlMessages.push(\n aguiToolMessageToGQLResultMessage(message, toolCallNames),\n );\n continue;\n }\n throw new Error(\n `Unknown message role: \"${(message as any).role}\" in message with id: ${(message as any).id}`,\n );\n }\n\n return gqlMessages;\n}\n\nexport function aguiTextMessageToGQLMessage(\n message: agui.Message,\n): gql.TextMessage {\n if (\n message.role !== \"developer\" &&\n message.role !== \"system\" &&\n message.role !== \"assistant\" &&\n message.role !== \"user\"\n ) {\n throw new Error(\n `Cannot convert message with role ${message.role} to TextMessage`,\n );\n }\n\n let roleValue: MessageRole;\n\n if (message.role === \"developer\") {\n roleValue = gql.Role.developer;\n } else if (message.role === \"system\") {\n roleValue = gql.Role.system;\n } else if (message.role === \"assistant\") {\n roleValue = gql.Role.assistant;\n } else {\n roleValue = gql.Role.user;\n }\n\n return new gql.TextMessage({\n id: message.id,\n content: normalizeMessageContent(message.content),\n role: roleValue,\n });\n}\n\nexport function aguiToolCallToGQLActionExecution(\n toolCall: agui.ToolCall,\n parentMessageId: string,\n): gql.ActionExecutionMessage {\n if (toolCall.type !== \"function\") {\n throw new Error(`Unsupported tool call type: ${toolCall.type}`);\n }\n\n // Handle arguments - they should be a JSON string in AGUI format,\n // but we need to convert them to an object for GQL format\n let argumentsObj: any;\n\n if (typeof toolCall.function.arguments === \"string\") {\n // Expected case: arguments is a JSON string\n try {\n argumentsObj = JSON.parse(toolCall.function.arguments);\n } catch (error) {\n console.warn(\n `Failed to parse tool call arguments for ${toolCall.function.name}:`,\n error,\n );\n // Provide fallback empty object to prevent application crash\n argumentsObj = {};\n }\n } else if (\n typeof toolCall.function.arguments === \"object\" &&\n toolCall.function.arguments !== null\n ) {\n // Backward compatibility: arguments is already an object\n argumentsObj = toolCall.function.arguments;\n } else {\n // Fallback for undefined, null, or other types\n console.warn(\n `Invalid tool call arguments type for ${toolCall.function.name}:`,\n typeof toolCall.function.arguments,\n );\n argumentsObj = {};\n }\n\n // Always include name and arguments\n return new gql.ActionExecutionMessage({\n id: toolCall.id,\n name: toolCall.function.name,\n arguments: argumentsObj,\n parentMessageId: parentMessageId,\n });\n}\n\nexport function aguiToolMessageToGQLResultMessage(\n message: agui.Message,\n toolCallNames: Record<string, string>,\n): gql.ResultMessage {\n if (message.role !== \"tool\") {\n throw new Error(\n `Cannot convert message with role ${message.role} to ResultMessage`,\n );\n }\n\n if (!message.toolCallId) {\n throw new Error(\"Tool message must have a toolCallId\");\n }\n\n const actionName = toolCallNames[message.toolCallId] || \"unknown\";\n\n // Handle result content - it could be a string or an object that needs serialization\n let resultContent: string;\n const messageContent = message.content || \"\";\n\n if (typeof messageContent === \"string\") {\n // Expected case: content is already a string\n resultContent = messageContent;\n } else if (typeof messageContent === \"object\" && messageContent !== null) {\n // Handle case where content is an object that needs to be serialized\n try {\n resultContent = JSON.stringify(messageContent);\n } catch (error) {\n console.warn(`Failed to stringify tool result for ${actionName}:`, error);\n resultContent = String(messageContent);\n }\n } else {\n // Handle other types (number, boolean, etc.)\n resultContent = String(messageContent);\n }\n\n return new gql.ResultMessage({\n id: message.id,\n result: resultContent,\n actionExecutionId: message.toolCallId,\n actionName: message.toolName || actionName,\n });\n}\n\n// New function to handle AGUI messages with render functions\nexport function aguiMessageWithRenderToGQL(\n message: agui.Message,\n actions?: Record<string, any>,\n coAgentStateRenders?: Record<string, any>,\n): gql.Message[] {\n // Handle the special case: assistant messages with render function but no tool calls\n if (\n message.role === \"assistant\" &&\n \"generativeUI\" in message &&\n message.generativeUI &&\n !message.toolCalls\n ) {\n const gqlMessages: gql.Message[] = [];\n gqlMessages.push(\n new gql.AgentStateMessage({\n id: message.id,\n agentName: \"unknown\",\n state: {},\n role: gql.Role.assistant,\n }),\n );\n if (coAgentStateRenders) {\n coAgentStateRenders.unknown = {\n name: \"unknown\",\n render: message.generativeUI,\n };\n }\n return gqlMessages;\n }\n\n // For all other cases, delegate to aguiToGQL\n return aguiToGQL([message], actions, coAgentStateRenders);\n}\n\nexport function aguiMessageWithImageToGQLMessage(\n message: agui.Message,\n): gql.ImageMessage {\n if (!hasImageProperty(message)) {\n throw new Error(\n `Cannot convert message to ImageMessage: missing format or bytes`,\n );\n }\n\n let roleValue: MessageRole;\n if (message.role === \"assistant\") {\n roleValue = gql.Role.assistant;\n } else {\n roleValue = gql.Role.user;\n }\n\n if (message.role !== \"assistant\" && message.role !== \"user\") {\n throw new Error(\n `Cannot convert message with role ${message.role} to ImageMessage`,\n );\n }\n\n return new gql.ImageMessage({\n id: message.id,\n format: message.image!.format,\n bytes: message.image!.bytes,\n role: roleValue,\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agui-to-gql.cjs","names":[],"sources":["../../../src/graphql/message-conversion/agui-to-gql.ts"],"sourcesContent":["import * as gql from \"../types/converted/index\";\nimport { MessageRole } from \"../types/enums\";\nimport agui from \"@copilotkit/shared\"; // named agui for clarity, but this only includes agui message types\n\n// Helper function to extract agent name from message\nfunction extractAgentName(message: agui.Message): string {\n if (message.role !== \"assistant\") {\n throw new Error(\n `Cannot extract agent name from message with role ${message.role}`,\n );\n }\n\n return message.agentName || \"unknown\";\n}\n\n// Type guard for agent state message\nfunction isAgentStateMessage(message: agui.Message): boolean {\n return (\n message.role === \"assistant\" && \"agentName\" in message && \"state\" in message\n );\n}\n\n// Type guard for messages with image property\nfunction hasImageProperty(message: agui.Message): boolean {\n const canContainImage =\n message.role === \"assistant\" || message.role === \"user\";\n if (!canContainImage || message.image === undefined) {\n return false;\n }\n\n const isMalformed =\n message.image.format === undefined || message.image.bytes === undefined;\n if (isMalformed) {\n return false;\n }\n\n return true;\n}\n\nfunction normalizeMessageContent(content: agui.Message[\"content\"]): string {\n if (typeof content === \"string\" || typeof content === \"undefined\") {\n return content || \"\";\n }\n\n if (Array.isArray(content)) {\n return content\n .map((part) => {\n if (part?.type === \"text\") {\n return part.text;\n }\n if (part?.type === \"binary\") {\n return (\n part.data ||\n part.url ||\n part.filename ||\n `[binary:${part.mimeType}]`\n );\n }\n return \"\";\n })\n .filter(Boolean)\n .join(\"\\n\");\n }\n\n if (content && typeof content === \"object\") {\n try {\n return JSON.stringify(content);\n } catch (error) {\n console.warn(\"Failed to serialize message content\", error);\n }\n }\n\n return String(content ?? \"\");\n}\n\n/*\n ----------------------------\n AGUI Message -> GQL Message\n ----------------------------\n*/\nexport function aguiToGQL(\n messages: agui.Message[] | agui.Message,\n actions?: Record<string, any>,\n coAgentStateRenders?: Record<string, any>,\n): gql.Message[] {\n const gqlMessages: gql.Message[] = [];\n messages = Array.isArray(messages) ? messages : [messages];\n\n // Track tool call names by their IDs for use in result messages\n const toolCallNames: Record<string, string> = {};\n\n for (const message of messages) {\n // Agent state message support\n if (isAgentStateMessage(message)) {\n const agentName = extractAgentName(message);\n const state = \"state\" in message && message.state ? message.state : {};\n gqlMessages.push(\n new gql.AgentStateMessage({\n id: message.id,\n agentName,\n state,\n role: gql.Role.assistant,\n }),\n );\n // Optionally preserve render function\n if (\n \"generativeUI\" in message &&\n message.generativeUI &&\n coAgentStateRenders\n ) {\n coAgentStateRenders[agentName] = {\n name: agentName,\n render: message.generativeUI,\n };\n }\n continue;\n }\n\n if (hasImageProperty(message)) {\n gqlMessages.push(aguiMessageWithImageToGQLMessage(message));\n continue;\n }\n\n // Action execution message support\n if (message.role === \"assistant\" && message.toolCalls) {\n gqlMessages.push(aguiTextMessageToGQLMessage(message));\n for (const toolCall of message.toolCalls) {\n // Track the tool call name by its ID\n toolCallNames[toolCall.id] = toolCall.function.name;\n\n const actionExecMsg = aguiToolCallToGQLActionExecution(\n toolCall,\n message.id,\n );\n // Preserve render function in actions context\n if (\"generativeUI\" in message && message.generativeUI && actions) {\n const actionName = toolCall.function.name;\n // Check for specific action first, then wild card action\n const specificAction = Object.values(actions).find(\n (action: any) => action.name === actionName,\n );\n const wildcardAction = Object.values(actions).find(\n (action: any) => action.name === \"*\",\n );\n\n // Assign render function to the matching action (specific takes priority)\n if (specificAction) {\n specificAction.render = message.generativeUI;\n } else if (wildcardAction) {\n wildcardAction.render = message.generativeUI;\n }\n }\n gqlMessages.push(actionExecMsg);\n }\n continue;\n }\n // Reasoning messages are ephemeral display-only content with no GQL equivalent — skip them\n if (message.role === \"reasoning\") {\n continue;\n }\n // Regular text messages\n if (\n message.role === \"developer\" ||\n message.role === \"system\" ||\n message.role === \"assistant\" ||\n message.role === \"user\"\n ) {\n gqlMessages.push(aguiTextMessageToGQLMessage(message));\n continue;\n }\n // Tool result message\n if (message.role === \"tool\") {\n gqlMessages.push(\n aguiToolMessageToGQLResultMessage(message, toolCallNames),\n );\n continue;\n }\n throw new Error(\n `Unknown message role: \"${(message as any).role}\" in message with id: ${(message as any).id}`,\n );\n }\n\n return gqlMessages;\n}\n\nexport function aguiTextMessageToGQLMessage(\n message: agui.Message,\n): gql.TextMessage {\n if (\n message.role !== \"developer\" &&\n message.role !== \"system\" &&\n message.role !== \"assistant\" &&\n message.role !== \"user\"\n ) {\n throw new Error(\n `Cannot convert message with role ${message.role} to TextMessage`,\n );\n }\n\n let roleValue: MessageRole;\n\n if (message.role === \"developer\") {\n roleValue = gql.Role.developer;\n } else if (message.role === \"system\") {\n roleValue = gql.Role.system;\n } else if (message.role === \"assistant\") {\n roleValue = gql.Role.assistant;\n } else {\n roleValue = gql.Role.user;\n }\n\n return new gql.TextMessage({\n id: message.id,\n content: normalizeMessageContent(message.content),\n role: roleValue,\n });\n}\n\nexport function aguiToolCallToGQLActionExecution(\n toolCall: agui.ToolCall,\n parentMessageId: string,\n): gql.ActionExecutionMessage {\n if (toolCall.type !== \"function\") {\n throw new Error(`Unsupported tool call type: ${toolCall.type}`);\n }\n\n // Handle arguments - they should be a JSON string in AGUI format,\n // but we need to convert them to an object for GQL format\n let argumentsObj: any;\n\n if (typeof toolCall.function.arguments === \"string\") {\n // Expected case: arguments is a JSON string\n try {\n argumentsObj = JSON.parse(toolCall.function.arguments);\n } catch (error) {\n console.warn(\n `[CopilotKit] Failed to parse tool arguments, falling back to empty object`,\n );\n // Provide fallback empty object to prevent application crash\n argumentsObj = {};\n }\n } else if (\n typeof toolCall.function.arguments === \"object\" &&\n toolCall.function.arguments !== null\n ) {\n // Backward compatibility: arguments is already an object\n argumentsObj = toolCall.function.arguments;\n } else {\n // Fallback for undefined, null, or other types\n console.warn(\n `[CopilotKit] Tool arguments parsed to non-object (${typeof toolCall.function.arguments}), falling back to empty object`,\n );\n argumentsObj = {};\n }\n\n // Guard against successfully parsed non-object values (e.g. JSON.parse('\"\"') → \"\")\n if (\n typeof argumentsObj !== \"object\" ||\n argumentsObj === null ||\n Array.isArray(argumentsObj)\n ) {\n console.warn(\n `[CopilotKit] Tool arguments parsed to non-object (${typeof argumentsObj}), falling back to empty object`,\n );\n argumentsObj = {};\n }\n\n // Always include name and arguments\n return new gql.ActionExecutionMessage({\n id: toolCall.id,\n name: toolCall.function.name,\n arguments: argumentsObj,\n parentMessageId: parentMessageId,\n });\n}\n\nexport function aguiToolMessageToGQLResultMessage(\n message: agui.Message,\n toolCallNames: Record<string, string>,\n): gql.ResultMessage {\n if (message.role !== \"tool\") {\n throw new Error(\n `Cannot convert message with role ${message.role} to ResultMessage`,\n );\n }\n\n if (!message.toolCallId) {\n throw new Error(\"Tool message must have a toolCallId\");\n }\n\n const actionName = toolCallNames[message.toolCallId] || \"unknown\";\n\n // Handle result content - it could be a string or an object that needs serialization\n let resultContent: string;\n const messageContent = message.content || \"\";\n\n if (typeof messageContent === \"string\") {\n // Expected case: content is already a string\n resultContent = messageContent;\n } else if (typeof messageContent === \"object\" && messageContent !== null) {\n // Handle case where content is an object that needs to be serialized\n try {\n resultContent = JSON.stringify(messageContent);\n } catch (error) {\n console.warn(`Failed to stringify tool result for ${actionName}:`, error);\n resultContent = String(messageContent);\n }\n } else {\n // Handle other types (number, boolean, etc.)\n resultContent = String(messageContent);\n }\n\n return new gql.ResultMessage({\n id: message.id,\n result: resultContent,\n actionExecutionId: message.toolCallId,\n actionName: message.toolName || actionName,\n });\n}\n\n// New function to handle AGUI messages with render functions\nexport function aguiMessageWithRenderToGQL(\n message: agui.Message,\n actions?: Record<string, any>,\n coAgentStateRenders?: Record<string, any>,\n): gql.Message[] {\n // Handle the special case: assistant messages with render function but no tool calls\n if (\n message.role === \"assistant\" &&\n \"generativeUI\" in message &&\n message.generativeUI &&\n !message.toolCalls\n ) {\n const gqlMessages: gql.Message[] = [];\n gqlMessages.push(\n new gql.AgentStateMessage({\n id: message.id,\n agentName: \"unknown\",\n state: {},\n role: gql.Role.assistant,\n }),\n );\n if (coAgentStateRenders) {\n coAgentStateRenders.unknown = {\n name: \"unknown\",\n render: message.generativeUI,\n };\n }\n return gqlMessages;\n }\n\n // For all other cases, delegate to aguiToGQL\n return aguiToGQL([message], actions, coAgentStateRenders);\n}\n\nexport function aguiMessageWithImageToGQLMessage(\n message: agui.Message,\n): gql.ImageMessage {\n if (!hasImageProperty(message)) {\n throw new Error(\n `Cannot convert message to ImageMessage: missing format or bytes`,\n );\n }\n\n let roleValue: MessageRole;\n if (message.role === \"assistant\") {\n roleValue = gql.Role.assistant;\n } else {\n roleValue = gql.Role.user;\n }\n\n if (message.role !== \"assistant\" && message.role !== \"user\") {\n throw new Error(\n `Cannot convert message with role ${message.role} to ImageMessage`,\n );\n }\n\n return new gql.ImageMessage({\n id: message.id,\n format: message.image!.format,\n bytes: message.image!.bytes,\n role: roleValue,\n });\n}\n"],"mappings":"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"}
@@ -100,12 +100,16 @@ function aguiToolCallToGQLActionExecution(toolCall, parentMessageId) {
100
100
  if (typeof toolCall.function.arguments === "string") try {
101
101
  argumentsObj = JSON.parse(toolCall.function.arguments);
102
102
  } catch (error) {
103
- console.warn(`Failed to parse tool call arguments for ${toolCall.function.name}:`, error);
103
+ console.warn(`[CopilotKit] Failed to parse tool arguments, falling back to empty object`);
104
104
  argumentsObj = {};
105
105
  }
106
106
  else if (typeof toolCall.function.arguments === "object" && toolCall.function.arguments !== null) argumentsObj = toolCall.function.arguments;
107
107
  else {
108
- console.warn(`Invalid tool call arguments type for ${toolCall.function.name}:`, typeof toolCall.function.arguments);
108
+ console.warn(`[CopilotKit] Tool arguments parsed to non-object (${typeof toolCall.function.arguments}), falling back to empty object`);
109
+ argumentsObj = {};
110
+ }
111
+ if (typeof argumentsObj !== "object" || argumentsObj === null || Array.isArray(argumentsObj)) {
112
+ console.warn(`[CopilotKit] Tool arguments parsed to non-object (${typeof argumentsObj}), falling back to empty object`);
109
113
  argumentsObj = {};
110
114
  }
111
115
  return new ActionExecutionMessage({
@@ -1 +1 @@
1
- {"version":3,"file":"agui-to-gql.mjs","names":["gql.AgentStateMessage","gql.TextMessage","gql.ActionExecutionMessage","gql.ResultMessage","gql.ImageMessage"],"sources":["../../../src/graphql/message-conversion/agui-to-gql.ts"],"sourcesContent":["import * as gql from \"../types/converted/index\";\nimport { MessageRole } from \"../types/enums\";\nimport agui from \"@copilotkit/shared\"; // named agui for clarity, but this only includes agui message types\n\n// Helper function to extract agent name from message\nfunction extractAgentName(message: agui.Message): string {\n if (message.role !== \"assistant\") {\n throw new Error(\n `Cannot extract agent name from message with role ${message.role}`,\n );\n }\n\n return message.agentName || \"unknown\";\n}\n\n// Type guard for agent state message\nfunction isAgentStateMessage(message: agui.Message): boolean {\n return (\n message.role === \"assistant\" && \"agentName\" in message && \"state\" in message\n );\n}\n\n// Type guard for messages with image property\nfunction hasImageProperty(message: agui.Message): boolean {\n const canContainImage =\n message.role === \"assistant\" || message.role === \"user\";\n if (!canContainImage || message.image === undefined) {\n return false;\n }\n\n const isMalformed =\n message.image.format === undefined || message.image.bytes === undefined;\n if (isMalformed) {\n return false;\n }\n\n return true;\n}\n\nfunction normalizeMessageContent(content: agui.Message[\"content\"]): string {\n if (typeof content === \"string\" || typeof content === \"undefined\") {\n return content || \"\";\n }\n\n if (Array.isArray(content)) {\n return content\n .map((part) => {\n if (part?.type === \"text\") {\n return part.text;\n }\n if (part?.type === \"binary\") {\n return (\n part.data ||\n part.url ||\n part.filename ||\n `[binary:${part.mimeType}]`\n );\n }\n return \"\";\n })\n .filter(Boolean)\n .join(\"\\n\");\n }\n\n if (content && typeof content === \"object\") {\n try {\n return JSON.stringify(content);\n } catch (error) {\n console.warn(\"Failed to serialize message content\", error);\n }\n }\n\n return String(content ?? \"\");\n}\n\n/*\n ----------------------------\n AGUI Message -> GQL Message\n ----------------------------\n*/\nexport function aguiToGQL(\n messages: agui.Message[] | agui.Message,\n actions?: Record<string, any>,\n coAgentStateRenders?: Record<string, any>,\n): gql.Message[] {\n const gqlMessages: gql.Message[] = [];\n messages = Array.isArray(messages) ? messages : [messages];\n\n // Track tool call names by their IDs for use in result messages\n const toolCallNames: Record<string, string> = {};\n\n for (const message of messages) {\n // Agent state message support\n if (isAgentStateMessage(message)) {\n const agentName = extractAgentName(message);\n const state = \"state\" in message && message.state ? message.state : {};\n gqlMessages.push(\n new gql.AgentStateMessage({\n id: message.id,\n agentName,\n state,\n role: gql.Role.assistant,\n }),\n );\n // Optionally preserve render function\n if (\n \"generativeUI\" in message &&\n message.generativeUI &&\n coAgentStateRenders\n ) {\n coAgentStateRenders[agentName] = {\n name: agentName,\n render: message.generativeUI,\n };\n }\n continue;\n }\n\n if (hasImageProperty(message)) {\n gqlMessages.push(aguiMessageWithImageToGQLMessage(message));\n continue;\n }\n\n // Action execution message support\n if (message.role === \"assistant\" && message.toolCalls) {\n gqlMessages.push(aguiTextMessageToGQLMessage(message));\n for (const toolCall of message.toolCalls) {\n // Track the tool call name by its ID\n toolCallNames[toolCall.id] = toolCall.function.name;\n\n const actionExecMsg = aguiToolCallToGQLActionExecution(\n toolCall,\n message.id,\n );\n // Preserve render function in actions context\n if (\"generativeUI\" in message && message.generativeUI && actions) {\n const actionName = toolCall.function.name;\n // Check for specific action first, then wild card action\n const specificAction = Object.values(actions).find(\n (action: any) => action.name === actionName,\n );\n const wildcardAction = Object.values(actions).find(\n (action: any) => action.name === \"*\",\n );\n\n // Assign render function to the matching action (specific takes priority)\n if (specificAction) {\n specificAction.render = message.generativeUI;\n } else if (wildcardAction) {\n wildcardAction.render = message.generativeUI;\n }\n }\n gqlMessages.push(actionExecMsg);\n }\n continue;\n }\n // Reasoning messages are ephemeral display-only content with no GQL equivalent — skip them\n if (message.role === \"reasoning\") {\n continue;\n }\n // Regular text messages\n if (\n message.role === \"developer\" ||\n message.role === \"system\" ||\n message.role === \"assistant\" ||\n message.role === \"user\"\n ) {\n gqlMessages.push(aguiTextMessageToGQLMessage(message));\n continue;\n }\n // Tool result message\n if (message.role === \"tool\") {\n gqlMessages.push(\n aguiToolMessageToGQLResultMessage(message, toolCallNames),\n );\n continue;\n }\n throw new Error(\n `Unknown message role: \"${(message as any).role}\" in message with id: ${(message as any).id}`,\n );\n }\n\n return gqlMessages;\n}\n\nexport function aguiTextMessageToGQLMessage(\n message: agui.Message,\n): gql.TextMessage {\n if (\n message.role !== \"developer\" &&\n message.role !== \"system\" &&\n message.role !== \"assistant\" &&\n message.role !== \"user\"\n ) {\n throw new Error(\n `Cannot convert message with role ${message.role} to TextMessage`,\n );\n }\n\n let roleValue: MessageRole;\n\n if (message.role === \"developer\") {\n roleValue = gql.Role.developer;\n } else if (message.role === \"system\") {\n roleValue = gql.Role.system;\n } else if (message.role === \"assistant\") {\n roleValue = gql.Role.assistant;\n } else {\n roleValue = gql.Role.user;\n }\n\n return new gql.TextMessage({\n id: message.id,\n content: normalizeMessageContent(message.content),\n role: roleValue,\n });\n}\n\nexport function aguiToolCallToGQLActionExecution(\n toolCall: agui.ToolCall,\n parentMessageId: string,\n): gql.ActionExecutionMessage {\n if (toolCall.type !== \"function\") {\n throw new Error(`Unsupported tool call type: ${toolCall.type}`);\n }\n\n // Handle arguments - they should be a JSON string in AGUI format,\n // but we need to convert them to an object for GQL format\n let argumentsObj: any;\n\n if (typeof toolCall.function.arguments === \"string\") {\n // Expected case: arguments is a JSON string\n try {\n argumentsObj = JSON.parse(toolCall.function.arguments);\n } catch (error) {\n console.warn(\n `Failed to parse tool call arguments for ${toolCall.function.name}:`,\n error,\n );\n // Provide fallback empty object to prevent application crash\n argumentsObj = {};\n }\n } else if (\n typeof toolCall.function.arguments === \"object\" &&\n toolCall.function.arguments !== null\n ) {\n // Backward compatibility: arguments is already an object\n argumentsObj = toolCall.function.arguments;\n } else {\n // Fallback for undefined, null, or other types\n console.warn(\n `Invalid tool call arguments type for ${toolCall.function.name}:`,\n typeof toolCall.function.arguments,\n );\n argumentsObj = {};\n }\n\n // Always include name and arguments\n return new gql.ActionExecutionMessage({\n id: toolCall.id,\n name: toolCall.function.name,\n arguments: argumentsObj,\n parentMessageId: parentMessageId,\n });\n}\n\nexport function aguiToolMessageToGQLResultMessage(\n message: agui.Message,\n toolCallNames: Record<string, string>,\n): gql.ResultMessage {\n if (message.role !== \"tool\") {\n throw new Error(\n `Cannot convert message with role ${message.role} to ResultMessage`,\n );\n }\n\n if (!message.toolCallId) {\n throw new Error(\"Tool message must have a toolCallId\");\n }\n\n const actionName = toolCallNames[message.toolCallId] || \"unknown\";\n\n // Handle result content - it could be a string or an object that needs serialization\n let resultContent: string;\n const messageContent = message.content || \"\";\n\n if (typeof messageContent === \"string\") {\n // Expected case: content is already a string\n resultContent = messageContent;\n } else if (typeof messageContent === \"object\" && messageContent !== null) {\n // Handle case where content is an object that needs to be serialized\n try {\n resultContent = JSON.stringify(messageContent);\n } catch (error) {\n console.warn(`Failed to stringify tool result for ${actionName}:`, error);\n resultContent = String(messageContent);\n }\n } else {\n // Handle other types (number, boolean, etc.)\n resultContent = String(messageContent);\n }\n\n return new gql.ResultMessage({\n id: message.id,\n result: resultContent,\n actionExecutionId: message.toolCallId,\n actionName: message.toolName || actionName,\n });\n}\n\n// New function to handle AGUI messages with render functions\nexport function aguiMessageWithRenderToGQL(\n message: agui.Message,\n actions?: Record<string, any>,\n coAgentStateRenders?: Record<string, any>,\n): gql.Message[] {\n // Handle the special case: assistant messages with render function but no tool calls\n if (\n message.role === \"assistant\" &&\n \"generativeUI\" in message &&\n message.generativeUI &&\n !message.toolCalls\n ) {\n const gqlMessages: gql.Message[] = [];\n gqlMessages.push(\n new gql.AgentStateMessage({\n id: message.id,\n agentName: \"unknown\",\n state: {},\n role: gql.Role.assistant,\n }),\n );\n if (coAgentStateRenders) {\n coAgentStateRenders.unknown = {\n name: \"unknown\",\n render: message.generativeUI,\n };\n }\n return gqlMessages;\n }\n\n // For all other cases, delegate to aguiToGQL\n return aguiToGQL([message], actions, coAgentStateRenders);\n}\n\nexport function aguiMessageWithImageToGQLMessage(\n message: agui.Message,\n): gql.ImageMessage {\n if (!hasImageProperty(message)) {\n throw new Error(\n `Cannot convert message to ImageMessage: missing format or bytes`,\n );\n }\n\n let roleValue: MessageRole;\n if (message.role === \"assistant\") {\n roleValue = gql.Role.assistant;\n } else {\n roleValue = gql.Role.user;\n }\n\n if (message.role !== \"assistant\" && message.role !== \"user\") {\n throw new Error(\n `Cannot convert message with role ${message.role} to ImageMessage`,\n );\n }\n\n return new gql.ImageMessage({\n id: message.id,\n format: message.image!.format,\n bytes: message.image!.bytes,\n role: roleValue,\n });\n}\n"],"mappings":";;;;AAKA,SAAS,iBAAiB,SAA+B;AACvD,KAAI,QAAQ,SAAS,YACnB,OAAM,IAAI,MACR,oDAAoD,QAAQ,OAC7D;AAGH,QAAO,QAAQ,aAAa;;AAI9B,SAAS,oBAAoB,SAAgC;AAC3D,QACE,QAAQ,SAAS,eAAe,eAAe,WAAW,WAAW;;AAKzE,SAAS,iBAAiB,SAAgC;AAGxD,KAAI,EADF,QAAQ,SAAS,eAAe,QAAQ,SAAS,WAC3B,QAAQ,UAAU,OACxC,QAAO;AAKT,KADE,QAAQ,MAAM,WAAW,UAAa,QAAQ,MAAM,UAAU,OAE9D,QAAO;AAGT,QAAO;;AAGT,SAAS,wBAAwB,SAA0C;AACzE,KAAI,OAAO,YAAY,YAAY,OAAO,YAAY,YACpD,QAAO,WAAW;AAGpB,KAAI,MAAM,QAAQ,QAAQ,CACxB,QAAO,QACJ,KAAK,SAAS;AACb,MAAI,MAAM,SAAS,OACjB,QAAO,KAAK;AAEd,MAAI,MAAM,SAAS,SACjB,QACE,KAAK,QACL,KAAK,OACL,KAAK,YACL,WAAW,KAAK,SAAS;AAG7B,SAAO;GACP,CACD,OAAO,QAAQ,CACf,KAAK,KAAK;AAGf,KAAI,WAAW,OAAO,YAAY,SAChC,KAAI;AACF,SAAO,KAAK,UAAU,QAAQ;UACvB,OAAO;AACd,UAAQ,KAAK,uCAAuC,MAAM;;AAI9D,QAAO,OAAO,WAAW,GAAG;;AAQ9B,SAAgB,UACd,UACA,SACA,qBACe;CACf,MAAM,cAA6B,EAAE;AACrC,YAAW,MAAM,QAAQ,SAAS,GAAG,WAAW,CAAC,SAAS;CAG1D,MAAM,gBAAwC,EAAE;AAEhD,MAAK,MAAM,WAAW,UAAU;AAE9B,MAAI,oBAAoB,QAAQ,EAAE;GAChC,MAAM,YAAY,iBAAiB,QAAQ;GAC3C,MAAM,QAAQ,WAAW,WAAW,QAAQ,QAAQ,QAAQ,QAAQ,EAAE;AACtE,eAAY,KACV,IAAIA,kBAAsB;IACxB,IAAI,QAAQ;IACZ;IACA;IACA,WAAe;IAChB,CAAC,CACH;AAED,OACE,kBAAkB,WAClB,QAAQ,gBACR,oBAEA,qBAAoB,aAAa;IAC/B,MAAM;IACN,QAAQ,QAAQ;IACjB;AAEH;;AAGF,MAAI,iBAAiB,QAAQ,EAAE;AAC7B,eAAY,KAAK,iCAAiC,QAAQ,CAAC;AAC3D;;AAIF,MAAI,QAAQ,SAAS,eAAe,QAAQ,WAAW;AACrD,eAAY,KAAK,4BAA4B,QAAQ,CAAC;AACtD,QAAK,MAAM,YAAY,QAAQ,WAAW;AAExC,kBAAc,SAAS,MAAM,SAAS,SAAS;IAE/C,MAAM,gBAAgB,iCACpB,UACA,QAAQ,GACT;AAED,QAAI,kBAAkB,WAAW,QAAQ,gBAAgB,SAAS;KAChE,MAAM,aAAa,SAAS,SAAS;KAErC,MAAM,iBAAiB,OAAO,OAAO,QAAQ,CAAC,MAC3C,WAAgB,OAAO,SAAS,WAClC;KACD,MAAM,iBAAiB,OAAO,OAAO,QAAQ,CAAC,MAC3C,WAAgB,OAAO,SAAS,IAClC;AAGD,SAAI,eACF,gBAAe,SAAS,QAAQ;cACvB,eACT,gBAAe,SAAS,QAAQ;;AAGpC,gBAAY,KAAK,cAAc;;AAEjC;;AAGF,MAAI,QAAQ,SAAS,YACnB;AAGF,MACE,QAAQ,SAAS,eACjB,QAAQ,SAAS,YACjB,QAAQ,SAAS,eACjB,QAAQ,SAAS,QACjB;AACA,eAAY,KAAK,4BAA4B,QAAQ,CAAC;AACtD;;AAGF,MAAI,QAAQ,SAAS,QAAQ;AAC3B,eAAY,KACV,kCAAkC,SAAS,cAAc,CAC1D;AACD;;AAEF,QAAM,IAAI,MACR,0BAA2B,QAAgB,KAAK,wBAAyB,QAAgB,KAC1F;;AAGH,QAAO;;AAGT,SAAgB,4BACd,SACiB;AACjB,KACE,QAAQ,SAAS,eACjB,QAAQ,SAAS,YACjB,QAAQ,SAAS,eACjB,QAAQ,SAAS,OAEjB,OAAM,IAAI,MACR,oCAAoC,QAAQ,KAAK,iBAClD;CAGH,IAAI;AAEJ,KAAI,QAAQ,SAAS,YACnB,kBAAqB;UACZ,QAAQ,SAAS,SAC1B,kBAAqB;UACZ,QAAQ,SAAS,YAC1B,kBAAqB;KAErB,kBAAqB;AAGvB,QAAO,IAAIC,YAAgB;EACzB,IAAI,QAAQ;EACZ,SAAS,wBAAwB,QAAQ,QAAQ;EACjD,MAAM;EACP,CAAC;;AAGJ,SAAgB,iCACd,UACA,iBAC4B;AAC5B,KAAI,SAAS,SAAS,WACpB,OAAM,IAAI,MAAM,+BAA+B,SAAS,OAAO;CAKjE,IAAI;AAEJ,KAAI,OAAO,SAAS,SAAS,cAAc,SAEzC,KAAI;AACF,iBAAe,KAAK,MAAM,SAAS,SAAS,UAAU;UAC/C,OAAO;AACd,UAAQ,KACN,2CAA2C,SAAS,SAAS,KAAK,IAClE,MACD;AAED,iBAAe,EAAE;;UAGnB,OAAO,SAAS,SAAS,cAAc,YACvC,SAAS,SAAS,cAAc,KAGhC,gBAAe,SAAS,SAAS;MAC5B;AAEL,UAAQ,KACN,wCAAwC,SAAS,SAAS,KAAK,IAC/D,OAAO,SAAS,SAAS,UAC1B;AACD,iBAAe,EAAE;;AAInB,QAAO,IAAIC,uBAA2B;EACpC,IAAI,SAAS;EACb,MAAM,SAAS,SAAS;EACxB,WAAW;EACM;EAClB,CAAC;;AAGJ,SAAgB,kCACd,SACA,eACmB;AACnB,KAAI,QAAQ,SAAS,OACnB,OAAM,IAAI,MACR,oCAAoC,QAAQ,KAAK,mBAClD;AAGH,KAAI,CAAC,QAAQ,WACX,OAAM,IAAI,MAAM,sCAAsC;CAGxD,MAAM,aAAa,cAAc,QAAQ,eAAe;CAGxD,IAAI;CACJ,MAAM,iBAAiB,QAAQ,WAAW;AAE1C,KAAI,OAAO,mBAAmB,SAE5B,iBAAgB;UACP,OAAO,mBAAmB,YAAY,mBAAmB,KAElE,KAAI;AACF,kBAAgB,KAAK,UAAU,eAAe;UACvC,OAAO;AACd,UAAQ,KAAK,uCAAuC,WAAW,IAAI,MAAM;AACzE,kBAAgB,OAAO,eAAe;;KAIxC,iBAAgB,OAAO,eAAe;AAGxC,QAAO,IAAIC,cAAkB;EAC3B,IAAI,QAAQ;EACZ,QAAQ;EACR,mBAAmB,QAAQ;EAC3B,YAAY,QAAQ,YAAY;EACjC,CAAC;;AAsCJ,SAAgB,iCACd,SACkB;AAClB,KAAI,CAAC,iBAAiB,QAAQ,CAC5B,OAAM,IAAI,MACR,kEACD;CAGH,IAAI;AACJ,KAAI,QAAQ,SAAS,YACnB,kBAAqB;KAErB,kBAAqB;AAGvB,KAAI,QAAQ,SAAS,eAAe,QAAQ,SAAS,OACnD,OAAM,IAAI,MACR,oCAAoC,QAAQ,KAAK,kBAClD;AAGH,QAAO,IAAIC,aAAiB;EAC1B,IAAI,QAAQ;EACZ,QAAQ,QAAQ,MAAO;EACvB,OAAO,QAAQ,MAAO;EACtB,MAAM;EACP,CAAC"}
1
+ {"version":3,"file":"agui-to-gql.mjs","names":["gql.AgentStateMessage","gql.TextMessage","gql.ActionExecutionMessage","gql.ResultMessage","gql.ImageMessage"],"sources":["../../../src/graphql/message-conversion/agui-to-gql.ts"],"sourcesContent":["import * as gql from \"../types/converted/index\";\nimport { MessageRole } from \"../types/enums\";\nimport agui from \"@copilotkit/shared\"; // named agui for clarity, but this only includes agui message types\n\n// Helper function to extract agent name from message\nfunction extractAgentName(message: agui.Message): string {\n if (message.role !== \"assistant\") {\n throw new Error(\n `Cannot extract agent name from message with role ${message.role}`,\n );\n }\n\n return message.agentName || \"unknown\";\n}\n\n// Type guard for agent state message\nfunction isAgentStateMessage(message: agui.Message): boolean {\n return (\n message.role === \"assistant\" && \"agentName\" in message && \"state\" in message\n );\n}\n\n// Type guard for messages with image property\nfunction hasImageProperty(message: agui.Message): boolean {\n const canContainImage =\n message.role === \"assistant\" || message.role === \"user\";\n if (!canContainImage || message.image === undefined) {\n return false;\n }\n\n const isMalformed =\n message.image.format === undefined || message.image.bytes === undefined;\n if (isMalformed) {\n return false;\n }\n\n return true;\n}\n\nfunction normalizeMessageContent(content: agui.Message[\"content\"]): string {\n if (typeof content === \"string\" || typeof content === \"undefined\") {\n return content || \"\";\n }\n\n if (Array.isArray(content)) {\n return content\n .map((part) => {\n if (part?.type === \"text\") {\n return part.text;\n }\n if (part?.type === \"binary\") {\n return (\n part.data ||\n part.url ||\n part.filename ||\n `[binary:${part.mimeType}]`\n );\n }\n return \"\";\n })\n .filter(Boolean)\n .join(\"\\n\");\n }\n\n if (content && typeof content === \"object\") {\n try {\n return JSON.stringify(content);\n } catch (error) {\n console.warn(\"Failed to serialize message content\", error);\n }\n }\n\n return String(content ?? \"\");\n}\n\n/*\n ----------------------------\n AGUI Message -> GQL Message\n ----------------------------\n*/\nexport function aguiToGQL(\n messages: agui.Message[] | agui.Message,\n actions?: Record<string, any>,\n coAgentStateRenders?: Record<string, any>,\n): gql.Message[] {\n const gqlMessages: gql.Message[] = [];\n messages = Array.isArray(messages) ? messages : [messages];\n\n // Track tool call names by their IDs for use in result messages\n const toolCallNames: Record<string, string> = {};\n\n for (const message of messages) {\n // Agent state message support\n if (isAgentStateMessage(message)) {\n const agentName = extractAgentName(message);\n const state = \"state\" in message && message.state ? message.state : {};\n gqlMessages.push(\n new gql.AgentStateMessage({\n id: message.id,\n agentName,\n state,\n role: gql.Role.assistant,\n }),\n );\n // Optionally preserve render function\n if (\n \"generativeUI\" in message &&\n message.generativeUI &&\n coAgentStateRenders\n ) {\n coAgentStateRenders[agentName] = {\n name: agentName,\n render: message.generativeUI,\n };\n }\n continue;\n }\n\n if (hasImageProperty(message)) {\n gqlMessages.push(aguiMessageWithImageToGQLMessage(message));\n continue;\n }\n\n // Action execution message support\n if (message.role === \"assistant\" && message.toolCalls) {\n gqlMessages.push(aguiTextMessageToGQLMessage(message));\n for (const toolCall of message.toolCalls) {\n // Track the tool call name by its ID\n toolCallNames[toolCall.id] = toolCall.function.name;\n\n const actionExecMsg = aguiToolCallToGQLActionExecution(\n toolCall,\n message.id,\n );\n // Preserve render function in actions context\n if (\"generativeUI\" in message && message.generativeUI && actions) {\n const actionName = toolCall.function.name;\n // Check for specific action first, then wild card action\n const specificAction = Object.values(actions).find(\n (action: any) => action.name === actionName,\n );\n const wildcardAction = Object.values(actions).find(\n (action: any) => action.name === \"*\",\n );\n\n // Assign render function to the matching action (specific takes priority)\n if (specificAction) {\n specificAction.render = message.generativeUI;\n } else if (wildcardAction) {\n wildcardAction.render = message.generativeUI;\n }\n }\n gqlMessages.push(actionExecMsg);\n }\n continue;\n }\n // Reasoning messages are ephemeral display-only content with no GQL equivalent — skip them\n if (message.role === \"reasoning\") {\n continue;\n }\n // Regular text messages\n if (\n message.role === \"developer\" ||\n message.role === \"system\" ||\n message.role === \"assistant\" ||\n message.role === \"user\"\n ) {\n gqlMessages.push(aguiTextMessageToGQLMessage(message));\n continue;\n }\n // Tool result message\n if (message.role === \"tool\") {\n gqlMessages.push(\n aguiToolMessageToGQLResultMessage(message, toolCallNames),\n );\n continue;\n }\n throw new Error(\n `Unknown message role: \"${(message as any).role}\" in message with id: ${(message as any).id}`,\n );\n }\n\n return gqlMessages;\n}\n\nexport function aguiTextMessageToGQLMessage(\n message: agui.Message,\n): gql.TextMessage {\n if (\n message.role !== \"developer\" &&\n message.role !== \"system\" &&\n message.role !== \"assistant\" &&\n message.role !== \"user\"\n ) {\n throw new Error(\n `Cannot convert message with role ${message.role} to TextMessage`,\n );\n }\n\n let roleValue: MessageRole;\n\n if (message.role === \"developer\") {\n roleValue = gql.Role.developer;\n } else if (message.role === \"system\") {\n roleValue = gql.Role.system;\n } else if (message.role === \"assistant\") {\n roleValue = gql.Role.assistant;\n } else {\n roleValue = gql.Role.user;\n }\n\n return new gql.TextMessage({\n id: message.id,\n content: normalizeMessageContent(message.content),\n role: roleValue,\n });\n}\n\nexport function aguiToolCallToGQLActionExecution(\n toolCall: agui.ToolCall,\n parentMessageId: string,\n): gql.ActionExecutionMessage {\n if (toolCall.type !== \"function\") {\n throw new Error(`Unsupported tool call type: ${toolCall.type}`);\n }\n\n // Handle arguments - they should be a JSON string in AGUI format,\n // but we need to convert them to an object for GQL format\n let argumentsObj: any;\n\n if (typeof toolCall.function.arguments === \"string\") {\n // Expected case: arguments is a JSON string\n try {\n argumentsObj = JSON.parse(toolCall.function.arguments);\n } catch (error) {\n console.warn(\n `[CopilotKit] Failed to parse tool arguments, falling back to empty object`,\n );\n // Provide fallback empty object to prevent application crash\n argumentsObj = {};\n }\n } else if (\n typeof toolCall.function.arguments === \"object\" &&\n toolCall.function.arguments !== null\n ) {\n // Backward compatibility: arguments is already an object\n argumentsObj = toolCall.function.arguments;\n } else {\n // Fallback for undefined, null, or other types\n console.warn(\n `[CopilotKit] Tool arguments parsed to non-object (${typeof toolCall.function.arguments}), falling back to empty object`,\n );\n argumentsObj = {};\n }\n\n // Guard against successfully parsed non-object values (e.g. JSON.parse('\"\"') → \"\")\n if (\n typeof argumentsObj !== \"object\" ||\n argumentsObj === null ||\n Array.isArray(argumentsObj)\n ) {\n console.warn(\n `[CopilotKit] Tool arguments parsed to non-object (${typeof argumentsObj}), falling back to empty object`,\n );\n argumentsObj = {};\n }\n\n // Always include name and arguments\n return new gql.ActionExecutionMessage({\n id: toolCall.id,\n name: toolCall.function.name,\n arguments: argumentsObj,\n parentMessageId: parentMessageId,\n });\n}\n\nexport function aguiToolMessageToGQLResultMessage(\n message: agui.Message,\n toolCallNames: Record<string, string>,\n): gql.ResultMessage {\n if (message.role !== \"tool\") {\n throw new Error(\n `Cannot convert message with role ${message.role} to ResultMessage`,\n );\n }\n\n if (!message.toolCallId) {\n throw new Error(\"Tool message must have a toolCallId\");\n }\n\n const actionName = toolCallNames[message.toolCallId] || \"unknown\";\n\n // Handle result content - it could be a string or an object that needs serialization\n let resultContent: string;\n const messageContent = message.content || \"\";\n\n if (typeof messageContent === \"string\") {\n // Expected case: content is already a string\n resultContent = messageContent;\n } else if (typeof messageContent === \"object\" && messageContent !== null) {\n // Handle case where content is an object that needs to be serialized\n try {\n resultContent = JSON.stringify(messageContent);\n } catch (error) {\n console.warn(`Failed to stringify tool result for ${actionName}:`, error);\n resultContent = String(messageContent);\n }\n } else {\n // Handle other types (number, boolean, etc.)\n resultContent = String(messageContent);\n }\n\n return new gql.ResultMessage({\n id: message.id,\n result: resultContent,\n actionExecutionId: message.toolCallId,\n actionName: message.toolName || actionName,\n });\n}\n\n// New function to handle AGUI messages with render functions\nexport function aguiMessageWithRenderToGQL(\n message: agui.Message,\n actions?: Record<string, any>,\n coAgentStateRenders?: Record<string, any>,\n): gql.Message[] {\n // Handle the special case: assistant messages with render function but no tool calls\n if (\n message.role === \"assistant\" &&\n \"generativeUI\" in message &&\n message.generativeUI &&\n !message.toolCalls\n ) {\n const gqlMessages: gql.Message[] = [];\n gqlMessages.push(\n new gql.AgentStateMessage({\n id: message.id,\n agentName: \"unknown\",\n state: {},\n role: gql.Role.assistant,\n }),\n );\n if (coAgentStateRenders) {\n coAgentStateRenders.unknown = {\n name: \"unknown\",\n render: message.generativeUI,\n };\n }\n return gqlMessages;\n }\n\n // For all other cases, delegate to aguiToGQL\n return aguiToGQL([message], actions, coAgentStateRenders);\n}\n\nexport function aguiMessageWithImageToGQLMessage(\n message: agui.Message,\n): gql.ImageMessage {\n if (!hasImageProperty(message)) {\n throw new Error(\n `Cannot convert message to ImageMessage: missing format or bytes`,\n );\n }\n\n let roleValue: MessageRole;\n if (message.role === \"assistant\") {\n roleValue = gql.Role.assistant;\n } else {\n roleValue = gql.Role.user;\n }\n\n if (message.role !== \"assistant\" && message.role !== \"user\") {\n throw new Error(\n `Cannot convert message with role ${message.role} to ImageMessage`,\n );\n }\n\n return new gql.ImageMessage({\n id: message.id,\n format: message.image!.format,\n bytes: message.image!.bytes,\n role: roleValue,\n });\n}\n"],"mappings":"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"}
@@ -84,7 +84,10 @@ var LangGraphAgent = class extends _ag_ui_langgraph.LangGraphAgent {
84
84
  if (rawEvent.metadata["copilotkit:emit-tool-calls"] === false && isToolEvent) return false;
85
85
  }
86
86
  if ("copilotkit:emit-messages" in (rawEvent.metadata || {})) {
87
- if (rawEvent.metadata["copilotkit:emit-messages"] === false && isMessageEvent) return false;
87
+ if (rawEvent.metadata["copilotkit:emit-messages"] === false && isMessageEvent) {
88
+ if (this.activeRun?.id) this.messagesInProcess[this.activeRun.id] = null;
89
+ return false;
90
+ }
88
91
  }
89
92
  this.subscriber.next(event);
90
93
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"agent.cjs","names":["AGUILangGraphAgent","EventType","CustomEventNames","LangGraphEventTypes"],"sources":["../../../../../src/lib/runtime/agent-integrations/langgraph/agent.ts"],"sourcesContent":["import { map } from \"rxjs\";\nimport { LangGraphEventTypes } from \"../../../../agents/langgraph/events\";\nimport { RawEvent } from \"@ag-ui/core\";\nimport {\n LangGraphAgent as AGUILangGraphAgent,\n LangGraphHttpAgent,\n type LangGraphAgentConfig,\n ProcessedEvents,\n SchemaKeys,\n type State,\n StateEnrichment,\n} from \"@ag-ui/langgraph\";\nimport { Message as LangGraphMessage } from \"@langchain/langgraph-sdk/dist/types.messages\";\nimport { ThreadState } from \"@langchain/langgraph-sdk\";\n\ninterface CopilotKitStateEnrichment {\n copilotkit: {\n actions: StateEnrichment[\"ag-ui\"][\"tools\"];\n context: StateEnrichment[\"ag-ui\"][\"context\"];\n };\n}\n\nimport { RunAgentInput, EventType, CustomEvent } from \"@ag-ui/client\";\n\n// Import and re-export from separate file to maintain API compatibility\nimport {\n CustomEventNames,\n TextMessageEvents,\n ToolCallEvents,\n PredictStateTool,\n} from \"./consts\";\nexport { CustomEventNames };\n\nexport class LangGraphAgent extends AGUILangGraphAgent {\n constructor(config: LangGraphAgentConfig) {\n super(config);\n }\n\n dispatchEvent(event: ProcessedEvents) {\n if (event.type === EventType.CUSTOM) {\n // const event = processedEvent as unknown as CustomEvent;\n const customEvent = event as unknown as CustomEvent;\n\n if (customEvent.name === CustomEventNames.CopilotKitManuallyEmitMessage) {\n this.subscriber.next({\n type: EventType.TEXT_MESSAGE_START,\n role: \"assistant\",\n messageId: customEvent.value.message_id,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: customEvent.value.message_id,\n delta: customEvent.value.message,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TEXT_MESSAGE_END,\n messageId: customEvent.value.message_id,\n rawEvent: event,\n });\n return true;\n }\n\n if (\n customEvent.name === CustomEventNames.CopilotKitManuallyEmitToolCall\n ) {\n this.subscriber.next({\n type: EventType.TOOL_CALL_START,\n toolCallId: customEvent.value.id,\n toolCallName: customEvent.value.name,\n parentMessageId: customEvent.value.id,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: customEvent.value.id,\n delta: customEvent.value.args,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TOOL_CALL_END,\n toolCallId: customEvent.value.id,\n rawEvent: event,\n });\n return true;\n }\n\n if (\n customEvent.name ===\n CustomEventNames.CopilotKitManuallyEmitIntermediateState\n ) {\n this.activeRun.manuallyEmittedState = customEvent.value;\n this.dispatchEvent({\n type: EventType.STATE_SNAPSHOT,\n snapshot: this.getStateSnapshot({\n values: this.activeRun.manuallyEmittedState,\n } as ThreadState<State>),\n rawEvent: event,\n });\n return true;\n }\n\n if (customEvent.name === CustomEventNames.CopilotKitExit) {\n this.subscriber.next({\n type: EventType.CUSTOM,\n name: \"Exit\",\n value: true,\n });\n return true;\n }\n }\n\n // Intercept all text message and tool call events and check if should disable\n const rawEvent = (event as ToolCallEvents | TextMessageEvents).rawEvent;\n if (!rawEvent) {\n this.subscriber.next(event);\n return true;\n }\n\n const isMessageEvent =\n event.type === EventType.TEXT_MESSAGE_START ||\n event.type === EventType.TEXT_MESSAGE_CONTENT ||\n event.type === EventType.TEXT_MESSAGE_END;\n const isToolEvent =\n event.type === EventType.TOOL_CALL_START ||\n event.type === EventType.TOOL_CALL_ARGS ||\n event.type === EventType.TOOL_CALL_END;\n if (\"copilotkit:emit-tool-calls\" in (rawEvent.metadata || {})) {\n if (\n rawEvent.metadata[\"copilotkit:emit-tool-calls\"] === false &&\n isToolEvent\n ) {\n return false;\n }\n }\n if (\"copilotkit:emit-messages\" in (rawEvent.metadata || {})) {\n if (\n rawEvent.metadata[\"copilotkit:emit-messages\"] === false &&\n isMessageEvent\n ) {\n return false;\n }\n }\n\n this.subscriber.next(event);\n return true;\n }\n\n // @ts-ignore\n run(input: RunAgentInput) {\n return super.run(input).pipe(\n map((processedEvent) => {\n // Turn raw event into emit state snapshot from tool call event\n if (processedEvent.type === EventType.RAW) {\n // Get the LangGraph event from the AGUI event.\n const event =\n (processedEvent as RawEvent).event ??\n (processedEvent as RawEvent).rawEvent;\n\n const eventType = event.event;\n const toolCallData = event.data?.chunk?.tool_call_chunks?.[0];\n const toolCallUsedToPredictState = event.metadata?.[\n \"copilotkit:emit-intermediate-state\"\n ]?.some(\n (predictStateTool: PredictStateTool) =>\n predictStateTool.tool === toolCallData?.name,\n );\n\n if (\n eventType === LangGraphEventTypes.OnChatModelStream &&\n toolCallUsedToPredictState\n ) {\n return {\n type: EventType.CUSTOM,\n name: \"PredictState\",\n value: event.metadata[\"copilotkit:emit-intermediate-state\"],\n };\n }\n }\n\n return processedEvent;\n }),\n );\n }\n\n langGraphDefaultMergeState(\n state: State,\n messages: LangGraphMessage[],\n input: RunAgentInput,\n ): State<StateEnrichment & CopilotKitStateEnrichment> {\n const aguiMergedState = super.langGraphDefaultMergeState(\n state,\n messages,\n input,\n );\n const { tools: returnedTools, \"ag-ui\": agui } = aguiMergedState;\n // tolerate undefined and de-duplicate by stable key (id | name | key)\n const rawCombinedTools = [\n ...((returnedTools as any[]) ?? []),\n ...((agui?.tools as any[]) ?? []),\n ];\n const combinedTools = Array.from(\n new Map(\n rawCombinedTools.map((t: any) => [\n t?.id ?? t?.name ?? t?.key ?? JSON.stringify(t),\n t,\n ]),\n ).values(),\n );\n\n return {\n ...aguiMergedState,\n copilotkit: {\n actions: combinedTools,\n context: agui?.context ?? [],\n },\n };\n }\n\n async getSchemaKeys(): Promise<SchemaKeys> {\n const CONSTANT_KEYS = [\"copilotkit\"];\n const schemaKeys = await super.getSchemaKeys();\n return {\n config: schemaKeys.config,\n input: schemaKeys.input ? [...schemaKeys.input, ...CONSTANT_KEYS] : null,\n output: schemaKeys.output\n ? [...schemaKeys.output, ...CONSTANT_KEYS]\n : null,\n context: schemaKeys.context\n ? [...schemaKeys.context, ...CONSTANT_KEYS]\n : null,\n };\n }\n}\n\nexport { LangGraphHttpAgent };\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent.cjs","names":["AGUILangGraphAgent","EventType","CustomEventNames","LangGraphEventTypes"],"sources":["../../../../../src/lib/runtime/agent-integrations/langgraph/agent.ts"],"sourcesContent":["import { map } from \"rxjs\";\nimport { LangGraphEventTypes } from \"../../../../agents/langgraph/events\";\nimport { RawEvent } from \"@ag-ui/core\";\nimport {\n LangGraphAgent as AGUILangGraphAgent,\n LangGraphHttpAgent,\n type LangGraphAgentConfig,\n ProcessedEvents,\n SchemaKeys,\n type State,\n StateEnrichment,\n} from \"@ag-ui/langgraph\";\nimport { Message as LangGraphMessage } from \"@langchain/langgraph-sdk/dist/types.messages\";\nimport { ThreadState } from \"@langchain/langgraph-sdk\";\n\ninterface CopilotKitStateEnrichment {\n copilotkit: {\n actions: StateEnrichment[\"ag-ui\"][\"tools\"];\n context: StateEnrichment[\"ag-ui\"][\"context\"];\n };\n}\n\nimport { RunAgentInput, EventType, CustomEvent } from \"@ag-ui/client\";\n\n// Import and re-export from separate file to maintain API compatibility\nimport {\n CustomEventNames,\n TextMessageEvents,\n ToolCallEvents,\n PredictStateTool,\n} from \"./consts\";\nexport { CustomEventNames };\n\nexport class LangGraphAgent extends AGUILangGraphAgent {\n constructor(config: LangGraphAgentConfig) {\n super(config);\n }\n\n dispatchEvent(event: ProcessedEvents) {\n if (event.type === EventType.CUSTOM) {\n // const event = processedEvent as unknown as CustomEvent;\n const customEvent = event as unknown as CustomEvent;\n\n if (customEvent.name === CustomEventNames.CopilotKitManuallyEmitMessage) {\n this.subscriber.next({\n type: EventType.TEXT_MESSAGE_START,\n role: \"assistant\",\n messageId: customEvent.value.message_id,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: customEvent.value.message_id,\n delta: customEvent.value.message,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TEXT_MESSAGE_END,\n messageId: customEvent.value.message_id,\n rawEvent: event,\n });\n return true;\n }\n\n if (\n customEvent.name === CustomEventNames.CopilotKitManuallyEmitToolCall\n ) {\n this.subscriber.next({\n type: EventType.TOOL_CALL_START,\n toolCallId: customEvent.value.id,\n toolCallName: customEvent.value.name,\n parentMessageId: customEvent.value.id,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: customEvent.value.id,\n delta: customEvent.value.args,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TOOL_CALL_END,\n toolCallId: customEvent.value.id,\n rawEvent: event,\n });\n return true;\n }\n\n if (\n customEvent.name ===\n CustomEventNames.CopilotKitManuallyEmitIntermediateState\n ) {\n this.activeRun.manuallyEmittedState = customEvent.value;\n this.dispatchEvent({\n type: EventType.STATE_SNAPSHOT,\n snapshot: this.getStateSnapshot({\n values: this.activeRun.manuallyEmittedState,\n } as ThreadState<State>),\n rawEvent: event,\n });\n return true;\n }\n\n if (customEvent.name === CustomEventNames.CopilotKitExit) {\n this.subscriber.next({\n type: EventType.CUSTOM,\n name: \"Exit\",\n value: true,\n });\n return true;\n }\n }\n\n // Intercept all text message and tool call events and check if should disable\n const rawEvent = (event as ToolCallEvents | TextMessageEvents).rawEvent;\n if (!rawEvent) {\n this.subscriber.next(event);\n return true;\n }\n\n const isMessageEvent =\n event.type === EventType.TEXT_MESSAGE_START ||\n event.type === EventType.TEXT_MESSAGE_CONTENT ||\n event.type === EventType.TEXT_MESSAGE_END;\n const isToolEvent =\n event.type === EventType.TOOL_CALL_START ||\n event.type === EventType.TOOL_CALL_ARGS ||\n event.type === EventType.TOOL_CALL_END;\n if (\"copilotkit:emit-tool-calls\" in (rawEvent.metadata || {})) {\n if (\n rawEvent.metadata[\"copilotkit:emit-tool-calls\"] === false &&\n isToolEvent\n ) {\n return false;\n }\n }\n if (\"copilotkit:emit-messages\" in (rawEvent.metadata || {})) {\n if (\n rawEvent.metadata[\"copilotkit:emit-messages\"] === false &&\n isMessageEvent\n ) {\n // Clean up tracked message state to prevent stale records from\n // leaking into subsequent nodes that have emit-messages enabled.\n if (this.activeRun?.id) {\n this.messagesInProcess[this.activeRun.id] = null;\n }\n return false;\n }\n }\n\n this.subscriber.next(event);\n return true;\n }\n\n // @ts-ignore\n run(input: RunAgentInput) {\n return super.run(input).pipe(\n map((processedEvent) => {\n // Turn raw event into emit state snapshot from tool call event\n if (processedEvent.type === EventType.RAW) {\n // Get the LangGraph event from the AGUI event.\n const event =\n (processedEvent as RawEvent).event ??\n (processedEvent as RawEvent).rawEvent;\n\n const eventType = event.event;\n const toolCallData = event.data?.chunk?.tool_call_chunks?.[0];\n const toolCallUsedToPredictState = event.metadata?.[\n \"copilotkit:emit-intermediate-state\"\n ]?.some(\n (predictStateTool: PredictStateTool) =>\n predictStateTool.tool === toolCallData?.name,\n );\n\n if (\n eventType === LangGraphEventTypes.OnChatModelStream &&\n toolCallUsedToPredictState\n ) {\n return {\n type: EventType.CUSTOM,\n name: \"PredictState\",\n value: event.metadata[\"copilotkit:emit-intermediate-state\"],\n };\n }\n }\n\n return processedEvent;\n }),\n );\n }\n\n langGraphDefaultMergeState(\n state: State,\n messages: LangGraphMessage[],\n input: RunAgentInput,\n ): State<StateEnrichment & CopilotKitStateEnrichment> {\n const aguiMergedState = super.langGraphDefaultMergeState(\n state,\n messages,\n input,\n );\n const { tools: returnedTools, \"ag-ui\": agui } = aguiMergedState;\n // tolerate undefined and de-duplicate by stable key (id | name | key)\n const rawCombinedTools = [\n ...((returnedTools as any[]) ?? []),\n ...((agui?.tools as any[]) ?? []),\n ];\n const combinedTools = Array.from(\n new Map(\n rawCombinedTools.map((t: any) => [\n t?.id ?? t?.name ?? t?.key ?? JSON.stringify(t),\n t,\n ]),\n ).values(),\n );\n\n return {\n ...aguiMergedState,\n copilotkit: {\n actions: combinedTools,\n context: agui?.context ?? [],\n },\n };\n }\n\n async getSchemaKeys(): Promise<SchemaKeys> {\n const CONSTANT_KEYS = [\"copilotkit\"];\n const schemaKeys = await super.getSchemaKeys();\n return {\n config: schemaKeys.config,\n input: schemaKeys.input ? [...schemaKeys.input, ...CONSTANT_KEYS] : null,\n output: schemaKeys.output\n ? [...schemaKeys.output, ...CONSTANT_KEYS]\n : null,\n context: schemaKeys.context\n ? [...schemaKeys.context, ...CONSTANT_KEYS]\n : null,\n };\n }\n}\n\nexport { LangGraphHttpAgent };\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.cts","names":[],"sources":["../../../../../src/lib/runtime/agent-integrations/langgraph/agent.ts"],"mappings":";;;;;;;;;UAeU,yBAAA;EACR,UAAA;IACE,OAAA,EAAS,eAAA;IACT,OAAA,EAAS,eAAA;EAAA;AAAA;AAAA,cAeA,gBAAA,SAAuB,cAAA;cACtB,MAAA,EAAQ,oBAAA;EAIpB,aAAA,CAAc,KAAA,EAAO,eAAA;EAgHrB,GAAA,CAAI,KAAA,EAAO,aAAA,QAAa,UAAA,KAAA,gBAAA;+BAAA,GAAA,CAAA,SAAA;;;;;;;+BAAA,GAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCxB,0BAAA,CACE,KAAA,EAAO,KAAA,EACP,QAAA,EAAU,OAAA,IACV,KAAA,EAAO,aAAA,GACN,KAAA,CAAM,eAAA,GAAkB,yBAAA;EA8BrB,aAAA,CAAA,GAAiB,OAAA,CAAQ,UAAA;AAAA"}
1
+ {"version":3,"file":"agent.d.cts","names":[],"sources":["../../../../../src/lib/runtime/agent-integrations/langgraph/agent.ts"],"mappings":";;;;;;;;;UAeU,yBAAA;EACR,UAAA;IACE,OAAA,EAAS,eAAA;IACT,OAAA,EAAS,eAAA;EAAA;AAAA;AAAA,cAeA,gBAAA,SAAuB,cAAA;cACtB,MAAA,EAAQ,oBAAA;EAIpB,aAAA,CAAc,KAAA,EAAO,eAAA;EAqHrB,GAAA,CAAI,KAAA,EAAO,aAAA,QAAa,UAAA,KAAA,gBAAA;+BAAA,GAAA,CAAA,SAAA;;;;;;;+BAAA,GAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCxB,0BAAA,CACE,KAAA,EAAO,KAAA,EACP,QAAA,EAAU,OAAA,IACV,KAAA,EAAO,aAAA,GACN,KAAA,CAAM,eAAA,GAAkB,yBAAA;EA8BrB,aAAA,CAAA,GAAiB,OAAA,CAAQ,UAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.mts","names":[],"sources":["../../../../../src/lib/runtime/agent-integrations/langgraph/agent.ts"],"mappings":";;;;;;;;;UAeU,yBAAA;EACR,UAAA;IACE,OAAA,EAAS,eAAA;IACT,OAAA,EAAS,eAAA;EAAA;AAAA;AAAA,cAeA,gBAAA,SAAuB,cAAA;cACtB,MAAA,EAAQ,oBAAA;EAIpB,aAAA,CAAc,KAAA,EAAO,eAAA;EAgHrB,GAAA,CAAI,KAAA,EAAO,aAAA,QAAa,UAAA,KAAA,gBAAA;+BAAA,GAAA,CAAA,SAAA;;;;;;;+BAAA,GAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCxB,0BAAA,CACE,KAAA,EAAO,KAAA,EACP,QAAA,EAAU,OAAA,IACV,KAAA,EAAO,aAAA,GACN,KAAA,CAAM,eAAA,GAAkB,yBAAA;EA8BrB,aAAA,CAAA,GAAiB,OAAA,CAAQ,UAAA;AAAA"}
1
+ {"version":3,"file":"agent.d.mts","names":[],"sources":["../../../../../src/lib/runtime/agent-integrations/langgraph/agent.ts"],"mappings":";;;;;;;;;UAeU,yBAAA;EACR,UAAA;IACE,OAAA,EAAS,eAAA;IACT,OAAA,EAAS,eAAA;EAAA;AAAA;AAAA,cAeA,gBAAA,SAAuB,cAAA;cACtB,MAAA,EAAQ,oBAAA;EAIpB,aAAA,CAAc,KAAA,EAAO,eAAA;EAqHrB,GAAA,CAAI,KAAA,EAAO,aAAA,QAAa,UAAA,KAAA,gBAAA;+BAAA,GAAA,CAAA,SAAA;;;;;;;+BAAA,GAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCxB,0BAAA,CACE,KAAA,EAAO,KAAA,EACP,QAAA,EAAU,OAAA,IACV,KAAA,EAAO,aAAA,GACN,KAAA,CAAM,eAAA,GAAkB,yBAAA;EA8BrB,aAAA,CAAA,GAAiB,OAAA,CAAQ,UAAA;AAAA"}
@@ -83,7 +83,10 @@ var LangGraphAgent$1 = class extends LangGraphAgent {
83
83
  if (rawEvent.metadata["copilotkit:emit-tool-calls"] === false && isToolEvent) return false;
84
84
  }
85
85
  if ("copilotkit:emit-messages" in (rawEvent.metadata || {})) {
86
- if (rawEvent.metadata["copilotkit:emit-messages"] === false && isMessageEvent) return false;
86
+ if (rawEvent.metadata["copilotkit:emit-messages"] === false && isMessageEvent) {
87
+ if (this.activeRun?.id) this.messagesInProcess[this.activeRun.id] = null;
88
+ return false;
89
+ }
87
90
  }
88
91
  this.subscriber.next(event);
89
92
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"agent.mjs","names":["LangGraphAgent","AGUILangGraphAgent"],"sources":["../../../../../src/lib/runtime/agent-integrations/langgraph/agent.ts"],"sourcesContent":["import { map } from \"rxjs\";\nimport { LangGraphEventTypes } from \"../../../../agents/langgraph/events\";\nimport { RawEvent } from \"@ag-ui/core\";\nimport {\n LangGraphAgent as AGUILangGraphAgent,\n LangGraphHttpAgent,\n type LangGraphAgentConfig,\n ProcessedEvents,\n SchemaKeys,\n type State,\n StateEnrichment,\n} from \"@ag-ui/langgraph\";\nimport { Message as LangGraphMessage } from \"@langchain/langgraph-sdk/dist/types.messages\";\nimport { ThreadState } from \"@langchain/langgraph-sdk\";\n\ninterface CopilotKitStateEnrichment {\n copilotkit: {\n actions: StateEnrichment[\"ag-ui\"][\"tools\"];\n context: StateEnrichment[\"ag-ui\"][\"context\"];\n };\n}\n\nimport { RunAgentInput, EventType, CustomEvent } from \"@ag-ui/client\";\n\n// Import and re-export from separate file to maintain API compatibility\nimport {\n CustomEventNames,\n TextMessageEvents,\n ToolCallEvents,\n PredictStateTool,\n} from \"./consts\";\nexport { CustomEventNames };\n\nexport class LangGraphAgent extends AGUILangGraphAgent {\n constructor(config: LangGraphAgentConfig) {\n super(config);\n }\n\n dispatchEvent(event: ProcessedEvents) {\n if (event.type === EventType.CUSTOM) {\n // const event = processedEvent as unknown as CustomEvent;\n const customEvent = event as unknown as CustomEvent;\n\n if (customEvent.name === CustomEventNames.CopilotKitManuallyEmitMessage) {\n this.subscriber.next({\n type: EventType.TEXT_MESSAGE_START,\n role: \"assistant\",\n messageId: customEvent.value.message_id,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: customEvent.value.message_id,\n delta: customEvent.value.message,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TEXT_MESSAGE_END,\n messageId: customEvent.value.message_id,\n rawEvent: event,\n });\n return true;\n }\n\n if (\n customEvent.name === CustomEventNames.CopilotKitManuallyEmitToolCall\n ) {\n this.subscriber.next({\n type: EventType.TOOL_CALL_START,\n toolCallId: customEvent.value.id,\n toolCallName: customEvent.value.name,\n parentMessageId: customEvent.value.id,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: customEvent.value.id,\n delta: customEvent.value.args,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TOOL_CALL_END,\n toolCallId: customEvent.value.id,\n rawEvent: event,\n });\n return true;\n }\n\n if (\n customEvent.name ===\n CustomEventNames.CopilotKitManuallyEmitIntermediateState\n ) {\n this.activeRun.manuallyEmittedState = customEvent.value;\n this.dispatchEvent({\n type: EventType.STATE_SNAPSHOT,\n snapshot: this.getStateSnapshot({\n values: this.activeRun.manuallyEmittedState,\n } as ThreadState<State>),\n rawEvent: event,\n });\n return true;\n }\n\n if (customEvent.name === CustomEventNames.CopilotKitExit) {\n this.subscriber.next({\n type: EventType.CUSTOM,\n name: \"Exit\",\n value: true,\n });\n return true;\n }\n }\n\n // Intercept all text message and tool call events and check if should disable\n const rawEvent = (event as ToolCallEvents | TextMessageEvents).rawEvent;\n if (!rawEvent) {\n this.subscriber.next(event);\n return true;\n }\n\n const isMessageEvent =\n event.type === EventType.TEXT_MESSAGE_START ||\n event.type === EventType.TEXT_MESSAGE_CONTENT ||\n event.type === EventType.TEXT_MESSAGE_END;\n const isToolEvent =\n event.type === EventType.TOOL_CALL_START ||\n event.type === EventType.TOOL_CALL_ARGS ||\n event.type === EventType.TOOL_CALL_END;\n if (\"copilotkit:emit-tool-calls\" in (rawEvent.metadata || {})) {\n if (\n rawEvent.metadata[\"copilotkit:emit-tool-calls\"] === false &&\n isToolEvent\n ) {\n return false;\n }\n }\n if (\"copilotkit:emit-messages\" in (rawEvent.metadata || {})) {\n if (\n rawEvent.metadata[\"copilotkit:emit-messages\"] === false &&\n isMessageEvent\n ) {\n return false;\n }\n }\n\n this.subscriber.next(event);\n return true;\n }\n\n // @ts-ignore\n run(input: RunAgentInput) {\n return super.run(input).pipe(\n map((processedEvent) => {\n // Turn raw event into emit state snapshot from tool call event\n if (processedEvent.type === EventType.RAW) {\n // Get the LangGraph event from the AGUI event.\n const event =\n (processedEvent as RawEvent).event ??\n (processedEvent as RawEvent).rawEvent;\n\n const eventType = event.event;\n const toolCallData = event.data?.chunk?.tool_call_chunks?.[0];\n const toolCallUsedToPredictState = event.metadata?.[\n \"copilotkit:emit-intermediate-state\"\n ]?.some(\n (predictStateTool: PredictStateTool) =>\n predictStateTool.tool === toolCallData?.name,\n );\n\n if (\n eventType === LangGraphEventTypes.OnChatModelStream &&\n toolCallUsedToPredictState\n ) {\n return {\n type: EventType.CUSTOM,\n name: \"PredictState\",\n value: event.metadata[\"copilotkit:emit-intermediate-state\"],\n };\n }\n }\n\n return processedEvent;\n }),\n );\n }\n\n langGraphDefaultMergeState(\n state: State,\n messages: LangGraphMessage[],\n input: RunAgentInput,\n ): State<StateEnrichment & CopilotKitStateEnrichment> {\n const aguiMergedState = super.langGraphDefaultMergeState(\n state,\n messages,\n input,\n );\n const { tools: returnedTools, \"ag-ui\": agui } = aguiMergedState;\n // tolerate undefined and de-duplicate by stable key (id | name | key)\n const rawCombinedTools = [\n ...((returnedTools as any[]) ?? []),\n ...((agui?.tools as any[]) ?? []),\n ];\n const combinedTools = Array.from(\n new Map(\n rawCombinedTools.map((t: any) => [\n t?.id ?? t?.name ?? t?.key ?? JSON.stringify(t),\n t,\n ]),\n ).values(),\n );\n\n return {\n ...aguiMergedState,\n copilotkit: {\n actions: combinedTools,\n context: agui?.context ?? [],\n },\n };\n }\n\n async getSchemaKeys(): Promise<SchemaKeys> {\n const CONSTANT_KEYS = [\"copilotkit\"];\n const schemaKeys = await super.getSchemaKeys();\n return {\n config: schemaKeys.config,\n input: schemaKeys.input ? [...schemaKeys.input, ...CONSTANT_KEYS] : null,\n output: schemaKeys.output\n ? [...schemaKeys.output, ...CONSTANT_KEYS]\n : null,\n context: schemaKeys.context\n ? [...schemaKeys.context, ...CONSTANT_KEYS]\n : null,\n };\n }\n}\n\nexport { LangGraphHttpAgent };\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent.mjs","names":["LangGraphAgent","AGUILangGraphAgent"],"sources":["../../../../../src/lib/runtime/agent-integrations/langgraph/agent.ts"],"sourcesContent":["import { map } from \"rxjs\";\nimport { LangGraphEventTypes } from \"../../../../agents/langgraph/events\";\nimport { RawEvent } from \"@ag-ui/core\";\nimport {\n LangGraphAgent as AGUILangGraphAgent,\n LangGraphHttpAgent,\n type LangGraphAgentConfig,\n ProcessedEvents,\n SchemaKeys,\n type State,\n StateEnrichment,\n} from \"@ag-ui/langgraph\";\nimport { Message as LangGraphMessage } from \"@langchain/langgraph-sdk/dist/types.messages\";\nimport { ThreadState } from \"@langchain/langgraph-sdk\";\n\ninterface CopilotKitStateEnrichment {\n copilotkit: {\n actions: StateEnrichment[\"ag-ui\"][\"tools\"];\n context: StateEnrichment[\"ag-ui\"][\"context\"];\n };\n}\n\nimport { RunAgentInput, EventType, CustomEvent } from \"@ag-ui/client\";\n\n// Import and re-export from separate file to maintain API compatibility\nimport {\n CustomEventNames,\n TextMessageEvents,\n ToolCallEvents,\n PredictStateTool,\n} from \"./consts\";\nexport { CustomEventNames };\n\nexport class LangGraphAgent extends AGUILangGraphAgent {\n constructor(config: LangGraphAgentConfig) {\n super(config);\n }\n\n dispatchEvent(event: ProcessedEvents) {\n if (event.type === EventType.CUSTOM) {\n // const event = processedEvent as unknown as CustomEvent;\n const customEvent = event as unknown as CustomEvent;\n\n if (customEvent.name === CustomEventNames.CopilotKitManuallyEmitMessage) {\n this.subscriber.next({\n type: EventType.TEXT_MESSAGE_START,\n role: \"assistant\",\n messageId: customEvent.value.message_id,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: customEvent.value.message_id,\n delta: customEvent.value.message,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TEXT_MESSAGE_END,\n messageId: customEvent.value.message_id,\n rawEvent: event,\n });\n return true;\n }\n\n if (\n customEvent.name === CustomEventNames.CopilotKitManuallyEmitToolCall\n ) {\n this.subscriber.next({\n type: EventType.TOOL_CALL_START,\n toolCallId: customEvent.value.id,\n toolCallName: customEvent.value.name,\n parentMessageId: customEvent.value.id,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: customEvent.value.id,\n delta: customEvent.value.args,\n rawEvent: event,\n });\n this.subscriber.next({\n type: EventType.TOOL_CALL_END,\n toolCallId: customEvent.value.id,\n rawEvent: event,\n });\n return true;\n }\n\n if (\n customEvent.name ===\n CustomEventNames.CopilotKitManuallyEmitIntermediateState\n ) {\n this.activeRun.manuallyEmittedState = customEvent.value;\n this.dispatchEvent({\n type: EventType.STATE_SNAPSHOT,\n snapshot: this.getStateSnapshot({\n values: this.activeRun.manuallyEmittedState,\n } as ThreadState<State>),\n rawEvent: event,\n });\n return true;\n }\n\n if (customEvent.name === CustomEventNames.CopilotKitExit) {\n this.subscriber.next({\n type: EventType.CUSTOM,\n name: \"Exit\",\n value: true,\n });\n return true;\n }\n }\n\n // Intercept all text message and tool call events and check if should disable\n const rawEvent = (event as ToolCallEvents | TextMessageEvents).rawEvent;\n if (!rawEvent) {\n this.subscriber.next(event);\n return true;\n }\n\n const isMessageEvent =\n event.type === EventType.TEXT_MESSAGE_START ||\n event.type === EventType.TEXT_MESSAGE_CONTENT ||\n event.type === EventType.TEXT_MESSAGE_END;\n const isToolEvent =\n event.type === EventType.TOOL_CALL_START ||\n event.type === EventType.TOOL_CALL_ARGS ||\n event.type === EventType.TOOL_CALL_END;\n if (\"copilotkit:emit-tool-calls\" in (rawEvent.metadata || {})) {\n if (\n rawEvent.metadata[\"copilotkit:emit-tool-calls\"] === false &&\n isToolEvent\n ) {\n return false;\n }\n }\n if (\"copilotkit:emit-messages\" in (rawEvent.metadata || {})) {\n if (\n rawEvent.metadata[\"copilotkit:emit-messages\"] === false &&\n isMessageEvent\n ) {\n // Clean up tracked message state to prevent stale records from\n // leaking into subsequent nodes that have emit-messages enabled.\n if (this.activeRun?.id) {\n this.messagesInProcess[this.activeRun.id] = null;\n }\n return false;\n }\n }\n\n this.subscriber.next(event);\n return true;\n }\n\n // @ts-ignore\n run(input: RunAgentInput) {\n return super.run(input).pipe(\n map((processedEvent) => {\n // Turn raw event into emit state snapshot from tool call event\n if (processedEvent.type === EventType.RAW) {\n // Get the LangGraph event from the AGUI event.\n const event =\n (processedEvent as RawEvent).event ??\n (processedEvent as RawEvent).rawEvent;\n\n const eventType = event.event;\n const toolCallData = event.data?.chunk?.tool_call_chunks?.[0];\n const toolCallUsedToPredictState = event.metadata?.[\n \"copilotkit:emit-intermediate-state\"\n ]?.some(\n (predictStateTool: PredictStateTool) =>\n predictStateTool.tool === toolCallData?.name,\n );\n\n if (\n eventType === LangGraphEventTypes.OnChatModelStream &&\n toolCallUsedToPredictState\n ) {\n return {\n type: EventType.CUSTOM,\n name: \"PredictState\",\n value: event.metadata[\"copilotkit:emit-intermediate-state\"],\n };\n }\n }\n\n return processedEvent;\n }),\n );\n }\n\n langGraphDefaultMergeState(\n state: State,\n messages: LangGraphMessage[],\n input: RunAgentInput,\n ): State<StateEnrichment & CopilotKitStateEnrichment> {\n const aguiMergedState = super.langGraphDefaultMergeState(\n state,\n messages,\n input,\n );\n const { tools: returnedTools, \"ag-ui\": agui } = aguiMergedState;\n // tolerate undefined and de-duplicate by stable key (id | name | key)\n const rawCombinedTools = [\n ...((returnedTools as any[]) ?? []),\n ...((agui?.tools as any[]) ?? []),\n ];\n const combinedTools = Array.from(\n new Map(\n rawCombinedTools.map((t: any) => [\n t?.id ?? t?.name ?? t?.key ?? JSON.stringify(t),\n t,\n ]),\n ).values(),\n );\n\n return {\n ...aguiMergedState,\n copilotkit: {\n actions: combinedTools,\n context: agui?.context ?? [],\n },\n };\n }\n\n async getSchemaKeys(): Promise<SchemaKeys> {\n const CONSTANT_KEYS = [\"copilotkit\"];\n const schemaKeys = await super.getSchemaKeys();\n return {\n config: schemaKeys.config,\n input: schemaKeys.input ? [...schemaKeys.input, ...CONSTANT_KEYS] : null,\n output: schemaKeys.output\n ? [...schemaKeys.output, ...CONSTANT_KEYS]\n : null,\n context: schemaKeys.context\n ? [...schemaKeys.context, ...CONSTANT_KEYS]\n : null,\n };\n }\n}\n\nexport { LangGraphHttpAgent };\n"],"mappings":"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"}
package/dist/package.cjs CHANGED
@@ -12,7 +12,7 @@ var require_package = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, m
12
12
  "url": "https://github.com/CopilotKit/CopilotKit.git"
13
13
  },
14
14
  "publishConfig": { "access": "public" },
15
- "version": "1.53.1-next.1",
15
+ "version": "1.54.0-next.3",
16
16
  "sideEffects": [
17
17
  "./dist/index.mjs",
18
18
  "./dist/index.cjs",
package/dist/package.mjs CHANGED
@@ -12,7 +12,7 @@ var require_package = /* @__PURE__ */ __commonJSMin(((exports, module) => {
12
12
  "url": "https://github.com/CopilotKit/CopilotKit.git"
13
13
  },
14
14
  "publishConfig": { "access": "public" },
15
- "version": "1.53.1-next.1",
15
+ "version": "1.54.0-next.3",
16
16
  "sideEffects": [
17
17
  "./dist/index.mjs",
18
18
  "./dist/index.cjs",
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "publishConfig": {
10
10
  "access": "public"
11
11
  },
12
- "version": "1.53.1-next.1",
12
+ "version": "1.54.0-next.3",
13
13
  "sideEffects": [
14
14
  "./dist/index.mjs",
15
15
  "./dist/index.cjs",
@@ -72,9 +72,9 @@
72
72
  "rxjs": "7.8.1",
73
73
  "type-graphql": "2.0.0-rc.1",
74
74
  "zod": "^3.23.3",
75
- "@copilotkit/shared": "1.53.1-next.1",
76
- "@copilotkitnext/agent": "1.53.1-next.1",
77
- "@copilotkitnext/runtime": "1.53.1-next.1"
75
+ "@copilotkit/shared": "1.54.0-next.3",
76
+ "@copilotkitnext/agent": "1.54.0-next.3",
77
+ "@copilotkitnext/runtime": "1.54.0-next.3"
78
78
  },
79
79
  "peerDependencies": {
80
80
  "@anthropic-ai/sdk": "^0.57.0",
@@ -135,6 +135,25 @@ describe("agui-to-gql", () => {
135
135
  aguiToolCallToGQLActionExecution(toolCall, "parent-id"),
136
136
  ).toThrow("Unsupported tool call type");
137
137
  });
138
+
139
+ test.each([
140
+ { label: "empty string", args: '""', desc: "JSON string" },
141
+ { label: "number", args: "42", desc: "JSON number" },
142
+ { label: "boolean", args: "true", desc: "JSON boolean" },
143
+ { label: "null", args: "null", desc: "JSON null" },
144
+ { label: "array", args: "[1,2,3]", desc: "JSON array" },
145
+ ])(
146
+ "should fall back to {} when arguments parse to $desc ($label)",
147
+ ({ args }) => {
148
+ const toolCall: agui.ToolCall = {
149
+ id: "tc-nonobj",
150
+ type: "function",
151
+ function: { name: "fn", arguments: args },
152
+ };
153
+ const result = aguiToolCallToGQLActionExecution(toolCall, "parent-id");
154
+ expect(result.arguments).toEqual({});
155
+ },
156
+ );
138
157
  });
139
158
 
140
159
  describe("aguiToolMessageToGQLResultMessage", () => {
@@ -234,8 +234,7 @@ export function aguiToolCallToGQLActionExecution(
234
234
  argumentsObj = JSON.parse(toolCall.function.arguments);
235
235
  } catch (error) {
236
236
  console.warn(
237
- `Failed to parse tool call arguments for ${toolCall.function.name}:`,
238
- error,
237
+ `[CopilotKit] Failed to parse tool arguments, falling back to empty object`,
239
238
  );
240
239
  // Provide fallback empty object to prevent application crash
241
240
  argumentsObj = {};
@@ -249,8 +248,19 @@ export function aguiToolCallToGQLActionExecution(
249
248
  } else {
250
249
  // Fallback for undefined, null, or other types
251
250
  console.warn(
252
- `Invalid tool call arguments type for ${toolCall.function.name}:`,
253
- typeof toolCall.function.arguments,
251
+ `[CopilotKit] Tool arguments parsed to non-object (${typeof toolCall.function.arguments}), falling back to empty object`,
252
+ );
253
+ argumentsObj = {};
254
+ }
255
+
256
+ // Guard against successfully parsed non-object values (e.g. JSON.parse('""') → "")
257
+ if (
258
+ typeof argumentsObj !== "object" ||
259
+ argumentsObj === null ||
260
+ Array.isArray(argumentsObj)
261
+ ) {
262
+ console.warn(
263
+ `[CopilotKit] Tool arguments parsed to non-object (${typeof argumentsObj}), falling back to empty object`,
254
264
  );
255
265
  argumentsObj = {};
256
266
  }
@@ -0,0 +1,155 @@
1
+ import { EventType } from "@ag-ui/client";
2
+ import { LangGraphAgent } from "../agent";
3
+
4
+ function createAgent() {
5
+ const agent = new LangGraphAgent({
6
+ graphId: "test-graph",
7
+ url: "http://localhost:8000",
8
+ });
9
+
10
+ const events: any[] = [];
11
+ (agent as any).subscriber = { next: (e: any) => events.push(e) };
12
+ (agent as any).activeRun = {
13
+ id: "run-1",
14
+ threadId: "thread-1",
15
+ hasFunctionStreaming: false,
16
+ };
17
+ (agent as any).messagesInProcess = {};
18
+
19
+ return { agent, events };
20
+ }
21
+
22
+ function makeTextEvent(
23
+ type: EventType,
24
+ metadata: Record<string, any>,
25
+ messageId = "msg-1",
26
+ ) {
27
+ return {
28
+ type,
29
+ messageId,
30
+ ...(type === EventType.TEXT_MESSAGE_CONTENT ? { delta: "hello" } : {}),
31
+ ...(type === EventType.TEXT_MESSAGE_START ? { role: "assistant" } : {}),
32
+ rawEvent: { metadata },
33
+ };
34
+ }
35
+
36
+ describe("dispatchEvent emit-messages filtering", () => {
37
+ it("suppresses message events when copilotkit:emit-messages is false", () => {
38
+ const { agent, events } = createAgent();
39
+
40
+ const result = agent.dispatchEvent(
41
+ makeTextEvent(EventType.TEXT_MESSAGE_START, {
42
+ "copilotkit:emit-messages": false,
43
+ }) as any,
44
+ );
45
+
46
+ expect(result).toBe(false);
47
+ expect(events).toHaveLength(0);
48
+ });
49
+
50
+ it("passes message events when copilotkit:emit-messages is true", () => {
51
+ const { agent, events } = createAgent();
52
+
53
+ const result = agent.dispatchEvent(
54
+ makeTextEvent(EventType.TEXT_MESSAGE_START, {
55
+ "copilotkit:emit-messages": true,
56
+ }) as any,
57
+ );
58
+
59
+ expect(result).toBe(true);
60
+ expect(events).toHaveLength(1);
61
+ });
62
+
63
+ it("clears messagesInProcess when suppressing message events", () => {
64
+ const { agent } = createAgent();
65
+
66
+ // Simulate parent class having set a stale message record
67
+ (agent as any).messagesInProcess["run-1"] = {
68
+ id: "msg-1",
69
+ toolCallId: null,
70
+ toolCallName: null,
71
+ };
72
+
73
+ agent.dispatchEvent(
74
+ makeTextEvent(EventType.TEXT_MESSAGE_START, {
75
+ "copilotkit:emit-messages": false,
76
+ }) as any,
77
+ );
78
+
79
+ expect((agent as any).messagesInProcess["run-1"]).toBeNull();
80
+ });
81
+
82
+ it("does NOT clear messagesInProcess when emit-messages is true", () => {
83
+ const { agent } = createAgent();
84
+
85
+ const staleRecord = {
86
+ id: "msg-1",
87
+ toolCallId: null,
88
+ toolCallName: null,
89
+ };
90
+ (agent as any).messagesInProcess["run-1"] = staleRecord;
91
+
92
+ agent.dispatchEvent(
93
+ makeTextEvent(EventType.TEXT_MESSAGE_CONTENT, {
94
+ "copilotkit:emit-messages": true,
95
+ }) as any,
96
+ );
97
+
98
+ // Record should still be there (not cleared)
99
+ expect((agent as any).messagesInProcess["run-1"]).toBe(staleRecord);
100
+ });
101
+
102
+ it("clears messagesInProcess on TEXT_MESSAGE_END suppression (the cross-node leak scenario)", () => {
103
+ const { agent } = createAgent();
104
+
105
+ // Orchestrator node set a message in progress, then its events get suppressed.
106
+ // The END event must also clear the tracking state.
107
+ (agent as any).messagesInProcess["run-1"] = {
108
+ id: "msg-orchestrator",
109
+ toolCallId: null,
110
+ toolCallName: null,
111
+ };
112
+
113
+ agent.dispatchEvent(
114
+ makeTextEvent(
115
+ EventType.TEXT_MESSAGE_END,
116
+ { "copilotkit:emit-messages": false },
117
+ "msg-orchestrator",
118
+ ) as any,
119
+ );
120
+
121
+ expect((agent as any).messagesInProcess["run-1"]).toBeNull();
122
+ });
123
+ });
124
+
125
+ describe("dispatchEvent emit-tool-calls filtering", () => {
126
+ it("suppresses tool events when copilotkit:emit-tool-calls is false", () => {
127
+ const { agent, events } = createAgent();
128
+
129
+ const result = agent.dispatchEvent({
130
+ type: EventType.TOOL_CALL_START,
131
+ toolCallId: "tc-1",
132
+ toolCallName: "search",
133
+ parentMessageId: "msg-1",
134
+ rawEvent: { metadata: { "copilotkit:emit-tool-calls": false } },
135
+ } as any);
136
+
137
+ expect(result).toBe(false);
138
+ expect(events).toHaveLength(0);
139
+ });
140
+
141
+ it("passes tool events when copilotkit:emit-tool-calls is true", () => {
142
+ const { agent, events } = createAgent();
143
+
144
+ const result = agent.dispatchEvent({
145
+ type: EventType.TOOL_CALL_START,
146
+ toolCallId: "tc-1",
147
+ toolCallName: "search",
148
+ parentMessageId: "msg-1",
149
+ rawEvent: { metadata: { "copilotkit:emit-tool-calls": true } },
150
+ } as any);
151
+
152
+ expect(result).toBe(true);
153
+ expect(events).toHaveLength(1);
154
+ });
155
+ });
@@ -139,6 +139,11 @@ export class LangGraphAgent extends AGUILangGraphAgent {
139
139
  rawEvent.metadata["copilotkit:emit-messages"] === false &&
140
140
  isMessageEvent
141
141
  ) {
142
+ // Clean up tracked message state to prevent stale records from
143
+ // leaking into subsequent nodes that have emit-messages enabled.
144
+ if (this.activeRun?.id) {
145
+ this.messagesInProcess[this.activeRun.id] = null;
146
+ }
142
147
  return false;
143
148
  }
144
149
  }
@@ -0,0 +1,56 @@
1
+ import { describe, it, expect } from "vitest";
2
+
3
+ /**
4
+ * safeParseToolArgs is a private (non-exported) function in conversion.ts.
5
+ * We duplicate its logic here to unit-test the algorithm in isolation.
6
+ * This mirrors the shared safeParseToolArgs in @copilotkitnext/shared.
7
+ */
8
+ function safeParseToolArgs(raw: string): Record<string, unknown> {
9
+ try {
10
+ const parsed = JSON.parse(raw);
11
+ if (
12
+ typeof parsed === "object" &&
13
+ parsed !== null &&
14
+ !Array.isArray(parsed)
15
+ ) {
16
+ return parsed as Record<string, unknown>;
17
+ }
18
+ return {};
19
+ } catch {
20
+ return {};
21
+ }
22
+ }
23
+
24
+ describe("safeParseToolArgs (v1 conversion)", () => {
25
+ it("parses a valid JSON object string", () => {
26
+ expect(safeParseToolArgs('{"key": "value"}')).toEqual({ key: "value" });
27
+ });
28
+
29
+ it("returns {} for a JSON string value", () => {
30
+ expect(safeParseToolArgs('"hello"')).toEqual({});
31
+ });
32
+
33
+ it("returns {} for a JSON number", () => {
34
+ expect(safeParseToolArgs("42")).toEqual({});
35
+ });
36
+
37
+ it("returns {} for a JSON array", () => {
38
+ expect(safeParseToolArgs("[1, 2, 3]")).toEqual({});
39
+ });
40
+
41
+ it("returns {} for malformed JSON", () => {
42
+ expect(safeParseToolArgs("{broken")).toEqual({});
43
+ });
44
+
45
+ it("returns {} for a JSON null", () => {
46
+ expect(safeParseToolArgs("null")).toEqual({});
47
+ });
48
+
49
+ it("returns {} for a JSON boolean", () => {
50
+ expect(safeParseToolArgs("true")).toEqual({});
51
+ });
52
+
53
+ it("returns {} for an empty string", () => {
54
+ expect(safeParseToolArgs("")).toEqual({});
55
+ });
56
+ });
@@ -36,7 +36,7 @@ export function convertGqlInputToMessages(
36
36
  id: message.id,
37
37
  createdAt: message.createdAt,
38
38
  name: message.actionExecutionMessage.name,
39
- arguments: JSON.parse(message.actionExecutionMessage.arguments),
39
+ arguments: safeParseToolArgs(message.actionExecutionMessage.arguments),
40
40
  parentMessageId: message.actionExecutionMessage.parentMessageId,
41
41
  });
42
42
  } else if (message.resultMessage) {
@@ -67,3 +67,30 @@ export function convertGqlInputToMessages(
67
67
 
68
68
  return messages.filter((m) => m);
69
69
  }
70
+
71
+ /**
72
+ * Safely parses a JSON string into a plain object for tool arguments.
73
+ * Mirrors the shared safeParseToolArgs in @copilotkitnext/shared (v2).
74
+ * Kept as a local copy because v1 does not import from v2 shared.
75
+ */
76
+ function safeParseToolArgs(raw: string): Record<string, unknown> {
77
+ try {
78
+ const parsed = JSON.parse(raw);
79
+ if (
80
+ typeof parsed === "object" &&
81
+ parsed !== null &&
82
+ !Array.isArray(parsed)
83
+ ) {
84
+ return parsed as Record<string, unknown>;
85
+ }
86
+ console.warn(
87
+ `[CopilotKit] Tool arguments parsed to non-object (${typeof parsed}), falling back to empty object`,
88
+ );
89
+ return {};
90
+ } catch {
91
+ console.warn(
92
+ "[CopilotKit] Failed to parse tool arguments, falling back to empty object",
93
+ );
94
+ return {};
95
+ }
96
+ }