illuma-agents 1.0.62 → 1.0.64

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.
@@ -1 +1 @@
1
- {"version":3,"file":"format.mjs","sources":["../../../src/messages/format.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n AIMessage,\n AIMessageChunk,\n ToolMessage,\n BaseMessage,\n HumanMessage,\n SystemMessage,\n getBufferString,\n} from '@langchain/core/messages';\nimport type { MessageContentImageUrl } from '@langchain/core/messages';\nimport type { ToolCall } from '@langchain/core/messages/tool';\nimport type {\n ExtendedMessageContent,\n MessageContentComplex,\n ReasoningContentText,\n ToolCallContent,\n ToolCallPart,\n TPayload,\n TMessage,\n} from '@/types';\nimport { Providers, ContentTypes, MessageTypes } from '@/common';\nimport { processToolOutput } from '@/utils/toonFormat';\n\ninterface MediaMessageParams {\n message: {\n role: string;\n content: string;\n name?: string;\n [key: string]: any;\n };\n mediaParts: MessageContentComplex[];\n endpoint?: Providers;\n}\n\n/**\n * Formats a message with media content (images, documents, videos, audios) to API payload format.\n *\n * @param params - The parameters for formatting.\n * @returns - The formatted message.\n */\nexport const formatMediaMessage = ({\n message,\n endpoint,\n mediaParts,\n}: MediaMessageParams): {\n role: string;\n content: MessageContentComplex[];\n name?: string;\n [key: string]: any;\n} => {\n // Create a new object to avoid mutating the input\n const result: {\n role: string;\n content: MessageContentComplex[];\n name?: string;\n [key: string]: any;\n } = {\n ...message,\n content: [] as MessageContentComplex[],\n };\n\n if (endpoint === Providers.ANTHROPIC) {\n result.content = [\n ...mediaParts,\n { type: ContentTypes.TEXT, text: message.content },\n ] as MessageContentComplex[];\n return result;\n }\n\n result.content = [\n { type: ContentTypes.TEXT, text: message.content },\n ...mediaParts,\n ] as MessageContentComplex[];\n\n return result;\n};\n\ninterface MessageInput {\n role?: string;\n _name?: string;\n sender?: string;\n text?: string;\n content?: string | MessageContentComplex[];\n image_urls?: MessageContentImageUrl[];\n documents?: MessageContentComplex[];\n videos?: MessageContentComplex[];\n audios?: MessageContentComplex[];\n lc_id?: string[];\n [key: string]: any;\n}\n\ninterface FormatMessageParams {\n message: MessageInput;\n userName?: string;\n assistantName?: string;\n endpoint?: Providers;\n langChain?: boolean;\n}\n\ninterface FormattedMessage {\n role: string;\n content: string | MessageContentComplex[];\n name?: string;\n [key: string]: any;\n}\n\n/**\n * Formats a message to OpenAI payload format based on the provided options.\n *\n * @param params - The parameters for formatting.\n * @returns - The formatted message.\n */\nexport const formatMessage = ({\n message,\n userName,\n endpoint,\n assistantName,\n langChain = false,\n}: FormatMessageParams):\n | FormattedMessage\n | HumanMessage\n | AIMessage\n | SystemMessage => {\n // eslint-disable-next-line prefer-const\n let { role: _role, _name, sender, text, content: _content, lc_id } = message;\n if (lc_id && lc_id[2] && !langChain) {\n const roleMapping: Record<string, string> = {\n SystemMessage: 'system',\n HumanMessage: 'user',\n AIMessage: 'assistant',\n };\n _role = roleMapping[lc_id[2]] || _role;\n }\n const role =\n _role ??\n (sender != null && sender && sender.toLowerCase() === 'user'\n ? 'user'\n : 'assistant');\n const content = _content ?? text ?? '';\n const formattedMessage: FormattedMessage = {\n role,\n content,\n };\n\n // Set name fields first\n if (_name != null && _name) {\n formattedMessage.name = _name;\n }\n\n if (userName != null && userName && formattedMessage.role === 'user') {\n formattedMessage.name = userName;\n }\n\n if (\n assistantName != null &&\n assistantName &&\n formattedMessage.role === 'assistant'\n ) {\n formattedMessage.name = assistantName;\n }\n\n if (formattedMessage.name != null && formattedMessage.name) {\n // Conform to API regex: ^[a-zA-Z0-9_-]{1,64}$\n // https://community.openai.com/t/the-format-of-the-name-field-in-the-documentation-is-incorrect/175684/2\n formattedMessage.name = formattedMessage.name.replace(\n /[^a-zA-Z0-9_-]/g,\n '_'\n );\n\n if (formattedMessage.name.length > 64) {\n formattedMessage.name = formattedMessage.name.substring(0, 64);\n }\n }\n\n const { image_urls, documents, videos, audios } = message;\n const mediaParts: MessageContentComplex[] = [];\n\n if (Array.isArray(documents) && documents.length > 0) {\n mediaParts.push(...documents);\n }\n\n if (Array.isArray(videos) && videos.length > 0) {\n mediaParts.push(...videos);\n }\n\n if (Array.isArray(audios) && audios.length > 0) {\n mediaParts.push(...audios);\n }\n\n if (Array.isArray(image_urls) && image_urls.length > 0) {\n mediaParts.push(...image_urls);\n }\n\n if (mediaParts.length > 0 && role === 'user') {\n const mediaMessage = formatMediaMessage({\n message: {\n ...formattedMessage,\n content:\n typeof formattedMessage.content === 'string'\n ? formattedMessage.content\n : '',\n },\n mediaParts,\n endpoint,\n });\n\n if (!langChain) {\n return mediaMessage;\n }\n\n return new HumanMessage(mediaMessage);\n }\n\n if (!langChain) {\n return formattedMessage;\n }\n\n if (role === 'user') {\n return new HumanMessage(formattedMessage);\n } else if (role === 'assistant') {\n return new AIMessage(formattedMessage);\n } else {\n return new SystemMessage(formattedMessage);\n }\n};\n\n/**\n * Formats an array of messages for LangChain.\n *\n * @param messages - The array of messages to format.\n * @param formatOptions - The options for formatting each message.\n * @returns - The array of formatted LangChain messages.\n */\nexport const formatLangChainMessages = (\n messages: Array<MessageInput>,\n formatOptions: Omit<FormatMessageParams, 'message' | 'langChain'>\n): Array<HumanMessage | AIMessage | SystemMessage> => {\n return messages.map((msg) => {\n const formatted = formatMessage({\n ...formatOptions,\n message: msg,\n langChain: true,\n });\n return formatted as HumanMessage | AIMessage | SystemMessage;\n });\n};\n\ninterface LangChainMessage {\n lc_kwargs?: {\n additional_kwargs?: Record<string, any>;\n [key: string]: any;\n };\n kwargs?: {\n additional_kwargs?: Record<string, any>;\n [key: string]: any;\n };\n [key: string]: any;\n}\n\n/**\n * Formats a LangChain message object by merging properties from `lc_kwargs` or `kwargs` and `additional_kwargs`.\n *\n * @param message - The message object to format.\n * @returns - The formatted LangChain message.\n */\nexport const formatFromLangChain = (\n message: LangChainMessage\n): Record<string, any> => {\n const kwargs = message.lc_kwargs ?? message.kwargs ?? {};\n const { additional_kwargs = {}, ...message_kwargs } = kwargs;\n return {\n ...message_kwargs,\n ...additional_kwargs,\n };\n};\n\n/**\n * Helper function to format an assistant message\n * @param message The message to format\n * @returns Array of formatted messages\n */\nfunction formatAssistantMessage(\n message: Partial<TMessage>\n): Array<AIMessage | ToolMessage> {\n const formattedMessages: Array<AIMessage | ToolMessage> = [];\n let currentContent: MessageContentComplex[] = [];\n let lastAIMessage: AIMessage | null = null;\n let hasReasoning = false;\n\n if (Array.isArray(message.content)) {\n for (const part of message.content) {\n if (part.type === ContentTypes.TEXT && part.tool_call_ids) {\n /*\n If there's pending content, it needs to be aggregated as a single string to prepare for tool calls.\n For Anthropic models, the \"tool_calls\" field on a message is only respected if content is a string.\n */\n if (currentContent.length > 0) {\n let content = currentContent.reduce((acc, curr) => {\n if (curr.type === ContentTypes.TEXT) {\n return `${acc}${curr[ContentTypes.TEXT] || ''}\\n`;\n }\n return acc;\n }, '');\n content =\n `${content}\\n${part[ContentTypes.TEXT] ?? part.text ?? ''}`.trim();\n lastAIMessage = new AIMessage({ content });\n formattedMessages.push(lastAIMessage);\n currentContent = [];\n continue;\n }\n // Create a new AIMessage with this text and prepare for tool calls\n lastAIMessage = new AIMessage({\n content: part.text != null ? part.text : '',\n });\n formattedMessages.push(lastAIMessage);\n } else if (part.type === ContentTypes.TOOL_CALL) {\n // Skip malformed tool call entries without tool_call property\n if (part.tool_call == null) {\n continue;\n }\n\n // Note: `tool_calls` list is defined when constructed by `AIMessage` class, and outputs should be excluded from it\n const {\n output,\n args: _args,\n ..._tool_call\n } = part.tool_call as ToolCallPart;\n\n // Skip invalid tool calls that have no name AND no output\n if (\n _tool_call.name == null ||\n (_tool_call.name === '' && (output == null || output === ''))\n ) {\n continue;\n }\n\n if (!lastAIMessage) {\n // \"Heal\" the payload by creating an AIMessage to precede the tool call\n lastAIMessage = new AIMessage({ content: '' });\n formattedMessages.push(lastAIMessage);\n }\n\n const tool_call: ToolCallPart = _tool_call;\n // TODO: investigate; args as dictionary may need to be providers-or-tool-specific\n let args: any = _args;\n try {\n if (typeof _args === 'string') {\n args = JSON.parse(_args);\n }\n } catch {\n if (typeof _args === 'string') {\n args = { input: _args };\n }\n }\n\n tool_call.args = args;\n if (!lastAIMessage.tool_calls) {\n lastAIMessage.tool_calls = [];\n }\n lastAIMessage.tool_calls.push(tool_call as ToolCall);\n\n // Apply TOON compression to historical tool outputs for context efficiency\n // processToolOutput handles: JSON→TOON conversion, already-TOON detection (skip), truncation\n const processedOutput =\n output != null ? processToolOutput(output).content : '';\n\n formattedMessages.push(\n new ToolMessage({\n tool_call_id: tool_call.id ?? '',\n name: tool_call.name,\n content: processedOutput,\n })\n );\n } else if (part.type === ContentTypes.THINK) {\n hasReasoning = true;\n continue;\n } else if (\n part.type === ContentTypes.ERROR ||\n part.type === ContentTypes.AGENT_UPDATE\n ) {\n continue;\n } else {\n currentContent.push(part);\n }\n }\n }\n\n if (hasReasoning && currentContent.length > 0) {\n const content = currentContent\n .reduce((acc, curr) => {\n if (curr.type === ContentTypes.TEXT) {\n return `${acc}${curr[ContentTypes.TEXT] || ''}\\n`;\n }\n return acc;\n }, '')\n .trim();\n\n if (content) {\n formattedMessages.push(new AIMessage({ content }));\n }\n } else if (currentContent.length > 0) {\n formattedMessages.push(new AIMessage({ content: currentContent }));\n }\n\n return formattedMessages;\n}\n\n/**\n * Labels all agent content for parallel patterns (fan-out/fan-in)\n * Groups consecutive content by agent and wraps with clear labels\n */\nfunction labelAllAgentContent(\n contentParts: MessageContentComplex[],\n agentIdMap: Record<number, string>,\n agentNames?: Record<string, string>\n): MessageContentComplex[] {\n const result: MessageContentComplex[] = [];\n let currentAgentId: string | undefined;\n let agentContentBuffer: MessageContentComplex[] = [];\n\n const flushAgentBuffer = (): void => {\n if (agentContentBuffer.length === 0) {\n return;\n }\n\n if (currentAgentId != null && currentAgentId !== '') {\n const agentName = (agentNames?.[currentAgentId] ?? '') || currentAgentId;\n const formattedParts: string[] = [];\n\n formattedParts.push(`--- ${agentName} ---`);\n\n for (const part of agentContentBuffer) {\n if (part.type === ContentTypes.THINK) {\n const thinkContent = (part as ReasoningContentText).think || '';\n if (thinkContent) {\n formattedParts.push(\n `${agentName}: ${JSON.stringify({\n type: 'think',\n think: thinkContent,\n })}`\n );\n }\n } else if (part.type === ContentTypes.TEXT) {\n const textContent: string = part.text ?? '';\n if (textContent) {\n formattedParts.push(`${agentName}: ${textContent}`);\n }\n } else if (part.type === ContentTypes.TOOL_CALL) {\n formattedParts.push(\n `${agentName}: ${JSON.stringify({\n type: 'tool_call',\n tool_call: (part as ToolCallContent).tool_call,\n })}`\n );\n }\n }\n\n formattedParts.push(`--- End of ${agentName} ---`);\n\n // Create a single text content part with all agent content\n result.push({\n type: ContentTypes.TEXT,\n text: formattedParts.join('\\n\\n'),\n } as MessageContentComplex);\n } else {\n // No agent ID, pass through as-is\n result.push(...agentContentBuffer);\n }\n\n agentContentBuffer = [];\n };\n\n for (let i = 0; i < contentParts.length; i++) {\n const part = contentParts[i];\n const agentId = agentIdMap[i];\n\n // If agent changed, flush previous buffer\n if (agentId !== currentAgentId && currentAgentId !== undefined) {\n flushAgentBuffer();\n }\n\n currentAgentId = agentId;\n agentContentBuffer.push(part);\n }\n\n // Flush any remaining content\n flushAgentBuffer();\n\n return result;\n}\n\n/**\n * Groups content parts by agent and formats them with agent labels\n * This preprocesses multi-agent content to prevent identity confusion\n *\n * @param contentParts - The content parts from a run\n * @param agentIdMap - Map of content part index to agent ID\n * @param agentNames - Optional map of agent ID to display name\n * @param options - Configuration options\n * @param options.labelNonTransferContent - If true, labels all agent transitions (for parallel patterns)\n * @returns Modified content parts with agent labels where appropriate\n */\nexport const labelContentByAgent = (\n contentParts: MessageContentComplex[],\n agentIdMap?: Record<number, string>,\n agentNames?: Record<string, string>,\n options?: { labelNonTransferContent?: boolean }\n): MessageContentComplex[] => {\n if (!agentIdMap || Object.keys(agentIdMap).length === 0) {\n return contentParts;\n }\n\n // If labelNonTransferContent is true, use a different strategy for parallel patterns\n if (options?.labelNonTransferContent === true) {\n return labelAllAgentContent(contentParts, agentIdMap, agentNames);\n }\n\n const result: MessageContentComplex[] = [];\n let currentAgentId: string | undefined;\n let agentContentBuffer: MessageContentComplex[] = [];\n let transferToolCallIndex: number | undefined;\n let transferToolCallId: string | undefined;\n\n const flushAgentBuffer = (): void => {\n if (agentContentBuffer.length === 0) {\n return;\n }\n\n // If this is content from a transferred agent, format it specially\n if (\n currentAgentId != null &&\n currentAgentId !== '' &&\n transferToolCallIndex !== undefined\n ) {\n const agentName = (agentNames?.[currentAgentId] ?? '') || currentAgentId;\n const formattedParts: string[] = [];\n\n formattedParts.push(`--- Transfer to ${agentName} ---`);\n\n for (const part of agentContentBuffer) {\n if (part.type === ContentTypes.THINK) {\n formattedParts.push(\n `${agentName}: ${JSON.stringify({\n type: 'think',\n think: (part as ReasoningContentText).think,\n })}`\n );\n } else if ('text' in part && part.type === ContentTypes.TEXT) {\n const textContent: string = part.text ?? '';\n if (textContent) {\n formattedParts.push(\n `${agentName}: ${JSON.stringify({\n type: 'text',\n text: textContent,\n })}`\n );\n }\n } else if (part.type === ContentTypes.TOOL_CALL) {\n formattedParts.push(\n `${agentName}: ${JSON.stringify({\n type: 'tool_call',\n tool_call: (part as ToolCallContent).tool_call,\n })}`\n );\n }\n }\n\n formattedParts.push(`--- End of ${agentName} response ---`);\n\n // Find the tool call that triggered this transfer and update its output\n if (transferToolCallIndex < result.length) {\n const transferToolCall = result[transferToolCallIndex];\n if (\n transferToolCall.type === ContentTypes.TOOL_CALL &&\n transferToolCall.tool_call?.id === transferToolCallId\n ) {\n transferToolCall.tool_call.output = formattedParts.join('\\n\\n');\n }\n }\n } else {\n // Not from a transfer, add as-is\n result.push(...agentContentBuffer);\n }\n\n agentContentBuffer = [];\n transferToolCallIndex = undefined;\n transferToolCallId = undefined;\n };\n\n for (let i = 0; i < contentParts.length; i++) {\n const part = contentParts[i];\n const agentId = agentIdMap[i];\n\n // Check if this is a transfer tool call\n const isTransferTool =\n (part.type === ContentTypes.TOOL_CALL &&\n (part as ToolCallContent).tool_call?.name?.startsWith(\n 'lc_transfer_to_'\n )) ??\n false;\n\n // If agent changed, flush previous buffer\n if (agentId !== currentAgentId && currentAgentId !== undefined) {\n flushAgentBuffer();\n }\n\n currentAgentId = agentId;\n\n if (isTransferTool) {\n // Flush any existing buffer first\n flushAgentBuffer();\n // Add the transfer tool call to result\n result.push(part);\n // Mark that the next agent's content should be captured\n transferToolCallIndex = result.length - 1;\n transferToolCallId = (part as ToolCallContent).tool_call?.id;\n currentAgentId = undefined; // Reset to capture the next agent\n } else {\n agentContentBuffer.push(part);\n }\n }\n\n flushAgentBuffer();\n\n return result;\n};\n\n/**\n * Formats an array of messages for LangChain, handling tool calls and creating ToolMessage instances.\n *\n * @param payload - The array of messages to format.\n * @param indexTokenCountMap - Optional map of message indices to token counts.\n * @param tools - Optional set of tool names that are allowed in the request.\n * @returns - Object containing formatted messages and updated indexTokenCountMap if provided.\n */\nexport const formatAgentMessages = (\n payload: TPayload,\n indexTokenCountMap?: Record<number, number | undefined>,\n tools?: Set<string>\n): {\n messages: Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>;\n indexTokenCountMap?: Record<number, number>;\n} => {\n const messages: Array<\n HumanMessage | AIMessage | SystemMessage | ToolMessage\n > = [];\n // If indexTokenCountMap is provided, create a new map to track the updated indices\n const updatedIndexTokenCountMap: Record<number, number> = {};\n // Keep track of the mapping from original payload indices to result indices\n const indexMapping: Record<number, number[] | undefined> = {};\n\n // Process messages with tool conversion if tools set is provided\n for (let i = 0; i < payload.length; i++) {\n const message = payload[i];\n // Q: Store the current length of messages to track where this payload message starts in the result?\n // const startIndex = messages.length;\n if (typeof message.content === 'string') {\n message.content = [\n { type: ContentTypes.TEXT, [ContentTypes.TEXT]: message.content },\n ];\n }\n if (message.role !== 'assistant') {\n messages.push(\n formatMessage({\n message: message as MessageInput,\n langChain: true,\n }) as HumanMessage | AIMessage | SystemMessage\n );\n\n // Update the index mapping for this message\n indexMapping[i] = [messages.length - 1];\n continue;\n }\n\n // For assistant messages, track the starting index before processing\n const startMessageIndex = messages.length;\n\n // If tools set is provided, we need to check if we need to convert tool messages to a string\n if (tools) {\n // First, check if this message contains tool calls\n let hasToolCalls = false;\n let hasInvalidTool = false;\n const toolNames: string[] = [];\n\n const content = message.content;\n if (content && Array.isArray(content)) {\n for (const part of content) {\n if (part.type === ContentTypes.TOOL_CALL) {\n hasToolCalls = true;\n if (tools.size === 0) {\n hasInvalidTool = true;\n break;\n }\n // Protect against malformed tool call entries\n if (\n part.tool_call == null ||\n part.tool_call.name == null ||\n part.tool_call.name === ''\n ) {\n hasInvalidTool = true;\n continue;\n }\n const toolName = part.tool_call.name;\n toolNames.push(toolName);\n if (!tools.has(toolName)) {\n hasInvalidTool = true;\n }\n }\n }\n }\n\n // If this message has tool calls and at least one is invalid, we need to convert it\n if (hasToolCalls && hasInvalidTool) {\n // We need to collect all related messages (this message and any subsequent tool messages)\n const toolSequence: BaseMessage[] = [];\n let sequenceEndIndex = i;\n\n // Process the current assistant message to get the AIMessage with tool calls\n const formattedMessages = formatAssistantMessage(message);\n toolSequence.push(...formattedMessages);\n\n // Look ahead for any subsequent assistant messages that might be part of this tool sequence\n let j = i + 1;\n while (j < payload.length && payload[j].role === 'assistant') {\n // Check if this is a continuation of the tool sequence\n let isToolResponse = false;\n const content = payload[j].content;\n if (content != null && Array.isArray(content)) {\n for (const part of content) {\n if (part.type === ContentTypes.TOOL_CALL) {\n isToolResponse = true;\n break;\n }\n }\n }\n\n if (isToolResponse) {\n // This is part of the tool sequence, add it\n const nextMessages = formatAssistantMessage(payload[j]);\n toolSequence.push(...nextMessages);\n sequenceEndIndex = j;\n j++;\n } else {\n // This is not part of the tool sequence, stop looking\n break;\n }\n }\n\n // Convert the sequence to a string\n const bufferString = getBufferString(toolSequence);\n messages.push(new AIMessage({ content: bufferString }));\n\n // Skip the messages we've already processed\n i = sequenceEndIndex;\n\n // Update the index mapping for this sequence\n const resultIndices = [messages.length - 1];\n for (let k = i; k >= i && k <= sequenceEndIndex; k++) {\n indexMapping[k] = resultIndices;\n }\n\n continue;\n }\n }\n\n // Process the assistant message using the helper function\n const formattedMessages = formatAssistantMessage(message);\n messages.push(...formattedMessages);\n\n // Update the index mapping for this assistant message\n // Store all indices that were created from this original message\n const endMessageIndex = messages.length;\n const resultIndices = [];\n for (let j = startMessageIndex; j < endMessageIndex; j++) {\n resultIndices.push(j);\n }\n indexMapping[i] = resultIndices;\n }\n\n // Update the token count map if it was provided\n if (indexTokenCountMap) {\n for (\n let originalIndex = 0;\n originalIndex < payload.length;\n originalIndex++\n ) {\n const resultIndices = indexMapping[originalIndex] || [];\n const tokenCount = indexTokenCountMap[originalIndex];\n\n if (tokenCount !== undefined) {\n if (resultIndices.length === 1) {\n // Simple 1:1 mapping\n updatedIndexTokenCountMap[resultIndices[0]] = tokenCount;\n } else if (resultIndices.length > 1) {\n // If one message was split into multiple, distribute the token count\n // This is a simplification - in reality, you might want a more sophisticated distribution\n const countPerMessage = Math.floor(tokenCount / resultIndices.length);\n resultIndices.forEach((resultIndex, idx) => {\n if (idx === resultIndices.length - 1) {\n // Give any remainder to the last message\n updatedIndexTokenCountMap[resultIndex] =\n tokenCount - countPerMessage * (resultIndices.length - 1);\n } else {\n updatedIndexTokenCountMap[resultIndex] = countPerMessage;\n }\n });\n }\n }\n }\n }\n\n return {\n messages,\n indexTokenCountMap: indexTokenCountMap\n ? updatedIndexTokenCountMap\n : undefined,\n };\n};\n\n/**\n * Adds a value at key 0 for system messages and shifts all key indices by one in an indexTokenCountMap.\n * This is useful when adding a system message at the beginning of a conversation.\n *\n * @param indexTokenCountMap - The original map of message indices to token counts\n * @param instructionsTokenCount - The token count for the system message to add at index 0\n * @returns A new map with the system message at index 0 and all other indices shifted by 1\n */\nexport function shiftIndexTokenCountMap(\n indexTokenCountMap: Record<number, number>,\n instructionsTokenCount: number\n): Record<number, number> {\n // Create a new map to avoid modifying the original\n const shiftedMap: Record<number, number> = {};\n shiftedMap[0] = instructionsTokenCount;\n\n // Shift all existing indices by 1\n for (const [indexStr, tokenCount] of Object.entries(indexTokenCountMap)) {\n const index = Number(indexStr);\n shiftedMap[index + 1] = tokenCount;\n }\n\n return shiftedMap;\n}\n\n/**\n * Ensures compatibility when switching from a non-thinking agent to a thinking-enabled agent.\n * Converts AI messages with tool calls (that lack thinking/reasoning blocks) into buffer strings,\n * avoiding the thinking block signature requirement.\n *\n * Recognizes the following as valid thinking/reasoning blocks:\n * - ContentTypes.THINKING (Anthropic)\n * - ContentTypes.REASONING_CONTENT (Bedrock)\n * - ContentTypes.REASONING (VertexAI / Google)\n * - 'redacted_thinking'\n *\n * @param messages - Array of messages to process\n * @param provider - The provider being used (unused but kept for future compatibility)\n * @returns The messages array with tool sequences converted to buffer strings if necessary\n */\nexport function ensureThinkingBlockInMessages(\n messages: BaseMessage[],\n _provider: Providers\n): BaseMessage[] {\n const result: BaseMessage[] = [];\n let i = 0;\n\n while (i < messages.length) {\n const msg = messages[i];\n const isAI = msg instanceof AIMessage || msg instanceof AIMessageChunk;\n\n if (!isAI) {\n result.push(msg);\n i++;\n continue;\n }\n\n const aiMsg = msg as AIMessage | AIMessageChunk;\n const hasToolCalls = aiMsg.tool_calls && aiMsg.tool_calls.length > 0;\n const contentIsArray = Array.isArray(aiMsg.content);\n\n // Check if the message has tool calls or tool_use content\n let hasToolUse = hasToolCalls ?? false;\n let firstContentType: string | undefined;\n\n if (contentIsArray && aiMsg.content.length > 0) {\n const content = aiMsg.content as ExtendedMessageContent[];\n firstContentType = content[0]?.type;\n hasToolUse =\n hasToolUse ||\n content.some((c) => typeof c === 'object' && c.type === 'tool_use');\n }\n\n // If message has tool use but no thinking block, convert to buffer string\n if (\n hasToolUse &&\n firstContentType !== ContentTypes.THINKING &&\n firstContentType !== ContentTypes.REASONING_CONTENT &&\n firstContentType !== ContentTypes.REASONING &&\n firstContentType !== 'redacted_thinking'\n ) {\n // Collect the AI message and any following tool messages\n const toolSequence: BaseMessage[] = [msg];\n let j = i + 1;\n\n // Look ahead for tool messages that belong to this AI message\n // Use getType() instead of instanceof to avoid module mismatch issues\n // where different copies of ToolMessage class might be loaded\n while (\n j < messages.length &&\n messages[j].getType() === MessageTypes.TOOL\n ) {\n toolSequence.push(messages[j]);\n j++;\n }\n\n // Convert the sequence to a buffer string and wrap in a HumanMessage\n // This avoids the thinking block requirement which only applies to AI messages\n const bufferString = getBufferString(toolSequence);\n result.push(\n new HumanMessage({\n content: `[Previous agent context]\\n${bufferString}`,\n })\n );\n\n // Skip the messages we've processed\n i = j;\n } else {\n // Keep the message as is\n result.push(msg);\n i++;\n }\n }\n\n return result;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"format.mjs","sources":["../../../src/messages/format.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n AIMessage,\n AIMessageChunk,\n ToolMessage,\n BaseMessage,\n HumanMessage,\n SystemMessage,\n getBufferString,\n} from '@langchain/core/messages';\nimport type { MessageContentImageUrl } from '@langchain/core/messages';\nimport type { ToolCall } from '@langchain/core/messages/tool';\nimport type {\n ExtendedMessageContent,\n MessageContentComplex,\n ReasoningContentText,\n ToolCallContent,\n ToolCallPart,\n TPayload,\n TMessage,\n} from '@/types';\nimport { Providers, ContentTypes, MessageTypes } from '@/common';\nimport { processToolOutput } from '@/utils/toonFormat';\n\ninterface MediaMessageParams {\n message: {\n role: string;\n content: string;\n name?: string;\n [key: string]: any;\n };\n mediaParts: MessageContentComplex[];\n endpoint?: Providers;\n}\n\n/**\n * Formats a message with media content (images, documents, videos, audios) to API payload format.\n *\n * @param params - The parameters for formatting.\n * @returns - The formatted message.\n */\nexport const formatMediaMessage = ({\n message,\n endpoint,\n mediaParts,\n}: MediaMessageParams): {\n role: string;\n content: MessageContentComplex[];\n name?: string;\n [key: string]: any;\n} => {\n // Create a new object to avoid mutating the input\n const result: {\n role: string;\n content: MessageContentComplex[];\n name?: string;\n [key: string]: any;\n } = {\n ...message,\n content: [] as MessageContentComplex[],\n };\n\n if (endpoint === Providers.ANTHROPIC) {\n result.content = [\n ...mediaParts,\n { type: ContentTypes.TEXT, text: message.content },\n ] as MessageContentComplex[];\n return result;\n }\n\n result.content = [\n { type: ContentTypes.TEXT, text: message.content },\n ...mediaParts,\n ] as MessageContentComplex[];\n\n return result;\n};\n\ninterface MessageInput {\n role?: string;\n _name?: string;\n sender?: string;\n text?: string;\n content?: string | MessageContentComplex[];\n image_urls?: MessageContentImageUrl[];\n documents?: MessageContentComplex[];\n videos?: MessageContentComplex[];\n audios?: MessageContentComplex[];\n lc_id?: string[];\n [key: string]: any;\n}\n\ninterface FormatMessageParams {\n message: MessageInput;\n userName?: string;\n assistantName?: string;\n endpoint?: Providers;\n langChain?: boolean;\n}\n\ninterface FormattedMessage {\n role: string;\n content: string | MessageContentComplex[];\n name?: string;\n [key: string]: any;\n}\n\n/**\n * Formats a message to OpenAI payload format based on the provided options.\n *\n * @param params - The parameters for formatting.\n * @returns - The formatted message.\n */\nexport const formatMessage = ({\n message,\n userName,\n endpoint,\n assistantName,\n langChain = false,\n}: FormatMessageParams):\n | FormattedMessage\n | HumanMessage\n | AIMessage\n | SystemMessage => {\n // eslint-disable-next-line prefer-const\n let { role: _role, _name, sender, text, content: _content, lc_id } = message;\n if (lc_id && lc_id[2] && !langChain) {\n const roleMapping: Record<string, string> = {\n SystemMessage: 'system',\n HumanMessage: 'user',\n AIMessage: 'assistant',\n };\n _role = roleMapping[lc_id[2]] || _role;\n }\n const role =\n _role ??\n (sender != null && sender && sender.toLowerCase() === 'user'\n ? 'user'\n : 'assistant');\n const content = _content ?? text ?? '';\n const formattedMessage: FormattedMessage = {\n role,\n content,\n };\n\n // Set name fields first\n if (_name != null && _name) {\n formattedMessage.name = _name;\n }\n\n if (userName != null && userName && formattedMessage.role === 'user') {\n formattedMessage.name = userName;\n }\n\n if (\n assistantName != null &&\n assistantName &&\n formattedMessage.role === 'assistant'\n ) {\n formattedMessage.name = assistantName;\n }\n\n if (formattedMessage.name != null && formattedMessage.name) {\n // Conform to API regex: ^[a-zA-Z0-9_-]{1,64}$\n // https://community.openai.com/t/the-format-of-the-name-field-in-the-documentation-is-incorrect/175684/2\n formattedMessage.name = formattedMessage.name.replace(\n /[^a-zA-Z0-9_-]/g,\n '_'\n );\n\n if (formattedMessage.name.length > 64) {\n formattedMessage.name = formattedMessage.name.substring(0, 64);\n }\n }\n\n const { image_urls, documents, videos, audios } = message;\n const mediaParts: MessageContentComplex[] = [];\n\n if (Array.isArray(documents) && documents.length > 0) {\n mediaParts.push(...documents);\n }\n\n if (Array.isArray(videos) && videos.length > 0) {\n mediaParts.push(...videos);\n }\n\n if (Array.isArray(audios) && audios.length > 0) {\n mediaParts.push(...audios);\n }\n\n if (Array.isArray(image_urls) && image_urls.length > 0) {\n mediaParts.push(...image_urls);\n }\n\n if (mediaParts.length > 0 && role === 'user') {\n const mediaMessage = formatMediaMessage({\n message: {\n ...formattedMessage,\n content:\n typeof formattedMessage.content === 'string'\n ? formattedMessage.content\n : '',\n },\n mediaParts,\n endpoint,\n });\n\n if (!langChain) {\n return mediaMessage;\n }\n\n return new HumanMessage(mediaMessage);\n }\n\n if (!langChain) {\n return formattedMessage;\n }\n\n if (role === 'user') {\n return new HumanMessage(formattedMessage);\n } else if (role === 'assistant') {\n return new AIMessage(formattedMessage);\n } else {\n return new SystemMessage(formattedMessage);\n }\n};\n\n/**\n * Formats an array of messages for LangChain.\n *\n * @param messages - The array of messages to format.\n * @param formatOptions - The options for formatting each message.\n * @returns - The array of formatted LangChain messages.\n */\nexport const formatLangChainMessages = (\n messages: Array<MessageInput>,\n formatOptions: Omit<FormatMessageParams, 'message' | 'langChain'>\n): Array<HumanMessage | AIMessage | SystemMessage> => {\n return messages.map((msg) => {\n const formatted = formatMessage({\n ...formatOptions,\n message: msg,\n langChain: true,\n });\n return formatted as HumanMessage | AIMessage | SystemMessage;\n });\n};\n\ninterface LangChainMessage {\n lc_kwargs?: {\n additional_kwargs?: Record<string, any>;\n [key: string]: any;\n };\n kwargs?: {\n additional_kwargs?: Record<string, any>;\n [key: string]: any;\n };\n [key: string]: any;\n}\n\n/**\n * Formats a LangChain message object by merging properties from `lc_kwargs` or `kwargs` and `additional_kwargs`.\n *\n * @param message - The message object to format.\n * @returns - The formatted LangChain message.\n */\nexport const formatFromLangChain = (\n message: LangChainMessage\n): Record<string, any> => {\n const kwargs = message.lc_kwargs ?? message.kwargs ?? {};\n const { additional_kwargs = {}, ...message_kwargs } = kwargs;\n return {\n ...message_kwargs,\n ...additional_kwargs,\n };\n};\n\n/**\n * Helper function to format an assistant message\n * @param message The message to format\n * @returns Array of formatted messages\n */\nfunction formatAssistantMessage(\n message: Partial<TMessage>\n): Array<AIMessage | ToolMessage> {\n const formattedMessages: Array<AIMessage | ToolMessage> = [];\n let currentContent: MessageContentComplex[] = [];\n let lastAIMessage: AIMessage | null = null;\n let hasReasoning = false;\n\n if (Array.isArray(message.content)) {\n for (const part of message.content) {\n if (part.type === ContentTypes.TEXT && part.tool_call_ids) {\n /*\n If there's pending content, it needs to be aggregated as a single string to prepare for tool calls.\n For Anthropic models, the \"tool_calls\" field on a message is only respected if content is a string.\n */\n if (currentContent.length > 0) {\n let content = currentContent.reduce((acc, curr) => {\n if (curr.type === ContentTypes.TEXT) {\n return `${acc}${curr[ContentTypes.TEXT] || ''}\\n`;\n }\n return acc;\n }, '');\n content =\n `${content}\\n${part[ContentTypes.TEXT] ?? part.text ?? ''}`.trim();\n lastAIMessage = new AIMessage({ content });\n formattedMessages.push(lastAIMessage);\n currentContent = [];\n continue;\n }\n // Create a new AIMessage with this text and prepare for tool calls\n lastAIMessage = new AIMessage({\n content: part.text != null ? part.text : '',\n });\n formattedMessages.push(lastAIMessage);\n } else if (part.type === ContentTypes.TOOL_CALL) {\n // Skip malformed tool call entries without tool_call property\n if (part.tool_call == null) {\n continue;\n }\n\n // Note: `tool_calls` list is defined when constructed by `AIMessage` class, and outputs should be excluded from it\n const {\n output,\n args: _args,\n ..._tool_call\n } = part.tool_call as ToolCallPart;\n\n // Skip invalid tool calls that have no name AND no output\n if (\n _tool_call.name == null ||\n (_tool_call.name === '' && (output == null || output === ''))\n ) {\n continue;\n }\n\n if (!lastAIMessage) {\n // \"Heal\" the payload by creating an AIMessage to precede the tool call\n lastAIMessage = new AIMessage({ content: '' });\n formattedMessages.push(lastAIMessage);\n }\n\n const tool_call: ToolCallPart = _tool_call;\n // TODO: investigate; args as dictionary may need to be providers-or-tool-specific\n let args: any = _args;\n try {\n if (typeof _args === 'string') {\n args = JSON.parse(_args);\n }\n } catch {\n if (typeof _args === 'string') {\n args = { input: _args };\n }\n }\n\n tool_call.args = args;\n if (!lastAIMessage.tool_calls) {\n lastAIMessage.tool_calls = [];\n }\n lastAIMessage.tool_calls.push(tool_call as ToolCall);\n\n // Apply TOON compression to historical tool outputs for context efficiency\n // processToolOutput handles: JSON→TOON conversion, already-TOON detection (skip), truncation\n const processedOutput =\n output != null ? processToolOutput(output).content : '';\n\n formattedMessages.push(\n new ToolMessage({\n tool_call_id: tool_call.id ?? '',\n name: tool_call.name,\n content: processedOutput,\n })\n );\n } else if (part.type === ContentTypes.THINK) {\n hasReasoning = true;\n continue;\n } else if (\n part.type === ContentTypes.ERROR ||\n part.type === ContentTypes.AGENT_UPDATE\n ) {\n continue;\n } else {\n currentContent.push(part);\n }\n }\n }\n\n if (hasReasoning && currentContent.length > 0) {\n const content = currentContent\n .reduce((acc, curr) => {\n if (curr.type === ContentTypes.TEXT) {\n return `${acc}${curr[ContentTypes.TEXT] || ''}\\n`;\n }\n return acc;\n }, '')\n .trim();\n\n if (content) {\n formattedMessages.push(new AIMessage({ content }));\n }\n } else if (currentContent.length > 0) {\n formattedMessages.push(new AIMessage({ content: currentContent }));\n }\n\n return formattedMessages;\n}\n\n/**\n * Labels all agent content for parallel patterns (fan-out/fan-in)\n * Groups consecutive content by agent and wraps with clear labels\n */\nfunction labelAllAgentContent(\n contentParts: MessageContentComplex[],\n agentIdMap: Record<number, string>,\n agentNames?: Record<string, string>\n): MessageContentComplex[] {\n const result: MessageContentComplex[] = [];\n let currentAgentId: string | undefined;\n let agentContentBuffer: MessageContentComplex[] = [];\n\n const flushAgentBuffer = (): void => {\n if (agentContentBuffer.length === 0) {\n return;\n }\n\n if (currentAgentId != null && currentAgentId !== '') {\n const agentName = (agentNames?.[currentAgentId] ?? '') || currentAgentId;\n const formattedParts: string[] = [];\n\n formattedParts.push(`--- ${agentName} ---`);\n\n for (const part of agentContentBuffer) {\n if (part.type === ContentTypes.THINK) {\n const thinkContent = (part as ReasoningContentText).think || '';\n if (thinkContent) {\n formattedParts.push(\n `${agentName}: ${JSON.stringify({\n type: 'think',\n think: thinkContent,\n })}`\n );\n }\n } else if (part.type === ContentTypes.TEXT) {\n const textContent: string = part.text ?? '';\n if (textContent) {\n formattedParts.push(`${agentName}: ${textContent}`);\n }\n } else if (part.type === ContentTypes.TOOL_CALL) {\n formattedParts.push(\n `${agentName}: ${JSON.stringify({\n type: 'tool_call',\n tool_call: (part as ToolCallContent).tool_call,\n })}`\n );\n }\n }\n\n formattedParts.push(`--- End of ${agentName} ---`);\n\n // Create a single text content part with all agent content\n result.push({\n type: ContentTypes.TEXT,\n text: formattedParts.join('\\n\\n'),\n } as MessageContentComplex);\n } else {\n // No agent ID, pass through as-is\n result.push(...agentContentBuffer);\n }\n\n agentContentBuffer = [];\n };\n\n for (let i = 0; i < contentParts.length; i++) {\n const part = contentParts[i];\n const agentId = agentIdMap[i];\n\n // If agent changed, flush previous buffer\n if (agentId !== currentAgentId && currentAgentId !== undefined) {\n flushAgentBuffer();\n }\n\n currentAgentId = agentId;\n agentContentBuffer.push(part);\n }\n\n // Flush any remaining content\n flushAgentBuffer();\n\n return result;\n}\n\n/**\n * Groups content parts by agent and formats them with agent labels\n * This preprocesses multi-agent content to prevent identity confusion\n *\n * @param contentParts - The content parts from a run\n * @param agentIdMap - Map of content part index to agent ID\n * @param agentNames - Optional map of agent ID to display name\n * @param options - Configuration options\n * @param options.labelNonTransferContent - If true, labels all agent transitions (for parallel patterns)\n * @returns Modified content parts with agent labels where appropriate\n */\nexport const labelContentByAgent = (\n contentParts: MessageContentComplex[],\n agentIdMap?: Record<number, string>,\n agentNames?: Record<string, string>,\n options?: { labelNonTransferContent?: boolean }\n): MessageContentComplex[] => {\n if (!agentIdMap || Object.keys(agentIdMap).length === 0) {\n return contentParts;\n }\n\n // If labelNonTransferContent is true, use a different strategy for parallel patterns\n if (options?.labelNonTransferContent === true) {\n return labelAllAgentContent(contentParts, agentIdMap, agentNames);\n }\n\n const result: MessageContentComplex[] = [];\n let currentAgentId: string | undefined;\n let agentContentBuffer: MessageContentComplex[] = [];\n let transferToolCallIndex: number | undefined;\n let transferToolCallId: string | undefined;\n\n const flushAgentBuffer = (): void => {\n if (agentContentBuffer.length === 0) {\n return;\n }\n\n // If this is content from a transferred agent, format it specially\n if (\n currentAgentId != null &&\n currentAgentId !== '' &&\n transferToolCallIndex !== undefined\n ) {\n const agentName = (agentNames?.[currentAgentId] ?? '') || currentAgentId;\n const formattedParts: string[] = [];\n\n formattedParts.push(`--- Transfer to ${agentName} ---`);\n\n for (const part of agentContentBuffer) {\n if (part.type === ContentTypes.THINK) {\n formattedParts.push(\n `${agentName}: ${JSON.stringify({\n type: 'think',\n think: (part as ReasoningContentText).think,\n })}`\n );\n } else if ('text' in part && part.type === ContentTypes.TEXT) {\n const textContent: string = part.text ?? '';\n if (textContent) {\n formattedParts.push(\n `${agentName}: ${JSON.stringify({\n type: 'text',\n text: textContent,\n })}`\n );\n }\n } else if (part.type === ContentTypes.TOOL_CALL) {\n formattedParts.push(\n `${agentName}: ${JSON.stringify({\n type: 'tool_call',\n tool_call: (part as ToolCallContent).tool_call,\n })}`\n );\n }\n }\n\n formattedParts.push(`--- End of ${agentName} response ---`);\n\n // Find the tool call that triggered this transfer and update its output\n if (transferToolCallIndex < result.length) {\n const transferToolCall = result[transferToolCallIndex];\n if (\n transferToolCall.type === ContentTypes.TOOL_CALL &&\n transferToolCall.tool_call?.id === transferToolCallId\n ) {\n transferToolCall.tool_call.output = formattedParts.join('\\n\\n');\n }\n }\n } else {\n // Not from a transfer, add as-is\n result.push(...agentContentBuffer);\n }\n\n agentContentBuffer = [];\n transferToolCallIndex = undefined;\n transferToolCallId = undefined;\n };\n\n for (let i = 0; i < contentParts.length; i++) {\n const part = contentParts[i];\n const agentId = agentIdMap[i];\n\n // Check if this is a transfer tool call\n const isTransferTool =\n (part.type === ContentTypes.TOOL_CALL &&\n (part as ToolCallContent).tool_call?.name?.startsWith(\n 'lc_transfer_to_'\n )) ??\n false;\n\n // If agent changed, flush previous buffer\n if (agentId !== currentAgentId && currentAgentId !== undefined) {\n flushAgentBuffer();\n }\n\n currentAgentId = agentId;\n\n if (isTransferTool) {\n // Flush any existing buffer first\n flushAgentBuffer();\n // Add the transfer tool call to result\n result.push(part);\n // Mark that the next agent's content should be captured\n transferToolCallIndex = result.length - 1;\n transferToolCallId = (part as ToolCallContent).tool_call?.id;\n currentAgentId = undefined; // Reset to capture the next agent\n } else {\n agentContentBuffer.push(part);\n }\n }\n\n flushAgentBuffer();\n\n return result;\n};\n\n/**\n * Formats an array of messages for LangChain, handling tool calls and creating ToolMessage instances.\n *\n * @param payload - The array of messages to format.\n * @param indexTokenCountMap - Optional map of message indices to token counts.\n * @param tools - Optional set of tool names that are allowed in the request.\n * @returns - Object containing formatted messages and updated indexTokenCountMap if provided.\n */\nexport const formatAgentMessages = (\n payload: TPayload,\n indexTokenCountMap?: Record<number, number | undefined>,\n tools?: Set<string>\n): {\n messages: Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>;\n indexTokenCountMap?: Record<number, number>;\n} => {\n const messages: Array<\n HumanMessage | AIMessage | SystemMessage | ToolMessage\n > = [];\n // If indexTokenCountMap is provided, create a new map to track the updated indices\n const updatedIndexTokenCountMap: Record<number, number> = {};\n // Keep track of the mapping from original payload indices to result indices\n const indexMapping: Record<number, number[] | undefined> = {};\n\n // Process messages with tool conversion if tools set is provided\n for (let i = 0; i < payload.length; i++) {\n const message = payload[i];\n // Q: Store the current length of messages to track where this payload message starts in the result?\n // const startIndex = messages.length;\n if (typeof message.content === 'string') {\n message.content = [\n { type: ContentTypes.TEXT, [ContentTypes.TEXT]: message.content },\n ];\n }\n if (message.role !== 'assistant') {\n messages.push(\n formatMessage({\n message: message as MessageInput,\n langChain: true,\n }) as HumanMessage | AIMessage | SystemMessage\n );\n\n // Update the index mapping for this message\n indexMapping[i] = [messages.length - 1];\n continue;\n }\n\n // For assistant messages, track the starting index before processing\n const startMessageIndex = messages.length;\n\n // If tools set is provided, we need to check if we need to convert tool messages to a string\n if (tools) {\n // First, check if this message contains tool calls\n let hasToolCalls = false;\n let hasInvalidTool = false;\n const toolNames: string[] = [];\n\n const content = message.content;\n if (content && Array.isArray(content)) {\n for (const part of content) {\n if (part.type === ContentTypes.TOOL_CALL) {\n hasToolCalls = true;\n if (tools.size === 0) {\n hasInvalidTool = true;\n break;\n }\n // Protect against malformed tool call entries\n if (\n part.tool_call == null ||\n part.tool_call.name == null ||\n part.tool_call.name === ''\n ) {\n hasInvalidTool = true;\n continue;\n }\n const toolName = part.tool_call.name;\n toolNames.push(toolName);\n if (!tools.has(toolName)) {\n hasInvalidTool = true;\n }\n }\n }\n }\n\n // If this message has tool calls and at least one is invalid, we need to convert it\n if (hasToolCalls && hasInvalidTool) {\n // We need to collect all related messages (this message and any subsequent tool messages)\n const toolSequence: BaseMessage[] = [];\n let sequenceEndIndex = i;\n\n // Process the current assistant message to get the AIMessage with tool calls\n const formattedMessages = formatAssistantMessage(message);\n toolSequence.push(...formattedMessages);\n\n // Look ahead for any subsequent assistant messages that might be part of this tool sequence\n let j = i + 1;\n while (j < payload.length && payload[j].role === 'assistant') {\n // Check if this is a continuation of the tool sequence\n let isToolResponse = false;\n const content = payload[j].content;\n if (content != null && Array.isArray(content)) {\n for (const part of content) {\n if (part.type === ContentTypes.TOOL_CALL) {\n isToolResponse = true;\n break;\n }\n }\n }\n\n if (isToolResponse) {\n // This is part of the tool sequence, add it\n const nextMessages = formatAssistantMessage(payload[j]);\n toolSequence.push(...nextMessages);\n sequenceEndIndex = j;\n j++;\n } else {\n // This is not part of the tool sequence, stop looking\n break;\n }\n }\n\n // Convert the sequence to a string\n const bufferString = getBufferString(toolSequence);\n messages.push(new AIMessage({ content: bufferString }));\n\n // Skip the messages we've already processed\n i = sequenceEndIndex;\n\n // Update the index mapping for this sequence\n const resultIndices = [messages.length - 1];\n for (let k = i; k >= i && k <= sequenceEndIndex; k++) {\n indexMapping[k] = resultIndices;\n }\n\n continue;\n }\n }\n\n // Process the assistant message using the helper function\n const formattedMessages = formatAssistantMessage(message);\n messages.push(...formattedMessages);\n\n // Update the index mapping for this assistant message\n // Store all indices that were created from this original message\n const endMessageIndex = messages.length;\n const resultIndices = [];\n for (let j = startMessageIndex; j < endMessageIndex; j++) {\n resultIndices.push(j);\n }\n indexMapping[i] = resultIndices;\n }\n\n // Update the token count map if it was provided\n if (indexTokenCountMap) {\n for (\n let originalIndex = 0;\n originalIndex < payload.length;\n originalIndex++\n ) {\n const resultIndices = indexMapping[originalIndex] || [];\n const tokenCount = indexTokenCountMap[originalIndex];\n\n if (tokenCount !== undefined) {\n if (resultIndices.length === 1) {\n // Simple 1:1 mapping\n updatedIndexTokenCountMap[resultIndices[0]] = tokenCount;\n } else if (resultIndices.length > 1) {\n // If one message was split into multiple, distribute the token count\n // This is a simplification - in reality, you might want a more sophisticated distribution\n const countPerMessage = Math.floor(tokenCount / resultIndices.length);\n resultIndices.forEach((resultIndex, idx) => {\n if (idx === resultIndices.length - 1) {\n // Give any remainder to the last message\n updatedIndexTokenCountMap[resultIndex] =\n tokenCount - countPerMessage * (resultIndices.length - 1);\n } else {\n updatedIndexTokenCountMap[resultIndex] = countPerMessage;\n }\n });\n }\n }\n }\n }\n\n return {\n messages,\n indexTokenCountMap: indexTokenCountMap\n ? updatedIndexTokenCountMap\n : undefined,\n };\n};\n\n/**\n * Adds a value at key 0 for system messages and shifts all key indices by one in an indexTokenCountMap.\n * This is useful when adding a system message at the beginning of a conversation.\n *\n * @param indexTokenCountMap - The original map of message indices to token counts\n * @param instructionsTokenCount - The token count for the system message to add at index 0\n * @returns A new map with the system message at index 0 and all other indices shifted by 1\n */\nexport function shiftIndexTokenCountMap(\n indexTokenCountMap: Record<number, number>,\n instructionsTokenCount: number\n): Record<number, number> {\n // Create a new map to avoid modifying the original\n const shiftedMap: Record<number, number> = {};\n shiftedMap[0] = instructionsTokenCount;\n\n // Shift all existing indices by 1\n for (const [indexStr, tokenCount] of Object.entries(indexTokenCountMap)) {\n const index = Number(indexStr);\n shiftedMap[index + 1] = tokenCount;\n }\n\n return shiftedMap;\n}\n\n/**\n * Ensures compatibility when switching from a non-thinking agent to a thinking-enabled agent.\n * Converts AI messages with tool calls (that lack thinking/reasoning blocks) into buffer strings,\n * avoiding the thinking block signature requirement.\n *\n * Recognizes the following as valid thinking/reasoning blocks:\n * - ContentTypes.THINKING (Anthropic)\n * - ContentTypes.REASONING_CONTENT (Bedrock)\n * - ContentTypes.REASONING (VertexAI / Google)\n * - 'redacted_thinking'\n *\n * @param messages - Array of messages to process\n * @param provider - The provider being used (unused but kept for future compatibility)\n * @returns The messages array with tool sequences converted to buffer strings if necessary\n */\nexport function ensureThinkingBlockInMessages(\n messages: BaseMessage[],\n _provider: Providers\n): BaseMessage[] {\n const result: BaseMessage[] = [];\n let i = 0;\n\n while (i < messages.length) {\n const msg = messages[i];\n const isAI = msg instanceof AIMessage || msg instanceof AIMessageChunk;\n\n if (!isAI) {\n result.push(msg);\n i++;\n continue;\n }\n\n const aiMsg = msg as AIMessage | AIMessageChunk;\n const hasToolCalls = aiMsg.tool_calls && aiMsg.tool_calls.length > 0;\n const contentIsArray = Array.isArray(aiMsg.content);\n\n // Check if the message has tool calls or tool_use content\n let hasToolUse = hasToolCalls ?? false;\n let firstContentType: string | undefined;\n\n if (contentIsArray && aiMsg.content.length > 0) {\n const content = aiMsg.content as ExtendedMessageContent[];\n firstContentType = content[0]?.type;\n hasToolUse =\n hasToolUse ||\n content.some((c) => typeof c === 'object' && c.type === 'tool_use');\n }\n\n // If message has tool use but no thinking block, convert to buffer string\n if (\n hasToolUse &&\n firstContentType !== ContentTypes.THINKING &&\n firstContentType !== ContentTypes.REASONING_CONTENT &&\n firstContentType !== ContentTypes.REASONING &&\n firstContentType !== 'redacted_thinking'\n ) {\n // Collect the AI message and any following tool messages\n const toolSequence: BaseMessage[] = [msg];\n let j = i + 1;\n\n // Look ahead for tool messages that belong to this AI message\n // Use getType() instead of instanceof to avoid module mismatch issues\n // where different copies of ToolMessage class might be loaded\n while (\n j < messages.length &&\n messages[j].getType() === MessageTypes.TOOL\n ) {\n toolSequence.push(messages[j]);\n j++;\n }\n\n // Convert the sequence to a buffer string and wrap in a HumanMessage\n // This avoids the thinking block requirement which only applies to AI messages\n const bufferString = getBufferString(toolSequence);\n result.push(\n new HumanMessage({\n content: `[Previous agent context]\\n${bufferString}`,\n })\n );\n\n // Skip the messages we've processed\n i = j;\n } else {\n // Keep the message as is\n result.push(msg);\n i++;\n }\n }\n\n return result;\n}\n\n/**\n * Strips thinking blocks from messages for structured output invocation.\n * When switching from thinking-enabled mode to structured output (which requires thinking disabled),\n * we need to remove thinking/reasoning blocks from the conversation to avoid Bedrock errors.\n *\n * @param messages - Array of messages to process\n * @returns The messages array with thinking blocks stripped from AI messages\n */\nexport function stripThinkingBlocksFromMessages(\n messages: BaseMessage[]\n): BaseMessage[] {\n return messages.map((msg) => {\n const isAI = msg instanceof AIMessage || msg instanceof AIMessageChunk;\n \n if (!isAI) {\n return msg;\n }\n \n const aiMsg = msg as AIMessage | AIMessageChunk;\n const content = aiMsg.content;\n \n // If content is not an array, nothing to strip\n if (!Array.isArray(content)) {\n return msg;\n }\n \n // Filter out thinking/reasoning blocks\n const filteredContent = content.filter((c) => {\n if (typeof c !== 'object' || c === null) {\n return true;\n }\n const type = (c as ExtendedMessageContent).type;\n return (\n type !== ContentTypes.THINKING &&\n type !== ContentTypes.REASONING_CONTENT &&\n type !== ContentTypes.REASONING &&\n type !== 'thinking' &&\n type !== 'redacted_thinking'\n );\n });\n \n // If no content left after filtering, add a placeholder\n if (filteredContent.length === 0) {\n filteredContent.push({\n type: 'text',\n text: '(previous response)',\n });\n }\n \n // Create a new AI message with the filtered content\n return new AIMessageChunk({\n content: filteredContent,\n id: aiMsg.id,\n response_metadata: aiMsg.response_metadata,\n usage_metadata: aiMsg.usage_metadata,\n // Don't include tool_calls - we're stripping those for structured output context\n });\n });\n}\n"],"names":[],"mappings":"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"}
@@ -134,4 +134,13 @@ export declare function shiftIndexTokenCountMap(indexTokenCountMap: Record<numbe
134
134
  * @returns The messages array with tool sequences converted to buffer strings if necessary
135
135
  */
136
136
  export declare function ensureThinkingBlockInMessages(messages: BaseMessage[], _provider: Providers): BaseMessage[];
137
+ /**
138
+ * Strips thinking blocks from messages for structured output invocation.
139
+ * When switching from thinking-enabled mode to structured output (which requires thinking disabled),
140
+ * we need to remove thinking/reasoning blocks from the conversation to avoid Bedrock errors.
141
+ *
142
+ * @param messages - Array of messages to process
143
+ * @returns The messages array with thinking blocks stripped from AI messages
144
+ */
145
+ export declare function stripThinkingBlocksFromMessages(messages: BaseMessage[]): BaseMessage[];
137
146
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "illuma-agents",
3
- "version": "1.0.62",
3
+ "version": "1.0.64",
4
4
  "main": "./dist/cjs/main.cjs",
5
5
  "module": "./dist/esm/main.mjs",
6
6
  "types": "./dist/types/index.d.ts",
@@ -793,6 +793,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
793
793
 
794
794
  // Debug: log what we got back
795
795
  console.log('[Graph] Structured output raw result type:', typeof result);
796
+ console.log('[Graph] Structured output result keys:', result ? Object.keys(result) : 'null');
796
797
  if (result?.raw) {
797
798
  const rawMsg = result.raw;
798
799
  console.log('[Graph] Raw message content type:', typeof rawMsg?.content);
@@ -800,17 +801,31 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
800
801
  if (rawMsg?.content && typeof rawMsg.content === 'string' && rawMsg.content.length > 0) {
801
802
  console.log('[Graph] Raw message text content (first 200):', rawMsg.content.substring(0, 200));
802
803
  }
804
+ // Log the parsed result if available
805
+ if (result?.parsed) {
806
+ console.log('[Graph] Parsed result keys:', Object.keys(result.parsed));
807
+ }
803
808
  }
804
809
 
805
810
  // Handle response - we always use includeRaw internally
806
811
  if (result?.raw && result?.parsed !== undefined) {
812
+ console.log('[Graph] Using parsed result from structured output');
807
813
  return {
808
814
  structuredResponse: result.parsed as Record<string, unknown>,
809
815
  rawMessage: result.raw as AIMessageChunk,
810
816
  };
811
817
  }
812
818
 
819
+ // Fallback: If result itself is the parsed object (no raw wrapper)
820
+ if (result && typeof result === 'object' && !result.raw && !result.parsed) {
821
+ console.log('[Graph] Result is the structured object directly');
822
+ return {
823
+ structuredResponse: result as Record<string, unknown>,
824
+ };
825
+ }
826
+
813
827
  // Fallback for models that don't support includeRaw
828
+ console.log('[Graph] Using fallback - treating result as structured response');
814
829
  return {
815
830
  structuredResponse: result as Record<string, unknown>,
816
831
  };
@@ -1191,6 +1206,9 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1191
1206
  clientOptions: structuredClientOptions,
1192
1207
  });
1193
1208
 
1209
+ // For no-tools case, we pass the original messages directly
1210
+ // There shouldn't be thinking blocks since this is the first invocation
1211
+
1194
1212
  const { structuredResponse, rawMessage } =
1195
1213
  await this.attemptStructuredInvoke(
1196
1214
  {
@@ -1515,17 +1533,46 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1515
1533
  clientOptions: structuredClientOptions,
1516
1534
  });
1517
1535
 
1518
- // Include the current result in the messages so the model knows what it just said
1519
- const messagesWithResult = [...finalMessages];
1536
+ // Following LangGraph's Option 2 pattern:
1537
+ // Instead of passing the full conversation (which has thinking blocks),
1538
+ // just pass the model's final response text as a HumanMessage asking for structured output.
1539
+ // This avoids issues with thinking blocks and is more token-efficient.
1540
+ let responseContent = '';
1520
1541
  if (resultMessage) {
1521
- messagesWithResult.push(resultMessage);
1542
+ if (typeof resultMessage.content === 'string') {
1543
+ responseContent = resultMessage.content;
1544
+ } else if (Array.isArray(resultMessage.content)) {
1545
+ // Extract text parts only (skip thinking blocks, tool_use, etc.)
1546
+ responseContent = resultMessage.content
1547
+ .filter((c): c is { type: string; text: string } =>
1548
+ typeof c === 'object' && c !== null &&
1549
+ (c as { type?: string }).type === 'text' &&
1550
+ typeof (c as { text?: string }).text === 'string'
1551
+ )
1552
+ .map(c => c.text)
1553
+ .join('\n');
1554
+ }
1555
+ }
1556
+
1557
+ if (!responseContent) {
1558
+ console.log('[Graph] No response content to structure, skipping');
1559
+ throw new Error('No response content available for structured output');
1522
1560
  }
1523
1561
 
1562
+ console.log('[Graph] Structuring response content (first 200 chars):', responseContent.substring(0, 200));
1563
+
1564
+ // Create a simple message asking to structure the response
1565
+ const structuredMessages: BaseMessage[] = [
1566
+ new HumanMessage({
1567
+ content: `Based on the following response, extract and return the data in the required structured format:\n\n${responseContent}`,
1568
+ }),
1569
+ ];
1570
+
1524
1571
  const { structuredResponse, rawMessage } =
1525
1572
  await this.attemptStructuredInvoke(
1526
1573
  {
1527
1574
  currentModel: structuredModel,
1528
- finalMessages: messagesWithResult,
1575
+ finalMessages: structuredMessages,
1529
1576
  schema,
1530
1577
  structuredOutputConfig: agentContext.structuredOutput!,
1531
1578
  provider: agentContext.provider,
@@ -934,3 +934,63 @@ export function ensureThinkingBlockInMessages(
934
934
 
935
935
  return result;
936
936
  }
937
+
938
+ /**
939
+ * Strips thinking blocks from messages for structured output invocation.
940
+ * When switching from thinking-enabled mode to structured output (which requires thinking disabled),
941
+ * we need to remove thinking/reasoning blocks from the conversation to avoid Bedrock errors.
942
+ *
943
+ * @param messages - Array of messages to process
944
+ * @returns The messages array with thinking blocks stripped from AI messages
945
+ */
946
+ export function stripThinkingBlocksFromMessages(
947
+ messages: BaseMessage[]
948
+ ): BaseMessage[] {
949
+ return messages.map((msg) => {
950
+ const isAI = msg instanceof AIMessage || msg instanceof AIMessageChunk;
951
+
952
+ if (!isAI) {
953
+ return msg;
954
+ }
955
+
956
+ const aiMsg = msg as AIMessage | AIMessageChunk;
957
+ const content = aiMsg.content;
958
+
959
+ // If content is not an array, nothing to strip
960
+ if (!Array.isArray(content)) {
961
+ return msg;
962
+ }
963
+
964
+ // Filter out thinking/reasoning blocks
965
+ const filteredContent = content.filter((c) => {
966
+ if (typeof c !== 'object' || c === null) {
967
+ return true;
968
+ }
969
+ const type = (c as ExtendedMessageContent).type;
970
+ return (
971
+ type !== ContentTypes.THINKING &&
972
+ type !== ContentTypes.REASONING_CONTENT &&
973
+ type !== ContentTypes.REASONING &&
974
+ type !== 'thinking' &&
975
+ type !== 'redacted_thinking'
976
+ );
977
+ });
978
+
979
+ // If no content left after filtering, add a placeholder
980
+ if (filteredContent.length === 0) {
981
+ filteredContent.push({
982
+ type: 'text',
983
+ text: '(previous response)',
984
+ });
985
+ }
986
+
987
+ // Create a new AI message with the filtered content
988
+ return new AIMessageChunk({
989
+ content: filteredContent,
990
+ id: aiMsg.id,
991
+ response_metadata: aiMsg.response_metadata,
992
+ usage_metadata: aiMsg.usage_metadata,
993
+ // Don't include tool_calls - we're stripping those for structured output context
994
+ });
995
+ });
996
+ }