From 00e05cfb4a2921940b02a67b8a2fcd669d4ea2da Mon Sep 17 00:00:00 2001 From: Anthony Bernabeu <64135631+brnaba-aws@users.noreply.github.com> Date: Tue, 26 Nov 2024 21:18:23 +0100 Subject: [PATCH 01/18] added inline_bedrock_agent --- .../inline_agent_bedrock.py | 300 ++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 examples/inline-agents-bedrock/inline_agent_bedrock.py diff --git a/examples/inline-agents-bedrock/inline_agent_bedrock.py b/examples/inline-agents-bedrock/inline_agent_bedrock.py new file mode 100644 index 00000000..1d9c790a --- /dev/null +++ b/examples/inline-agents-bedrock/inline_agent_bedrock.py @@ -0,0 +1,300 @@ +from typing import List, Dict, Any, Optional, Callable +from dataclasses import dataclass, field +import boto3 +import os +from multi_agent_orchestrator.utils import conversation_to_dict, Logger +from multi_agent_orchestrator.agents import Agent, AgentOptions +from multi_agent_orchestrator.types import (ConversationMessage, + ParticipantRole, + BEDROCK_MODEL_ID_CLAUDE_3_HAIKU, + BEDROCK_MODEL_ID_CLAUDE_3_SONNET, + TemplateVariables) +import re + +# BedrockInlineAgentOptions Dataclass +@dataclass +class BedrockInlineAgentOptions(AgentOptions): + inference_config: Optional[Dict[str, Any]] = None + client: Optional[Any] = None + bedrock_agent_client: Optional[Any] = None + model_id: Optional[str] = None + foundation_model: Optional[str] = None + region: Optional[str] = None + action_groups_list: List[Dict[str, Any]] = field(default_factory=list) + knowledge_bases: Optional[List[Dict[str, Any]]] = None + custom_system_prompt: Optional[Dict[str, Any]] = None + + +# BedrockInlineAgent Class +class BedrockInlineAgent(Agent): + + TOOL_INPUT_SCHEMA = { + "json": { + "type": "object", + "properties": { + "action_group_names": { + "type": "array", + "items": {"type": "string"}, + "description": "A string array of action group names needed to solve the customer request" + }, + "knowledge_bases": { + "type": "array", + "items": {"type": "string"}, + "description": "A string array of knowledge base names needed to solve the customer request" + }, + "description": { + "type": "string", + "description": "Description to instruct the agent how to solve the user request using available action groups" + }, + "user_request": { + "type": "string", + "description": "The initial user request" + } + }, + "required": ["action_group_names", "description", "user_request"], + } + } + + KEYS_TO_REMOVE = ['actionGroupId', 'actionGroupState', 'agentId', 'agentVersion'] + + def __init__(self, options: BedrockInlineAgentOptions): + super().__init__(options) + + # Initialize Bedrock client + if options.client: + self.client = options.client + else: + if options.region: + self.client = boto3.client( + 'bedrock-runtime', + region_name=options.region or os.environ.get('AWS_REGION') + ) + else: + self.client = boto3.client('bedrock-runtime') + + # Initialize bedrock agent client + if options.bedrock_agent_client: + self.bedrock_agent_client = options.bedrock_agent_client + else: + if options.region: + self.bedrock_agent_client = boto3.client( + 'bedrock-agent-runtime', + region_name=options.region or os.environ.get('AWS_REGION') + ) + else: + self.bedrock_agent_client = boto3.client('bedrock-agent-runtime') + + # Set model ID + self.model_id = options.model_id or BEDROCK_MODEL_ID_CLAUDE_3_HAIKU + + self.foundation_model = options.foundation_model or BEDROCK_MODEL_ID_CLAUDE_3_SONNET + + # Set inference configuration + default_inference_config = { + 'maxTokens': 1000, + 'temperature': 0.0, + 'topP': 0.9, + 'stopSequences': [] + } + self.inference_config = {**default_inference_config, **(options.inference_config or {})} + + # Store action groups and knowledge bases + self.action_groups_list = options.action_groups_list + self.knowledge_bases = options.knowledge_bases or [] + + # Define inline agent tool configuration + self.inline_agent_tool = [{ + "toolSpec": { + "name": "inline_agent_creation", + "description": "Create an inline agent with a list of action groups and knowledge bases", + "inputSchema": self.TOOL_INPUT_SCHEMA, + } + }] + + # Define the tool handler + self.use_tool_handler = self.inline_agent_tool_handler + + # Configure tool usage + self.tool_config = { + 'tool': self.inline_agent_tool, + 'toolMaxRecursions': 1, + 'useToolHandler': self.use_tool_handler + } + + self.prompt_template: str = f"""You are a {self.name}. + {self.description} + You will engage in an open-ended conversation, + providing helpful and accurate information based on your expertise. + The conversation will proceed as follows: + - The human may ask an initial question or provide a prompt on any topic. + - You will provide a relevant and informative response. + - The human may then follow up with additional questions or prompts related to your previous + response, allowing for a multi-turn dialogue on that topic. + - Or, the human may switch to a completely new and unrelated topic at any point. + - You will seamlessly shift your focus to the new topic, providing thoughtful and + coherent responses based on your broad knowledge base. + Throughout the conversation, you should aim to: + - Understand the context and intent behind each new question or prompt. + - Provide substantive and well-reasoned responses that directly address the query. + - Draw insights and connections from your extensive knowledge when appropriate. + - Ask for clarification if any part of the question or prompt is ambiguous. + - Maintain a consistent, respectful, and engaging tone tailored + to the human's communication style. + - Seamlessly transition between topics as the human introduces new subjects.""" + + self.system_prompt: str = "" + self.custom_variables: TemplateVariables = {} + self.default_max_recursions: int = 20 + + if options.custom_system_prompt: + self.set_system_prompt( + options.custom_system_prompt.get('template'), + options.custom_system_prompt.get('variables') + ) + + + async def inline_agent_tool_handler(self, session_id, response, conversation): + """Handler for processing tool use.""" + response_content_blocks = response.content + + if not response_content_blocks: + raise ValueError("No content blocks in response") + + for content_block in response_content_blocks: + if "toolUse" in content_block: + tool_use_block = content_block["toolUse"] + tool_use_name = tool_use_block.get("name") + if tool_use_name == "inline_agent_creation": + action_group_names = tool_use_block["input"].get('action_group_names', []) + kb_names = tool_use_block["input"].get('knowledge_bases','') + + description = tool_use_block["input"].get('description', '') + user_request = tool_use_block["input"].get('user_request', '') + + # Fetch relevant action groups + action_groups = [ + item for item in self.action_groups_list + if item.get('actionGroupName') in action_group_names + ] + for entry in action_groups: + for key in self.KEYS_TO_REMOVE: + entry.pop(key, None) + if 'parentActionGroupSignature' in entry: + entry.pop('description', None) + + kbs = [] + if kb_names and self.knowledge_bases: + kbs = [item for item in self.knowledge_bases + if item.get('knowledgeBaseId') == kb_names[0]] + + import uuid + inline_response = self.bedrock_agent_client.invoke_inline_agent( + actionGroups=action_groups, + knowledgeBases=kbs, + enableTrace=True, + endSession=False, + foundationModel=self.foundation_model, + inputText=user_request, + instruction=description, + sessionId=session_id + ) + + eventstream = inline_response.get('completion') + tool_results = [] + for event in eventstream: + print(event) + if 'chunk' in event: + chunk = event['chunk'] + if 'bytes' in chunk: + tool_results.append(chunk['bytes'].decode('utf-8')) + + # Return the tool results as a new message + return ConversationMessage( + role=ParticipantRole.ASSISTANT.value, + content=[{'text': ''.join(tool_results)}] + ) + + raise ValueError("Tool use block not handled") + + async def process_request( + self, + input_text: str, + user_id: str, + session_id: str, + chat_history: List[ConversationMessage], + additional_params: Optional[Dict[str, str]] = None + ) -> ConversationMessage: + try: + # Create the user message + user_message = ConversationMessage( + role=ParticipantRole.USER.value, + content=[{'text': input_text}] + ) + + # Combine chat history with current message + conversation = [*chat_history, user_message] + + self.update_system_prompt() + + system_prompt = self.system_prompt + + converse_cmd = { + 'modelId': self.model_id, + 'messages': conversation_to_dict(conversation), + 'system': [{'text': system_prompt}], + 'inferenceConfig': { + 'maxTokens': self.inference_config.get('maxTokens'), + 'temperature': self.inference_config.get('temperature'), + 'topP': self.inference_config.get('topP'), + 'stopSequences': self.inference_config.get('stopSequences'), + }, + 'toolConfig': { + 'tools': self.inline_agent_tool, + } + } + # Call Bedrock's converse API + response = self.client.converse(**converse_cmd) + + if 'output' not in response: + raise ValueError("No output received from Bedrock model") + + bedrock_response = ConversationMessage( + role=response['output']['message']['role'], + content=response['output']['message']['content'] + ) + + # Check if tool use is required + for content in bedrock_response.content: + if isinstance(content, dict) and 'toolUse' in content: + return await self.use_tool_handler(session_id, bedrock_response, conversation) + + # Return Bedrock's initial response if no tool is used + return bedrock_response + + except Exception as error: + Logger.error(f"Error processing request with Bedrock: {str(error)}") + raise error + + def set_system_prompt(self, + template: Optional[str] = None, + variables: Optional[TemplateVariables] = None) -> None: + if template: + self.prompt_template = template + if variables: + self.custom_variables = variables + self.update_system_prompt() + + def update_system_prompt(self) -> None: + all_variables: TemplateVariables = {**self.custom_variables} + self.system_prompt = self.replace_placeholders(self.prompt_template, all_variables) + + @staticmethod + def replace_placeholders(template: str, variables: TemplateVariables) -> str: + def replace(match): + key = match.group(1) + if key in variables: + value = variables[key] + return '\n'.join(value) if isinstance(value, list) else str(value) + return match.group(0) + + return re.sub(r'{{(\w+)}}', replace, template) From 00d3aaa5bfb56d33e8409f2751afea41d4c2f656 Mon Sep 17 00:00:00 2001 From: Corneliu Croitoru Date: Tue, 26 Nov 2024 21:27:59 +0100 Subject: [PATCH 02/18] add ts inlinebedrockagent --- typescript/src/agents/bedrockInlineAgent.ts | 331 ++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 typescript/src/agents/bedrockInlineAgent.ts diff --git a/typescript/src/agents/bedrockInlineAgent.ts b/typescript/src/agents/bedrockInlineAgent.ts new file mode 100644 index 00000000..498a9b3f --- /dev/null +++ b/typescript/src/agents/bedrockInlineAgent.ts @@ -0,0 +1,331 @@ +import { + BedrockRuntimeClient, + BedrockAgentRuntimeClient, + ConverseCommand, + } from "@aws-sdk/client-bedrock-runtime"; + import { Agent, AgentOptions } from "./agent"; + import { + BEDROCK_MODEL_ID_CLAUDE_3_HAIKU, + BEDROCK_MODEL_ID_CLAUDE_3_SONNET, + ConversationMessage, + ParticipantRole, + TemplateVariables, + } from "../types"; + import { Logger } from "../utils/logger"; + + export interface BedrockInlineAgentOptions extends AgentOptions { + inferenceConfig?: { + maxTokens?: number; + temperature?: number; + topP?: number; + stopSequences?: string[]; + }; + client?: BedrockRuntimeClient; + bedrockAgentClient?: BedrockAgentRuntimeClient; + modelId?: string; + foundationModel?: string; + region?: string; + actionGroupsList: Record[]; + knowledgeBases?: Record[]; + customSystemPrompt?: { + template?: string; + variables?: TemplateVariables; + }; + } + + export class BedrockInlineAgent extends Agent { + /** Class-level constants */ + protected static readonly TOOL_INPUT_SCHEMA = { + json: { + type: "object", + properties: { + action_group_names: { + type: "array", + items: { type: "string" }, + description: "A string array of action group names needed to solve the customer request" + }, + knowledge_bases: { + type: "array", + items: { type: "string" }, + description: "A string array of knowledge base names needed to solve the customer request" + }, + description: { + type: "string", + description: "Description to instruct the agent how to solve the user request using available action groups" + }, + user_request: { + type: "string", + description: "The initial user request" + } + }, + required: ["action_group_names", "description", "user_request"] + } + }; + + protected static readonly KEYS_TO_REMOVE = [ + 'actionGroupId', + 'actionGroupState', + 'agentId', + 'agentVersion' + ]; + + /** Protected class members */ + protected client: BedrockRuntimeClient; + protected bedrockAgentClient: BedrockAgentRuntimeClient; + protected modelId: string; + protected foundationModel: string; + protected inferenceConfig: { + maxTokens?: number; + temperature?: number; + topP?: number; + stopSequences?: string[]; + }; + protected actionGroupsList: Record[]; + protected knowledgeBases: Record[]; + protected inlineAgentTool: any[]; + protected toolConfig: { + tool: any[]; + useToolHandler: (response: ConversationMessage, conversation: ConversationMessage[]) => Promise; + toolMaxRecursions: number; + }; + + private promptTemplate: string; + private systemPrompt: string = ''; + private customVariables: TemplateVariables = {}; + + constructor(options: BedrockInlineAgentOptions) { + super(options); + + // Initialize clients + this.client = options.client ?? ( + options.region + ? new BedrockRuntimeClient({ region: options.region }) + : new BedrockRuntimeClient() + ); + + this.bedrockAgentClient = options.bedrockAgentClient ?? ( + options.region + ? new BedrockAgentRuntimeClient({ region: options.region }) + : new BedrockAgentRuntimeClient() + ); + + // Set model IDs + this.modelId = options.modelId ?? BEDROCK_MODEL_ID_CLAUDE_3_HAIKU; + this.foundationModel = options.foundationModel ?? BEDROCK_MODEL_ID_CLAUDE_3_SONNET; + + // Set inference configuration + this.inferenceConfig = options.inferenceConfig ?? { + maxTokens: 1000, + temperature: 0.0, + topP: 0.9, + stopSequences: [] + }; + + // Store action groups and knowledge bases + this.actionGroupsList = options.actionGroupsList; + this.knowledgeBases = options.knowledgeBases ?? []; + + // Define inline agent tool configuration + this.inlineAgentTool = [{ + toolSpec: { + name: "inline_agent_creation", + description: "Create an inline agent with a list of action groups and knowledge bases", + inputSchema: BedrockInlineAgent.TOOL_INPUT_SCHEMA + } + }]; + + // Configure tool usage + this.toolConfig = { + tool: this.inlineAgentTool, + useToolHandler: this.inlineAgentToolHandler.bind(this), + toolMaxRecursions: 1 + }; + + // Set prompt template + this.promptTemplate = `You are a ${this.name}. + ${this.description} + You will engage in an open-ended conversation, + providing helpful and accurate information based on your expertise. + The conversation will proceed as follows: + - The human may ask an initial question or provide a prompt on any topic. + - You will provide a relevant and informative response. + - The human may then follow up with additional questions or prompts related to your previous + response, allowing for a multi-turn dialogue on that topic. + - Or, the human may switch to a completely new and unrelated topic at any point. + - You will seamlessly shift your focus to the new topic, providing thoughtful and + coherent responses based on your broad knowledge base. + Throughout the conversation, you should aim to: + - Understand the context and intent behind each new question or prompt. + - Provide substantive and well-reasoned responses that directly address the query. + - Draw insights and connections from your extensive knowledge when appropriate. + - Ask for clarification if any part of the question or prompt is ambiguous. + - Maintain a consistent, respectful, and engaging tone tailored + to the human's communication style. + - Seamlessly transition between topics as the human introduces new subjects.`; + + if (options.customSystemPrompt) { + this.setSystemPrompt( + options.customSystemPrompt.template, + options.customSystemPrompt.variables + ); + } + } + + private async inlineAgentToolHandler( + response: ConversationMessage, + conversation: ConversationMessage[] + ): Promise { + const responseContentBlocks = response.content; + + if (!responseContentBlocks) { + throw new Error("No content blocks in response"); + } + + for (const contentBlock of responseContentBlocks) { + if ("toolUse" in contentBlock) { + const toolUseBlock = contentBlock.toolUse; + const toolUseName = toolUseBlock?.name; + + if (toolUseName === "inline_agent_creation") { + const actionGroupNames = toolUseBlock.input?.action_group_names || []; + const kbNames = toolUseBlock.input?.knowledge_bases || ''; + const description = toolUseBlock.input?.description || ''; + const userRequest = toolUseBlock.input?.user_request || ''; + + // Fetch relevant action groups + const actionGroups = this.actionGroupsList + .filter(item => actionGroupNames.includes(item.actionGroupName)) + .map(item => { + const newItem = { ...item }; + BedrockInlineAgent.KEYS_TO_REMOVE.forEach(key => delete newItem[key]); + if ('parentActionGroupSignature' in newItem) { + delete newItem.description; + } + return newItem; + }); + + // Handle knowledge bases + const kbs = kbNames && this.knowledgeBases.length + ? this.knowledgeBases.filter(item => item.knowledgeBaseId === kbNames[0]) + : []; + + const inlineResponse = await this.bedrockAgentClient.invokeInlineAgent({ + actionGroups, + knowledgeBases: kbs, + enableTrace: true, + endSession: false, + foundationModel: this.foundationModel, + inputText: userRequest, + instruction: description, + sessionId: 'session-3' + }); + + const eventstream = inlineResponse.completion; + const toolResults: string[] = []; + + for (const event of eventstream || []) { + if ('chunk' in event && event.chunk?.bytes) { + toolResults.push(new TextDecoder().decode(event.chunk.bytes)); + } + } + + return { + role: ParticipantRole.ASSISTANT, + content: [{ text: toolResults.join('') }] + }; + } + } + } + + throw new Error("Tool use block not handled"); + } + + async processRequest( + inputText: string, + userId: string, + sessionId: string, + chatHistory: ConversationMessage[], + additionalParams?: Record + ): Promise { + try { + // Construct the user's message + const userMessage: ConversationMessage = { + role: ParticipantRole.USER, + content: [{ text: inputText }] + }; + + // Combine chat history with current message + const conversation: ConversationMessage[] = [...chatHistory, userMessage]; + + this.updateSystemPrompt(); + + // Prepare the command to converse with the Bedrock API + const converseCmd = { + modelId: this.modelId, + messages: conversation, + system: [{ text: this.systemPrompt }], + inferenceConfig: this.inferenceConfig, + toolConfig: { + tools: this.inlineAgentTool + } + }; + + // Call Bedrock's converse API + const command = new ConverseCommand(converseCmd); + const response = await this.client.send(command); + + if (!response.output) { + throw new Error("No output received from Bedrock model"); + } + + const bedrockResponse = response.output.message as ConversationMessage; + + // Check if tool use is required + if (bedrockResponse.content) { // Add null check + for (const content of bedrockResponse.content) { + if (content && typeof content === 'object' && 'toolUse' in content) { + return await this.toolConfig.useToolHandler(bedrockResponse, conversation); + } + } + } + + return bedrockResponse; + + } catch (error: unknown) { // Explicitly type error as unknown + // Handle error with proper type checking + const errorMessage = error instanceof Error + ? error.message + : 'Unknown error occurred'; + + Logger.logger.error("Error processing request with Bedrock:", errorMessage); + throw new Error(`Error processing request with Bedrock: ${errorMessage}`); + } + } + + setSystemPrompt(template?: string, variables?: TemplateVariables): void { + if (template) { + this.promptTemplate = template; + } + if (variables) { + this.customVariables = variables; + } + this.updateSystemPrompt(); + } + + private updateSystemPrompt(): void { + const allVariables: TemplateVariables = { + ...this.customVariables + }; + this.systemPrompt = this.replaceplaceholders(this.promptTemplate, allVariables); + } + + private replaceplaceholders(template: string, variables: TemplateVariables): string { + return template.replace(/{{(\w+)}}/g, (match, key) => { + if (key in variables) { + const value = variables[key]; + return Array.isArray(value) ? value.join('\n') : String(value); + } + return match; + }); + } + } \ No newline at end of file From b3049c4ec2c60ce758a0d26493fa2d367ace9b16 Mon Sep 17 00:00:00 2001 From: Anthony Bernabeu <64135631+brnaba-aws@users.noreply.github.com> Date: Wed, 27 Nov 2024 10:10:01 +0100 Subject: [PATCH 03/18] Updating inline agent with action_groups and kbs in the prompt template. Added logging and trace as an option. --- .../inline_agent_bedrock.py | 72 +++++++++++++------ 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/examples/inline-agents-bedrock/inline_agent_bedrock.py b/examples/inline-agents-bedrock/inline_agent_bedrock.py index 1d9c790a..e3bf0248 100644 --- a/examples/inline-agents-bedrock/inline_agent_bedrock.py +++ b/examples/inline-agents-bedrock/inline_agent_bedrock.py @@ -23,6 +23,7 @@ class BedrockInlineAgentOptions(AgentOptions): action_groups_list: List[Dict[str, Any]] = field(default_factory=list) knowledge_bases: Optional[List[Dict[str, Any]]] = None custom_system_prompt: Optional[Dict[str, Any]] = None + trace: Optional[bool] = False # BedrockInlineAgent Class @@ -123,24 +124,45 @@ def __init__(self, options: BedrockInlineAgentOptions): self.prompt_template: str = f"""You are a {self.name}. {self.description} - You will engage in an open-ended conversation, - providing helpful and accurate information based on your expertise. - The conversation will proceed as follows: - - The human may ask an initial question or provide a prompt on any topic. - - You will provide a relevant and informative response. - - The human may then follow up with additional questions or prompts related to your previous - response, allowing for a multi-turn dialogue on that topic. - - Or, the human may switch to a completely new and unrelated topic at any point. - - You will seamlessly shift your focus to the new topic, providing thoughtful and - coherent responses based on your broad knowledge base. - Throughout the conversation, you should aim to: - - Understand the context and intent behind each new question or prompt. - - Provide substantive and well-reasoned responses that directly address the query. - - Draw insights and connections from your extensive knowledge when appropriate. - - Ask for clarification if any part of the question or prompt is ambiguous. - - Maintain a consistent, respectful, and engaging tone tailored - to the human's communication style. - - Seamlessly transition between topics as the human introduces new subjects.""" +You will engage in an open-ended conversation, +providing helpful and accurate information based on your expertise. +The conversation will proceed as follows: +- The human may ask an initial question or provide a prompt on any topic. +- You will provide a relevant and informative response. +- The human may then follow up with additional questions or prompts related to your previous +response, allowing for a multi-turn dialogue on that topic. +- Or, the human may switch to a completely new and unrelated topic at any point. +- You will seamlessly shift your focus to the new topic, providing thoughtful and +coherent responses based on your broad knowledge base. +Throughout the conversation, you should aim to: +- Understand the context and intent behind each new question or prompt. +- Provide substantive and well-reasoned responses that directly address the query. +- Draw insights and connections from your extensive knowledge when appropriate. +- Ask for clarification if any part of the question or prompt is ambiguous. +- Maintain a consistent, respectful, and engaging tone tailored +to the human's communication style. +- Seamlessly transition between topics as the human introduces new subjects. +""" + self.prompt_template += "\n\nHere are the action groups that you can use to solve the customer request:\n" + self.prompt_template += "\n" + for action_group in self.action_groups_list: + self.prompt_template += f"Action Group Name: {action_group.get('actionGroupName')}\n" + self.prompt_template += f"Action Group Description: {action_group.get('description','')}\n" + self.prompt_template += f"Action Group ID: {action_group.get('actionGroupId','')}\n" + self.prompt_template += f"Action Group API Schema: {action_group.get('apiSchema','')}\n" + self.prompt_template += f"Action Group Executor: {action_group.get('actionGroupExecutor','')}\n" + self.prompt_template += f"Action Group State: {action_group.get('actionGroupState','')}\n" + self.prompt_template += f"Action Group Parent Action Group Signature: {action_group.get('parentActionGroupSignature','')}\n" + self.prompt_template += f"Action Group Agent ID: {action_group.get('agentId','')}\n" + self.prompt_template += f"Action Group Agent Version: {action_group.get('agentVersion','')}\n" + self.prompt_template += "\n" + + self.prompt_template += "\n\nHere are the knwoledge bases that you can use to solve the customer request:\n" + self.prompt_template += "\n" + for kb in self.knowledge_bases: + self.prompt_template += f"Knowledge Base ID: {kb['knowledgeBaseId']}\n" + self.prompt_template += f"Knowledge Base Description: {kb.get('description', '')}\n" + self.prompt_template += "\n" self.system_prompt: str = "" self.custom_variables: TemplateVariables = {} @@ -152,6 +174,8 @@ def __init__(self, options: BedrockInlineAgentOptions): options.custom_system_prompt.get('variables') ) + self.trace = options.trace + async def inline_agent_tool_handler(self, session_id, response, conversation): """Handler for processing tool use.""" @@ -185,13 +209,19 @@ async def inline_agent_tool_handler(self, session_id, response, conversation): kbs = [] if kb_names and self.knowledge_bases: kbs = [item for item in self.knowledge_bases - if item.get('knowledgeBaseId') == kb_names[0]] + if item.get('knowledgeBaseId') in kb_names] + + Logger.info(f"Calling Agents for Bedrock with:\n") + Logger.info(f"user input:{user_request}") + Logger.info(f"Action Groups: {action_groups}\n") + Logger.info(f"Knowledge Bases: {kbs}\n") + Logger.info(f"Description: {description}\n") import uuid inline_response = self.bedrock_agent_client.invoke_inline_agent( actionGroups=action_groups, knowledgeBases=kbs, - enableTrace=True, + enableTrace=self.trace, endSession=False, foundationModel=self.foundation_model, inputText=user_request, @@ -202,7 +232,7 @@ async def inline_agent_tool_handler(self, session_id, response, conversation): eventstream = inline_response.get('completion') tool_results = [] for event in eventstream: - print(event) + Logger.info(event) if self.trace else None if 'chunk' in event: chunk = event['chunk'] if 'bytes' in chunk: From 48d1cd47c36fb54fe81f25816b8b4a490ce2b073 Mon Sep 17 00:00:00 2001 From: Anthony Bernabeu <64135631+brnaba-aws@users.noreply.github.com> Date: Wed, 27 Nov 2024 11:16:41 +0100 Subject: [PATCH 04/18] updated agent --- .../inline_agent_bedrock.py | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/examples/inline-agents-bedrock/inline_agent_bedrock.py b/examples/inline-agents-bedrock/inline_agent_bedrock.py index e3bf0248..65e3b7ec 100644 --- a/examples/inline-agents-bedrock/inline_agent_bedrock.py +++ b/examples/inline-agents-bedrock/inline_agent_bedrock.py @@ -23,12 +23,13 @@ class BedrockInlineAgentOptions(AgentOptions): action_groups_list: List[Dict[str, Any]] = field(default_factory=list) knowledge_bases: Optional[List[Dict[str, Any]]] = None custom_system_prompt: Optional[Dict[str, Any]] = None - trace: Optional[bool] = False + enableTrace: Optional[bool] = False # BedrockInlineAgent Class class BedrockInlineAgent(Agent): + TOOL_NAME = 'inline_agent_creation' TOOL_INPUT_SCHEMA = { "json": { "type": "object", @@ -52,12 +53,10 @@ class BedrockInlineAgent(Agent): "description": "The initial user request" } }, - "required": ["action_group_names", "description", "user_request"], + "required": ["action_group_names", "description", "user_request", "knowledge_bases"], } } - KEYS_TO_REMOVE = ['actionGroupId', 'actionGroupState', 'agentId', 'agentVersion'] - def __init__(self, options: BedrockInlineAgentOptions): super().__init__(options) @@ -106,7 +105,7 @@ def __init__(self, options: BedrockInlineAgentOptions): # Define inline agent tool configuration self.inline_agent_tool = [{ "toolSpec": { - "name": "inline_agent_creation", + "name": BedrockInlineAgent.TOOL_NAME, "description": "Create an inline agent with a list of action groups and knowledge bases", "inputSchema": self.TOOL_INPUT_SCHEMA, } @@ -119,7 +118,7 @@ def __init__(self, options: BedrockInlineAgentOptions): self.tool_config = { 'tool': self.inline_agent_tool, 'toolMaxRecursions': 1, - 'useToolHandler': self.use_tool_handler + 'useToolHandler': self.use_tool_handler, } self.prompt_template: str = f"""You are a {self.name}. @@ -148,13 +147,6 @@ def __init__(self, options: BedrockInlineAgentOptions): for action_group in self.action_groups_list: self.prompt_template += f"Action Group Name: {action_group.get('actionGroupName')}\n" self.prompt_template += f"Action Group Description: {action_group.get('description','')}\n" - self.prompt_template += f"Action Group ID: {action_group.get('actionGroupId','')}\n" - self.prompt_template += f"Action Group API Schema: {action_group.get('apiSchema','')}\n" - self.prompt_template += f"Action Group Executor: {action_group.get('actionGroupExecutor','')}\n" - self.prompt_template += f"Action Group State: {action_group.get('actionGroupState','')}\n" - self.prompt_template += f"Action Group Parent Action Group Signature: {action_group.get('parentActionGroupSignature','')}\n" - self.prompt_template += f"Action Group Agent ID: {action_group.get('agentId','')}\n" - self.prompt_template += f"Action Group Agent Version: {action_group.get('agentVersion','')}\n" self.prompt_template += "\n" self.prompt_template += "\n\nHere are the knwoledge bases that you can use to solve the customer request:\n" @@ -174,7 +166,7 @@ def __init__(self, options: BedrockInlineAgentOptions): options.custom_system_prompt.get('variables') ) - self.trace = options.trace + self.enableTrace = options.enableTrace async def inline_agent_tool_handler(self, session_id, response, conversation): @@ -201,9 +193,9 @@ async def inline_agent_tool_handler(self, session_id, response, conversation): if item.get('actionGroupName') in action_group_names ] for entry in action_groups: - for key in self.KEYS_TO_REMOVE: - entry.pop(key, None) - if 'parentActionGroupSignature' in entry: + # remove description for AMAZON.CodeInterpreter + if 'parentActionGroupSignature' in entry and \ + entry['parentActionGroupSignature'] == 'AMAZON.CodeInterpreter': entry.pop('description', None) kbs = [] @@ -221,7 +213,7 @@ async def inline_agent_tool_handler(self, session_id, response, conversation): inline_response = self.bedrock_agent_client.invoke_inline_agent( actionGroups=action_groups, knowledgeBases=kbs, - enableTrace=self.trace, + enableTrace=self.enableTrace, endSession=False, foundationModel=self.foundation_model, inputText=user_request, @@ -232,7 +224,7 @@ async def inline_agent_tool_handler(self, session_id, response, conversation): eventstream = inline_response.get('completion') tool_results = [] for event in eventstream: - Logger.info(event) if self.trace else None + Logger.info(event) if self.enableTrace else None if 'chunk' in event: chunk = event['chunk'] if 'bytes' in chunk: @@ -280,6 +272,11 @@ async def process_request( }, 'toolConfig': { 'tools': self.inline_agent_tool, + "toolChoice": { + "tool": { + "name": BedrockInlineAgent.TOOL_NAME, + }, + }, } } # Call Bedrock's converse API From c32e2f1b46a2ac54b8516b41aa6887b466a1d7ee Mon Sep 17 00:00:00 2001 From: Anthony Bernabeu <64135631+brnaba-aws@users.noreply.github.com> Date: Wed, 27 Nov 2024 12:00:26 +0100 Subject: [PATCH 05/18] updated tool definition --- examples/inline-agents-bedrock/inline_agent_bedrock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/inline-agents-bedrock/inline_agent_bedrock.py b/examples/inline-agents-bedrock/inline_agent_bedrock.py index 65e3b7ec..d4853b0a 100644 --- a/examples/inline-agents-bedrock/inline_agent_bedrock.py +++ b/examples/inline-agents-bedrock/inline_agent_bedrock.py @@ -46,7 +46,7 @@ class BedrockInlineAgent(Agent): }, "description": { "type": "string", - "description": "Description to instruct the agent how to solve the user request using available action groups" + "description": "Description to instruct the agent how to solve the user request using available action groups and knowledge bases." }, "user_request": { "type": "string", From ff07519ee8274ec617fe8853093356ef117527b3 Mon Sep 17 00:00:00 2001 From: Corneliu Croitoru Date: Wed, 27 Nov 2024 12:36:18 +0100 Subject: [PATCH 06/18] add log in Agent class --- typescript/package-lock.json | 943 +++++++++++++++----- typescript/package.json | 2 +- typescript/src/agents/agent.ts | 21 + typescript/src/agents/bedrockInlineAgent.ts | 175 +++- 4 files changed, 867 insertions(+), 274 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index ebfa9910..d39fa19d 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,16 +1,16 @@ { "name": "multi-agent-orchestrator", - "version": "0.0.15", + "version": "0.0.17", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "multi-agent-orchestrator", - "version": "0.0.15", + "version": "0.0.17", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/sdk": "^0.24.3", - "@aws-sdk/client-bedrock-agent-runtime": "^3.621.0", + "@aws-sdk/client-bedrock-agent-runtime": "^3.701.0", "@aws-sdk/client-bedrock-runtime": "^3.621.0", "@aws-sdk/client-comprehend": "^3.637.0", "@aws-sdk/client-dynamodb": "^3.621.0", @@ -214,59 +214,528 @@ } }, "node_modules/@aws-sdk/client-bedrock-agent-runtime": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-agent-runtime/-/client-bedrock-agent-runtime-3.621.0.tgz", - "integrity": "sha512-YBkB8CwqA/AnQPFhH9WMTnD/vLzrgoU/NwERMD46162zJnpjJy1T7yl2phEbr4FRyZqAe1HVQt9g72pN3rcimg==", + "version": "3.701.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-agent-runtime/-/client-bedrock-agent-runtime-3.701.0.tgz", + "integrity": "sha512-OllyQ2AkVX7GSEJIzNVrJxs2/F8Ao5StEtOBJhURgPnFxFC07s8d73ZAkwdWyhJHTAV+oqRo9mfB696bEJw/mA==", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.621.0", - "@aws-sdk/client-sts": "3.621.0", - "@aws-sdk/core": "3.621.0", - "@aws-sdk/credential-provider-node": "3.621.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.620.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.1", - "@smithy/eventstream-serde-browser": "^3.0.5", - "@smithy/eventstream-serde-config-resolver": "^3.0.3", - "@smithy/eventstream-serde-node": "^3.0.4", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.13", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", + "@aws-sdk/client-sso-oidc": "3.699.0", + "@aws-sdk/client-sts": "3.699.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/eventstream-serde-browser": "^3.0.13", + "@smithy/eventstream-serde-config-resolver": "^3.0.10", + "@smithy/eventstream-serde-node": "^3.0.12", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.13", - "@smithy/util-defaults-mode-node": "^3.0.13", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/client-sso": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.696.0.tgz", + "integrity": "sha512-q5TTkd08JS0DOkHfUL853tuArf7NrPeqoS5UOvqJho8ibV9Ak/a/HO4kNvy9Nj3cib/toHYHsQIEtecUPSUUrQ==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/client-sso-oidc": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.699.0.tgz", + "integrity": "sha512-u8a1GorY5D1l+4FQAf4XBUC1T10/t7neuwT21r0ymrtMFSK2a9QqVHKMoLkvavAwyhJnARSBM9/UQC797PFOFw==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.699.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/client-sts": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.699.0.tgz", + "integrity": "sha512-++lsn4x2YXsZPIzFVwv3fSUVM55ZT0WRFmPeNilYIhZClxHLmVAWKH4I55cY9ry60/aTKYjzOXkWwyBKGsGvQg==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.699.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/core": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.696.0.tgz", + "integrity": "sha512-3c9III1k03DgvRZWg8vhVmfIXPG6hAciN9MzQTzqGngzWAELZF/WONRTRQuDFixVtarQatmLHYVw/atGeA2Byw==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/core": "^2.5.3", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.9", + "@smithy/protocol-http": "^4.1.7", + "@smithy/signature-v4": "^4.2.2", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/util-middleware": "^3.0.10", + "fast-xml-parser": "4.4.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/credential-provider-env": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.696.0.tgz", + "integrity": "sha512-T9iMFnJL7YTlESLpVFT3fg1Lkb1lD+oiaIC8KMpepb01gDUBIpj9+Y+pA/cgRWW0yRxmkDXNazAE2qQTVFGJzA==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/credential-provider-http": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.696.0.tgz", + "integrity": "sha512-GV6EbvPi2eq1+WgY/o2RFA3P7HGmnkIzCNmhwtALFlqMroLYWKE7PSeHw66Uh1dFQeVESn0/+hiUNhu1mB0emA==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/property-provider": "^3.1.9", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/util-stream": "^3.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.699.0.tgz", + "integrity": "sha512-dXmCqjJnKmG37Q+nLjPVu22mNkrGHY8hYoOt3Jo9R2zr5MYV7s/NHsCHr+7E+BZ+tfZYLRPeB1wkpTeHiEcdRw==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-env": "3.696.0", + "@aws-sdk/credential-provider-http": "3.696.0", + "@aws-sdk/credential-provider-process": "3.696.0", + "@aws-sdk/credential-provider-sso": "3.699.0", + "@aws-sdk/credential-provider-web-identity": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/credential-provider-imds": "^3.2.6", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.699.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/credential-provider-node": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.699.0.tgz", + "integrity": "sha512-MmEmNDo1bBtTgRmdNfdQksXu4uXe66s0p1hi1YPrn1h59Q605eq/xiWbGL6/3KdkViH6eGUuABeV2ODld86ylg==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.696.0", + "@aws-sdk/credential-provider-http": "3.696.0", + "@aws-sdk/credential-provider-ini": "3.699.0", + "@aws-sdk/credential-provider-process": "3.696.0", + "@aws-sdk/credential-provider-sso": "3.699.0", + "@aws-sdk/credential-provider-web-identity": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/credential-provider-imds": "^3.2.6", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/credential-provider-process": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.696.0.tgz", + "integrity": "sha512-mL1RcFDe9sfmyU5K1nuFkO8UiJXXxLX4JO1gVaDIOvPqwStpUAwi3A1BoeZhWZZNQsiKI810RnYGo0E0WB/hUA==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.699.0.tgz", + "integrity": "sha512-Ekp2cZG4pl9D8+uKWm4qO1xcm8/MeiI8f+dnlZm8aQzizeC+aXYy9GyoclSf6daK8KfRPiRfM7ZHBBL5dAfdMA==", + "dependencies": { + "@aws-sdk/client-sso": "3.696.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/token-providers": "3.699.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.696.0.tgz", + "integrity": "sha512-XJ/CVlWChM0VCoc259vWguFUjJDn/QwDqHwbx+K9cg3v6yrqXfK5ai+p/6lx0nQpnk4JzPVeYYxWRpaTsGC9rg==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.696.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/middleware-host-header": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.696.0.tgz", + "integrity": "sha512-zELJp9Ta2zkX7ELggMN9qMCgekqZhFC5V2rOr4hJDEb/Tte7gpfKSObAnw/3AYiVqt36sjHKfdkoTsuwGdEoDg==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/middleware-logger": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.696.0.tgz", + "integrity": "sha512-KhkHt+8AjCxcR/5Zp3++YPJPpFQzxpr+jmONiT/Jw2yqnSngZ0Yspm5wGoRx2hS1HJbyZNuaOWEGuJoxLeBKfA==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, "engines": { "node": ">=16.0.0" } }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.696.0.tgz", + "integrity": "sha512-si/maV3Z0hH7qa99f9ru2xpS5HlfSVcasRlNUXKSDm611i7jFMWwGNLUOXFAOLhXotPX5G3Z6BLwL34oDeBMug==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.696.0.tgz", + "integrity": "sha512-Lvyj8CTyxrHI6GHd2YVZKIRI5Fmnugt3cpJo0VrKKEgK5zMySwEZ1n4dqPK6czYRWKd5+WnYHYAuU+Wdk6Jsjw==", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@smithy/core": "^2.5.3", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/region-config-resolver": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.696.0.tgz", + "integrity": "sha512-7EuH142lBXjI8yH6dVS/CZeiK/WZsmb/8zP6bQbVYpMrppSTgB3MzZZdxVZGzL5r8zPQOU10wLC4kIMy0qdBVQ==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/token-providers": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.699.0.tgz", + "integrity": "sha512-kuiEW9DWs7fNos/SM+y58HCPhcIzm1nEZLhe2/7/6+TvAYLuEWURYsbK48gzsxXlaJ2k/jGY3nIsA7RptbMOwA==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sso-oidc": "^3.699.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/types": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.696.0.tgz", + "integrity": "sha512-9rTvUJIAj5d3//U5FDPWGJ1nFJLuWb30vugGOrWk7aNZ6y9tuA3PI7Cc9dP8WEXKVyK1vuuk8rSFP2iqXnlgrw==", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/util-endpoints": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.696.0.tgz", + "integrity": "sha512-T5s0IlBVX+gkb9g/I6CLt4yAZVzMSiGnbUqWihWsHvQR1WOoIcndQy/Oz/IJXT9T2ipoy7a80gzV6a5mglrioA==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "@smithy/util-endpoints": "^2.1.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.696.0.tgz", + "integrity": "sha512-Z5rVNDdmPOe6ELoM5AhF/ja5tSjbe6ctSctDPb0JdDf4dT0v2MfwhJKzXju2RzX8Es/77Glh7MlaXLE0kCB9+Q==", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.696.0.tgz", + "integrity": "sha512-KhKqcfyXIB0SCCt+qsu4eJjsfiOrNzK5dCV7RAW2YIpp+msxGUUX0NdRE9rkzjiv+3EMktgJm3eEIS+yxtlVdQ==", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime/node_modules/@smithy/fetch-http-handler": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz", + "integrity": "sha512-bH7QW0+JdX0bPBadXt8GwMof/jz0H28I84hU1Uet9ISpzUqXqRQ3fEZJ+ANPOhzSEczYvANNl3uDQDYArSFDtA==", + "dependencies": { + "@smithy/protocol-http": "^4.1.7", + "@smithy/querystring-builder": "^3.0.10", + "@smithy/types": "^3.7.1", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, "node_modules/@aws-sdk/client-bedrock-runtime": { "version": "3.621.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.621.0.tgz", @@ -2621,11 +3090,11 @@ "dev": true }, "node_modules/@smithy/abort-controller": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.1.tgz", - "integrity": "sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.8.tgz", + "integrity": "sha512-+3DOBcUn5/rVjlxGvUPKc416SExarAQ+Qe0bqk30YSUjbepwpS7QN0cyKUSifvLJhdMZ0WPzPP5ymut0oonrpQ==", "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2633,14 +3102,14 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.5.tgz", - "integrity": "sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.12.tgz", + "integrity": "sha512-YAJP9UJFZRZ8N+UruTeq78zkdjUHmzsY62J4qKWZ4SXB4QXJ/+680EfXXgkYA2xj77ooMqtUY9m406zGNqwivQ==", "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", + "@smithy/util-middleware": "^3.0.10", "tslib": "^2.6.2" }, "engines": { @@ -2648,18 +3117,16 @@ } }, "node_modules/@smithy/core": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.4.0.tgz", - "integrity": "sha512-cHXq+FneIF/KJbt4q4pjN186+Jf4ZB0ZOqEaZMBhT79srEyGDDBV31NqBRBjazz8ppQ1bJbDJMY9ba5wKFV36w==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.4.tgz", + "integrity": "sha512-iFh2Ymn2sCziBRLPuOOxRPkuCx/2gBdXtBGuCUFLUe6bWYjKnhHyIPqGeNkLZ5Aco/5GjebRTBFiWID3sDbrKw==", "dependencies": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.15", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-stream": "^3.3.1", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -2668,14 +3135,14 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.0.tgz", - "integrity": "sha512-0SCIzgd8LYZ9EJxUjLXBmEKSZR/P/w6l7Rz/pab9culE/RWuqelAKGJvn5qUOl8BgX8Yj5HWM50A5hiB/RzsgA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.7.tgz", + "integrity": "sha512-cEfbau+rrWF8ylkmmVAObOmjbTIzKyUC5TkBL58SbLywD0RCBC4JAUKbmtSm2w5KUJNRPGgpGFMvE2FKnuNlWQ==", "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.10", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", "tslib": "^2.6.2" }, "engines": { @@ -2683,23 +3150,23 @@ } }, "node_modules/@smithy/eventstream-codec": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.2.tgz", - "integrity": "sha512-0mBcu49JWt4MXhrhRAlxASNy0IjDRFU+aWNDRal9OtUJvJNiwDuyKMUONSOjLjSCeGwZaE0wOErdqULer8r7yw==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.9.tgz", + "integrity": "sha512-F574nX0hhlNOjBnP+noLtsPFqXnWh2L0+nZKCwcu7P7J8k+k+rdIDs+RMnrMwrzhUE4mwMgyN0cYnEn0G8yrnQ==", "dependencies": { "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.7.1", "@smithy/util-hex-encoding": "^3.0.0", "tslib": "^2.6.2" } }, "node_modules/@smithy/eventstream-serde-browser": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.5.tgz", - "integrity": "sha512-dEyiUYL/ekDfk+2Ra4GxV+xNnFoCmk1nuIXg+fMChFTrM2uI/1r9AdiTYzPqgb72yIv/NtAj6C3dG//1wwgakQ==", + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.13.tgz", + "integrity": "sha512-Nee9m+97o9Qj6/XeLz2g2vANS2SZgAxV4rDBMKGHvFJHU/xz88x2RwCkwsvEwYjSX4BV1NG1JXmxEaDUzZTAtw==", "dependencies": { - "@smithy/eventstream-serde-universal": "^3.0.4", - "@smithy/types": "^3.3.0", + "@smithy/eventstream-serde-universal": "^3.0.12", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2707,11 +3174,11 @@ } }, "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.3.tgz", - "integrity": "sha512-NVTYjOuYpGfrN/VbRQgn31x73KDLfCXCsFdad8DiIc3IcdxL+dYA9zEQPyOP7Fy2QL8CPy2WE4WCUD+ZsLNfaQ==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.10.tgz", + "integrity": "sha512-K1M0x7P7qbBUKB0UWIL5KOcyi6zqV5mPJoL0/o01HPJr0CSq3A9FYuJC6e11EX6hR8QTIR++DBiGrYveOu6trw==", "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2719,12 +3186,12 @@ } }, "node_modules/@smithy/eventstream-serde-node": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.4.tgz", - "integrity": "sha512-mjlG0OzGAYuUpdUpflfb9zyLrBGgmQmrobNT8b42ZTsGv/J03+t24uhhtVEKG/b2jFtPIHF74Bq+VUtbzEKOKg==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.12.tgz", + "integrity": "sha512-kiZymxXvZ4tnuYsPSMUHe+MMfc4FTeFWJIc0Q5wygJoUQM4rVHNghvd48y7ppuulNMbuYt95ah71pYc2+o4JOA==", "dependencies": { - "@smithy/eventstream-serde-universal": "^3.0.4", - "@smithy/types": "^3.3.0", + "@smithy/eventstream-serde-universal": "^3.0.12", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2732,12 +3199,12 @@ } }, "node_modules/@smithy/eventstream-serde-universal": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.4.tgz", - "integrity": "sha512-Od9dv8zh3PgOD7Vj4T3HSuox16n0VG8jJIM2gvKASL6aCtcS8CfHZDWe1Ik3ZXW6xBouU+45Q5wgoliWDZiJ0A==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.12.tgz", + "integrity": "sha512-1i8ifhLJrOZ+pEifTlF0EfZzMLUGQggYQ6WmZ4d5g77zEKf7oZ0kvh1yKWHPjofvOwqrkwRDVuxuYC8wVd662A==", "dependencies": { - "@smithy/eventstream-codec": "^3.1.2", - "@smithy/types": "^3.3.0", + "@smithy/eventstream-codec": "^3.1.9", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2757,11 +3224,11 @@ } }, "node_modules/@smithy/hash-node": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.3.tgz", - "integrity": "sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.10.tgz", + "integrity": "sha512-3zWGWCHI+FlJ5WJwx73Mw2llYR8aflVyZN5JhoqLxbdPZi6UyKSdCeXAWJw9ja22m6S6Tzz1KZ+kAaSwvydi0g==", "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.7.1", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" @@ -2771,11 +3238,11 @@ } }, "node_modules/@smithy/invalid-dependency": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.3.tgz", - "integrity": "sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.10.tgz", + "integrity": "sha512-Lp2L65vFi+cj0vFMu2obpPW69DU+6O5g3086lmI4XcnRCG8PxvpWC7XyaVwJCxsZFzueHjXnrOH/E0pl0zikfA==", "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" } }, @@ -2791,12 +3258,12 @@ } }, "node_modules/@smithy/middleware-content-length": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.5.tgz", - "integrity": "sha512-ILEzC2eyxx6ncej3zZSwMpB5RJ0zuqH7eMptxC4KN3f+v9bqT8ohssKbhNR78k/2tWW+KS5Spw+tbPF4Ejyqvw==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.12.tgz", + "integrity": "sha512-1mDEXqzM20yywaMDuf5o9ue8OkJ373lSPbaSjyEvkWdqELhFMyNNgKGWL/rCSf4KME8B+HlHKuR8u9kRj8HzEQ==", "dependencies": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2804,16 +3271,17 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.1.0.tgz", - "integrity": "sha512-5y5aiKCEwg9TDPB4yFE7H6tYvGFf1OJHNczeY10/EFF8Ir8jZbNntQJxMWNfeQjC1mxPsaQ6mR9cvQbf+0YeMw==", - "dependencies": { - "@smithy/middleware-serde": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-middleware": "^3.0.3", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.4.tgz", + "integrity": "sha512-TybiW2LA3kYVd3e+lWhINVu1o26KJbBwOpADnf0L4x/35vLVica77XVR5hvV9+kWeTGeSJ3IHTcYxbRxlbwhsg==", + "dependencies": { + "@smithy/core": "^2.5.4", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/shared-ini-file-loader": "^3.1.11", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-middleware": "^3.0.10", "tslib": "^2.6.2" }, "engines": { @@ -2821,17 +3289,17 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.15.tgz", - "integrity": "sha512-iTMedvNt1ApdvkaoE8aSDuwaoc+BhvHqttbA/FO4Ty+y/S5hW6Ci/CTScG7vam4RYJWZxdTElc3MEfHRVH6cgQ==", - "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/service-error-classification": "^3.0.3", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", + "version": "3.0.28", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.28.tgz", + "integrity": "sha512-vK2eDfvIXG1U64FEUhYxoZ1JSj4XFbYWkK36iz02i3pFwWiDz1Q7jKhGTBCwx/7KqJNk4VS7d7cDLXFOvP7M+g==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.11", + "@smithy/protocol-http": "^4.1.7", + "@smithy/service-error-classification": "^3.0.10", + "@smithy/smithy-client": "^3.4.5", + "@smithy/types": "^3.7.1", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", "tslib": "^2.6.2", "uuid": "^9.0.1" }, @@ -2840,11 +3308,11 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.3.tgz", - "integrity": "sha512-puUbyJQBcg9eSErFXjKNiGILJGtiqmuuNKEYNYfUD57fUl4i9+mfmThtQhvFXU0hCVG0iEJhvQUipUf+/SsFdA==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.10.tgz", + "integrity": "sha512-MnAuhh+dD14F428ubSJuRnmRsfOpxSzvRhaGVTvd/lrUDE3kxzCCmH8lnVTvoNQnV2BbJ4c15QwZ3UdQBtFNZA==", "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2852,11 +3320,11 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.3.tgz", - "integrity": "sha512-r4klY9nFudB0r9UdSMaGSyjyQK5adUyPnQN/ZM6M75phTxOdnc/AhpvGD1fQUvgmqjQEBGCwpnPbDm8pH5PapA==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.10.tgz", + "integrity": "sha512-grCHyoiARDBBGPyw2BeicpjgpsDFWZZxptbVKb3CRd/ZA15F/T6rZjCCuBUjJwdck1nwUuIxYtsS4H9DDpbP5w==", "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2864,13 +3332,13 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.4.tgz", - "integrity": "sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==", + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.11.tgz", + "integrity": "sha512-URq3gT3RpDikh/8MBJUB+QGZzfS7Bm6TQTqoh4CqE8NBuyPkWa5eUXj0XFcFfeZVgg3WMh1u19iaXn8FvvXxZw==", "dependencies": { - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", + "@smithy/property-provider": "^3.1.10", + "@smithy/shared-ini-file-loader": "^3.1.11", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2878,14 +3346,14 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.4.tgz", - "integrity": "sha512-+UmxgixgOr/yLsUxcEKGH0fMNVteJFGkmRltYFHnBMlogyFdpzn2CwqWmxOrfJELhV34v0WSlaqG1UtE1uXlJg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.1.tgz", + "integrity": "sha512-fr+UAOMGWh6bn4YSEezBCpJn9Ukp9oR4D32sCjCo7U81evE11YePOQ58ogzyfgmjIO79YeOdfXXqr0jyhPQeMg==", "dependencies": { - "@smithy/abort-controller": "^3.1.1", - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", + "@smithy/abort-controller": "^3.1.8", + "@smithy/protocol-http": "^4.1.7", + "@smithy/querystring-builder": "^3.0.10", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2893,11 +3361,11 @@ } }, "node_modules/@smithy/property-provider": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.3.tgz", - "integrity": "sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.10.tgz", + "integrity": "sha512-n1MJZGTorTH2DvyTVj+3wXnd4CzjJxyXeOgnTlgNVFxaaMeT4OteEp4QrzF8p9ee2yg42nvyVK6R/awLCakjeQ==", "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2905,11 +3373,11 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.7.tgz", + "integrity": "sha512-FP2LepWD0eJeOTm0SjssPcgqAlDFzOmRXqXmGhfIM52G7Lrox/pcpQf6RP4F21k0+O12zaqQt5fCDOeBtqY6Cg==", "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2917,11 +3385,11 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", - "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.10.tgz", + "integrity": "sha512-nT9CQF3EIJtIUepXQuBFb8dxJi3WVZS3XfuDksxSCSn+/CzZowRLdhDn+2acbBv8R6eaJqPupoI/aRFIImNVPQ==", "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.7.1", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" }, @@ -2930,11 +3398,11 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.3.tgz", - "integrity": "sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.10.tgz", + "integrity": "sha512-Oa0XDcpo9SmjhiDD9ua2UyM3uU01ZTuIrNdZvzwUTykW1PM8o2yJvMh1Do1rY5sUQg4NDV70dMi0JhDx4GyxuQ==", "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2942,22 +3410,22 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.3.tgz", - "integrity": "sha512-Jn39sSl8cim/VlkLsUhRFq/dKDnRUFlfRkvhOJaUbLBXUsLRLNf9WaxDv/z9BjuQ3A6k/qE8af1lsqcwm7+DaQ==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.10.tgz", + "integrity": "sha512-zHe642KCqDxXLuhs6xmHVgRwy078RfqxP2wRDpIyiF8EmsWXptMwnMwbVa50lw+WOGNrYm9zbaEg0oDe3PTtvQ==", "dependencies": { - "@smithy/types": "^3.3.0" + "@smithy/types": "^3.7.1" }, "engines": { "node": ">=16.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.4.tgz", - "integrity": "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==", + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.11.tgz", + "integrity": "sha512-AUdrIZHFtUgmfSN4Gq9nHu3IkHMa1YDcN+s061Nfm+6pQ0mJy85YQDB0tZBCmls0Vuj22pLwDPmL92+Hvfwwlg==", "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -2965,15 +3433,15 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.1.0.tgz", - "integrity": "sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.3.tgz", + "integrity": "sha512-pPSQQ2v2vu9vc8iew7sszLd0O09I5TRc5zhY71KA+Ao0xYazIG+uLeHbTJfIWGO3BGVLiXjUr3EEeCcEQLjpWQ==", "dependencies": { "@smithy/is-array-buffer": "^3.0.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", + "@smithy/util-middleware": "^3.0.10", "@smithy/util-uri-escape": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" @@ -2983,15 +3451,16 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.2.0.tgz", - "integrity": "sha512-pDbtxs8WOhJLJSeaF/eAbPgXg4VVYFlRcL/zoNYA5WbG3wBL06CHtBSg53ppkttDpAJ/hdiede+xApip1CwSLw==", - "dependencies": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.5.tgz", + "integrity": "sha512-k0sybYT9zlP79sIKd1XGm4TmK0AS1nA2bzDHXx7m0nGi3RQ8dxxQUs4CPkSmQTKAo+KF9aINU3KzpGIpV7UoMw==", + "dependencies": { + "@smithy/core": "^2.5.4", + "@smithy/middleware-endpoint": "^3.2.4", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "@smithy/util-stream": "^3.3.1", "tslib": "^2.6.2" }, "engines": { @@ -2999,9 +3468,9 @@ } }, "node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.1.tgz", + "integrity": "sha512-XKLcLXZY7sUQgvvWyeaL/qwNPp6V3dWcUjqrQKjSb+tzYiCy340R/c64LV5j+Tnb2GhmunEX0eou+L+m2hJNYA==", "dependencies": { "tslib": "^2.6.2" }, @@ -3010,12 +3479,12 @@ } }, "node_modules/@smithy/url-parser": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.3.tgz", - "integrity": "sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.10.tgz", + "integrity": "sha512-j90NUalTSBR2NaZTuruEgavSdh8MLirf58LoGSk4AtQfyIymogIhgnGUU2Mga2bkMkpSoC9gxb74xBXL5afKAQ==", "dependencies": { - "@smithy/querystring-parser": "^3.0.3", - "@smithy/types": "^3.3.0", + "@smithy/querystring-parser": "^3.0.10", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" } }, @@ -3075,13 +3544,13 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.15.tgz", - "integrity": "sha512-FZ4Psa3vjp8kOXcd3HJOiDPBCWtiilLl57r0cnNtq/Ga9RSDrM5ERL6xt+tO43+2af6Pn5Yp92x2n5vPuduNfg==", + "version": "3.0.28", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.28.tgz", + "integrity": "sha512-6bzwAbZpHRFVJsOztmov5PGDmJYsbNSoIEfHSJJyFLzfBGCCChiO3od9k7E/TLgrCsIifdAbB9nqbVbyE7wRUw==", "dependencies": { - "@smithy/property-provider": "^3.1.3", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", + "@smithy/property-provider": "^3.1.10", + "@smithy/smithy-client": "^3.4.5", + "@smithy/types": "^3.7.1", "bowser": "^2.11.0", "tslib": "^2.6.2" }, @@ -3090,16 +3559,16 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.15.tgz", - "integrity": "sha512-KSyAAx2q6d0t6f/S4XB2+3+6aQacm3aLMhs9aLMqn18uYGUepbdssfogW5JQZpc6lXNBnp0tEnR5e9CEKmEd7A==", - "dependencies": { - "@smithy/config-resolver": "^3.0.5", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", + "version": "3.0.28", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.28.tgz", + "integrity": "sha512-78ENJDorV1CjOQselGmm3+z7Yqjj5HWCbjzh0Ixuq736dh1oEnD9sAttSBNSLlpZsX8VQnmERqA2fEFlmqWn8w==", + "dependencies": { + "@smithy/config-resolver": "^3.0.12", + "@smithy/credential-provider-imds": "^3.2.7", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.10", + "@smithy/smithy-client": "^3.4.5", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -3107,12 +3576,12 @@ } }, "node_modules/@smithy/util-endpoints": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.5.tgz", - "integrity": "sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.6.tgz", + "integrity": "sha512-mFV1t3ndBh0yZOJgWxO9J/4cHZVn5UG1D8DeCc6/echfNkeEJWu9LD7mgGH5fHrEdR7LDoWw7PQO6QiGpHXhgA==", "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -3131,11 +3600,11 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.3.tgz", - "integrity": "sha512-l+StyYYK/eO3DlVPbU+4Bi06Jjal+PFLSMmlWM1BEwyLxZ3aKkf1ROnoIakfaA7mC6uw3ny7JBkau4Yc+5zfWw==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.10.tgz", + "integrity": "sha512-eJO+/+RsrG2RpmY68jZdwQtnfsxjmPxzMlQpnHKjFPwrYqvlcT+fHdT+ZVwcjlWSrByOhGr9Ff2GG17efc192A==", "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -3143,12 +3612,12 @@ } }, "node_modules/@smithy/util-retry": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.3.tgz", - "integrity": "sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.10.tgz", + "integrity": "sha512-1l4qatFp4PiU6j7UsbasUHL2VU023NRB/gfaa1M0rDqVrRN4g3mCArLRyH3OuktApA4ye+yjWQHjdziunw2eWA==", "dependencies": { - "@smithy/service-error-classification": "^3.0.3", - "@smithy/types": "^3.3.0", + "@smithy/service-error-classification": "^3.0.10", + "@smithy/types": "^3.7.1", "tslib": "^2.6.2" }, "engines": { @@ -3156,13 +3625,13 @@ } }, "node_modules/@smithy/util-stream": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.1.3.tgz", - "integrity": "sha512-FIv/bRhIlAxC0U7xM1BCnF2aDRPq0UaelqBHkM2lsCp26mcBbgI0tCVTv+jGdsQLUmAMybua/bjDsSu8RQHbmw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.1.tgz", + "integrity": "sha512-Ff68R5lJh2zj+AUTvbAU/4yx+6QPRzg7+pI7M1FbtQHcRIp7xvguxVsQBKyB3fwiOwhAKu0lnNyYBaQfSW6TNw==", "dependencies": { - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/types": "^3.3.0", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/types": "^3.7.1", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", @@ -3173,6 +3642,18 @@ "node": ">=16.0.0" } }, + "node_modules/@smithy/util-stream/node_modules/@smithy/fetch-http-handler": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz", + "integrity": "sha512-bH7QW0+JdX0bPBadXt8GwMof/jz0H28I84hU1Uet9ISpzUqXqRQ3fEZJ+ANPOhzSEczYvANNl3uDQDYArSFDtA==", + "dependencies": { + "@smithy/protocol-http": "^4.1.7", + "@smithy/querystring-builder": "^3.0.10", + "@smithy/types": "^3.7.1", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, "node_modules/@smithy/util-uri-escape": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", diff --git a/typescript/package.json b/typescript/package.json index 9350087e..f8b981e3 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -28,7 +28,7 @@ "license": "Apache-2.0", "dependencies": { "@anthropic-ai/sdk": "^0.24.3", - "@aws-sdk/client-bedrock-agent-runtime": "^3.621.0", + "@aws-sdk/client-bedrock-agent-runtime": "^3.701.0", "@aws-sdk/client-bedrock-runtime": "^3.621.0", "@aws-sdk/client-comprehend": "^3.637.0", "@aws-sdk/client-dynamodb": "^3.621.0", diff --git a/typescript/src/agents/agent.ts b/typescript/src/agents/agent.ts index bf2c1ca6..50d5b8f4 100644 --- a/typescript/src/agents/agent.ts +++ b/typescript/src/agents/agent.ts @@ -1,6 +1,7 @@ import { ConversationMessage } from "../types"; import { AccumulatorTransform } from "../utils/helpers"; + export interface AgentProcessingResult { // The original input provided by the user userInput: string; @@ -50,6 +51,14 @@ export interface AgentOptions { // Optional: Determines whether to save the chat, defaults to true saveChat?: boolean; + + // Optional: Logger instance + // If provided, the agent will use this logger for logging instead of the default console + logger?: any | Console; + + // Optional: Flag to enable/disable agent debug trace logging + // If true, the agent will log additional debug information + LOG_AGENT_DEBUG_TRACE?: boolean; } /** @@ -69,6 +78,14 @@ export abstract class Agent { /** Whether to save the chat or not. */ saveChat: boolean; + // Optional logger instance + // If provided, the agent will use this logger for logging instead of the default console + logger: any | Console = console + + // Flag to enable/disable agent debug trace logging + // If true, the agent will log additional debug information + LOG_AGENT_DEBUG_TRACE?: boolean; + /** * Constructs a new Agent instance. * @param options - Configuration options for the agent. @@ -78,6 +95,10 @@ export abstract class Agent { this.id = this.generateKeyFromName(options.name); this.description = options.description; this.saveChat = options.saveChat ?? true; // Default to true if not provided + + this.LOG_AGENT_DEBUG_TRACE = options.LOG_AGENT_DEBUG_TRACE ?? false; + this.logger = options.logger ?? (this.LOG_AGENT_DEBUG_TRACE ? console : { info: () => {}, warn: () => {}, error: () => {}, debug: () => {}, log: () => {} }); + } /** diff --git a/typescript/src/agents/bedrockInlineAgent.ts b/typescript/src/agents/bedrockInlineAgent.ts index 498a9b3f..18f1aef5 100644 --- a/typescript/src/agents/bedrockInlineAgent.ts +++ b/typescript/src/agents/bedrockInlineAgent.ts @@ -1,8 +1,9 @@ import { BedrockRuntimeClient, - BedrockAgentRuntimeClient, ConverseCommand, } from "@aws-sdk/client-bedrock-runtime"; + + import { BedrockAgentRuntimeClient, InvokeInlineAgentCommand, AgentActionGroup, KnowledgeBase } from "@aws-sdk/client-bedrock-agent-runtime"; import { Agent, AgentOptions } from "./agent"; import { BEDROCK_MODEL_ID_CLAUDE_3_HAIKU, @@ -25,12 +26,14 @@ import { modelId?: string; foundationModel?: string; region?: string; - actionGroupsList: Record[]; - knowledgeBases?: Record[]; + actionGroupsList: AgentActionGroup[]; + knowledgeBases?: KnowledgeBase[]; + enableTrace?: boolean; customSystemPrompt?: { template?: string; variables?: TemplateVariables; }; + } export class BedrockInlineAgent extends Agent { @@ -68,6 +71,8 @@ import { 'agentId', 'agentVersion' ]; + + protected static readonly TOOL_NAME = "inline_agent_creation"; /** Protected class members */ protected client: BedrockRuntimeClient; @@ -80,22 +85,25 @@ import { topP?: number; stopSequences?: string[]; }; - protected actionGroupsList: Record[]; - protected knowledgeBases: Record[]; + protected actionGroupsList: AgentActionGroup[]; + protected knowledgeBases: KnowledgeBase[]; + protected enableTrace: boolean; protected inlineAgentTool: any[]; protected toolConfig: { tool: any[]; - useToolHandler: (response: ConversationMessage, conversation: ConversationMessage[]) => Promise; + useToolHandler: (response: ConversationMessage, conversation: ConversationMessage[], sessionId: string) => Promise; toolMaxRecursions: number; }; private promptTemplate: string; private systemPrompt: string = ''; private customVariables: TemplateVariables = {}; - + constructor(options: BedrockInlineAgentOptions) { super(options); + + // Initialize clients this.client = options.client ?? ( options.region @@ -113,6 +121,8 @@ import { this.modelId = options.modelId ?? BEDROCK_MODEL_ID_CLAUDE_3_HAIKU; this.foundationModel = options.foundationModel ?? BEDROCK_MODEL_ID_CLAUDE_3_SONNET; + this.enableTrace = options.enableTrace ?? false; + // Set inference configuration this.inferenceConfig = options.inferenceConfig ?? { maxTokens: 1000, @@ -128,7 +138,7 @@ import { // Define inline agent tool configuration this.inlineAgentTool = [{ toolSpec: { - name: "inline_agent_creation", + name: BedrockInlineAgent.TOOL_NAME, description: "Create an inline agent with a list of action groups and knowledge bases", inputSchema: BedrockInlineAgent.TOOL_INPUT_SCHEMA } @@ -138,7 +148,7 @@ import { this.toolConfig = { tool: this.inlineAgentTool, useToolHandler: this.inlineAgentToolHandler.bind(this), - toolMaxRecursions: 1 + toolMaxRecursions: 1 }; // Set prompt template @@ -162,21 +172,46 @@ import { - Maintain a consistent, respectful, and engaging tone tailored to the human's communication style. - Seamlessly transition between topics as the human introduces new subjects.`; - + + this.promptTemplate += "\n\nHere are the action groups that you can use to solve the customer request:\n"; + this.promptTemplate += "\n"; + + for (const actionGroup of this.actionGroupsList) { + this.promptTemplate += `Action Group Name: ${actionGroup.actionGroupName ?? ''}\n`; + this.promptTemplate += `Action Group Description: ${actionGroup.description ?? ''}\n`; + + } + + this.promptTemplate += "\n"; + this.promptTemplate += "\n\nHere are the knowledge bases that you can use to solve the customer request:\n"; + this.promptTemplate += "\n"; + + for (const kb of this.knowledgeBases) { + this.promptTemplate += `Knowledge Base ID: ${kb.knowledgeBaseId ?? ''}\n`; + this.promptTemplate += `Knowledge Base Description: ${kb.description ?? ''}\n`; + } + + this.promptTemplate += "\n"; + + if (options.customSystemPrompt) { this.setSystemPrompt( options.customSystemPrompt.template, options.customSystemPrompt.variables ); } + + + } private async inlineAgentToolHandler( response: ConversationMessage, - conversation: ConversationMessage[] + conversation: ConversationMessage[], + sessionId: string ): Promise { const responseContentBlocks = response.content; - + if (!responseContentBlocks) { throw new Error("No content blocks in response"); } @@ -187,51 +222,85 @@ import { const toolUseName = toolUseBlock?.name; if (toolUseName === "inline_agent_creation") { + // Get valid action group names from the tool use input const actionGroupNames = toolUseBlock.input?.action_group_names || []; const kbNames = toolUseBlock.input?.knowledge_bases || ''; const description = toolUseBlock.input?.description || ''; const userRequest = toolUseBlock.input?.user_request || ''; - - // Fetch relevant action groups - const actionGroups = this.actionGroupsList - .filter(item => actionGroupNames.includes(item.actionGroupName)) - .map(item => { - const newItem = { ...item }; - BedrockInlineAgent.KEYS_TO_REMOVE.forEach(key => delete newItem[key]); - if ('parentActionGroupSignature' in newItem) { - delete newItem.description; - } - return newItem; + + if (this.LOG_AGENT_DEBUG_TRACE && this.logger) { + this.logger.info('Tool Handler Parameters:', { + userRequest, + actionGroupNames, + knowledgeBases: kbNames, + description, + sessionId }); + } + + const actionGroups = this.actionGroupsList + .filter(item => actionGroupNames.includes(item.actionGroupName)) // Keep only requested action groups + .map(item => ({ + actionGroupName: item.actionGroupName, + parentActionGroupSignature: item.parentActionGroupSignature, + // Only include description if it's not a child action group + ...(item.parentActionGroupSignature ? {} : { description: item.description }) + })); - // Handle knowledge bases const kbs = kbNames && this.knowledgeBases.length - ? this.knowledgeBases.filter(item => item.knowledgeBaseId === kbNames[0]) - : []; + ? this.knowledgeBases.filter(item => kbNames.includes(item.knowledgeBaseId)) + : []; + + if (this.LOG_AGENT_DEBUG_TRACE && this.logger) { + this.logger.info('Prepared Resources', { + actionGroups, + knowledgeBases: kbs + }); + } + + if (this.LOG_AGENT_DEBUG_TRACE && this.logger) { + this.logger.info('Invoking Inline Agent', { + foundationModel: this.foundationModel, + enableTrace: this.enableTrace, + sessionId + }); + } - const inlineResponse = await this.bedrockAgentClient.invokeInlineAgent({ + const command = new InvokeInlineAgentCommand({ actionGroups, knowledgeBases: kbs, - enableTrace: true, + enableTrace: this.enableTrace, endSession: false, foundationModel: this.foundationModel, inputText: userRequest, instruction: description, - sessionId: 'session-3' + sessionId: sessionId }); - - const eventstream = inlineResponse.completion; - const toolResults: string[] = []; - - for (const event of eventstream || []) { - if ('chunk' in event && event.chunk?.bytes) { - toolResults.push(new TextDecoder().decode(event.chunk.bytes)); + + let completion = ""; + const response = await this.bedrockAgentClient.send(command); + + // Process the response from the Amazon Bedrock agent + if (response.completion === undefined) { + throw new Error("Completion is undefined"); + } + + // Aggregate chunks of response data + for await (const chunkEvent of response.completion) { + if (chunkEvent.chunk) { + const chunk = chunkEvent.chunk; + const decodedResponse = new TextDecoder("utf-8").decode(chunk.bytes); + completion += decodedResponse; + } else if (this.enableTrace) { + // Log chunk event details if tracing is enabled + this.logger ? this.logger.info("Chunk Event Details:", JSON.stringify(chunkEvent, null, 2)) : undefined; } } - + + // Return the completed response as a Message object return { role: ParticipantRole.ASSISTANT, - content: [{ text: toolResults.join('') }] + content: [{ text: completion }], }; } } @@ -259,6 +328,15 @@ import { this.updateSystemPrompt(); + // Log prompt if debug trace is enabled + if (this.LOG_AGENT_DEBUG_TRACE && this.logger) { + this.logger.info('System Prompt', { + promptTemplate: this.promptTemplate, + systemPrompt: this.systemPrompt, + conversation: conversation + }); + } + // Prepare the command to converse with the Bedrock API const converseCmd = { modelId: this.modelId, @@ -266,9 +344,22 @@ import { system: [{ text: this.systemPrompt }], inferenceConfig: this.inferenceConfig, toolConfig: { - tools: this.inlineAgentTool - } + tools: this.inlineAgentTool, + toolChoice: { + tool: { + name: BedrockInlineAgent.TOOL_NAME, + }, + }, + }, }; + + // Log the command if debug trace is enabled + if (this.LOG_AGENT_DEBUG_TRACE && this.logger) { + this.logger.info('Bedrock Command', { + command: converseCmd + }); + } + // Call Bedrock's converse API const command = new ConverseCommand(converseCmd); @@ -284,7 +375,7 @@ import { if (bedrockResponse.content) { // Add null check for (const content of bedrockResponse.content) { if (content && typeof content === 'object' && 'toolUse' in content) { - return await this.toolConfig.useToolHandler(bedrockResponse, conversation); + return await this.toolConfig.useToolHandler(bedrockResponse, conversation, sessionId); } } } @@ -297,7 +388,7 @@ import { ? error.message : 'Unknown error occurred'; - Logger.logger.error("Error processing request with Bedrock:", errorMessage); + this.logger ? this.logger.error("Error processing request with Bedrock:", errorMessage) : undefined; throw new Error(`Error processing request with Bedrock: ${errorMessage}`); } } From c6db424cd1438dcfc004011c33b41043c5f75304 Mon Sep 17 00:00:00 2001 From: Corneliu Croitoru Date: Wed, 27 Nov 2024 14:22:15 +0100 Subject: [PATCH 07/18] cleanup logging --- typescript/src/agents/agent.ts | 16 ++++++ typescript/src/agents/bedrockInlineAgent.ts | 60 ++++++++------------- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/typescript/src/agents/agent.ts b/typescript/src/agents/agent.ts index 50d5b8f4..cb8a82e6 100644 --- a/typescript/src/agents/agent.ts +++ b/typescript/src/agents/agent.ts @@ -121,6 +121,22 @@ export abstract class Agent { return key; } + /** + * Logs debug information with class name and agent name prefix if debug tracing is enabled. + * @param message - The message to log + * @param data - Optional data to include with the log message + */ + protected logDebug(className: string, message: string, data?: any): void { + if (this.LOG_AGENT_DEBUG_TRACE && this.logger) { + const prefix = `> ${className} \n> ${this.name} \n>`; + if (data) { + this.logger.info(`${prefix} ${message} \n>`, data); + } else { + this.logger.info(`${prefix} ${message} \n>`); + } + } + } + /** * Abstract method to process a request. * This method must be implemented by all concrete agent classes. diff --git a/typescript/src/agents/bedrockInlineAgent.ts b/typescript/src/agents/bedrockInlineAgent.ts index 18f1aef5..99f32317 100644 --- a/typescript/src/agents/bedrockInlineAgent.ts +++ b/typescript/src/agents/bedrockInlineAgent.ts @@ -228,15 +228,14 @@ import { const description = toolUseBlock.input?.description || ''; const userRequest = toolUseBlock.input?.user_request || ''; - if (this.LOG_AGENT_DEBUG_TRACE && this.logger) { - this.logger.info('Tool Handler Parameters:', { - userRequest, - actionGroupNames, - knowledgeBases: kbNames, - description, - sessionId - }); - } + + this.logDebug("BedrockInlineAgent", 'Tool Handler Parameters', { + userRequest, + actionGroupNames, + knowledgeBases: kbNames, + description, + sessionId + }); const actionGroups = this.actionGroupsList .filter(item => actionGroupNames.includes(item.actionGroupName)) // Keep only requested action groups @@ -251,20 +250,17 @@ import { ? this.knowledgeBases.filter(item => kbNames.includes(item.knowledgeBaseId)) : []; - if (this.LOG_AGENT_DEBUG_TRACE && this.logger) { - this.logger.info('Prepared Resources', { - actionGroups, - knowledgeBases: kbs - }); - } + this.logDebug("BedrockInlineAgent", 'Action Group & Knowledge Base', { + actionGroups, + knowledgeBases: kbs + }); + + this.logDebug("BedrockInlineAgent", 'Invoking Inline Agent', { + foundationModel: this.foundationModel, + enableTrace: this.enableTrace, + sessionId + }); - if (this.LOG_AGENT_DEBUG_TRACE && this.logger) { - this.logger.info('Invoking Inline Agent', { - foundationModel: this.foundationModel, - enableTrace: this.enableTrace, - sessionId - }); - } const command = new InvokeInlineAgentCommand({ actionGroups, @@ -328,15 +324,9 @@ import { this.updateSystemPrompt(); - // Log prompt if debug trace is enabled - if (this.LOG_AGENT_DEBUG_TRACE && this.logger) { - this.logger.info('System Prompt', { - promptTemplate: this.promptTemplate, - systemPrompt: this.systemPrompt, - conversation: conversation - }); - } - + + this.logDebug("BedrockInlineAgent", 'System Prompt', this.systemPrompt); + // Prepare the command to converse with the Bedrock API const converseCmd = { modelId: this.modelId, @@ -353,12 +343,8 @@ import { }, }; - // Log the command if debug trace is enabled - if (this.LOG_AGENT_DEBUG_TRACE && this.logger) { - this.logger.info('Bedrock Command', { - command: converseCmd - }); - } + + this.logDebug("BedrockInlineAgent", 'Bedrock Command', JSON.stringify(converseCmd)); // Call Bedrock's converse API From 5c61f04ad5e9cb852575fd030df6fec919234fbc Mon Sep 17 00:00:00 2001 From: Anthony Bernabeu <64135631+brnaba-aws@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:28:41 +0100 Subject: [PATCH 08/18] moved inline_agent_bedrock --- python/src/multi_agent_orchestrator/agents/__init__.py | 3 +++ .../multi_agent_orchestrator/agents}/inline_agent_bedrock.py | 0 2 files changed, 3 insertions(+) rename {examples/inline-agents-bedrock => python/src/multi_agent_orchestrator/agents}/inline_agent_bedrock.py (100%) diff --git a/python/src/multi_agent_orchestrator/agents/__init__.py b/python/src/multi_agent_orchestrator/agents/__init__.py index d13be8a5..16b61cfd 100644 --- a/python/src/multi_agent_orchestrator/agents/__init__.py +++ b/python/src/multi_agent_orchestrator/agents/__init__.py @@ -9,6 +9,7 @@ from .comprehend_filter_agent import ComprehendFilterAgent, ComprehendFilterAgentOptions from .chain_agent import ChainAgent, ChainAgentOptions from .bedrock_translator_agent import BedrockTranslatorAgent, BedrockTranslatorAgentOptions +from .inline_agent_bedrock import BedrockInlineAgent, BedrockInlineAgentOptions try: from .anthropic_agent import AnthropicAgent, AnthropicAgentOptions @@ -37,6 +38,8 @@ 'BedrockTranslatorAgentOptions', 'ChainAgent', 'ChainAgentOptions', + 'BedrockInlineAgent', + 'BedrockInlineAgentOptions' ] if _ANTHROPIC_AVAILABLE: diff --git a/examples/inline-agents-bedrock/inline_agent_bedrock.py b/python/src/multi_agent_orchestrator/agents/inline_agent_bedrock.py similarity index 100% rename from examples/inline-agents-bedrock/inline_agent_bedrock.py rename to python/src/multi_agent_orchestrator/agents/inline_agent_bedrock.py From 2fc4c373f3ebdb622defa38bdddf2ca1762acde7 Mon Sep 17 00:00:00 2001 From: Corneliu Croitoru Date: Wed, 27 Nov 2024 14:29:49 +0100 Subject: [PATCH 09/18] increase version --- typescript/package.json | 2 +- typescript/src/agents/bedrockInlineAgent.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/typescript/package.json b/typescript/package.json index f8b981e3..711266c3 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "multi-agent-orchestrator", - "version": "0.0.17", + "version": "0.1.0", "description": "Multi-Agent Orchestrator framework", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/typescript/src/agents/bedrockInlineAgent.ts b/typescript/src/agents/bedrockInlineAgent.ts index 99f32317..26329e5c 100644 --- a/typescript/src/agents/bedrockInlineAgent.ts +++ b/typescript/src/agents/bedrockInlineAgent.ts @@ -12,7 +12,6 @@ import { ParticipantRole, TemplateVariables, } from "../types"; - import { Logger } from "../utils/logger"; export interface BedrockInlineAgentOptions extends AgentOptions { inferenceConfig?: { From b8ac160a635ec9ca0c65f9895b44253eae67d9d9 Mon Sep 17 00:00:00 2001 From: Anthony Bernabeu <64135631+brnaba-aws@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:36:16 +0100 Subject: [PATCH 10/18] updated agent file name, upgraded minimal python version from 1.34.151 to 1.35.0 --- python/setup.cfg | 4 ++-- .../{inline_agent_bedrock.py => bedrock_inline_agent.py} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename python/src/multi_agent_orchestrator/agents/{inline_agent_bedrock.py => bedrock_inline_agent.py} (100%) diff --git a/python/setup.cfg b/python/setup.cfg index 3eb706ba..62208da0 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = multi_agent_orchestrator -version = 0.0.21 +version = 0.1.1 author = Anthony Bernabeu, Corneliu Croitoru author_email = brnaba@amazon.com, ccroito@amazon.com description = Multi-agent orchestrator framework @@ -20,7 +20,7 @@ package_dir = packages = find: python_requires = >=3.11 install_requires = - boto3==1.34.151 + boto3==1.35.0 [options.extras_require] anthropic = diff --git a/python/src/multi_agent_orchestrator/agents/inline_agent_bedrock.py b/python/src/multi_agent_orchestrator/agents/bedrock_inline_agent.py similarity index 100% rename from python/src/multi_agent_orchestrator/agents/inline_agent_bedrock.py rename to python/src/multi_agent_orchestrator/agents/bedrock_inline_agent.py From a2f579e2eeddd902cfe39c5392d666b12598c61b Mon Sep 17 00:00:00 2001 From: Anthony Bernabeu <64135631+brnaba-aws@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:36:35 +0100 Subject: [PATCH 11/18] added code example for bedrock inline agents --- examples/bedrock-inline-agents/python/main.py | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 examples/bedrock-inline-agents/python/main.py diff --git a/examples/bedrock-inline-agents/python/main.py b/examples/bedrock-inline-agents/python/main.py new file mode 100644 index 00000000..3a9504e3 --- /dev/null +++ b/examples/bedrock-inline-agents/python/main.py @@ -0,0 +1,75 @@ +import asyncio +import uuid +import sys +from multi_agent_orchestrator.agents import BedrockInlineAgent, BedrockInlineAgentOptions +import boto3 + +action_groups_list = [ + { + 'actionGroupName': 'CodeInterpreterAction', + 'parentActionGroupSignature': 'AMAZON.CodeInterpreter', + 'description':'Use this to write and execute python code to answer questions and other tasks.' + }, + { + "actionGroupExecutor": { + "lambda": "arn:aws:lambda:region:0123456789012:function:my-function-name" + }, + "actionGroupName": "MyActionGroupName", + "apiSchema": { + "s3": { + "s3BucketName": "bucket-name", + "s3ObjectKey": "openapi-schema.json" + } + }, + "description": "My action group for doing a specific task" + } +] + +knowledge_bases = [ + { + "knowledgeBaseId": "knowledge-base-id-01", + "description": 'This is my knowledge base for documents 01', + }, + { + "knowledgeBaseId": "knowledge-base-id-02", + "description": 'This is my knowledge base for documents 02', + }, + { + "knowledgeBaseId": "knowledge-base-id-0", + "description": 'This is my knowledge base for documents 03', + } +] + +bedrock_inline_agent = BedrockInlineAgent(BedrockInlineAgentOptions( + name="Inline Agent Creator for Agents for Amazon Bedrock", + region='us-east-1', + model_id="anthropic.claude-3-haiku-20240307-v1:0", + description="Specalized in creating Agent to solve customer request dynamically. You are provided with a list of Action groups and Knowledge bases which can help you in answering customer request", + action_groups_list=action_groups_list, + bedrock_agent_client=boto3.client('bedrock-agent-runtime', region_name='us-east-1'), + client=boto3.client('bedrock-runtime', region_name='us-west-2'), + knowledge_bases=knowledge_bases, + enableTrace=True +)) + +async def run_inline_agent(user_input, user_id, session_id): + response = await bedrock_inline_agent.process_request(user_input, user_id, session_id, [], None) + return response + +if __name__ == "__main__": + + session_id = str(uuid.uuid4()) + user_id = str(uuid.uuid4()) + print("Welcome to the interactive Multi-Agent system. Type 'quit' to exit.") + + while True: + # Get user input + user_input = input("\nYou: ").strip() + + if user_input.lower() == 'quit': + print("Exiting the program. Goodbye!") + sys.exit() + + # Run the async function + response = asyncio.run(run_inline_agent(user_input=user_input, user_id=user_id, session_id=session_id)) + print(response.content[0].get('text','No response')) \ No newline at end of file From 8ceb0d6f0465106e4dfc097c98fd0067c5428d73 Mon Sep 17 00:00:00 2001 From: Anthony Bernabeu <64135631+brnaba-aws@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:39:36 +0100 Subject: [PATCH 12/18] fixed import --- python/src/multi_agent_orchestrator/agents/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/src/multi_agent_orchestrator/agents/__init__.py b/python/src/multi_agent_orchestrator/agents/__init__.py index 16b61cfd..975cde56 100644 --- a/python/src/multi_agent_orchestrator/agents/__init__.py +++ b/python/src/multi_agent_orchestrator/agents/__init__.py @@ -9,7 +9,7 @@ from .comprehend_filter_agent import ComprehendFilterAgent, ComprehendFilterAgentOptions from .chain_agent import ChainAgent, ChainAgentOptions from .bedrock_translator_agent import BedrockTranslatorAgent, BedrockTranslatorAgentOptions -from .inline_agent_bedrock import BedrockInlineAgent, BedrockInlineAgentOptions +from .bedrock_inline_agent import BedrockInlineAgent, BedrockInlineAgentOptions try: from .anthropic_agent import AnthropicAgent, AnthropicAgentOptions From c864214c3e2557304cabcfc168733f953a1c73ff Mon Sep 17 00:00:00 2001 From: Corneliu Croitoru Date: Wed, 27 Nov 2024 15:03:34 +0100 Subject: [PATCH 13/18] update doc - add inline agent --- docs/astro.config.mjs | 3 +- .../agents/built-in/bedrock-inline-agent.mdx | 220 ++++++++++++++++++ typescript/src/agents/bedrockInlineAgent.ts | 4 +- 3 files changed, 224 insertions(+), 3 deletions(-) create mode 100644 docs/src/content/docs/agents/built-in/bedrock-inline-agent.mdx diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 8f178b56..9b4b600c 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -69,7 +69,8 @@ export default defineConfig({ { label: 'Anthropic Agent', link: '/agents/built-in/anthropic-agent'}, { label: 'Chain Agent', link: '/agents/built-in/chain-agent' }, { label: 'Comprehend Filter Agent', link: '/agents/built-in/comprehend-filter-agent' }, - { label: 'Amazon Bedrock Translator Agent', link: '/agents/built-in/bedrock-translator-agent' } + { label: 'Amazon Bedrock Translator Agent', link: '/agents/built-in/bedrock-translator-agent' }, + { label: 'Amazon Bedrock Inline Agent', link: '/agents/built-in/bedrock-inline-agent' } ] }, { label: 'Custom Agents', link: '/agents/custom-agents' }, diff --git a/docs/src/content/docs/agents/built-in/bedrock-inline-agent.mdx b/docs/src/content/docs/agents/built-in/bedrock-inline-agent.mdx new file mode 100644 index 00000000..2163609c --- /dev/null +++ b/docs/src/content/docs/agents/built-in/bedrock-inline-agent.mdx @@ -0,0 +1,220 @@ +--- +title: Bedrock Inline Agent +description: Documentation for the BedrockInlineAgent in the Multi-Agent Orchestrator +--- + +## Overview + +The **Bedrock Inline Agent** represents a powerful new approach to dynamic agent creation. At its core, it leverages [Amazon Bedrock's Converse API](https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html) and its tool capabilities to interact with foundation models and orchestrate agent creation. Through a specialized tool, it intelligently analyzes user requests and selects the most relevant action groups and knowledge bases from your available resources. + +Once the optimal [Action Groups](https://docs.aws.amazon.com/bedrock/latest/userguide/agents-action-create.html) and/or [Knowledge Bases](https://aws.amazon.com/bedrock/knowledge-bases/) are identified, the agent uses the [InvokeInlineAgent API](https://docs.aws.amazon.com/bedrock/latest/userguide/agents-create-inline.html) to dynamically create purpose-specific Agents for Amazon Bedrock. This eliminates the need to pre-configure static agent combinations - instead, agents are created on-demand with precisely the capabilities needed for each specific request. + +This architecture removes practical limits on the number of action groups and knowledge bases you can maintain. Whether you have dozens or hundreds of different action groups and knowledge bases, the agent can efficiently select and combine just the ones needed for each query. This enables sophisticated use cases that would be impractical with traditional static agent configurations. + +## Key Features + +- Dynamic agent creation through InvokeInlineAgent API +- Tool-based selection of action groups and knowledge bases +- Support for multiple foundation models +- Customizable inference configuration +- Enhanced debug logging capabilities +- Support for custom logging implementations + +## Creating a BedrockInlineAgent + +### Basic Example + +import { Tabs, TabItem } from '@astrojs/starlight/components'; + + + + ```typescript + import { BedrockInlineAgent } from 'multi-agent-orchestrator'; + import { CustomLogger } from './logger'; + + const actionGroups = [ + { + actionGroupName: "OrderManagement", + description: "Handles order-related operations like status checks and updates" + }, + { + actionGroupName: "InventoryLookup", + description: "Checks product availability and stock levels" + } + ]; + + const knowledgeBases = [ + { + knowledgeBaseId: "KB001", + description: "Product catalog and specifications" + } + ]; + + const agent = new BedrockInlineAgent({ + name: 'Inline Agent Creator for Agents for Amazon Bedrock', + description: 'Specialized in creating Agent to solve customer request dynamically. You are provided with a list of Action groups and Knowledge bases which can help you in answering customer request', + actionGroupsList: actionGroups, + knowledgeBases: knowledgeBases, + region: "us-east-1", + LOG_AGENT_DEBUG_TRACE: true, + inferenceConfig: { + maxTokens: 500, + temperature: 0.5, + topP: 0.9 + } + }); + ``` + + + ```python + from multi_agent_orchestrator.agents import BedrockInlineAgent, BedrockInlineAgentOptions + from custom_logger import CustomLogger + + action_groups = [ + { + "actionGroupName": "OrderManagement", + "description": "Handles order-related operations like status checks and updates" + }, + { + "actionGroupName": "InventoryLookup", + "description": "Checks product availability and stock levels" + } + ] + + knowledge_bases = [ + { + "knowledgeBaseId": "KB001", + "description": "Product catalog and specifications" + } + ] + + agent = BedrockInlineAgent(BedrockInlineAgentOptions( + name='Inline Agent Creator for Agents for Amazon Bedrock', + description='Specialized in creating Agent to solve customer request dynamically. You are provided with a list of Action groups and Knowledge bases which can help you in answering customer request', + action_groups_list=action_groups, + knowledge_bases=knowledge_bases, + region="us-east-1", + LOG_AGENT_DEBUG_TRACE=True, + inference_config={ + 'maxTokens': 500, + 'temperature': 0.5, + 'topP': 0.9 + } + )) + ``` + + + +## Debug Logging + +### LOG_AGENT_DEBUG_TRACE + +When enabled, this flag activates detailed debug logging that helps you understand the agent's operation. Example output: + +```text +> BedrockInlineAgent +> Inline Agent Creator for Agents for Amazon Bedrock +> System Prompt +> You are a Inline Agent Creator for Agents for Amazon Bedrock... + +> BedrockInlineAgent +> Inline Agent Creator for Agents for Amazon Bedrock +> Tool Handler Parameters +> { + userRequest: 'Please execute...', + actionGroupNames: ['CodeInterpreterAction'], + knowledgeBases: [], + description: 'To solve this request...', + sessionId: 'session-456' +} + +> BedrockInlineAgent +> Inline Agent Creator for Agents for Amazon Bedrock +> Action Group & Knowledge Base +> { + actionGroups: [ + { + actionGroupName: 'CodeInterpreterAction', + parentActionGroupSignature: 'AMAZON.CodeInterpreter' + } + ], + knowledgeBases: [] +} +``` + +### Custom Logger Implementation + +You can provide your own logger implementation to customize log formatting and handling. Here's an example: + + + + ```typescript + export class CustomLogger { + private static instance: CustomLogger; + + private constructor() {} + + static getInstance(): CustomLogger { + if (!CustomLogger.instance) { + CustomLogger.instance = new CustomLogger(); + } + return CustomLogger.instance; + } + + info(message: string, ...args: any[]): void { + console.info(">>: " + message, ...args); + } + + warn(message: string, ...args: any[]): void { + console.warn(">>: " + message, ...args); + } + + error(message: string, ...args: any[]): void { + console.error(">>: " + message, ...args); + } + + debug(message: string, ...args: any[]): void { + console.debug(">>: " + message, ...args); + } + + log(message: string, ...args: any[]): void { + console.log(">>: " + message, ...args); + } + } + ``` + + + ```python + class CustomLogger: + _instance = None + + def __new__(cls): + if cls._instance is None: + cls._instance = super(CustomLogger, cls).__new__(cls) + return cls._instance + + @classmethod + def get_instance(cls): + if cls._instance is None: + cls._instance = CustomLogger() + return cls._instance + + def info(self, message: str, *args): + print(f">>: {message}", *args) + + def warn(self, message: str, *args): + print(f">>: [WARNING] {message}", *args) + + def error(self, message: str, *args): + print(f">>: [ERROR] {message}", *args) + + def debug(self, message: str, *args): + print(f">>: [DEBUG] {message}", *args) + + def log(self, message: str, *args): + print(f">>: {message}", *args) + ``` + + + +The BedrockInlineAgent represents a significant advancement in agent flexibility and efficiency, enabling truly dynamic, context-aware responses while optimizing resource usage. \ No newline at end of file diff --git a/typescript/src/agents/bedrockInlineAgent.ts b/typescript/src/agents/bedrockInlineAgent.ts index 26329e5c..2ccea674 100644 --- a/typescript/src/agents/bedrockInlineAgent.ts +++ b/typescript/src/agents/bedrockInlineAgent.ts @@ -25,7 +25,7 @@ import { modelId?: string; foundationModel?: string; region?: string; - actionGroupsList: AgentActionGroup[]; + actionGroupsList?: AgentActionGroup[]; knowledgeBases?: KnowledgeBase[]; enableTrace?: boolean; customSystemPrompt?: { @@ -131,7 +131,7 @@ import { }; // Store action groups and knowledge bases - this.actionGroupsList = options.actionGroupsList; + this.actionGroupsList = options.actionGroupsList ?? []; this.knowledgeBases = options.knowledgeBases ?? []; // Define inline agent tool configuration From 20bc948ef9381f50cdb776e42d04aec4cf0f3c54 Mon Sep 17 00:00:00 2001 From: Anthony Bernabeu <64135631+brnaba-aws@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:06:08 +0100 Subject: [PATCH 14/18] added agent logging option --- python/src/multi_agent_orchestrator/agents/agent.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/python/src/multi_agent_orchestrator/agents/agent.py b/python/src/multi_agent_orchestrator/agents/agent.py index 236dab2b..05d4f16c 100644 --- a/python/src/multi_agent_orchestrator/agents/agent.py +++ b/python/src/multi_agent_orchestrator/agents/agent.py @@ -2,6 +2,7 @@ from abc import ABC, abstractmethod from dataclasses import dataclass, field from multi_agent_orchestrator.types import ConversationMessage +from multi_agent_orchestrator.utils import Logger @dataclass class AgentProcessingResult: @@ -32,6 +33,9 @@ class AgentOptions: region: Optional[str] = None save_chat: bool = True callbacks: Optional[AgentCallbacks] = None + # Optional: Flag to enable/disable agent debug trace logging + # If true, the agent will log additional debug information + LOG_AGENT_DEBUG_TRACE: Optional[bool] = False class Agent(ABC): @@ -41,6 +45,7 @@ def __init__(self, options: AgentOptions): self.description = options.description self.save_chat = options.save_chat self.callbacks = options.callbacks if options.callbacks is not None else AgentCallbacks() + self.LOG_AGENT_DEBUG_TRACE = options.LOG_AGENT_DEBUG_TRACE if options.LOG_AGENT_DEBUG_TRACE is not None else False def is_streaming_enabled(self) -> bool: return False @@ -63,3 +68,11 @@ async def process_request( additional_params: Optional[Dict[str, str]] = None ) -> Union[ConversationMessage, AsyncIterable[any]]: pass + + def log_debug(self, class_name, message, data=None): + if self.LOG_AGENT_DEBUG_TRACE: + prefix = f"> {class_name} \n> {self.name} \n>" + if data: + Logger.info(f"{prefix} {message} \n> {data}") + else: + Logger.info(f"{prefix} {message} \n>") From 0ef3d1ce8c08adfdb41343638ca4ff30d05ef06c Mon Sep 17 00:00:00 2001 From: Anthony Bernabeu <64135631+brnaba-aws@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:06:41 +0100 Subject: [PATCH 15/18] added logging --- .../agents/bedrock_inline_agent.py | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/python/src/multi_agent_orchestrator/agents/bedrock_inline_agent.py b/python/src/multi_agent_orchestrator/agents/bedrock_inline_agent.py index d4853b0a..2540a9b0 100644 --- a/python/src/multi_agent_orchestrator/agents/bedrock_inline_agent.py +++ b/python/src/multi_agent_orchestrator/agents/bedrock_inline_agent.py @@ -1,7 +1,8 @@ from typing import List, Dict, Any, Optional, Callable from dataclasses import dataclass, field -import boto3 +import json import os +import boto3 from multi_agent_orchestrator.utils import conversation_to_dict, Logger from multi_agent_orchestrator.agents import Agent, AgentOptions from multi_agent_orchestrator.types import (ConversationMessage, @@ -17,9 +18,7 @@ class BedrockInlineAgentOptions(AgentOptions): inference_config: Optional[Dict[str, Any]] = None client: Optional[Any] = None bedrock_agent_client: Optional[Any] = None - model_id: Optional[str] = None foundation_model: Optional[str] = None - region: Optional[str] = None action_groups_list: List[Dict[str, Any]] = field(default_factory=list) knowledge_bases: Optional[List[Dict[str, Any]]] = None custom_system_prompt: Optional[Dict[str, Any]] = None @@ -181,12 +180,22 @@ async def inline_agent_tool_handler(self, session_id, response, conversation): tool_use_block = content_block["toolUse"] tool_use_name = tool_use_block.get("name") if tool_use_name == "inline_agent_creation": + action_group_names = tool_use_block["input"].get('action_group_names', []) kb_names = tool_use_block["input"].get('knowledge_bases','') description = tool_use_block["input"].get('description', '') user_request = tool_use_block["input"].get('user_request', '') + self.log_debug("BedrockInlineAgent", 'Tool Handler Parameters', { + 'user_request':user_request, + 'action_group_names':action_group_names, + 'kb_names':kb_names, + 'description':description, + 'session_id':session_id + }) + + # Fetch relevant action groups action_groups = [ item for item in self.action_groups_list @@ -203,13 +212,17 @@ async def inline_agent_tool_handler(self, session_id, response, conversation): kbs = [item for item in self.knowledge_bases if item.get('knowledgeBaseId') in kb_names] - Logger.info(f"Calling Agents for Bedrock with:\n") - Logger.info(f"user input:{user_request}") - Logger.info(f"Action Groups: {action_groups}\n") - Logger.info(f"Knowledge Bases: {kbs}\n") - Logger.info(f"Description: {description}\n") + self.log_debug("BedrockInlineAgent", 'Action Group & Knowledge Base', { + 'action_groups':action_groups, + 'kbs':kbs + }) + + self.log_debug("BedrockInlineAgent", 'Invoking Inline Agent', { + 'foundationModel': self.foundation_model, + 'enableTrace': self.enableTrace, + 'sessionId':session_id + }) - import uuid inline_response = self.bedrock_agent_client.invoke_inline_agent( actionGroups=action_groups, knowledgeBases=kbs, @@ -258,6 +271,8 @@ async def process_request( self.update_system_prompt() + self.log_debug("BedrockInlineAgent", 'System Prompt', self.system_prompt) + system_prompt = self.system_prompt converse_cmd = { From d67a56ef8a372da2eb1bbc478799abb1dc42ee13 Mon Sep 17 00:00:00 2001 From: Corneliu Croitoru Date: Wed, 27 Nov 2024 15:30:12 +0100 Subject: [PATCH 16/18] add ts sample for bedrock inline agent --- .../bedrock-inline-agents/typescript/main.ts | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 examples/bedrock-inline-agents/typescript/main.ts diff --git a/examples/bedrock-inline-agents/typescript/main.ts b/examples/bedrock-inline-agents/typescript/main.ts new file mode 100644 index 00000000..c05504d6 --- /dev/null +++ b/examples/bedrock-inline-agents/typescript/main.ts @@ -0,0 +1,116 @@ +//import { BedrockInlineAgent, BedrockInlineAgentOptions } from 'multi-agent-orchestrator'; +import { BedrockInlineAgent, BedrockInlineAgentOptions } from '../../../typescript/src/agents/bedrockInlineAgent'; +import { + BedrockAgentRuntimeClient, + AgentActionGroup, + KnowledgeBase +} from "@aws-sdk/client-bedrock-agent-runtime"; +import { BedrockRuntimeClient } from "@aws-sdk/client-bedrock-runtime"; +import { v4 as uuidv4 } from 'uuid'; +import { createInterface } from 'readline'; + +// Define action groups +const actionGroupsList: AgentActionGroup[] = [ + { + actionGroupName: 'CodeInterpreterAction', + parentActionGroupSignature: 'AMAZON.CodeInterpreter', + description: 'Use this to write and execute python code to answer questions and other tasks.' + }, + { + actionGroupExecutor: { + lambda: "arn:aws:lambda:region:0123456789012:function:my-function-name" + }, + actionGroupName: "MyActionGroupName", + apiSchema: { + s3: { + s3BucketName: "bucket-name", + s3ObjectKey: "openapi-schema.json" + } + }, + description: "My action group for doing a specific task" + } +]; + +// Define knowledge bases +const knowledgeBases: KnowledgeBase[] = [ + { + knowledgeBaseId: "knowledge-base-id-01", + description: 'This is my knowledge base for documents 01', + }, + { + knowledgeBaseId: "knowledge-base-id-02", + description: 'This is my knowledge base for documents 02', + }, + { + knowledgeBaseId: "knowledge-base-id-03", + description: 'This is my knowledge base for documents 03', + } +]; + + +// Initialize BedrockInlineAgent +const bedrickInlineAgent = new BedrockInlineAgent({ + name: "Inline Agent Creator for Agents for Amazon Bedrock", + region: 'us-east-1', + modelId: "anthropic.claude-3-haiku-20240307-v1:0", + description: "Specialized in creating Agent to solve customer request dynamically. You are provided with a list of Action groups and Knowledge bases which can help you in answering customer request", + actionGroupsList: actionGroupsList, + knowledgeBases: knowledgeBases, + LOG_AGENT_DEBUG_TRACE: true +}); + +async function runInlineAgent(userInput: string, userId: string, sessionId: string) { + const response = await bedrickInlineAgent.processRequest( + userInput, + userId, + sessionId, + [], // empty chat history + undefined // no additional params + ); + return response; +} + +async function main() { + const sessionId = uuidv4(); + const userId = uuidv4(); + + console.log("Welcome to the interactive Multi-Agent system. Type 'quit' to exit."); + + const readline = createInterface({ + input: process.stdin, + output: process.stdout + }); + + const getUserInput = () => { + return new Promise((resolve) => { + readline.question('\nYou: ', (input) => { + resolve(input.trim()); + }); + }); + }; + + while (true) { + const userInput = await getUserInput() as string; + + if (userInput.toLowerCase() === 'quit') { + console.log("Exiting the program. Goodbye!"); + readline.close(); + process.exit(0); + } + + try { + const response = await runInlineAgent(userInput, userId, sessionId); + if (response && response.content && response.content.length > 0) { + const text = response.content[0]?.text; + console.log(text || 'No response content'); + } else { + console.log('No response'); + } + } catch (error) { + console.error('Error:', error); + } + } +} + +// Run the program +main().catch(console.error); \ No newline at end of file From 988d57a53d290bfd7fade5020d9d6e6091c36e68 Mon Sep 17 00:00:00 2001 From: Corneliu Croitoru Date: Wed, 27 Nov 2024 15:34:25 +0100 Subject: [PATCH 17/18] update doc --- README.md | 1 + .../content/docs/agents/built-in/bedrock-inline-agent.mdx | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/README.md b/README.md index ac9068a7..d817a865 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ Get hands-on experience with the Multi-Agent Orchestrator through our diverse se - [`chat-chainlit-app`](https://github.com/awslabs/multi-agent-orchestrator/tree/main/examples/chat-chainlit-app): Chat application built with Chainlit - [`fast-api-streaming`](https://github.com/awslabs/multi-agent-orchestrator/tree/main/examples/fast-api-streaming): FastAPI implementation with streaming support - [`text-2-structured-output`](https://github.com/awslabs/multi-agent-orchestrator/tree/main/examples/text-2-structured-output): Natural Language to Structured Data + - [`bedrock-inline-agents`](https://github.com/awslabs/multi-agent-orchestrator/tree/main/examples/bedrock-inline-agents): Bedrock Inline Agents sample All examples are available in both Python and TypeScript implementations. Check out our [documentation](https://awslabs.github.io/multi-agent-orchestrator/) for comprehensive guides on setting up and using the Multi-Agent Orchestrator! diff --git a/docs/src/content/docs/agents/built-in/bedrock-inline-agent.mdx b/docs/src/content/docs/agents/built-in/bedrock-inline-agent.mdx index 2163609c..e07e57e9 100644 --- a/docs/src/content/docs/agents/built-in/bedrock-inline-agent.mdx +++ b/docs/src/content/docs/agents/built-in/bedrock-inline-agent.mdx @@ -217,4 +217,12 @@ You can provide your own logger implementation to customize log formatting and h +## Sample Code + +You can find sample code for using the BedrockInlineAgent in both TypeScript and Python: + +- [TypeScript Sample](https://github.com/awslabs/multi-agent-orchestrator/tree/main/examples/bedrock-inline-agents/typescript) +- [Python Sample](https://github.com/awslabs/multi-agent-orchestrator/tree/main/examples/bedrock-inline-agents/python) + + The BedrockInlineAgent represents a significant advancement in agent flexibility and efficiency, enabling truly dynamic, context-aware responses while optimizing resource usage. \ No newline at end of file From 0459b8c666b7f5298810183adde7959b3ec14b6a Mon Sep 17 00:00:00 2001 From: Anthony Bernabeu <64135631+brnaba-aws@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:37:24 +0100 Subject: [PATCH 18/18] fixed ts lint --- typescript/src/agents/bedrockInlineAgent.ts | 84 ++++++++++----------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/typescript/src/agents/bedrockInlineAgent.ts b/typescript/src/agents/bedrockInlineAgent.ts index 2ccea674..bb7649ea 100644 --- a/typescript/src/agents/bedrockInlineAgent.ts +++ b/typescript/src/agents/bedrockInlineAgent.ts @@ -12,7 +12,7 @@ import { ParticipantRole, TemplateVariables, } from "../types"; - + export interface BedrockInlineAgentOptions extends AgentOptions { inferenceConfig?: { maxTokens?: number; @@ -34,7 +34,7 @@ import { }; } - + export class BedrockInlineAgent extends Agent { /** Class-level constants */ protected static readonly TOOL_INPUT_SCHEMA = { @@ -63,7 +63,7 @@ import { required: ["action_group_names", "description", "user_request"] } }; - + protected static readonly KEYS_TO_REMOVE = [ 'actionGroupId', 'actionGroupState', @@ -72,7 +72,7 @@ import { ]; protected static readonly TOOL_NAME = "inline_agent_creation"; - + /** Protected class members */ protected client: BedrockRuntimeClient; protected bedrockAgentClient: BedrockAgentRuntimeClient; @@ -93,14 +93,14 @@ import { useToolHandler: (response: ConversationMessage, conversation: ConversationMessage[], sessionId: string) => Promise; toolMaxRecursions: number; }; - + private promptTemplate: string; private systemPrompt: string = ''; private customVariables: TemplateVariables = {}; constructor(options: BedrockInlineAgentOptions) { super(options); - + // Initialize clients @@ -109,18 +109,18 @@ import { ? new BedrockRuntimeClient({ region: options.region }) : new BedrockRuntimeClient() ); - + this.bedrockAgentClient = options.bedrockAgentClient ?? ( options.region ? new BedrockAgentRuntimeClient({ region: options.region }) : new BedrockAgentRuntimeClient() ); - + // Set model IDs this.modelId = options.modelId ?? BEDROCK_MODEL_ID_CLAUDE_3_HAIKU; this.foundationModel = options.foundationModel ?? BEDROCK_MODEL_ID_CLAUDE_3_SONNET; - - this.enableTrace = options.enableTrace ?? false; + + this.enableTrace = options.enableTrace ?? false; // Set inference configuration this.inferenceConfig = options.inferenceConfig ?? { @@ -129,11 +129,11 @@ import { topP: 0.9, stopSequences: [] }; - + // Store action groups and knowledge bases this.actionGroupsList = options.actionGroupsList ?? []; this.knowledgeBases = options.knowledgeBases ?? []; - + // Define inline agent tool configuration this.inlineAgentTool = [{ toolSpec: { @@ -142,14 +142,14 @@ import { inputSchema: BedrockInlineAgent.TOOL_INPUT_SCHEMA } }]; - + // Configure tool usage this.toolConfig = { tool: this.inlineAgentTool, useToolHandler: this.inlineAgentToolHandler.bind(this), - toolMaxRecursions: 1 + toolMaxRecursions: 1 }; - + // Set prompt template this.promptTemplate = `You are a ${this.name}. ${this.description} @@ -178,7 +178,7 @@ import { for (const actionGroup of this.actionGroupsList) { this.promptTemplate += `Action Group Name: ${actionGroup.actionGroupName ?? ''}\n`; this.promptTemplate += `Action Group Description: ${actionGroup.description ?? ''}\n`; - + } this.promptTemplate += "\n"; @@ -190,7 +190,7 @@ import { this.promptTemplate += `Knowledge Base Description: ${kb.description ?? ''}\n`; } - this.promptTemplate += "\n"; + this.promptTemplate += "\n"; if (options.customSystemPrompt) { @@ -200,26 +200,26 @@ import { ); } - + } - + private async inlineAgentToolHandler( response: ConversationMessage, conversation: ConversationMessage[], - sessionId: string + sessionId: string ): Promise { const responseContentBlocks = response.content; if (!responseContentBlocks) { throw new Error("No content blocks in response"); } - + for (const contentBlock of responseContentBlocks) { if ("toolUse" in contentBlock) { const toolUseBlock = contentBlock.toolUse; const toolUseName = toolUseBlock?.name; - + if (toolUseName === "inline_agent_creation") { // Get valid action group names from the tool use input const actionGroupNames = toolUseBlock.input?.action_group_names || []; @@ -244,7 +244,7 @@ import { // Only include description if it's not a child action group ...(item.parentActionGroupSignature ? {} : { description: item.description }) })); - + const kbs = kbNames && this.knowledgeBases.length ? this.knowledgeBases.filter(item => kbNames.includes(item.knowledgeBaseId)) : []; @@ -260,7 +260,7 @@ import { sessionId }); - + const command = new InvokeInlineAgentCommand({ actionGroups, knowledgeBases: kbs, @@ -300,16 +300,16 @@ import { } } } - + throw new Error("Tool use block not handled"); } - + async processRequest( inputText: string, userId: string, sessionId: string, chatHistory: ConversationMessage[], - additionalParams?: Record + _additionalParams?: Record ): Promise { try { // Construct the user's message @@ -317,12 +317,12 @@ import { role: ParticipantRole.USER, content: [{ text: inputText }] }; - + // Combine chat history with current message const conversation: ConversationMessage[] = [...chatHistory, userMessage]; - + this.updateSystemPrompt(); - + this.logDebug("BedrockInlineAgent", 'System Prompt', this.systemPrompt); @@ -345,17 +345,17 @@ import { this.logDebug("BedrockInlineAgent", 'Bedrock Command', JSON.stringify(converseCmd)); - + // Call Bedrock's converse API const command = new ConverseCommand(converseCmd); const response = await this.client.send(command); - + if (!response.output) { throw new Error("No output received from Bedrock model"); } - + const bedrockResponse = response.output.message as ConversationMessage; - + // Check if tool use is required if (bedrockResponse.content) { // Add null check for (const content of bedrockResponse.content) { @@ -364,20 +364,20 @@ import { } } } - + return bedrockResponse; - + } catch (error: unknown) { // Explicitly type error as unknown // Handle error with proper type checking - const errorMessage = error instanceof Error - ? error.message + const errorMessage = error instanceof Error + ? error.message : 'Unknown error occurred'; - + this.logger ? this.logger.error("Error processing request with Bedrock:", errorMessage) : undefined; throw new Error(`Error processing request with Bedrock: ${errorMessage}`); } } - + setSystemPrompt(template?: string, variables?: TemplateVariables): void { if (template) { this.promptTemplate = template; @@ -387,14 +387,14 @@ import { } this.updateSystemPrompt(); } - + private updateSystemPrompt(): void { const allVariables: TemplateVariables = { ...this.customVariables }; this.systemPrompt = this.replaceplaceholders(this.promptTemplate, allVariables); } - + private replaceplaceholders(template: string, variables: TemplateVariables): string { return template.replace(/{{(\w+)}}/g, (match, key) => { if (key in variables) {