@langchain/community
Version:
Third-party integrations for LangChain.js
1 lines • 23.1 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","names":["messages: BaseMessage[]","system","provider: string","prompt: string","stopSequences: string[] | undefined","modelKwargs: Record<string, unknown>","bedrockMethod: \"invoke\" | \"invoke-with-response-stream\"","guardrailConfig:\n | {\n tagSuffix: string;\n streamProcessingMode: \"SYNCHRONOUS\" | \"ASYNCHRONOUS\";\n }\n | undefined","inputBody: Dict","tools: (StructuredToolInterface | Record<string, unknown>)[]","formatMessagesForAnthropic","responseBody: any","response: any","fields?: {\n coerceContentToString?: boolean;\n }","_makeMessageChunkFromAnthropicEvent","extractToolCallChunk","extractToolUseContent","extractToken","ChatGenerationChunk","AIMessageChunk","asChunk?: boolean","extractToolCalls","AIMessage"],"sources":["../../../src/utils/bedrock/index.ts"],"sourcesContent":["import type { AwsCredentialIdentity, Provider } from \"@aws-sdk/types\";\nimport {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n} from \"@langchain/core/messages\";\nimport { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { ChatGeneration, ChatGenerationChunk } from \"@langchain/core/outputs\";\nimport {\n _makeMessageChunkFromAnthropicEvent,\n extractToken,\n extractToolCallChunk,\n extractToolUseContent,\n extractToolCalls,\n formatMessagesForAnthropic,\n} from \"./anthropic.js\";\n\nexport type CredentialType =\n | AwsCredentialIdentity\n | Provider<AwsCredentialIdentity>;\n\n/**\n * format messages for Cohere Command-R and CommandR+ via AWS Bedrock.\n *\n * @param messages messages The base messages to format as a prompt.\n *\n * @returns The formatted prompt for Cohere.\n *\n * `system`: user system prompts. Overrides the default preamble for search query generation. Has no effect on tool use generations.\\\n * `message`: (Required) Text input for the model to respond to.\\\n * `chatHistory`: A list of previous messages between the user and the model, meant to give the model conversational context for responding to the user's message.\\\n * The following are required fields.\n * - `role` - The role for the message. Valid values are USER or CHATBOT.\\\n * - `message` – Text contents of the message.\\\n *\n * The following is example JSON for the chat_history field.\\\n * \"chat_history\": [\n * {\"role\": \"USER\", \"message\": \"Who discovered gravity?\"},\n * {\"role\": \"CHATBOT\", \"message\": \"The man who is widely credited with discovering gravity is Sir Isaac Newton\"}]\\\n *\n * docs: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-cohere-command-r-plus.html\n */\nfunction formatMessagesForCohere(messages: BaseMessage[]): {\n system?: string;\n message: string;\n chatHistory: Record<string, unknown>[];\n} {\n const systemMessages = messages.filter(\n (system) => system._getType() === \"system\"\n );\n\n const system = systemMessages\n .filter((m) => typeof m.content === \"string\")\n .map((m) => m.content)\n .join(\"\\n\\n\");\n\n const conversationMessages = messages.filter(\n (message) => message._getType() !== \"system\"\n );\n\n const questionContent = conversationMessages.slice(-1);\n\n if (!questionContent.length || questionContent[0]._getType() !== \"human\") {\n throw new Error(\"question message content must be a human message.\");\n }\n\n if (typeof questionContent[0].content !== \"string\") {\n throw new Error(\"question message content must be a string.\");\n }\n\n const formattedMessage = questionContent[0].content;\n\n const formattedChatHistories = conversationMessages\n .slice(0, -1)\n .map((message) => {\n let role;\n switch (message._getType()) {\n case \"human\":\n role = \"USER\" as const;\n break;\n case \"ai\":\n role = \"CHATBOT\" as const;\n break;\n case \"system\":\n throw new Error(\"chat_history can not include system prompts.\");\n default:\n throw new Error(\n `Message type \"${message._getType()}\" is not supported.`\n );\n }\n\n if (typeof message.content !== \"string\") {\n throw new Error(\"message content must be a string.\");\n }\n return {\n role,\n message: message.content,\n };\n });\n\n return {\n chatHistory: formattedChatHistories,\n message: formattedMessage,\n system,\n };\n}\n\n/** Bedrock models.\n To authenticate, the AWS client uses the following methods to automatically load credentials:\n https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html\n If a specific credential profile should be used, you must pass the name of the profile from the ~/.aws/credentials file that is to be used.\n Make sure the credentials / roles used have the required policies to access the Bedrock service.\n*/\nexport interface BaseBedrockInput {\n /** Model to use.\n For example, \"amazon.titan-tg1-large\", this is equivalent to the modelId property in the list-foundation-models api.\n */\n model: string;\n\n /** Optional URL Encoded overide for URL model parameter in fetch. Necessary for invoking an Application Inference Profile.\n For example, \"arn%3Aaws%3Abedrock%3Aus-east-1%3A1234567890%3Aapplication-inference-profile%2Fabcdefghi\", will override this.model in final /invoke URL call.\n Must still provide `model` as normal modelId to benefit from all the metadata.\n */\n applicationInferenceProfile?: string;\n\n /** The AWS region e.g. `us-west-2`.\n Fallback to AWS_DEFAULT_REGION env variable or region specified in ~/.aws/config in case it is not provided here.\n */\n region?: string;\n\n /** AWS Credentials.\n If no credentials are provided, the default credentials from `@aws-sdk/credential-provider-node` will be used.\n */\n credentials?: CredentialType;\n\n /** Temperature. */\n temperature?: number;\n\n /** Max tokens. */\n maxTokens?: number;\n\n /** A custom fetch function for low-level access to AWS API. Defaults to fetch(). */\n fetchFn?: typeof fetch;\n\n /** Override the default endpoint hostname. */\n endpointHost?: string;\n\n /** Additional kwargs to pass to the model. */\n modelKwargs?: Record<string, unknown>;\n\n /** Whether or not to stream responses */\n streaming: boolean;\n\n /** Trace settings for the Bedrock Guardrails. */\n trace?: \"ENABLED\" | \"DISABLED\";\n\n /** Identifier for the guardrail configuration. */\n guardrailIdentifier?: string;\n\n /** Version for the guardrail configuration. */\n guardrailVersion?: string;\n\n /** Required when Guardrail is in use. */\n guardrailConfig?: {\n tagSuffix: string;\n streamProcessingMode: \"SYNCHRONOUS\" | \"ASYNCHRONOUS\";\n };\n\n awsAccessKeyId?: string;\n\n awsSecretAccessKey?: string;\n\n awsSessionToken?: string;\n}\n\ntype Dict = { [key: string]: unknown };\n\n/**\n * A helper class used within the `Bedrock` class. It is responsible for\n * preparing the input and output for the Bedrock service. It formats the\n * input prompt based on the provider (e.g., \"anthropic\", \"ai21\",\n * \"amazon\") and extracts the generated text from the service response.\n */\nexport class BedrockLLMInputOutputAdapter {\n /** Adapter class to prepare the inputs from Langchain to a format\n that LLM model expects. Also, provides a helper function to extract\n the generated text from the model response. */\n\n static prepareInput(\n provider: string,\n prompt: string,\n maxTokens = 50,\n temperature = 0,\n stopSequences: string[] | undefined = undefined,\n modelKwargs: Record<string, unknown> = {},\n bedrockMethod: \"invoke\" | \"invoke-with-response-stream\" = \"invoke\",\n guardrailConfig:\n | {\n tagSuffix: string;\n streamProcessingMode: \"SYNCHRONOUS\" | \"ASYNCHRONOUS\";\n }\n | undefined = undefined\n ): Dict {\n const inputBody: Dict = {};\n\n if (provider === \"anthropic\") {\n inputBody.prompt = prompt;\n inputBody.max_tokens_to_sample = maxTokens;\n inputBody.temperature = temperature;\n inputBody.stop_sequences = stopSequences;\n } else if (provider === \"ai21\") {\n inputBody.prompt = prompt;\n inputBody.maxTokens = maxTokens;\n inputBody.temperature = temperature;\n inputBody.stopSequences = stopSequences;\n } else if (provider === \"meta\") {\n inputBody.prompt = prompt;\n inputBody.max_gen_len = maxTokens;\n inputBody.temperature = temperature;\n } else if (provider === \"amazon\") {\n inputBody.inputText = prompt;\n inputBody.textGenerationConfig = {\n maxTokenCount: maxTokens,\n temperature,\n };\n } else if (provider === \"cohere\") {\n inputBody.prompt = prompt;\n inputBody.max_tokens = maxTokens;\n inputBody.temperature = temperature;\n inputBody.stop_sequences = stopSequences;\n if (bedrockMethod === \"invoke-with-response-stream\") {\n inputBody.stream = true;\n }\n } else if (provider === \"mistral\") {\n inputBody.prompt = prompt;\n inputBody.max_tokens = maxTokens;\n inputBody.temperature = temperature;\n inputBody.stop = stopSequences;\n }\n\n if (\n guardrailConfig &&\n guardrailConfig.tagSuffix &&\n guardrailConfig.streamProcessingMode\n ) {\n inputBody[\"amazon-bedrock-guardrailConfig\"] = guardrailConfig;\n }\n\n return { ...inputBody, ...modelKwargs };\n }\n\n static prepareMessagesInput(\n provider: string,\n messages: BaseMessage[],\n maxTokens = 1024,\n temperature = 0,\n stopSequences: string[] | undefined = undefined,\n modelKwargs: Record<string, unknown> = {},\n guardrailConfig:\n | {\n tagSuffix: string;\n streamProcessingMode: \"SYNCHRONOUS\" | \"ASYNCHRONOUS\";\n }\n | undefined = undefined,\n tools: (StructuredToolInterface | Record<string, unknown>)[] = []\n ): Dict {\n const inputBody: Dict = {};\n\n if (provider === \"anthropic\") {\n const { system, messages: formattedMessages } =\n formatMessagesForAnthropic(messages);\n if (system !== undefined) {\n inputBody.system = system;\n }\n inputBody.anthropic_version = \"bedrock-2023-05-31\";\n inputBody.messages = formattedMessages;\n inputBody.max_tokens = maxTokens;\n inputBody.temperature = temperature;\n inputBody.stop_sequences = stopSequences;\n\n if (tools.length > 0) {\n inputBody.tools = tools;\n }\n } else if (provider === \"cohere\") {\n const {\n system,\n message: formattedMessage,\n chatHistory: formattedChatHistories,\n } = formatMessagesForCohere(messages);\n\n if (system !== undefined && system.length > 0) {\n inputBody.preamble = system;\n }\n inputBody.message = formattedMessage;\n inputBody.chat_history = formattedChatHistories;\n inputBody.max_tokens = maxTokens;\n inputBody.temperature = temperature;\n inputBody.stop_sequences = stopSequences;\n } else {\n throw new Error(\n \"The messages API is currently only supported by Anthropic or Cohere\"\n );\n }\n\n if (\n guardrailConfig &&\n guardrailConfig.tagSuffix &&\n guardrailConfig.streamProcessingMode\n ) {\n inputBody[\"amazon-bedrock-guardrailConfig\"] = guardrailConfig;\n }\n\n return { ...inputBody, ...modelKwargs };\n }\n\n /**\n * Extracts the generated text from the service response.\n * @param provider The provider name.\n * @param responseBody The response body from the service.\n * @returns The generated text.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static prepareOutput(provider: string, responseBody: any): string {\n if (provider === \"anthropic\") {\n return responseBody.completion;\n } else if (provider === \"ai21\") {\n return responseBody?.completions?.[0]?.data?.text ?? \"\";\n } else if (provider === \"cohere\") {\n return responseBody?.generations?.[0]?.text ?? responseBody?.text ?? \"\";\n } else if (provider === \"meta\") {\n return responseBody.generation;\n } else if (provider === \"mistral\") {\n return responseBody?.outputs?.[0]?.text;\n }\n\n // I haven't been able to get a response with more than one result in it.\n return responseBody.results?.[0]?.outputText;\n }\n\n static prepareMessagesOutput(\n provider: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n response: any,\n fields?: {\n coerceContentToString?: boolean;\n }\n ): ChatGeneration | undefined {\n const responseBody = response ?? {};\n if (provider === \"anthropic\") {\n if (responseBody.type === \"message\") {\n return parseMessage(responseBody);\n } else if (responseBody.type === \"message_start\") {\n return parseMessage(responseBody.message, true);\n }\n const chunk = _makeMessageChunkFromAnthropicEvent(response, {\n coerceContentToString: fields?.coerceContentToString,\n });\n if (!chunk) return undefined;\n\n const newToolCallChunk = extractToolCallChunk(chunk);\n let toolUseContent;\n const extractedContent = extractToolUseContent(chunk, undefined);\n if (extractedContent) {\n toolUseContent = extractedContent.toolUseContent;\n }\n // Filter partial `tool_use` content, and only add `tool_use` chunks if complete JSON available.\n const chunkContent = Array.isArray(chunk.content)\n ? chunk.content.filter((c) => c.type !== \"tool_use\")\n : chunk.content;\n if (Array.isArray(chunkContent) && toolUseContent) {\n chunkContent.push(toolUseContent);\n }\n // Extract the text content token for text field and runManager.\n const token = extractToken(chunk);\n return new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: chunkContent,\n additional_kwargs: chunk.additional_kwargs,\n tool_call_chunks: newToolCallChunk ? [newToolCallChunk] : undefined,\n usage_metadata: chunk.usage_metadata,\n response_metadata: chunk.response_metadata,\n }),\n // Backwards compatibility\n generationInfo: { ...chunk.response_metadata },\n text: token ?? \"\",\n });\n } else if (provider === \"cohere\") {\n if (responseBody.event_type === \"stream-start\") {\n return parseMessageCohere(responseBody.message, true);\n } else if (\n responseBody.event_type === \"text-generation\" &&\n typeof responseBody?.text === \"string\"\n ) {\n return new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: responseBody.text,\n }),\n text: responseBody.text,\n });\n } else if (responseBody.event_type === \"search-queries-generation\") {\n return parseMessageCohere(responseBody);\n } else if (\n responseBody.event_type === \"stream-end\" &&\n responseBody.response !== undefined &&\n responseBody[\"amazon-bedrock-invocationMetrics\"] !== undefined\n ) {\n return new ChatGenerationChunk({\n message: new AIMessageChunk({ content: \"\" }),\n text: \"\",\n generationInfo: {\n response: responseBody.response,\n \"amazon-bedrock-invocationMetrics\":\n responseBody[\"amazon-bedrock-invocationMetrics\"],\n },\n });\n } else {\n if (\n responseBody.finish_reason === \"COMPLETE\" ||\n responseBody.finish_reason === \"MAX_TOKENS\"\n ) {\n return parseMessageCohere(responseBody);\n } else {\n return undefined;\n }\n }\n } else {\n throw new Error(\n \"The messages API is currently only supported by Anthropic or Cohere.\"\n );\n }\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction parseMessage(responseBody: any, asChunk?: boolean): ChatGeneration {\n const { content, id, ...generationInfo } = responseBody;\n let parsedContent;\n if (\n Array.isArray(content) &&\n content.length === 1 &&\n content[0].type === \"text\"\n ) {\n parsedContent = content[0].text;\n } else if (Array.isArray(content) && content.length === 0) {\n parsedContent = \"\";\n } else {\n parsedContent = content;\n }\n if (asChunk) {\n return new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: parsedContent,\n additional_kwargs: { id },\n }),\n text: typeof parsedContent === \"string\" ? parsedContent : \"\",\n generationInfo,\n });\n } else {\n const toolCalls = extractToolCalls(responseBody.content);\n\n if (toolCalls.length > 0) {\n return {\n message: new AIMessage({\n content: responseBody.content,\n additional_kwargs: { id },\n tool_calls: toolCalls,\n }),\n text: typeof parsedContent === \"string\" ? parsedContent : \"\",\n generationInfo,\n };\n }\n\n return {\n message: new AIMessage({\n content: parsedContent,\n additional_kwargs: { id },\n tool_calls: toolCalls,\n }),\n text: typeof parsedContent === \"string\" ? parsedContent : \"\",\n generationInfo,\n };\n }\n}\n\nfunction parseMessageCohere(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n responseBody: any,\n asChunk?: boolean\n): ChatGeneration {\n const { text, ...generationInfo } = responseBody;\n let parsedContent = text;\n if (typeof text !== \"string\") {\n parsedContent = \"\";\n }\n if (asChunk) {\n return new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: parsedContent,\n }),\n text: parsedContent,\n generationInfo,\n });\n } else {\n return {\n message: new AIMessage({\n content: parsedContent,\n }),\n text: parsedContent,\n generationInfo,\n };\n }\n}\n"],"mappings":"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"}