{"version":3,"file":"message_outputs.cjs","sources":["../../../../../src/llm/bedrock/utils/message_outputs.ts"],"sourcesContent":["/**\n * Utility functions for converting Bedrock Converse responses to LangChain messages.\n * Ported from @langchain/aws common.js\n */\nimport { ChatGenerationChunk } from '@langchain/core/outputs';\nimport { AIMessage, AIMessageChunk } from '@langchain/core/messages';\nimport type { UsageMetadata } from '@langchain/core/messages';\nimport type {\n  BedrockMessage,\n  ConverseResponse,\n  ContentBlockDeltaEvent,\n  ConverseStreamMetadataEvent,\n  ContentBlockStartEvent,\n  ReasoningContentBlock,\n  ReasoningContentBlockDelta,\n  MessageContentReasoningBlock,\n  MessageContentReasoningBlockReasoningTextPartial,\n  MessageContentReasoningBlockRedacted,\n} from '../types';\n\n/**\n * Convert a Bedrock reasoning block delta to a LangChain partial reasoning block.\n */\nexport function bedrockReasoningDeltaToLangchainPartialReasoningBlock(\n  reasoningContent: ReasoningContentBlockDelta\n):\n  | MessageContentReasoningBlockReasoningTextPartial\n  | MessageContentReasoningBlockRedacted {\n  const { text, redactedContent, signature } =\n    reasoningContent as ReasoningContentBlockDelta & {\n      text?: string;\n      redactedContent?: Uint8Array;\n      signature?: string;\n    };\n\n  if (typeof text === 'string') {\n    return {\n      type: 'reasoning_content',\n      reasoningText: { text },\n    };\n  }\n  if (signature != null) {\n    return {\n      type: 'reasoning_content',\n      reasoningText: { signature },\n    };\n  }\n  if (redactedContent != null) {\n    return {\n      type: 'reasoning_content',\n      redactedContent: Buffer.from(redactedContent).toString('base64'),\n    };\n  }\n  throw new Error('Invalid reasoning content');\n}\n\n/**\n * Convert a Bedrock reasoning block to a LangChain reasoning block.\n */\nexport function bedrockReasoningBlockToLangchainReasoningBlock(\n  reasoningContent: ReasoningContentBlock\n): MessageContentReasoningBlock {\n  const { reasoningText, redactedContent } =\n    reasoningContent as ReasoningContentBlock & {\n      reasoningText?: { text?: string; signature?: string };\n      redactedContent?: Uint8Array;\n    };\n\n  if (reasoningText != null) {\n    return {\n      type: 'reasoning_content',\n      reasoningText: reasoningText,\n    };\n  }\n  if (redactedContent != null) {\n    return {\n      type: 'reasoning_content',\n      redactedContent: Buffer.from(redactedContent).toString('base64'),\n    };\n  }\n  throw new Error('Invalid reasoning content');\n}\n\n/**\n * Convert a Bedrock Converse message to a LangChain message.\n */\nexport function convertConverseMessageToLangChainMessage(\n  message: BedrockMessage,\n  responseMetadata: Omit<ConverseResponse, 'output'>\n): AIMessage {\n  if (message.content == null) {\n    throw new Error('No message content found in response.');\n  }\n  if (message.role !== 'assistant') {\n    throw new Error(\n      `Unsupported message role received in ChatBedrockConverse response: ${message.role}`\n    );\n  }\n\n  let requestId: string | undefined;\n  if (\n    '$metadata' in responseMetadata &&\n    responseMetadata.$metadata != null &&\n    typeof responseMetadata.$metadata === 'object' &&\n    'requestId' in responseMetadata.$metadata\n  ) {\n    requestId = responseMetadata.$metadata.requestId as string;\n  }\n\n  let tokenUsage:\n    | {\n        input_tokens: number;\n        output_tokens: number;\n        total_tokens: number;\n        input_token_details?: {\n          cache_read: number;\n          cache_creation: number;\n        };\n      }\n    | undefined;\n  if (responseMetadata.usage != null) {\n    const usage = responseMetadata.usage as NonNullable<\n      typeof responseMetadata.usage\n    > & {\n      cacheReadInputTokens?: number;\n      cacheWriteInputTokens?: number;\n    };\n    const input_tokens = usage.inputTokens ?? 0;\n    const output_tokens = usage.outputTokens ?? 0;\n    const cacheRead = usage.cacheReadInputTokens;\n    const cacheWrite = usage.cacheWriteInputTokens;\n    tokenUsage = {\n      input_tokens,\n      output_tokens,\n      total_tokens: usage.totalTokens ?? input_tokens + output_tokens,\n    };\n    if (cacheRead != null || cacheWrite != null) {\n      tokenUsage.input_token_details = {\n        cache_read: cacheRead ?? 0,\n        cache_creation: cacheWrite ?? 0,\n      };\n    }\n  }\n\n  if (\n    message.content.length === 1 &&\n    'text' in message.content[0] &&\n    typeof message.content[0].text === 'string'\n  ) {\n    return new AIMessage({\n      content: message.content[0].text,\n      response_metadata: responseMetadata,\n      usage_metadata: tokenUsage,\n      id: requestId,\n    });\n  } else {\n    const toolCalls: Array<{\n      id?: string;\n      name: string;\n      args: Record<string, unknown>;\n      type: 'tool_call';\n    }> = [];\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    const content: any[] = [];\n\n    message.content.forEach((c) => {\n      if (\n        'toolUse' in c &&\n        c.toolUse != null &&\n        c.toolUse.name != null &&\n        c.toolUse.name !== '' &&\n        c.toolUse.input != null &&\n        typeof c.toolUse.input === 'object'\n      ) {\n        toolCalls.push({\n          id: c.toolUse.toolUseId,\n          name: c.toolUse.name,\n          args: c.toolUse.input as Record<string, unknown>,\n          type: 'tool_call',\n        });\n      } else if ('text' in c && typeof c.text === 'string') {\n        content.push({ type: 'text', text: c.text });\n      } else if ('reasoningContent' in c && c.reasoningContent != null) {\n        content.push(\n          bedrockReasoningBlockToLangchainReasoningBlock(c.reasoningContent)\n        );\n      } else {\n        content.push(c);\n      }\n    });\n\n    return new AIMessage({\n      content: content.length ? content : '',\n      tool_calls: toolCalls.length ? toolCalls : undefined,\n      response_metadata: responseMetadata,\n      usage_metadata: tokenUsage,\n      id: requestId,\n    });\n  }\n}\n\n/**\n * Handle a content block delta event from Bedrock Converse stream.\n */\nexport function handleConverseStreamContentBlockDelta(\n  contentBlockDelta: ContentBlockDeltaEvent\n): ChatGenerationChunk {\n  if (contentBlockDelta.delta == null) {\n    throw new Error('No delta found in content block.');\n  }\n\n  if (typeof contentBlockDelta.delta.text === 'string') {\n    return new ChatGenerationChunk({\n      text: contentBlockDelta.delta.text,\n      message: new AIMessageChunk({\n        content: contentBlockDelta.delta.text,\n        response_metadata: {\n          contentBlockIndex: contentBlockDelta.contentBlockIndex,\n        },\n      }),\n    });\n  } else if (contentBlockDelta.delta.toolUse != null) {\n    const index = contentBlockDelta.contentBlockIndex;\n    return new ChatGenerationChunk({\n      text: '',\n      message: new AIMessageChunk({\n        content: '',\n        tool_call_chunks: [\n          {\n            args: contentBlockDelta.delta.toolUse.input as string,\n            index,\n            type: 'tool_call_chunk',\n          },\n        ],\n        response_metadata: {\n          contentBlockIndex: contentBlockDelta.contentBlockIndex,\n        },\n      }),\n    });\n  } else if (contentBlockDelta.delta.reasoningContent != null) {\n    const reasoningBlock =\n      bedrockReasoningDeltaToLangchainPartialReasoningBlock(\n        contentBlockDelta.delta.reasoningContent\n      );\n    let reasoningText = '';\n    if ('reasoningText' in reasoningBlock) {\n      reasoningText = reasoningBlock.reasoningText.text ?? '';\n    } else if ('redactedContent' in reasoningBlock) {\n      reasoningText = reasoningBlock.redactedContent;\n    }\n    return new ChatGenerationChunk({\n      text: '',\n      message: new AIMessageChunk({\n        content: [reasoningBlock],\n        additional_kwargs: {\n          // Set reasoning_content for stream handler to detect reasoning mode\n          reasoning_content: reasoningText,\n        },\n        response_metadata: {\n          contentBlockIndex: contentBlockDelta.contentBlockIndex,\n        },\n      }),\n    });\n  } else {\n    // Silent healing: unknown content block types are logged and skipped\n    // instead of crashing the stream. This can happen with new Bedrock features.\n    console.warn(\n      `[Bedrock:SilentHeal] Unknown content block delta type — skipping: ${JSON.stringify(contentBlockDelta.delta, null, 2)}`\n    );\n    return new ChatGenerationChunk({\n      text: '',\n      message: new AIMessageChunk({\n        content: '',\n        response_metadata: {\n          contentBlockIndex: contentBlockDelta.contentBlockIndex,\n        },\n      }),\n    });\n  }\n}\n\n/**\n * Handle a content block start event from Bedrock Converse stream.\n */\nexport function handleConverseStreamContentBlockStart(\n  contentBlockStart: ContentBlockStartEvent\n): ChatGenerationChunk | null {\n  const index = contentBlockStart.contentBlockIndex;\n\n  if (contentBlockStart.start?.toolUse != null) {\n    return new ChatGenerationChunk({\n      text: '',\n      message: new AIMessageChunk({\n        content: '',\n        tool_call_chunks: [\n          {\n            name: contentBlockStart.start.toolUse.name,\n            id: contentBlockStart.start.toolUse.toolUseId,\n            index,\n            type: 'tool_call_chunk',\n          },\n        ],\n        response_metadata: {\n          contentBlockIndex: index,\n        },\n      }),\n    });\n  }\n\n  // Return null for non-tool content block starts (text blocks don't need special handling)\n  return null;\n}\n\n/**\n * Handle a metadata event from Bedrock Converse stream.\n */\nexport function handleConverseStreamMetadata(\n  metadata: ConverseStreamMetadataEvent,\n  extra: { streamUsage: boolean }\n): ChatGenerationChunk {\n  const usage = metadata.usage as\n    | (NonNullable<ConverseStreamMetadataEvent['usage']> & {\n        cacheReadInputTokens?: number;\n        cacheWriteInputTokens?: number;\n      })\n    | undefined;\n  const inputTokens = usage?.inputTokens ?? 0;\n  const outputTokens = usage?.outputTokens ?? 0;\n  const cacheRead = usage?.cacheReadInputTokens;\n  const cacheWrite = usage?.cacheWriteInputTokens;\n\n  const usage_metadata: Record<string, unknown> = {\n    input_tokens: inputTokens,\n    output_tokens: outputTokens,\n    total_tokens: usage?.totalTokens ?? inputTokens + outputTokens,\n  };\n\n  if (cacheRead != null || cacheWrite != null) {\n    usage_metadata.input_token_details = {\n      cache_read: cacheRead ?? 0,\n      cache_creation: cacheWrite ?? 0,\n    };\n  }\n\n  return new ChatGenerationChunk({\n    text: '',\n    message: new AIMessageChunk({\n      content: '',\n      usage_metadata: extra.streamUsage\n        ? (usage_metadata as UsageMetadata)\n        : undefined,\n      response_metadata: {\n        // Use the same key as returned from the Converse API\n        metadata,\n      },\n    }),\n  });\n}\n"],"names":["ChatGenerationChunk","AIMessageChunk"],"mappings":"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"}