UNPKG

@langchain/community

Version:
1 lines 22.6 kB
{"version":3,"file":"index.cjs","names":["formatMessagesForAnthropic","_makeMessageChunkFromAnthropicEvent","extractToolCallChunk","extractToolUseContent","extractToken","ChatGenerationChunk","AIMessageChunk","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 // oxlint-disable-next-line typescript/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 // oxlint-disable-next-line typescript/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// oxlint-disable-next-line typescript/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 // oxlint-disable-next-line typescript/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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"}