{"version":3,"file":"gql-to-agui.mjs","names":[],"sources":["../../src/message-conversion/gql-to-agui.ts"],"sourcesContent":["import * as gql from \"../client\";\nimport * as agui from \"@copilotkit/shared\";\nimport { MessageStatusCode } from \"../graphql/@generated/graphql\";\n\n// Define valid image formats based on the supported formats in the codebase\nconst VALID_IMAGE_FORMATS = [\"jpeg\", \"png\", \"webp\", \"gif\"] as const;\ntype ValidImageFormat = (typeof VALID_IMAGE_FORMATS)[number];\n\n// Validation function for image format\nfunction validateImageFormat(format: string): format is ValidImageFormat {\n  return VALID_IMAGE_FORMATS.includes(format as ValidImageFormat);\n}\n\n/*\n  ----------------------------\n  GQL Message -> AGUI Message\n  ----------------------------\n*/\nexport function gqlToAGUI(\n  messages: gql.Message[] | gql.Message,\n  actions?: Record<string, any>,\n  coAgentStateRenders?: Record<string, any>,\n): agui.Message[] {\n  let aguiMessages: agui.Message[] = [];\n  messages = Array.isArray(messages) ? messages : [messages];\n\n  // Create a map of action execution ID to result for completed actions\n  const actionResults = new Map<string, string>();\n  for (const message of messages) {\n    if (message.isResultMessage()) {\n      actionResults.set(message.actionExecutionId, message.result);\n    }\n  }\n\n  for (const message of messages) {\n    if (message.isTextMessage()) {\n      aguiMessages.push(gqlTextMessageToAGUIMessage(message));\n    } else if (message.isResultMessage()) {\n      aguiMessages.push(gqlResultMessageToAGUIMessage(message));\n    } else if (message.isActionExecutionMessage()) {\n      aguiMessages.push(\n        gqlActionExecutionMessageToAGUIMessage(message, actions, actionResults),\n      );\n    } else if (message.isAgentStateMessage()) {\n      aguiMessages.push(\n        gqlAgentStateMessageToAGUIMessage(message, coAgentStateRenders),\n      );\n    } else if (message.isImageMessage()) {\n      aguiMessages.push(gqlImageMessageToAGUIMessage(message));\n    } else {\n      throw new Error(\"Unknown message type\");\n    }\n  }\n\n  return aguiMessages;\n}\n\nexport function gqlActionExecutionMessageToAGUIMessage(\n  message: gql.ActionExecutionMessage,\n  actions?: Record<string, any>,\n  actionResults?: Map<string, string>,\n): agui.Message {\n  // Check if we have actions and if there's a specific action or wild card action\n  const hasSpecificAction =\n    actions &&\n    Object.values(actions).some((action: any) => action.name === message.name);\n  const hasWildcardAction =\n    actions &&\n    Object.values(actions).some((action: any) => action.name === \"*\");\n\n  if (!actions || (!hasSpecificAction && !hasWildcardAction)) {\n    return {\n      id: message.id,\n      role: \"assistant\",\n      toolCalls: [actionExecutionMessageToAGUIMessage(message)],\n      name: message.name,\n    };\n  }\n\n  // Find the specific action first, then fall back to wild card action\n  const action =\n    Object.values(actions).find(\n      (action: any) => action.name === message.name,\n    ) || Object.values(actions).find((action: any) => action.name === \"*\");\n\n  // Create render function wrapper that provides proper props\n  const createRenderWrapper = (originalRender: any) => {\n    if (!originalRender) return undefined;\n\n    return (props?: any) => {\n      // Determine the correct status based on the same logic as RenderActionExecutionMessage\n      let actionResult: any = actionResults?.get(message.id);\n      let status: \"inProgress\" | \"executing\" | \"complete\" = \"inProgress\";\n\n      if (actionResult !== undefined) {\n        status = \"complete\";\n      } else if (message.status?.code !== MessageStatusCode.Pending) {\n        status = \"executing\";\n      }\n\n      // if props.result is a string, parse it as JSON but don't throw an error if it's not valid JSON\n      if (typeof props?.result === \"string\") {\n        try {\n          props.result = JSON.parse(props.result);\n        } catch (e) {\n          /* do nothing */\n        }\n      }\n\n      // if actionResult is a string, parse it as JSON but don't throw an error if it's not valid JSON\n      if (typeof actionResult === \"string\") {\n        try {\n          actionResult = JSON.parse(actionResult);\n        } catch (e) {\n          /* do nothing */\n        }\n      }\n\n      // Base props that all actions receive\n      const baseProps = {\n        status: props?.status || status,\n        args: message.arguments || {},\n        result: props?.result || actionResult || undefined,\n        messageId: message.id,\n      };\n\n      // Add properties based on action type\n      if (action.name === \"*\") {\n        // Wildcard actions get the tool name; ensure it cannot be overridden by incoming props\n        return originalRender({\n          ...baseProps,\n          ...props,\n          name: message.name,\n        });\n      } else {\n        // Regular actions get respond (defaulting to a no-op if not provided)\n        const respond = props?.respond ?? (() => {});\n        return originalRender({\n          ...baseProps,\n          ...props,\n          respond,\n        });\n      }\n    };\n  };\n\n  return {\n    id: message.id,\n    role: \"assistant\",\n    content: \"\",\n    toolCalls: [actionExecutionMessageToAGUIMessage(message)],\n    generativeUI: createRenderWrapper(action.render),\n    name: message.name,\n  } as agui.AIMessage;\n}\n\nfunction gqlAgentStateMessageToAGUIMessage(\n  message: gql.AgentStateMessage,\n  coAgentStateRenders?: Record<string, any>,\n): agui.Message {\n  if (\n    coAgentStateRenders &&\n    Object.values(coAgentStateRenders).some(\n      (render: any) => render.name === message.agentName,\n    )\n  ) {\n    const render = Object.values(coAgentStateRenders).find(\n      (render: any) => render.name === message.agentName,\n    );\n\n    // Create render function wrapper that provides proper props\n    const createRenderWrapper = (originalRender: any) => {\n      if (!originalRender) return undefined;\n\n      return (props?: any) => {\n        // Determine the correct status based on the same logic as RenderActionExecutionMessage\n        const state = message.state;\n\n        // Provide the full props structure that the render function expects\n        const renderProps = {\n          state: state,\n        };\n\n        return originalRender(renderProps);\n      };\n    };\n\n    return {\n      id: message.id,\n      role: \"assistant\",\n      generativeUI: createRenderWrapper(render.render),\n      agentName: message.agentName,\n      state: message.state,\n    };\n  }\n\n  return {\n    id: message.id,\n    role: \"assistant\",\n    agentName: message.agentName,\n    state: message.state,\n  };\n}\n\nfunction actionExecutionMessageToAGUIMessage(\n  actionExecutionMessage: gql.ActionExecutionMessage,\n): agui.ToolCall {\n  return {\n    id: actionExecutionMessage.id,\n    function: {\n      name: actionExecutionMessage.name,\n      arguments: JSON.stringify(actionExecutionMessage.arguments),\n    },\n    type: \"function\",\n  };\n}\n\nexport function gqlTextMessageToAGUIMessage(\n  message: gql.TextMessage,\n): agui.Message {\n  switch (message.role) {\n    case gql.Role.Developer:\n      return {\n        id: message.id,\n        role: \"developer\",\n        content: message.content,\n      };\n    case gql.Role.System:\n      return {\n        id: message.id,\n        role: \"system\",\n        content: message.content,\n      };\n    case gql.Role.Assistant:\n      return {\n        id: message.id,\n        role: \"assistant\",\n        content: message.content,\n      };\n    case gql.Role.User:\n      return {\n        id: message.id,\n        role: \"user\",\n        content: message.content,\n      };\n    default:\n      throw new Error(\"Unknown message role\");\n  }\n}\n\nexport function gqlResultMessageToAGUIMessage(\n  message: gql.ResultMessage,\n): agui.Message {\n  return {\n    id: message.id,\n    role: \"tool\",\n    content: message.result,\n    toolCallId: message.actionExecutionId,\n    toolName: message.actionName,\n  };\n}\n\nexport function gqlImageMessageToAGUIMessage(\n  message: gql.ImageMessage,\n): agui.Message {\n  // Validate image format\n  if (!validateImageFormat(message.format)) {\n    throw new Error(\n      `Invalid image format: ${message.format}. Supported formats are: ${VALID_IMAGE_FORMATS.join(\", \")}`,\n    );\n  }\n\n  // Validate that bytes is a non-empty string\n  if (\n    !message.bytes ||\n    typeof message.bytes !== \"string\" ||\n    message.bytes.trim() === \"\"\n  ) {\n    throw new Error(\"Image bytes must be a non-empty string\");\n  }\n\n  // Determine the role based on the message role\n  const role = message.role === gql.Role.Assistant ? \"assistant\" : \"user\";\n\n  // Create the image message with proper typing\n  const imageMessage: agui.Message = {\n    id: message.id,\n    role,\n    content: \"\",\n    image: {\n      format: message.format,\n      bytes: message.bytes,\n    },\n  };\n\n  return imageMessage;\n}\n"],"mappings":";;;;AAKA,MAAM,sBAAsB;CAAC;CAAQ;CAAO;CAAQ;CAAM;AAI1D,SAAS,oBAAoB,QAA4C;AACvE,QAAO,oBAAoB,SAAS,OAA2B;;AAQjE,SAAgB,UACd,UACA,SACA,qBACgB;CAChB,IAAI,eAA+B,EAAE;AACrC,YAAW,MAAM,QAAQ,SAAS,GAAG,WAAW,CAAC,SAAS;CAG1D,MAAM,gCAAgB,IAAI,KAAqB;AAC/C,MAAK,MAAM,WAAW,SACpB,KAAI,QAAQ,iBAAiB,CAC3B,eAAc,IAAI,QAAQ,mBAAmB,QAAQ,OAAO;AAIhE,MAAK,MAAM,WAAW,SACpB,KAAI,QAAQ,eAAe,CACzB,cAAa,KAAK,4BAA4B,QAAQ,CAAC;UAC9C,QAAQ,iBAAiB,CAClC,cAAa,KAAK,8BAA8B,QAAQ,CAAC;UAChD,QAAQ,0BAA0B,CAC3C,cAAa,KACX,uCAAuC,SAAS,SAAS,cAAc,CACxE;UACQ,QAAQ,qBAAqB,CACtC,cAAa,KACX,kCAAkC,SAAS,oBAAoB,CAChE;UACQ,QAAQ,gBAAgB,CACjC,cAAa,KAAK,6BAA6B,QAAQ,CAAC;KAExD,OAAM,IAAI,MAAM,uBAAuB;AAI3C,QAAO;;AAGT,SAAgB,uCACd,SACA,SACA,eACc;CAEd,MAAM,oBACJ,WACA,OAAO,OAAO,QAAQ,CAAC,MAAM,WAAgB,OAAO,SAAS,QAAQ,KAAK;CAC5E,MAAM,oBACJ,WACA,OAAO,OAAO,QAAQ,CAAC,MAAM,WAAgB,OAAO,SAAS,IAAI;AAEnE,KAAI,CAAC,WAAY,CAAC,qBAAqB,CAAC,kBACtC,QAAO;EACL,IAAI,QAAQ;EACZ,MAAM;EACN,WAAW,CAAC,oCAAoC,QAAQ,CAAC;EACzD,MAAM,QAAQ;EACf;CAIH,MAAM,SACJ,OAAO,OAAO,QAAQ,CAAC,MACpB,WAAgB,OAAO,SAAS,QAAQ,KAC1C,IAAI,OAAO,OAAO,QAAQ,CAAC,MAAM,WAAgB,OAAO,SAAS,IAAI;CAGxE,MAAM,uBAAuB,mBAAwB;AACnD,MAAI,CAAC,eAAgB,QAAO;AAE5B,UAAQ,UAAgB;GAEtB,IAAI,eAAoB,eAAe,IAAI,QAAQ,GAAG;GACtD,IAAI,SAAkD;AAEtD,OAAI,iBAAiB,OACnB,UAAS;YACA,QAAQ,QAAQ,SAAS,kBAAkB,QACpD,UAAS;AAIX,OAAI,OAAO,OAAO,WAAW,SAC3B,KAAI;AACF,UAAM,SAAS,KAAK,MAAM,MAAM,OAAO;YAChC,GAAG;AAMd,OAAI,OAAO,iBAAiB,SAC1B,KAAI;AACF,mBAAe,KAAK,MAAM,aAAa;YAChC,GAAG;GAMd,MAAM,YAAY;IAChB,QAAQ,OAAO,UAAU;IACzB,MAAM,QAAQ,aAAa,EAAE;IAC7B,QAAQ,OAAO,UAAU,gBAAgB;IACzC,WAAW,QAAQ;IACpB;AAGD,OAAI,OAAO,SAAS,IAElB,QAAO,eAAe;IACpB,GAAG;IACH,GAAG;IACH,MAAM,QAAQ;IACf,CAAC;QACG;IAEL,MAAM,UAAU,OAAO,kBAAkB;AACzC,WAAO,eAAe;KACpB,GAAG;KACH,GAAG;KACH;KACD,CAAC;;;;AAKR,QAAO;EACL,IAAI,QAAQ;EACZ,MAAM;EACN,SAAS;EACT,WAAW,CAAC,oCAAoC,QAAQ,CAAC;EACzD,cAAc,oBAAoB,OAAO,OAAO;EAChD,MAAM,QAAQ;EACf;;AAGH,SAAS,kCACP,SACA,qBACc;AACd,KACE,uBACA,OAAO,OAAO,oBAAoB,CAAC,MAChC,WAAgB,OAAO,SAAS,QAAQ,UAC1C,EACD;EACA,MAAM,SAAS,OAAO,OAAO,oBAAoB,CAAC,MAC/C,WAAgB,OAAO,SAAS,QAAQ,UAC1C;EAGD,MAAM,uBAAuB,mBAAwB;AACnD,OAAI,CAAC,eAAgB,QAAO;AAE5B,WAAQ,UAAgB;AAStB,WAAO,eAJa,EAClB,OAJY,QAAQ,OAKrB,CAEiC;;;AAItC,SAAO;GACL,IAAI,QAAQ;GACZ,MAAM;GACN,cAAc,oBAAoB,OAAO,OAAO;GAChD,WAAW,QAAQ;GACnB,OAAO,QAAQ;GAChB;;AAGH,QAAO;EACL,IAAI,QAAQ;EACZ,MAAM;EACN,WAAW,QAAQ;EACnB,OAAO,QAAQ;EAChB;;AAGH,SAAS,oCACP,wBACe;AACf,QAAO;EACL,IAAI,uBAAuB;EAC3B,UAAU;GACR,MAAM,uBAAuB;GAC7B,WAAW,KAAK,UAAU,uBAAuB,UAAU;GAC5D;EACD,MAAM;EACP;;AAGH,SAAgB,4BACd,SACc;AACd,SAAQ,QAAQ,MAAhB;EACE,UAAc,UACZ,QAAO;GACL,IAAI,QAAQ;GACZ,MAAM;GACN,SAAS,QAAQ;GAClB;EACH,UAAc,OACZ,QAAO;GACL,IAAI,QAAQ;GACZ,MAAM;GACN,SAAS,QAAQ;GAClB;EACH,UAAc,UACZ,QAAO;GACL,IAAI,QAAQ;GACZ,MAAM;GACN,SAAS,QAAQ;GAClB;EACH,UAAc,KACZ,QAAO;GACL,IAAI,QAAQ;GACZ,MAAM;GACN,SAAS,QAAQ;GAClB;EACH,QACE,OAAM,IAAI,MAAM,uBAAuB;;;AAI7C,SAAgB,8BACd,SACc;AACd,QAAO;EACL,IAAI,QAAQ;EACZ,MAAM;EACN,SAAS,QAAQ;EACjB,YAAY,QAAQ;EACpB,UAAU,QAAQ;EACnB;;AAGH,SAAgB,6BACd,SACc;AAEd,KAAI,CAAC,oBAAoB,QAAQ,OAAO,CACtC,OAAM,IAAI,MACR,yBAAyB,QAAQ,OAAO,2BAA2B,oBAAoB,KAAK,KAAK,GAClG;AAIH,KACE,CAAC,QAAQ,SACT,OAAO,QAAQ,UAAU,YACzB,QAAQ,MAAM,MAAM,KAAK,GAEzB,OAAM,IAAI,MAAM,yCAAyC;CAI3D,MAAM,OAAO,QAAQ,cAAkB,YAAY,cAAc;AAajE,QAVmC;EACjC,IAAI,QAAQ;EACZ;EACA,SAAS;EACT,OAAO;GACL,QAAQ,QAAQ;GAChB,OAAO,QAAQ;GAChB;EACF"}