diff --git a/backend/app/repositories/custom_bot.py b/backend/app/repositories/custom_bot.py index e06b663b6..8909936b9 100644 --- a/backend/app/repositories/custom_bot.py +++ b/backend/app/repositories/custom_bot.py @@ -21,6 +21,7 @@ decompose_bot_id, ) from app.repositories.models.custom_bot import ( + ActiveModelsModel, AgentModel, BotAliasModel, BotMeta, @@ -88,6 +89,7 @@ def store_bot(user_id: str, custom_bot: BotModel): "ConversationQuickStarters": [ starter.model_dump() for starter in custom_bot.conversation_quick_starters ], + "ActiveModels": custom_bot.active_models.model_dump(), # type: ignore[attr-defined] } if custom_bot.bedrock_knowledge_base: item["BedrockKnowledgeBase"] = custom_bot.bedrock_knowledge_base.model_dump() @@ -110,6 +112,7 @@ def update_bot( sync_status: type_sync_status, sync_status_reason: str, display_retrieved_chunks: bool, + active_models: ActiveModelsModel, # type: ignore conversation_quick_starters: list[ConversationQuickStarterModel], bedrock_knowledge_base: BedrockKnowledgeBaseModel | None = None, bedrock_guardrails: BedrockGuardrailsModel | None = None, @@ -130,7 +133,8 @@ def update_bot( "SyncStatusReason = :sync_status_reason, " "GenerationParams = :generation_params, " "DisplayRetrievedChunks = :display_retrieved_chunks, " - "ConversationQuickStarters = :conversation_quick_starters" + "ConversationQuickStarters = :conversation_quick_starters, " + "ActiveModels = :active_models" ) expression_attribute_values = { @@ -146,6 +150,7 @@ def update_bot( ":conversation_quick_starters": [ starter.model_dump() for starter in conversation_quick_starters ], + ":active_models": active_models.model_dump(), # type: ignore[attr-defined] } if bedrock_knowledge_base: update_expression += ", BedrockKnowledgeBase = :bedrock_knowledge_base" @@ -195,6 +200,7 @@ def store_alias(user_id: str, alias: BotAliasModel): "ConversationQuickStarters": [ starter.model_dump() for starter in alias.conversation_quick_starters ], + "ActiveModels": alias.active_models.model_dump(), # type: ignore[attr-defined] } response = table.put_item(Item=item) @@ -484,6 +490,7 @@ def find_private_bot_by_id(user_id: str, bot_id: str) -> BotModel: if "GuardrailsParams" in item else None ), + active_models=ActiveModelsModel.model_validate(item.get("ActiveModels", {})), ) logger.info(f"Found bot: {bot}") @@ -502,6 +509,7 @@ def find_public_bot_by_id(bot_id: str) -> BotModel: raise RecordNotFoundError(f"Public bot with id {bot_id} not found") item = response["Items"][0] + bot = BotModel( id=decompose_bot_id(item["SK"]), title=item["Title"], @@ -560,6 +568,7 @@ def find_public_bot_by_id(bot_id: str) -> BotModel: if "GuardrailsParams" in item else None ), + active_models=ActiveModelsModel.model_validate(item.get("ActiveModels")), ) logger.info(f"Found public bot: {bot}") return bot @@ -589,6 +598,7 @@ def find_alias_by_id(user_id: str, alias_id: str) -> BotAliasModel: has_knowledge=item["HasKnowledge"], has_agent=item.get("HasAgent", False), conversation_quick_starters=item.get("ConversationQuickStarters", []), + active_models=ActiveModelsModel.model_validate(item.get("ActiveModels")), ) logger.info(f"Found alias: {bot}") diff --git a/backend/app/repositories/models/common.py b/backend/app/repositories/models/common.py index 7e5f3bd4d..448f7dca5 100644 --- a/backend/app/repositories/models/common.py +++ b/backend/app/repositories/models/common.py @@ -1,9 +1,10 @@ import base64 from decimal import Decimal +from typing import Annotated, Any, Dict, List, Type, get_args +from pydantic import BaseModel, ConfigDict from pydantic.functional_serializers import PlainSerializer from pydantic.functional_validators import PlainValidator -from typing import Annotated, Any # Declare customized float type Float = Annotated[ @@ -35,3 +36,7 @@ def decode_base64_string(value: Any) -> bytes: return_type=str, ), ] + + +class DynamicBaseModel(BaseModel): + model_config = ConfigDict(extra="allow") diff --git a/backend/app/repositories/models/conversation.py b/backend/app/repositories/models/conversation.py index 2779e40da..5627f7df2 100644 --- a/backend/app/repositories/models/conversation.py +++ b/backend/app/repositories/models/conversation.py @@ -1,44 +1,40 @@ from __future__ import annotations -from typing import Literal, Any, Annotated, Self, TypedDict, TypeGuard -from pathlib import Path import re +from pathlib import Path +from typing import Annotated, Any, Literal, Self, TypedDict, TypeGuard from urllib.parse import urlparse from app.repositories.models.common import Base64EncodedBytes from app.routes.schemas.conversation import ( - SimpleMessage, - MessageInput, - type_model_name, + AttachmentContent, Content, - TextContent, + DocumentToolResult, ImageContent, - AttachmentContent, - ToolUseContent, - ToolUseContentBody, - ToolResult, - TextToolResult, - JsonToolResult, ImageToolResult, - DocumentToolResult, - ToolResultContentBody, - ToolResultContent, + JsonToolResult, + MessageInput, RelatedDocument, + SimpleMessage, + TextContent, + TextToolResult, + ToolResult, + ToolResultContent, + ToolResultContentBody, + ToolUseContent, + ToolUseContentBody, + type_model_name, ) from app.utils import generate_presigned_url - -from pydantic import BaseModel, Field, field_validator, Discriminator, JsonValue +from mypy_boto3_bedrock_runtime.literals import DocumentFormatType, ImageFormatType from mypy_boto3_bedrock_runtime.type_defs import ( ContentBlockTypeDef, - ToolUseBlockTypeDef, - ToolUseBlockOutputTypeDef, ToolResultBlockTypeDef, ToolResultContentBlockOutputTypeDef, + ToolUseBlockOutputTypeDef, + ToolUseBlockTypeDef, ) -from mypy_boto3_bedrock_runtime.literals import ( - DocumentFormatType, - ImageFormatType, -) +from pydantic import BaseModel, Discriminator, Field, JsonValue, field_validator class TextContentModel(BaseModel): diff --git a/backend/app/repositories/models/custom_bot.py b/backend/app/repositories/models/custom_bot.py index c0361419e..b159b6aed 100644 --- a/backend/app/repositories/models/custom_bot.py +++ b/backend/app/repositories/models/custom_bot.py @@ -1,8 +1,23 @@ -from app.repositories.models.common import Float +from typing import Any, Dict, List, Literal, Type, get_args + +from app.repositories.models.common import DynamicBaseModel, Float from app.repositories.models.custom_bot_guardrails import BedrockGuardrailsModel from app.repositories.models.custom_bot_kb import BedrockKnowledgeBaseModel from app.routes.schemas.bot import type_sync_status -from pydantic import BaseModel +from app.routes.schemas.conversation import type_model_name +from pydantic import BaseModel, ConfigDict, create_model + + +def _create_model_activate_model(model_names: List[str]) -> Type[DynamicBaseModel]: + fields: Dict[str, Any] = { + name.replace("-", "_").replace(".", "_"): (bool, True) for name in model_names + } + return create_model("ActiveModelsModel", __base__=DynamicBaseModel, **fields) + + +ActiveModelsModel: Type[BaseModel] = _create_model_activate_model( + list(get_args(type_model_name)) +) class KnowledgeModel(BaseModel): @@ -78,6 +93,7 @@ class BotModel(BaseModel): conversation_quick_starters: list[ConversationQuickStarterModel] bedrock_knowledge_base: BedrockKnowledgeBaseModel | None bedrock_guardrails: BedrockGuardrailsModel | None + active_models: ActiveModelsModel # type: ignore def has_knowledge(self) -> bool: return ( @@ -91,7 +107,10 @@ def is_agent_enabled(self) -> bool: return len(self.agent.tools) > 0 def has_bedrock_knowledge_base(self) -> bool: - return self.bedrock_knowledge_base is not None + return ( + self.bedrock_knowledge_base is not None + and self.bedrock_knowledge_base.knowledge_base_id is not None + ) class BotAliasModel(BaseModel): @@ -106,6 +125,7 @@ class BotAliasModel(BaseModel): has_knowledge: bool has_agent: bool conversation_quick_starters: list[ConversationQuickStarterModel] + active_models: ActiveModelsModel # type: ignore class BotMeta(BaseModel): diff --git a/backend/app/routes/bot.py b/backend/app/routes/bot.py index 8da7c3227..b6b60b30a 100644 --- a/backend/app/routes/bot.py +++ b/backend/app/routes/bot.py @@ -1,4 +1,4 @@ -from typing import Literal +from typing import Any, Dict, Literal from app.dependencies import check_creating_bot_allowed from app.repositories.custom_bot import ( @@ -7,6 +7,7 @@ update_bot_visibility, ) from app.routes.schemas.bot import ( + ActiveModelsOutput, Agent, AgentTool, BedrockGuardrailsOutput, @@ -23,6 +24,7 @@ GenerationParams, Knowledge, ) +from app.routes.schemas.conversation import type_model_name from app.usecases.bot import ( create_new_bot, fetch_all_bots, @@ -152,6 +154,7 @@ def get_private_bot(request: Request, bot_id: str): if bot.bedrock_guardrails else None ), + active_models=ActiveModelsOutput.model_validate(dict(bot.active_models)), ) return output diff --git a/backend/app/routes/schemas/bot.py b/backend/app/routes/schemas/bot.py index 26f2a7a54..a267859f0 100644 --- a/backend/app/routes/schemas/bot.py +++ b/backend/app/routes/schemas/bot.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Literal, Optional +from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Type, get_args from app.routes.schemas.base import BaseSchema from app.routes.schemas.bot_guardrails import ( @@ -11,7 +11,8 @@ BedrockKnowledgeBaseInput, BedrockKnowledgeBaseOutput, ) -from pydantic import Field, root_validator, validator +from app.routes.schemas.conversation import type_model_name +from pydantic import Field, create_model, validator if TYPE_CHECKING: from app.repositories.models.custom_bot import BotModel @@ -28,6 +29,26 @@ ] +def _create_model_activate_input(model_names: List[str]) -> Type[BaseSchema]: + fields: Dict[str, Any] = { + name.replace("-", "_").replace(".", "_"): (bool, True) for name in model_names + } + return create_model("ActiveModelsInput", **fields, __base__=BaseSchema) + + +ActiveModelsInput = _create_model_activate_input(list(get_args(type_model_name))) + + +def create_model_activate_output(model_names: List[str]) -> Type[BaseSchema]: + fields: Dict[str, Any] = { + name.replace("-", "_").replace(".", "_"): (bool, True) for name in model_names + } + return create_model("ActiveModelsOutput", **fields, __base__=BaseSchema) + + +ActiveModelsOutput = create_model_activate_output(list(get_args(type_model_name))) + + class GenerationParams(BaseSchema): max_tokens: int top_k: int @@ -102,6 +123,7 @@ class BotInput(BaseSchema): conversation_quick_starters: list[ConversationQuickStarter] | None bedrock_knowledge_base: BedrockKnowledgeBaseInput | None = None bedrock_guardrails: BedrockGuardrailsInput | None = None + active_models: ActiveModelsInput # type: ignore class BotModifyInput(BaseSchema): @@ -115,6 +137,7 @@ class BotModifyInput(BaseSchema): conversation_quick_starters: list[ConversationQuickStarter] | None bedrock_knowledge_base: BedrockKnowledgeBaseInput | None = None bedrock_guardrails: BedrockGuardrailsInput | None = None + active_models: ActiveModelsInput # type: ignore def _has_update_files(self) -> bool: return self.knowledge is not None and ( @@ -228,6 +251,7 @@ class BotModifyOutput(BaseSchema): conversation_quick_starters: list[ConversationQuickStarter] bedrock_knowledge_base: BedrockKnowledgeBaseOutput | None bedrock_guardrails: BedrockGuardrailsOutput | None + active_models: ActiveModelsOutput # type: ignore class BotOutput(BaseSchema): @@ -251,6 +275,7 @@ class BotOutput(BaseSchema): conversation_quick_starters: list[ConversationQuickStarter] bedrock_knowledge_base: BedrockKnowledgeBaseOutput | None bedrock_guardrails: BedrockGuardrailsOutput | None + active_models: ActiveModelsOutput # type: ignore class BotMetaOutput(BaseSchema): @@ -281,6 +306,7 @@ class BotSummaryOutput(BaseSchema): sync_status: type_sync_status has_knowledge: bool conversation_quick_starters: list[ConversationQuickStarter] + active_models: ActiveModelsOutput # type: ignore class BotSwitchVisibilityInput(BaseSchema): diff --git a/backend/app/routes/schemas/conversation.py b/backend/app/routes/schemas/conversation.py index 552c1755e..3e57fccfd 100644 --- a/backend/app/routes/schemas/conversation.py +++ b/backend/app/routes/schemas/conversation.py @@ -1,13 +1,9 @@ -from typing import Literal, Annotated +from typing import Annotated, Literal -from app.routes.schemas.base import BaseSchema from app.repositories.models.common import Base64EncodedBytes -from pydantic import Field, Discriminator, JsonValue, root_validator - -from mypy_boto3_bedrock_runtime.literals import ( - DocumentFormatType, - ImageFormatType, -) +from app.routes.schemas.base import BaseSchema +from mypy_boto3_bedrock_runtime.literals import DocumentFormatType, ImageFormatType +from pydantic import Discriminator, Field, JsonValue, root_validator type_model_name = Literal[ "claude-instant-v1", diff --git a/backend/app/usecases/bot.py b/backend/app/usecases/bot.py index 25079d25c..95a994219 100644 --- a/backend/app/usecases/bot.py +++ b/backend/app/usecases/bot.py @@ -28,6 +28,7 @@ update_bot_pin_status, ) from app.repositories.models.custom_bot import ( + ActiveModelsModel, AgentModel, AgentToolModel, BotAliasModel, @@ -40,6 +41,8 @@ from app.repositories.models.custom_bot_guardrails import BedrockGuardrailsModel from app.repositories.models.custom_bot_kb import BedrockKnowledgeBaseModel from app.routes.schemas.bot import ( + ActiveModelsInput, + ActiveModelsOutput, Agent, AgentTool, BotInput, @@ -210,6 +213,9 @@ def create_new_bot(user_id: str, bot_input: BotInput) -> BotOutput: if bot_input.bedrock_guardrails else None ), + active_models=ActiveModelsModel.model_validate( + dict(bot_input.active_models) + ), ), ) return BotOutput( @@ -262,6 +268,7 @@ def create_new_bot(user_id: str, bot_input: BotInput) -> BotOutput: if bot_input.bedrock_guardrails else None ), + active_models=ActiveModelsOutput.model_validate(dict(bot_input.active_models)), ) @@ -374,6 +381,9 @@ def modify_owned_bot( if modify_input.bedrock_guardrails else None ), + active_models=ActiveModelsOutput.model_validate( + dict(modify_input.active_models) + ), ) return BotModifyOutput( @@ -417,6 +427,9 @@ def modify_owned_bot( if modify_input.bedrock_guardrails else None ), + active_models=ActiveModelsOutput.model_validate( + dict(modify_input.active_models) + ), ) @@ -518,6 +531,7 @@ def fetch_all_bots_by_user_id( ConversationQuickStarter(**starter) for starter in item.get("ConversationQuickStarters", []) ] + or bot.active_models != item["ActiveModels"] ): # Update alias to the latest original bot store_alias( @@ -535,6 +549,9 @@ def fetch_all_bots_by_user_id( has_knowledge=bot.has_knowledge(), has_agent=bot.is_agent_enabled(), conversation_quick_starters=bot.conversation_quick_starters, + active_models=ActiveModelsModel.model_validate( + dict(bot.active_models) + ), ), ) @@ -631,6 +648,7 @@ def fetch_bot_summary(user_id: str, bot_id: str) -> BotSummaryOutput: ) for starter in bot.conversation_quick_starters ], + active_models=ActiveModelsOutput.model_validate(dict(bot.active_models)), ) except RecordNotFoundError: @@ -638,6 +656,10 @@ def fetch_bot_summary(user_id: str, bot_id: str) -> BotSummaryOutput: try: alias = find_alias_by_id(user_id, bot_id) + + # update bot model activate if alias is found. + bot = find_public_bot_by_id(bot_id) + return BotSummaryOutput( id=alias.id, title=alias.title, @@ -661,6 +683,7 @@ def fetch_bot_summary(user_id: str, bot_id: str) -> BotSummaryOutput: for starter in alias.conversation_quick_starters ] ), + active_models=ActiveModelsOutput.model_validate(dict(alias.active_models)), ) except RecordNotFoundError: pass @@ -690,6 +713,9 @@ def fetch_bot_summary(user_id: str, bot_id: str) -> BotSummaryOutput: ) for starter in bot.conversation_quick_starters ], + active_models=ActiveModelsOutput.model_validate( + dict(bot.active_models) + ), ), ) return BotSummaryOutput( @@ -711,6 +737,7 @@ def fetch_bot_summary(user_id: str, bot_id: str) -> BotSummaryOutput: ) for starter in bot.conversation_quick_starters ], + active_models=ActiveModelsOutput.model_validate(dict(bot.active_models)), ) except RecordNotFoundError: raise RecordNotFoundError( diff --git a/backend/app/usecases/chat.py b/backend/app/usecases/chat.py index ef810b925..44d7808db 100644 --- a/backend/app/usecases/chat.py +++ b/backend/app/usecases/chat.py @@ -7,11 +7,8 @@ ) from app.agents.tools.knowledge import create_knowledge_tool from app.agents.utils import get_tool_by_name -from app.bedrock import ( - call_converse_api, - compose_args_for_converse_api, -) -from app.prompt import build_rag_prompt, PROMPT_TO_CITE_TOOL_RESULTS +from app.bedrock import call_converse_api, compose_args_for_converse_api +from app.prompt import PROMPT_TO_CITE_TOOL_RESULTS, build_rag_prompt from app.repositories.conversation import ( RecordNotFoundError, find_conversation_by_id, @@ -20,13 +17,13 @@ ) from app.repositories.custom_bot import find_alias_by_id, store_alias from app.repositories.models.conversation import ( - SimpleMessageModel, ConversationModel, MessageModel, RelatedDocumentModel, + SimpleMessageModel, TextContentModel, - ToolUseContentModel, ToolResultContentModel, + ToolUseContentModel, ) from app.repositories.models.custom_bot import ( BotAliasModel, @@ -47,8 +44,8 @@ from app.utils import get_current_time from app.vector_search import ( SearchResult, - search_result_to_related_document, search_related_docs, + search_result_to_related_document, to_guardrails_grounding_source, ) from ulid import ULID @@ -159,6 +156,7 @@ def prepare_conversation( for starter in bot.conversation_quick_starters ] ), + active_models=bot.active_models, ), ) diff --git a/backend/poetry.lock b/backend/poetry.lock index f5518e6c5..a71f21b9c 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "annotated-types" @@ -13,13 +13,13 @@ files = [ [[package]] name = "anyio" -version = "4.6.0" +version = "4.6.2.post1" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a"}, - {file = "anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb"}, + {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, + {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, ] [package.dependencies] @@ -28,7 +28,7 @@ sniffio = ">=1.1" [package.extras] doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.21.0b1)"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -99,17 +99,17 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "boto3" -version = "1.35.41" +version = "1.35.71" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.35.41-py3-none-any.whl", hash = "sha256:2bf7e7f376aee52155fc4ae4487f29333a6bcdf3a05c3bc4fede10b972d951a6"}, - {file = "boto3-1.35.41.tar.gz", hash = "sha256:e74bc6d69c04ca611b7f58afe08e2ded6cb6504a4a80557b656abeefee395f88"}, + {file = "boto3-1.35.71-py3-none-any.whl", hash = "sha256:e2969a246bb3208122b3c349c49cc6604c6fc3fc2b2f65d99d3e8ccd745b0c16"}, + {file = "boto3-1.35.71.tar.gz", hash = "sha256:3ed7172b3d4fceb6218bb0ec3668c4d40c03690939c2fca4f22bb875d741a07f"}, ] [package.dependencies] -botocore = ">=1.35.41,<1.36.0" +botocore = ">=1.35.71,<1.36.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -118,18 +118,18 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "boto3-stubs" -version = "1.35.41" -description = "Type annotations for boto3 1.35.41 generated with mypy-boto3-builder 8.1.2" +version = "1.35.71" +description = "Type annotations for boto3 1.35.71 generated with mypy-boto3-builder 8.4.0" optional = false python-versions = ">=3.8" files = [ - {file = "boto3_stubs-1.35.41-py3-none-any.whl", hash = "sha256:724c5999390eed5ed84832dcd003d1dcd1b12c941e50f6a6f63378c407d8fa0a"}, - {file = "boto3_stubs-1.35.41.tar.gz", hash = "sha256:5884048edf0581479ecc3726c0b4b6d83640b5590d4646cbd229bae8f5a5666b"}, + {file = "boto3_stubs-1.35.71-py3-none-any.whl", hash = "sha256:4abf357250bdb16d1a56489a59bfc385d132a43677956bd984f6578638d599c0"}, + {file = "boto3_stubs-1.35.71.tar.gz", hash = "sha256:50e20fa74248c96b3e3498b2d81388585583e38b9f0609d2fa58257e49c986a5"}, ] [package.dependencies] -boto3 = {version = "1.35.41", optional = true, markers = "extra == \"boto3\""} -botocore = {version = "1.35.41", optional = true, markers = "extra == \"boto3\""} +boto3 = {version = "1.35.71", optional = true, markers = "extra == \"boto3\""} +botocore = {version = "1.35.71", optional = true, markers = "extra == \"boto3\""} botocore-stubs = "*" mypy-boto3-bedrock = {version = ">=1.35.0,<1.36.0", optional = true, markers = "extra == \"bedrock\""} mypy-boto3-bedrock-agent-runtime = {version = ">=1.35.0,<1.36.0", optional = true, markers = "extra == \"bedrock-agent-runtime\""} @@ -142,7 +142,7 @@ accessanalyzer = ["mypy-boto3-accessanalyzer (>=1.35.0,<1.36.0)"] account = ["mypy-boto3-account (>=1.35.0,<1.36.0)"] acm = ["mypy-boto3-acm (>=1.35.0,<1.36.0)"] acm-pca = ["mypy-boto3-acm-pca (>=1.35.0,<1.36.0)"] -all = ["mypy-boto3-accessanalyzer (>=1.35.0,<1.36.0)", "mypy-boto3-account (>=1.35.0,<1.36.0)", "mypy-boto3-acm (>=1.35.0,<1.36.0)", "mypy-boto3-acm-pca (>=1.35.0,<1.36.0)", "mypy-boto3-amp (>=1.35.0,<1.36.0)", "mypy-boto3-amplify (>=1.35.0,<1.36.0)", "mypy-boto3-amplifybackend (>=1.35.0,<1.36.0)", "mypy-boto3-amplifyuibuilder (>=1.35.0,<1.36.0)", "mypy-boto3-apigateway (>=1.35.0,<1.36.0)", "mypy-boto3-apigatewaymanagementapi (>=1.35.0,<1.36.0)", "mypy-boto3-apigatewayv2 (>=1.35.0,<1.36.0)", "mypy-boto3-appconfig (>=1.35.0,<1.36.0)", "mypy-boto3-appconfigdata (>=1.35.0,<1.36.0)", "mypy-boto3-appfabric (>=1.35.0,<1.36.0)", "mypy-boto3-appflow (>=1.35.0,<1.36.0)", "mypy-boto3-appintegrations (>=1.35.0,<1.36.0)", "mypy-boto3-application-autoscaling (>=1.35.0,<1.36.0)", "mypy-boto3-application-insights (>=1.35.0,<1.36.0)", "mypy-boto3-application-signals (>=1.35.0,<1.36.0)", "mypy-boto3-applicationcostprofiler (>=1.35.0,<1.36.0)", "mypy-boto3-appmesh (>=1.35.0,<1.36.0)", "mypy-boto3-apprunner (>=1.35.0,<1.36.0)", "mypy-boto3-appstream (>=1.35.0,<1.36.0)", "mypy-boto3-appsync (>=1.35.0,<1.36.0)", "mypy-boto3-apptest (>=1.35.0,<1.36.0)", "mypy-boto3-arc-zonal-shift (>=1.35.0,<1.36.0)", "mypy-boto3-artifact (>=1.35.0,<1.36.0)", "mypy-boto3-athena (>=1.35.0,<1.36.0)", "mypy-boto3-auditmanager (>=1.35.0,<1.36.0)", "mypy-boto3-autoscaling (>=1.35.0,<1.36.0)", "mypy-boto3-autoscaling-plans (>=1.35.0,<1.36.0)", "mypy-boto3-b2bi (>=1.35.0,<1.36.0)", "mypy-boto3-backup (>=1.35.0,<1.36.0)", "mypy-boto3-backup-gateway (>=1.35.0,<1.36.0)", "mypy-boto3-batch (>=1.35.0,<1.36.0)", "mypy-boto3-bcm-data-exports (>=1.35.0,<1.36.0)", "mypy-boto3-bedrock (>=1.35.0,<1.36.0)", "mypy-boto3-bedrock-agent (>=1.35.0,<1.36.0)", "mypy-boto3-bedrock-agent-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-bedrock-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-billingconductor (>=1.35.0,<1.36.0)", "mypy-boto3-braket (>=1.35.0,<1.36.0)", "mypy-boto3-budgets (>=1.35.0,<1.36.0)", "mypy-boto3-ce (>=1.35.0,<1.36.0)", "mypy-boto3-chatbot (>=1.35.0,<1.36.0)", "mypy-boto3-chime (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-identity (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-media-pipelines (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-meetings (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-messaging (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-voice (>=1.35.0,<1.36.0)", "mypy-boto3-cleanrooms (>=1.35.0,<1.36.0)", "mypy-boto3-cleanroomsml (>=1.35.0,<1.36.0)", "mypy-boto3-cloud9 (>=1.35.0,<1.36.0)", "mypy-boto3-cloudcontrol (>=1.35.0,<1.36.0)", "mypy-boto3-clouddirectory (>=1.35.0,<1.36.0)", "mypy-boto3-cloudformation (>=1.35.0,<1.36.0)", "mypy-boto3-cloudfront (>=1.35.0,<1.36.0)", "mypy-boto3-cloudfront-keyvaluestore (>=1.35.0,<1.36.0)", "mypy-boto3-cloudhsm (>=1.35.0,<1.36.0)", "mypy-boto3-cloudhsmv2 (>=1.35.0,<1.36.0)", "mypy-boto3-cloudsearch (>=1.35.0,<1.36.0)", "mypy-boto3-cloudsearchdomain (>=1.35.0,<1.36.0)", "mypy-boto3-cloudtrail (>=1.35.0,<1.36.0)", "mypy-boto3-cloudtrail-data (>=1.35.0,<1.36.0)", "mypy-boto3-cloudwatch (>=1.35.0,<1.36.0)", "mypy-boto3-codeartifact (>=1.35.0,<1.36.0)", "mypy-boto3-codebuild (>=1.35.0,<1.36.0)", "mypy-boto3-codecatalyst (>=1.35.0,<1.36.0)", "mypy-boto3-codecommit (>=1.35.0,<1.36.0)", "mypy-boto3-codeconnections (>=1.35.0,<1.36.0)", "mypy-boto3-codedeploy (>=1.35.0,<1.36.0)", "mypy-boto3-codeguru-reviewer (>=1.35.0,<1.36.0)", "mypy-boto3-codeguru-security (>=1.35.0,<1.36.0)", "mypy-boto3-codeguruprofiler (>=1.35.0,<1.36.0)", "mypy-boto3-codepipeline (>=1.35.0,<1.36.0)", "mypy-boto3-codestar-connections (>=1.35.0,<1.36.0)", "mypy-boto3-codestar-notifications (>=1.35.0,<1.36.0)", "mypy-boto3-cognito-identity (>=1.35.0,<1.36.0)", "mypy-boto3-cognito-idp (>=1.35.0,<1.36.0)", "mypy-boto3-cognito-sync (>=1.35.0,<1.36.0)", "mypy-boto3-comprehend (>=1.35.0,<1.36.0)", "mypy-boto3-comprehendmedical (>=1.35.0,<1.36.0)", "mypy-boto3-compute-optimizer (>=1.35.0,<1.36.0)", "mypy-boto3-config (>=1.35.0,<1.36.0)", "mypy-boto3-connect (>=1.35.0,<1.36.0)", "mypy-boto3-connect-contact-lens (>=1.35.0,<1.36.0)", "mypy-boto3-connectcampaigns (>=1.35.0,<1.36.0)", "mypy-boto3-connectcases (>=1.35.0,<1.36.0)", "mypy-boto3-connectparticipant (>=1.35.0,<1.36.0)", "mypy-boto3-controlcatalog (>=1.35.0,<1.36.0)", "mypy-boto3-controltower (>=1.35.0,<1.36.0)", "mypy-boto3-cost-optimization-hub (>=1.35.0,<1.36.0)", "mypy-boto3-cur (>=1.35.0,<1.36.0)", "mypy-boto3-customer-profiles (>=1.35.0,<1.36.0)", "mypy-boto3-databrew (>=1.35.0,<1.36.0)", "mypy-boto3-dataexchange (>=1.35.0,<1.36.0)", "mypy-boto3-datapipeline (>=1.35.0,<1.36.0)", "mypy-boto3-datasync (>=1.35.0,<1.36.0)", "mypy-boto3-datazone (>=1.35.0,<1.36.0)", "mypy-boto3-dax (>=1.35.0,<1.36.0)", "mypy-boto3-deadline (>=1.35.0,<1.36.0)", "mypy-boto3-detective (>=1.35.0,<1.36.0)", "mypy-boto3-devicefarm (>=1.35.0,<1.36.0)", "mypy-boto3-devops-guru (>=1.35.0,<1.36.0)", "mypy-boto3-directconnect (>=1.35.0,<1.36.0)", "mypy-boto3-discovery (>=1.35.0,<1.36.0)", "mypy-boto3-dlm (>=1.35.0,<1.36.0)", "mypy-boto3-dms (>=1.35.0,<1.36.0)", "mypy-boto3-docdb (>=1.35.0,<1.36.0)", "mypy-boto3-docdb-elastic (>=1.35.0,<1.36.0)", "mypy-boto3-drs (>=1.35.0,<1.36.0)", "mypy-boto3-ds (>=1.35.0,<1.36.0)", "mypy-boto3-ds-data (>=1.35.0,<1.36.0)", "mypy-boto3-dynamodb (>=1.35.0,<1.36.0)", "mypy-boto3-dynamodbstreams (>=1.35.0,<1.36.0)", "mypy-boto3-ebs (>=1.35.0,<1.36.0)", "mypy-boto3-ec2 (>=1.35.0,<1.36.0)", "mypy-boto3-ec2-instance-connect (>=1.35.0,<1.36.0)", "mypy-boto3-ecr (>=1.35.0,<1.36.0)", "mypy-boto3-ecr-public (>=1.35.0,<1.36.0)", "mypy-boto3-ecs (>=1.35.0,<1.36.0)", "mypy-boto3-efs (>=1.35.0,<1.36.0)", "mypy-boto3-eks (>=1.35.0,<1.36.0)", "mypy-boto3-eks-auth (>=1.35.0,<1.36.0)", "mypy-boto3-elastic-inference (>=1.35.0,<1.36.0)", "mypy-boto3-elasticache (>=1.35.0,<1.36.0)", "mypy-boto3-elasticbeanstalk (>=1.35.0,<1.36.0)", "mypy-boto3-elastictranscoder (>=1.35.0,<1.36.0)", "mypy-boto3-elb (>=1.35.0,<1.36.0)", "mypy-boto3-elbv2 (>=1.35.0,<1.36.0)", "mypy-boto3-emr (>=1.35.0,<1.36.0)", "mypy-boto3-emr-containers (>=1.35.0,<1.36.0)", "mypy-boto3-emr-serverless (>=1.35.0,<1.36.0)", "mypy-boto3-entityresolution (>=1.35.0,<1.36.0)", "mypy-boto3-es (>=1.35.0,<1.36.0)", "mypy-boto3-events (>=1.35.0,<1.36.0)", "mypy-boto3-evidently (>=1.35.0,<1.36.0)", "mypy-boto3-finspace (>=1.35.0,<1.36.0)", "mypy-boto3-finspace-data (>=1.35.0,<1.36.0)", "mypy-boto3-firehose (>=1.35.0,<1.36.0)", "mypy-boto3-fis (>=1.35.0,<1.36.0)", "mypy-boto3-fms (>=1.35.0,<1.36.0)", "mypy-boto3-forecast (>=1.35.0,<1.36.0)", "mypy-boto3-forecastquery (>=1.35.0,<1.36.0)", "mypy-boto3-frauddetector (>=1.35.0,<1.36.0)", "mypy-boto3-freetier (>=1.35.0,<1.36.0)", "mypy-boto3-fsx (>=1.35.0,<1.36.0)", "mypy-boto3-gamelift (>=1.35.0,<1.36.0)", "mypy-boto3-glacier (>=1.35.0,<1.36.0)", "mypy-boto3-globalaccelerator (>=1.35.0,<1.36.0)", "mypy-boto3-glue (>=1.35.0,<1.36.0)", "mypy-boto3-grafana (>=1.35.0,<1.36.0)", "mypy-boto3-greengrass (>=1.35.0,<1.36.0)", "mypy-boto3-greengrassv2 (>=1.35.0,<1.36.0)", "mypy-boto3-groundstation (>=1.35.0,<1.36.0)", "mypy-boto3-guardduty (>=1.35.0,<1.36.0)", "mypy-boto3-health (>=1.35.0,<1.36.0)", "mypy-boto3-healthlake (>=1.35.0,<1.36.0)", "mypy-boto3-iam (>=1.35.0,<1.36.0)", "mypy-boto3-identitystore (>=1.35.0,<1.36.0)", "mypy-boto3-imagebuilder (>=1.35.0,<1.36.0)", "mypy-boto3-importexport (>=1.35.0,<1.36.0)", "mypy-boto3-inspector (>=1.35.0,<1.36.0)", "mypy-boto3-inspector-scan (>=1.35.0,<1.36.0)", "mypy-boto3-inspector2 (>=1.35.0,<1.36.0)", "mypy-boto3-internetmonitor (>=1.35.0,<1.36.0)", "mypy-boto3-iot (>=1.35.0,<1.36.0)", "mypy-boto3-iot-data (>=1.35.0,<1.36.0)", "mypy-boto3-iot-jobs-data (>=1.35.0,<1.36.0)", "mypy-boto3-iot1click-devices (>=1.35.0,<1.36.0)", "mypy-boto3-iot1click-projects (>=1.35.0,<1.36.0)", "mypy-boto3-iotanalytics (>=1.35.0,<1.36.0)", "mypy-boto3-iotdeviceadvisor (>=1.35.0,<1.36.0)", "mypy-boto3-iotevents (>=1.35.0,<1.36.0)", "mypy-boto3-iotevents-data (>=1.35.0,<1.36.0)", "mypy-boto3-iotfleethub (>=1.35.0,<1.36.0)", "mypy-boto3-iotfleetwise (>=1.35.0,<1.36.0)", "mypy-boto3-iotsecuretunneling (>=1.35.0,<1.36.0)", "mypy-boto3-iotsitewise (>=1.35.0,<1.36.0)", "mypy-boto3-iotthingsgraph (>=1.35.0,<1.36.0)", "mypy-boto3-iottwinmaker (>=1.35.0,<1.36.0)", "mypy-boto3-iotwireless (>=1.35.0,<1.36.0)", "mypy-boto3-ivs (>=1.35.0,<1.36.0)", "mypy-boto3-ivs-realtime (>=1.35.0,<1.36.0)", "mypy-boto3-ivschat (>=1.35.0,<1.36.0)", "mypy-boto3-kafka (>=1.35.0,<1.36.0)", "mypy-boto3-kafkaconnect (>=1.35.0,<1.36.0)", "mypy-boto3-kendra (>=1.35.0,<1.36.0)", "mypy-boto3-kendra-ranking (>=1.35.0,<1.36.0)", "mypy-boto3-keyspaces (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis-video-archived-media (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis-video-media (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis-video-signaling (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis-video-webrtc-storage (>=1.35.0,<1.36.0)", "mypy-boto3-kinesisanalytics (>=1.35.0,<1.36.0)", "mypy-boto3-kinesisanalyticsv2 (>=1.35.0,<1.36.0)", "mypy-boto3-kinesisvideo (>=1.35.0,<1.36.0)", "mypy-boto3-kms (>=1.35.0,<1.36.0)", "mypy-boto3-lakeformation (>=1.35.0,<1.36.0)", "mypy-boto3-lambda (>=1.35.0,<1.36.0)", "mypy-boto3-launch-wizard (>=1.35.0,<1.36.0)", "mypy-boto3-lex-models (>=1.35.0,<1.36.0)", "mypy-boto3-lex-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-lexv2-models (>=1.35.0,<1.36.0)", "mypy-boto3-lexv2-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-license-manager (>=1.35.0,<1.36.0)", "mypy-boto3-license-manager-linux-subscriptions (>=1.35.0,<1.36.0)", "mypy-boto3-license-manager-user-subscriptions (>=1.35.0,<1.36.0)", "mypy-boto3-lightsail (>=1.35.0,<1.36.0)", "mypy-boto3-location (>=1.35.0,<1.36.0)", "mypy-boto3-logs (>=1.35.0,<1.36.0)", "mypy-boto3-lookoutequipment (>=1.35.0,<1.36.0)", "mypy-boto3-lookoutmetrics (>=1.35.0,<1.36.0)", "mypy-boto3-lookoutvision (>=1.35.0,<1.36.0)", "mypy-boto3-m2 (>=1.35.0,<1.36.0)", "mypy-boto3-machinelearning (>=1.35.0,<1.36.0)", "mypy-boto3-macie2 (>=1.35.0,<1.36.0)", "mypy-boto3-mailmanager (>=1.35.0,<1.36.0)", "mypy-boto3-managedblockchain (>=1.35.0,<1.36.0)", "mypy-boto3-managedblockchain-query (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-agreement (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-catalog (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-deployment (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-entitlement (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-reporting (>=1.35.0,<1.36.0)", "mypy-boto3-marketplacecommerceanalytics (>=1.35.0,<1.36.0)", "mypy-boto3-mediaconnect (>=1.35.0,<1.36.0)", "mypy-boto3-mediaconvert (>=1.35.0,<1.36.0)", "mypy-boto3-medialive (>=1.35.0,<1.36.0)", "mypy-boto3-mediapackage (>=1.35.0,<1.36.0)", "mypy-boto3-mediapackage-vod (>=1.35.0,<1.36.0)", "mypy-boto3-mediapackagev2 (>=1.35.0,<1.36.0)", "mypy-boto3-mediastore (>=1.35.0,<1.36.0)", "mypy-boto3-mediastore-data (>=1.35.0,<1.36.0)", "mypy-boto3-mediatailor (>=1.35.0,<1.36.0)", "mypy-boto3-medical-imaging (>=1.35.0,<1.36.0)", "mypy-boto3-memorydb (>=1.35.0,<1.36.0)", "mypy-boto3-meteringmarketplace (>=1.35.0,<1.36.0)", "mypy-boto3-mgh (>=1.35.0,<1.36.0)", "mypy-boto3-mgn (>=1.35.0,<1.36.0)", "mypy-boto3-migration-hub-refactor-spaces (>=1.35.0,<1.36.0)", "mypy-boto3-migrationhub-config (>=1.35.0,<1.36.0)", "mypy-boto3-migrationhuborchestrator (>=1.35.0,<1.36.0)", "mypy-boto3-migrationhubstrategy (>=1.35.0,<1.36.0)", "mypy-boto3-mq (>=1.35.0,<1.36.0)", "mypy-boto3-mturk (>=1.35.0,<1.36.0)", "mypy-boto3-mwaa (>=1.35.0,<1.36.0)", "mypy-boto3-neptune (>=1.35.0,<1.36.0)", "mypy-boto3-neptune-graph (>=1.35.0,<1.36.0)", "mypy-boto3-neptunedata (>=1.35.0,<1.36.0)", "mypy-boto3-network-firewall (>=1.35.0,<1.36.0)", "mypy-boto3-networkmanager (>=1.35.0,<1.36.0)", "mypy-boto3-networkmonitor (>=1.35.0,<1.36.0)", "mypy-boto3-nimble (>=1.35.0,<1.36.0)", "mypy-boto3-oam (>=1.35.0,<1.36.0)", "mypy-boto3-omics (>=1.35.0,<1.36.0)", "mypy-boto3-opensearch (>=1.35.0,<1.36.0)", "mypy-boto3-opensearchserverless (>=1.35.0,<1.36.0)", "mypy-boto3-opsworks (>=1.35.0,<1.36.0)", "mypy-boto3-opsworkscm (>=1.35.0,<1.36.0)", "mypy-boto3-organizations (>=1.35.0,<1.36.0)", "mypy-boto3-osis (>=1.35.0,<1.36.0)", "mypy-boto3-outposts (>=1.35.0,<1.36.0)", "mypy-boto3-panorama (>=1.35.0,<1.36.0)", "mypy-boto3-payment-cryptography (>=1.35.0,<1.36.0)", "mypy-boto3-payment-cryptography-data (>=1.35.0,<1.36.0)", "mypy-boto3-pca-connector-ad (>=1.35.0,<1.36.0)", "mypy-boto3-pca-connector-scep (>=1.35.0,<1.36.0)", "mypy-boto3-pcs (>=1.35.0,<1.36.0)", "mypy-boto3-personalize (>=1.35.0,<1.36.0)", "mypy-boto3-personalize-events (>=1.35.0,<1.36.0)", "mypy-boto3-personalize-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-pi (>=1.35.0,<1.36.0)", "mypy-boto3-pinpoint (>=1.35.0,<1.36.0)", "mypy-boto3-pinpoint-email (>=1.35.0,<1.36.0)", "mypy-boto3-pinpoint-sms-voice (>=1.35.0,<1.36.0)", "mypy-boto3-pinpoint-sms-voice-v2 (>=1.35.0,<1.36.0)", "mypy-boto3-pipes (>=1.35.0,<1.36.0)", "mypy-boto3-polly (>=1.35.0,<1.36.0)", "mypy-boto3-pricing (>=1.35.0,<1.36.0)", "mypy-boto3-privatenetworks (>=1.35.0,<1.36.0)", "mypy-boto3-proton (>=1.35.0,<1.36.0)", "mypy-boto3-qapps (>=1.35.0,<1.36.0)", "mypy-boto3-qbusiness (>=1.35.0,<1.36.0)", "mypy-boto3-qconnect (>=1.35.0,<1.36.0)", "mypy-boto3-qldb (>=1.35.0,<1.36.0)", "mypy-boto3-qldb-session (>=1.35.0,<1.36.0)", "mypy-boto3-quicksight (>=1.35.0,<1.36.0)", "mypy-boto3-ram (>=1.35.0,<1.36.0)", "mypy-boto3-rbin (>=1.35.0,<1.36.0)", "mypy-boto3-rds (>=1.35.0,<1.36.0)", "mypy-boto3-rds-data (>=1.35.0,<1.36.0)", "mypy-boto3-redshift (>=1.35.0,<1.36.0)", "mypy-boto3-redshift-data (>=1.35.0,<1.36.0)", "mypy-boto3-redshift-serverless (>=1.35.0,<1.36.0)", "mypy-boto3-rekognition (>=1.35.0,<1.36.0)", "mypy-boto3-repostspace (>=1.35.0,<1.36.0)", "mypy-boto3-resiliencehub (>=1.35.0,<1.36.0)", "mypy-boto3-resource-explorer-2 (>=1.35.0,<1.36.0)", "mypy-boto3-resource-groups (>=1.35.0,<1.36.0)", "mypy-boto3-resourcegroupstaggingapi (>=1.35.0,<1.36.0)", "mypy-boto3-robomaker (>=1.35.0,<1.36.0)", "mypy-boto3-rolesanywhere (>=1.35.0,<1.36.0)", "mypy-boto3-route53 (>=1.35.0,<1.36.0)", "mypy-boto3-route53-recovery-cluster (>=1.35.0,<1.36.0)", "mypy-boto3-route53-recovery-control-config (>=1.35.0,<1.36.0)", "mypy-boto3-route53-recovery-readiness (>=1.35.0,<1.36.0)", "mypy-boto3-route53domains (>=1.35.0,<1.36.0)", "mypy-boto3-route53profiles (>=1.35.0,<1.36.0)", "mypy-boto3-route53resolver (>=1.35.0,<1.36.0)", "mypy-boto3-rum (>=1.35.0,<1.36.0)", "mypy-boto3-s3 (>=1.35.0,<1.36.0)", "mypy-boto3-s3control (>=1.35.0,<1.36.0)", "mypy-boto3-s3outposts (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-a2i-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-edge (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-featurestore-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-geospatial (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-metrics (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-savingsplans (>=1.35.0,<1.36.0)", "mypy-boto3-scheduler (>=1.35.0,<1.36.0)", "mypy-boto3-schemas (>=1.35.0,<1.36.0)", "mypy-boto3-sdb (>=1.35.0,<1.36.0)", "mypy-boto3-secretsmanager (>=1.35.0,<1.36.0)", "mypy-boto3-securityhub (>=1.35.0,<1.36.0)", "mypy-boto3-securitylake (>=1.35.0,<1.36.0)", "mypy-boto3-serverlessrepo (>=1.35.0,<1.36.0)", "mypy-boto3-service-quotas (>=1.35.0,<1.36.0)", "mypy-boto3-servicecatalog (>=1.35.0,<1.36.0)", "mypy-boto3-servicecatalog-appregistry (>=1.35.0,<1.36.0)", "mypy-boto3-servicediscovery (>=1.35.0,<1.36.0)", "mypy-boto3-ses (>=1.35.0,<1.36.0)", "mypy-boto3-sesv2 (>=1.35.0,<1.36.0)", "mypy-boto3-shield (>=1.35.0,<1.36.0)", "mypy-boto3-signer (>=1.35.0,<1.36.0)", "mypy-boto3-simspaceweaver (>=1.35.0,<1.36.0)", "mypy-boto3-sms (>=1.35.0,<1.36.0)", "mypy-boto3-sms-voice (>=1.35.0,<1.36.0)", "mypy-boto3-snow-device-management (>=1.35.0,<1.36.0)", "mypy-boto3-snowball (>=1.35.0,<1.36.0)", "mypy-boto3-sns (>=1.35.0,<1.36.0)", "mypy-boto3-socialmessaging (>=1.35.0,<1.36.0)", "mypy-boto3-sqs (>=1.35.0,<1.36.0)", "mypy-boto3-ssm (>=1.35.0,<1.36.0)", "mypy-boto3-ssm-contacts (>=1.35.0,<1.36.0)", "mypy-boto3-ssm-incidents (>=1.35.0,<1.36.0)", "mypy-boto3-ssm-quicksetup (>=1.35.0,<1.36.0)", "mypy-boto3-ssm-sap (>=1.35.0,<1.36.0)", "mypy-boto3-sso (>=1.35.0,<1.36.0)", "mypy-boto3-sso-admin (>=1.35.0,<1.36.0)", "mypy-boto3-sso-oidc (>=1.35.0,<1.36.0)", "mypy-boto3-stepfunctions (>=1.35.0,<1.36.0)", "mypy-boto3-storagegateway (>=1.35.0,<1.36.0)", "mypy-boto3-sts (>=1.35.0,<1.36.0)", "mypy-boto3-supplychain (>=1.35.0,<1.36.0)", "mypy-boto3-support (>=1.35.0,<1.36.0)", "mypy-boto3-support-app (>=1.35.0,<1.36.0)", "mypy-boto3-swf (>=1.35.0,<1.36.0)", "mypy-boto3-synthetics (>=1.35.0,<1.36.0)", "mypy-boto3-taxsettings (>=1.35.0,<1.36.0)", "mypy-boto3-textract (>=1.35.0,<1.36.0)", "mypy-boto3-timestream-influxdb (>=1.35.0,<1.36.0)", "mypy-boto3-timestream-query (>=1.35.0,<1.36.0)", "mypy-boto3-timestream-write (>=1.35.0,<1.36.0)", "mypy-boto3-tnb (>=1.35.0,<1.36.0)", "mypy-boto3-transcribe (>=1.35.0,<1.36.0)", "mypy-boto3-transfer (>=1.35.0,<1.36.0)", "mypy-boto3-translate (>=1.35.0,<1.36.0)", "mypy-boto3-trustedadvisor (>=1.35.0,<1.36.0)", "mypy-boto3-verifiedpermissions (>=1.35.0,<1.36.0)", "mypy-boto3-voice-id (>=1.35.0,<1.36.0)", "mypy-boto3-vpc-lattice (>=1.35.0,<1.36.0)", "mypy-boto3-waf (>=1.35.0,<1.36.0)", "mypy-boto3-waf-regional (>=1.35.0,<1.36.0)", "mypy-boto3-wafv2 (>=1.35.0,<1.36.0)", "mypy-boto3-wellarchitected (>=1.35.0,<1.36.0)", "mypy-boto3-wisdom (>=1.35.0,<1.36.0)", "mypy-boto3-workdocs (>=1.35.0,<1.36.0)", "mypy-boto3-workmail (>=1.35.0,<1.36.0)", "mypy-boto3-workmailmessageflow (>=1.35.0,<1.36.0)", "mypy-boto3-workspaces (>=1.35.0,<1.36.0)", "mypy-boto3-workspaces-thin-client (>=1.35.0,<1.36.0)", "mypy-boto3-workspaces-web (>=1.35.0,<1.36.0)", "mypy-boto3-xray (>=1.35.0,<1.36.0)"] +all = ["mypy-boto3-accessanalyzer (>=1.35.0,<1.36.0)", "mypy-boto3-account (>=1.35.0,<1.36.0)", "mypy-boto3-acm (>=1.35.0,<1.36.0)", "mypy-boto3-acm-pca (>=1.35.0,<1.36.0)", "mypy-boto3-amp (>=1.35.0,<1.36.0)", "mypy-boto3-amplify (>=1.35.0,<1.36.0)", "mypy-boto3-amplifybackend (>=1.35.0,<1.36.0)", "mypy-boto3-amplifyuibuilder (>=1.35.0,<1.36.0)", "mypy-boto3-apigateway (>=1.35.0,<1.36.0)", "mypy-boto3-apigatewaymanagementapi (>=1.35.0,<1.36.0)", "mypy-boto3-apigatewayv2 (>=1.35.0,<1.36.0)", "mypy-boto3-appconfig (>=1.35.0,<1.36.0)", "mypy-boto3-appconfigdata (>=1.35.0,<1.36.0)", "mypy-boto3-appfabric (>=1.35.0,<1.36.0)", "mypy-boto3-appflow (>=1.35.0,<1.36.0)", "mypy-boto3-appintegrations (>=1.35.0,<1.36.0)", "mypy-boto3-application-autoscaling (>=1.35.0,<1.36.0)", "mypy-boto3-application-insights (>=1.35.0,<1.36.0)", "mypy-boto3-application-signals (>=1.35.0,<1.36.0)", "mypy-boto3-applicationcostprofiler (>=1.35.0,<1.36.0)", "mypy-boto3-appmesh (>=1.35.0,<1.36.0)", "mypy-boto3-apprunner (>=1.35.0,<1.36.0)", "mypy-boto3-appstream (>=1.35.0,<1.36.0)", "mypy-boto3-appsync (>=1.35.0,<1.36.0)", "mypy-boto3-apptest (>=1.35.0,<1.36.0)", "mypy-boto3-arc-zonal-shift (>=1.35.0,<1.36.0)", "mypy-boto3-artifact (>=1.35.0,<1.36.0)", "mypy-boto3-athena (>=1.35.0,<1.36.0)", "mypy-boto3-auditmanager (>=1.35.0,<1.36.0)", "mypy-boto3-autoscaling (>=1.35.0,<1.36.0)", "mypy-boto3-autoscaling-plans (>=1.35.0,<1.36.0)", "mypy-boto3-b2bi (>=1.35.0,<1.36.0)", "mypy-boto3-backup (>=1.35.0,<1.36.0)", "mypy-boto3-backup-gateway (>=1.35.0,<1.36.0)", "mypy-boto3-batch (>=1.35.0,<1.36.0)", "mypy-boto3-bcm-data-exports (>=1.35.0,<1.36.0)", "mypy-boto3-bcm-pricing-calculator (>=1.35.0,<1.36.0)", "mypy-boto3-bedrock (>=1.35.0,<1.36.0)", "mypy-boto3-bedrock-agent (>=1.35.0,<1.36.0)", "mypy-boto3-bedrock-agent-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-bedrock-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-billing (>=1.35.0,<1.36.0)", "mypy-boto3-billingconductor (>=1.35.0,<1.36.0)", "mypy-boto3-braket (>=1.35.0,<1.36.0)", "mypy-boto3-budgets (>=1.35.0,<1.36.0)", "mypy-boto3-ce (>=1.35.0,<1.36.0)", "mypy-boto3-chatbot (>=1.35.0,<1.36.0)", "mypy-boto3-chime (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-identity (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-media-pipelines (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-meetings (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-messaging (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-voice (>=1.35.0,<1.36.0)", "mypy-boto3-cleanrooms (>=1.35.0,<1.36.0)", "mypy-boto3-cleanroomsml (>=1.35.0,<1.36.0)", "mypy-boto3-cloud9 (>=1.35.0,<1.36.0)", "mypy-boto3-cloudcontrol (>=1.35.0,<1.36.0)", "mypy-boto3-clouddirectory (>=1.35.0,<1.36.0)", "mypy-boto3-cloudformation (>=1.35.0,<1.36.0)", "mypy-boto3-cloudfront (>=1.35.0,<1.36.0)", "mypy-boto3-cloudfront-keyvaluestore (>=1.35.0,<1.36.0)", "mypy-boto3-cloudhsm (>=1.35.0,<1.36.0)", "mypy-boto3-cloudhsmv2 (>=1.35.0,<1.36.0)", "mypy-boto3-cloudsearch (>=1.35.0,<1.36.0)", "mypy-boto3-cloudsearchdomain (>=1.35.0,<1.36.0)", "mypy-boto3-cloudtrail (>=1.35.0,<1.36.0)", "mypy-boto3-cloudtrail-data (>=1.35.0,<1.36.0)", "mypy-boto3-cloudwatch (>=1.35.0,<1.36.0)", "mypy-boto3-codeartifact (>=1.35.0,<1.36.0)", "mypy-boto3-codebuild (>=1.35.0,<1.36.0)", "mypy-boto3-codecatalyst (>=1.35.0,<1.36.0)", "mypy-boto3-codecommit (>=1.35.0,<1.36.0)", "mypy-boto3-codeconnections (>=1.35.0,<1.36.0)", "mypy-boto3-codedeploy (>=1.35.0,<1.36.0)", "mypy-boto3-codeguru-reviewer (>=1.35.0,<1.36.0)", "mypy-boto3-codeguru-security (>=1.35.0,<1.36.0)", "mypy-boto3-codeguruprofiler (>=1.35.0,<1.36.0)", "mypy-boto3-codepipeline (>=1.35.0,<1.36.0)", "mypy-boto3-codestar-connections (>=1.35.0,<1.36.0)", "mypy-boto3-codestar-notifications (>=1.35.0,<1.36.0)", "mypy-boto3-cognito-identity (>=1.35.0,<1.36.0)", "mypy-boto3-cognito-idp (>=1.35.0,<1.36.0)", "mypy-boto3-cognito-sync (>=1.35.0,<1.36.0)", "mypy-boto3-comprehend (>=1.35.0,<1.36.0)", "mypy-boto3-comprehendmedical (>=1.35.0,<1.36.0)", "mypy-boto3-compute-optimizer (>=1.35.0,<1.36.0)", "mypy-boto3-config (>=1.35.0,<1.36.0)", "mypy-boto3-connect (>=1.35.0,<1.36.0)", "mypy-boto3-connect-contact-lens (>=1.35.0,<1.36.0)", "mypy-boto3-connectcampaigns (>=1.35.0,<1.36.0)", "mypy-boto3-connectcampaignsv2 (>=1.35.0,<1.36.0)", "mypy-boto3-connectcases (>=1.35.0,<1.36.0)", "mypy-boto3-connectparticipant (>=1.35.0,<1.36.0)", "mypy-boto3-controlcatalog (>=1.35.0,<1.36.0)", "mypy-boto3-controltower (>=1.35.0,<1.36.0)", "mypy-boto3-cost-optimization-hub (>=1.35.0,<1.36.0)", "mypy-boto3-cur (>=1.35.0,<1.36.0)", "mypy-boto3-customer-profiles (>=1.35.0,<1.36.0)", "mypy-boto3-databrew (>=1.35.0,<1.36.0)", "mypy-boto3-dataexchange (>=1.35.0,<1.36.0)", "mypy-boto3-datapipeline (>=1.35.0,<1.36.0)", "mypy-boto3-datasync (>=1.35.0,<1.36.0)", "mypy-boto3-datazone (>=1.35.0,<1.36.0)", "mypy-boto3-dax (>=1.35.0,<1.36.0)", "mypy-boto3-deadline (>=1.35.0,<1.36.0)", "mypy-boto3-detective (>=1.35.0,<1.36.0)", "mypy-boto3-devicefarm (>=1.35.0,<1.36.0)", "mypy-boto3-devops-guru (>=1.35.0,<1.36.0)", "mypy-boto3-directconnect (>=1.35.0,<1.36.0)", "mypy-boto3-discovery (>=1.35.0,<1.36.0)", "mypy-boto3-dlm (>=1.35.0,<1.36.0)", "mypy-boto3-dms (>=1.35.0,<1.36.0)", "mypy-boto3-docdb (>=1.35.0,<1.36.0)", "mypy-boto3-docdb-elastic (>=1.35.0,<1.36.0)", "mypy-boto3-drs (>=1.35.0,<1.36.0)", "mypy-boto3-ds (>=1.35.0,<1.36.0)", "mypy-boto3-ds-data (>=1.35.0,<1.36.0)", "mypy-boto3-dynamodb (>=1.35.0,<1.36.0)", "mypy-boto3-dynamodbstreams (>=1.35.0,<1.36.0)", "mypy-boto3-ebs (>=1.35.0,<1.36.0)", "mypy-boto3-ec2 (>=1.35.0,<1.36.0)", "mypy-boto3-ec2-instance-connect (>=1.35.0,<1.36.0)", "mypy-boto3-ecr (>=1.35.0,<1.36.0)", "mypy-boto3-ecr-public (>=1.35.0,<1.36.0)", "mypy-boto3-ecs (>=1.35.0,<1.36.0)", "mypy-boto3-efs (>=1.35.0,<1.36.0)", "mypy-boto3-eks (>=1.35.0,<1.36.0)", "mypy-boto3-eks-auth (>=1.35.0,<1.36.0)", "mypy-boto3-elastic-inference (>=1.35.0,<1.36.0)", "mypy-boto3-elasticache (>=1.35.0,<1.36.0)", "mypy-boto3-elasticbeanstalk (>=1.35.0,<1.36.0)", "mypy-boto3-elastictranscoder (>=1.35.0,<1.36.0)", "mypy-boto3-elb (>=1.35.0,<1.36.0)", "mypy-boto3-elbv2 (>=1.35.0,<1.36.0)", "mypy-boto3-emr (>=1.35.0,<1.36.0)", "mypy-boto3-emr-containers (>=1.35.0,<1.36.0)", "mypy-boto3-emr-serverless (>=1.35.0,<1.36.0)", "mypy-boto3-entityresolution (>=1.35.0,<1.36.0)", "mypy-boto3-es (>=1.35.0,<1.36.0)", "mypy-boto3-events (>=1.35.0,<1.36.0)", "mypy-boto3-evidently (>=1.35.0,<1.36.0)", "mypy-boto3-finspace (>=1.35.0,<1.36.0)", "mypy-boto3-finspace-data (>=1.35.0,<1.36.0)", "mypy-boto3-firehose (>=1.35.0,<1.36.0)", "mypy-boto3-fis (>=1.35.0,<1.36.0)", "mypy-boto3-fms (>=1.35.0,<1.36.0)", "mypy-boto3-forecast (>=1.35.0,<1.36.0)", "mypy-boto3-forecastquery (>=1.35.0,<1.36.0)", "mypy-boto3-frauddetector (>=1.35.0,<1.36.0)", "mypy-boto3-freetier (>=1.35.0,<1.36.0)", "mypy-boto3-fsx (>=1.35.0,<1.36.0)", "mypy-boto3-gamelift (>=1.35.0,<1.36.0)", "mypy-boto3-geo-maps (>=1.35.0,<1.36.0)", "mypy-boto3-geo-places (>=1.35.0,<1.36.0)", "mypy-boto3-geo-routes (>=1.35.0,<1.36.0)", "mypy-boto3-glacier (>=1.35.0,<1.36.0)", "mypy-boto3-globalaccelerator (>=1.35.0,<1.36.0)", "mypy-boto3-glue (>=1.35.0,<1.36.0)", "mypy-boto3-grafana (>=1.35.0,<1.36.0)", "mypy-boto3-greengrass (>=1.35.0,<1.36.0)", "mypy-boto3-greengrassv2 (>=1.35.0,<1.36.0)", "mypy-boto3-groundstation (>=1.35.0,<1.36.0)", "mypy-boto3-guardduty (>=1.35.0,<1.36.0)", "mypy-boto3-health (>=1.35.0,<1.36.0)", "mypy-boto3-healthlake (>=1.35.0,<1.36.0)", "mypy-boto3-iam (>=1.35.0,<1.36.0)", "mypy-boto3-identitystore (>=1.35.0,<1.36.0)", "mypy-boto3-imagebuilder (>=1.35.0,<1.36.0)", "mypy-boto3-importexport (>=1.35.0,<1.36.0)", "mypy-boto3-inspector (>=1.35.0,<1.36.0)", "mypy-boto3-inspector-scan (>=1.35.0,<1.36.0)", "mypy-boto3-inspector2 (>=1.35.0,<1.36.0)", "mypy-boto3-internetmonitor (>=1.35.0,<1.36.0)", "mypy-boto3-iot (>=1.35.0,<1.36.0)", "mypy-boto3-iot-data (>=1.35.0,<1.36.0)", "mypy-boto3-iot-jobs-data (>=1.35.0,<1.36.0)", "mypy-boto3-iot1click-devices (>=1.35.0,<1.36.0)", "mypy-boto3-iot1click-projects (>=1.35.0,<1.36.0)", "mypy-boto3-iotanalytics (>=1.35.0,<1.36.0)", "mypy-boto3-iotdeviceadvisor (>=1.35.0,<1.36.0)", "mypy-boto3-iotevents (>=1.35.0,<1.36.0)", "mypy-boto3-iotevents-data (>=1.35.0,<1.36.0)", "mypy-boto3-iotfleethub (>=1.35.0,<1.36.0)", "mypy-boto3-iotfleetwise (>=1.35.0,<1.36.0)", "mypy-boto3-iotsecuretunneling (>=1.35.0,<1.36.0)", "mypy-boto3-iotsitewise (>=1.35.0,<1.36.0)", "mypy-boto3-iotthingsgraph (>=1.35.0,<1.36.0)", "mypy-boto3-iottwinmaker (>=1.35.0,<1.36.0)", "mypy-boto3-iotwireless (>=1.35.0,<1.36.0)", "mypy-boto3-ivs (>=1.35.0,<1.36.0)", "mypy-boto3-ivs-realtime (>=1.35.0,<1.36.0)", "mypy-boto3-ivschat (>=1.35.0,<1.36.0)", "mypy-boto3-kafka (>=1.35.0,<1.36.0)", "mypy-boto3-kafkaconnect (>=1.35.0,<1.36.0)", "mypy-boto3-kendra (>=1.35.0,<1.36.0)", "mypy-boto3-kendra-ranking (>=1.35.0,<1.36.0)", "mypy-boto3-keyspaces (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis-video-archived-media (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis-video-media (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis-video-signaling (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis-video-webrtc-storage (>=1.35.0,<1.36.0)", "mypy-boto3-kinesisanalytics (>=1.35.0,<1.36.0)", "mypy-boto3-kinesisanalyticsv2 (>=1.35.0,<1.36.0)", "mypy-boto3-kinesisvideo (>=1.35.0,<1.36.0)", "mypy-boto3-kms (>=1.35.0,<1.36.0)", "mypy-boto3-lakeformation (>=1.35.0,<1.36.0)", "mypy-boto3-lambda (>=1.35.0,<1.36.0)", "mypy-boto3-launch-wizard (>=1.35.0,<1.36.0)", "mypy-boto3-lex-models (>=1.35.0,<1.36.0)", "mypy-boto3-lex-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-lexv2-models (>=1.35.0,<1.36.0)", "mypy-boto3-lexv2-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-license-manager (>=1.35.0,<1.36.0)", "mypy-boto3-license-manager-linux-subscriptions (>=1.35.0,<1.36.0)", "mypy-boto3-license-manager-user-subscriptions (>=1.35.0,<1.36.0)", "mypy-boto3-lightsail (>=1.35.0,<1.36.0)", "mypy-boto3-location (>=1.35.0,<1.36.0)", "mypy-boto3-logs (>=1.35.0,<1.36.0)", "mypy-boto3-lookoutequipment (>=1.35.0,<1.36.0)", "mypy-boto3-lookoutmetrics (>=1.35.0,<1.36.0)", "mypy-boto3-lookoutvision (>=1.35.0,<1.36.0)", "mypy-boto3-m2 (>=1.35.0,<1.36.0)", "mypy-boto3-machinelearning (>=1.35.0,<1.36.0)", "mypy-boto3-macie2 (>=1.35.0,<1.36.0)", "mypy-boto3-mailmanager (>=1.35.0,<1.36.0)", "mypy-boto3-managedblockchain (>=1.35.0,<1.36.0)", "mypy-boto3-managedblockchain-query (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-agreement (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-catalog (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-deployment (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-entitlement (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-reporting (>=1.35.0,<1.36.0)", "mypy-boto3-marketplacecommerceanalytics (>=1.35.0,<1.36.0)", "mypy-boto3-mediaconnect (>=1.35.0,<1.36.0)", "mypy-boto3-mediaconvert (>=1.35.0,<1.36.0)", "mypy-boto3-medialive (>=1.35.0,<1.36.0)", "mypy-boto3-mediapackage (>=1.35.0,<1.36.0)", "mypy-boto3-mediapackage-vod (>=1.35.0,<1.36.0)", "mypy-boto3-mediapackagev2 (>=1.35.0,<1.36.0)", "mypy-boto3-mediastore (>=1.35.0,<1.36.0)", "mypy-boto3-mediastore-data (>=1.35.0,<1.36.0)", "mypy-boto3-mediatailor (>=1.35.0,<1.36.0)", "mypy-boto3-medical-imaging (>=1.35.0,<1.36.0)", "mypy-boto3-memorydb (>=1.35.0,<1.36.0)", "mypy-boto3-meteringmarketplace (>=1.35.0,<1.36.0)", "mypy-boto3-mgh (>=1.35.0,<1.36.0)", "mypy-boto3-mgn (>=1.35.0,<1.36.0)", "mypy-boto3-migration-hub-refactor-spaces (>=1.35.0,<1.36.0)", "mypy-boto3-migrationhub-config (>=1.35.0,<1.36.0)", "mypy-boto3-migrationhuborchestrator (>=1.35.0,<1.36.0)", "mypy-boto3-migrationhubstrategy (>=1.35.0,<1.36.0)", "mypy-boto3-mq (>=1.35.0,<1.36.0)", "mypy-boto3-mturk (>=1.35.0,<1.36.0)", "mypy-boto3-mwaa (>=1.35.0,<1.36.0)", "mypy-boto3-neptune (>=1.35.0,<1.36.0)", "mypy-boto3-neptune-graph (>=1.35.0,<1.36.0)", "mypy-boto3-neptunedata (>=1.35.0,<1.36.0)", "mypy-boto3-network-firewall (>=1.35.0,<1.36.0)", "mypy-boto3-networkmanager (>=1.35.0,<1.36.0)", "mypy-boto3-networkmonitor (>=1.35.0,<1.36.0)", "mypy-boto3-notifications (>=1.35.0,<1.36.0)", "mypy-boto3-notificationscontacts (>=1.35.0,<1.36.0)", "mypy-boto3-oam (>=1.35.0,<1.36.0)", "mypy-boto3-observabilityadmin (>=1.35.0,<1.36.0)", "mypy-boto3-omics (>=1.35.0,<1.36.0)", "mypy-boto3-opensearch (>=1.35.0,<1.36.0)", "mypy-boto3-opensearchserverless (>=1.35.0,<1.36.0)", "mypy-boto3-opsworks (>=1.35.0,<1.36.0)", "mypy-boto3-opsworkscm (>=1.35.0,<1.36.0)", "mypy-boto3-organizations (>=1.35.0,<1.36.0)", "mypy-boto3-osis (>=1.35.0,<1.36.0)", "mypy-boto3-outposts (>=1.35.0,<1.36.0)", "mypy-boto3-panorama (>=1.35.0,<1.36.0)", "mypy-boto3-partnercentral-selling (>=1.35.0,<1.36.0)", "mypy-boto3-payment-cryptography (>=1.35.0,<1.36.0)", "mypy-boto3-payment-cryptography-data (>=1.35.0,<1.36.0)", "mypy-boto3-pca-connector-ad (>=1.35.0,<1.36.0)", "mypy-boto3-pca-connector-scep (>=1.35.0,<1.36.0)", "mypy-boto3-pcs (>=1.35.0,<1.36.0)", "mypy-boto3-personalize (>=1.35.0,<1.36.0)", "mypy-boto3-personalize-events (>=1.35.0,<1.36.0)", "mypy-boto3-personalize-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-pi (>=1.35.0,<1.36.0)", "mypy-boto3-pinpoint (>=1.35.0,<1.36.0)", "mypy-boto3-pinpoint-email (>=1.35.0,<1.36.0)", "mypy-boto3-pinpoint-sms-voice (>=1.35.0,<1.36.0)", "mypy-boto3-pinpoint-sms-voice-v2 (>=1.35.0,<1.36.0)", "mypy-boto3-pipes (>=1.35.0,<1.36.0)", "mypy-boto3-polly (>=1.35.0,<1.36.0)", "mypy-boto3-pricing (>=1.35.0,<1.36.0)", "mypy-boto3-privatenetworks (>=1.35.0,<1.36.0)", "mypy-boto3-proton (>=1.35.0,<1.36.0)", "mypy-boto3-qapps (>=1.35.0,<1.36.0)", "mypy-boto3-qbusiness (>=1.35.0,<1.36.0)", "mypy-boto3-qconnect (>=1.35.0,<1.36.0)", "mypy-boto3-qldb (>=1.35.0,<1.36.0)", "mypy-boto3-qldb-session (>=1.35.0,<1.36.0)", "mypy-boto3-quicksight (>=1.35.0,<1.36.0)", "mypy-boto3-ram (>=1.35.0,<1.36.0)", "mypy-boto3-rbin (>=1.35.0,<1.36.0)", "mypy-boto3-rds (>=1.35.0,<1.36.0)", "mypy-boto3-rds-data (>=1.35.0,<1.36.0)", "mypy-boto3-redshift (>=1.35.0,<1.36.0)", "mypy-boto3-redshift-data (>=1.35.0,<1.36.0)", "mypy-boto3-redshift-serverless (>=1.35.0,<1.36.0)", "mypy-boto3-rekognition (>=1.35.0,<1.36.0)", "mypy-boto3-repostspace (>=1.35.0,<1.36.0)", "mypy-boto3-resiliencehub (>=1.35.0,<1.36.0)", "mypy-boto3-resource-explorer-2 (>=1.35.0,<1.36.0)", "mypy-boto3-resource-groups (>=1.35.0,<1.36.0)", "mypy-boto3-resourcegroupstaggingapi (>=1.35.0,<1.36.0)", "mypy-boto3-robomaker (>=1.35.0,<1.36.0)", "mypy-boto3-rolesanywhere (>=1.35.0,<1.36.0)", "mypy-boto3-route53 (>=1.35.0,<1.36.0)", "mypy-boto3-route53-recovery-cluster (>=1.35.0,<1.36.0)", "mypy-boto3-route53-recovery-control-config (>=1.35.0,<1.36.0)", "mypy-boto3-route53-recovery-readiness (>=1.35.0,<1.36.0)", "mypy-boto3-route53domains (>=1.35.0,<1.36.0)", "mypy-boto3-route53profiles (>=1.35.0,<1.36.0)", "mypy-boto3-route53resolver (>=1.35.0,<1.36.0)", "mypy-boto3-rum (>=1.35.0,<1.36.0)", "mypy-boto3-s3 (>=1.35.0,<1.36.0)", "mypy-boto3-s3control (>=1.35.0,<1.36.0)", "mypy-boto3-s3outposts (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-a2i-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-edge (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-featurestore-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-geospatial (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-metrics (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-savingsplans (>=1.35.0,<1.36.0)", "mypy-boto3-scheduler (>=1.35.0,<1.36.0)", "mypy-boto3-schemas (>=1.35.0,<1.36.0)", "mypy-boto3-sdb (>=1.35.0,<1.36.0)", "mypy-boto3-secretsmanager (>=1.35.0,<1.36.0)", "mypy-boto3-securityhub (>=1.35.0,<1.36.0)", "mypy-boto3-securitylake (>=1.35.0,<1.36.0)", "mypy-boto3-serverlessrepo (>=1.35.0,<1.36.0)", "mypy-boto3-service-quotas (>=1.35.0,<1.36.0)", "mypy-boto3-servicecatalog (>=1.35.0,<1.36.0)", "mypy-boto3-servicecatalog-appregistry (>=1.35.0,<1.36.0)", "mypy-boto3-servicediscovery (>=1.35.0,<1.36.0)", "mypy-boto3-ses (>=1.35.0,<1.36.0)", "mypy-boto3-sesv2 (>=1.35.0,<1.36.0)", "mypy-boto3-shield (>=1.35.0,<1.36.0)", "mypy-boto3-signer (>=1.35.0,<1.36.0)", "mypy-boto3-simspaceweaver (>=1.35.0,<1.36.0)", "mypy-boto3-sms (>=1.35.0,<1.36.0)", "mypy-boto3-sms-voice (>=1.35.0,<1.36.0)", "mypy-boto3-snow-device-management (>=1.35.0,<1.36.0)", "mypy-boto3-snowball (>=1.35.0,<1.36.0)", "mypy-boto3-sns (>=1.35.0,<1.36.0)", "mypy-boto3-socialmessaging (>=1.35.0,<1.36.0)", "mypy-boto3-sqs (>=1.35.0,<1.36.0)", "mypy-boto3-ssm (>=1.35.0,<1.36.0)", "mypy-boto3-ssm-contacts (>=1.35.0,<1.36.0)", "mypy-boto3-ssm-incidents (>=1.35.0,<1.36.0)", "mypy-boto3-ssm-quicksetup (>=1.35.0,<1.36.0)", "mypy-boto3-ssm-sap (>=1.35.0,<1.36.0)", "mypy-boto3-sso (>=1.35.0,<1.36.0)", "mypy-boto3-sso-admin (>=1.35.0,<1.36.0)", "mypy-boto3-sso-oidc (>=1.35.0,<1.36.0)", "mypy-boto3-stepfunctions (>=1.35.0,<1.36.0)", "mypy-boto3-storagegateway (>=1.35.0,<1.36.0)", "mypy-boto3-sts (>=1.35.0,<1.36.0)", "mypy-boto3-supplychain (>=1.35.0,<1.36.0)", "mypy-boto3-support (>=1.35.0,<1.36.0)", "mypy-boto3-support-app (>=1.35.0,<1.36.0)", "mypy-boto3-swf (>=1.35.0,<1.36.0)", "mypy-boto3-synthetics (>=1.35.0,<1.36.0)", "mypy-boto3-taxsettings (>=1.35.0,<1.36.0)", "mypy-boto3-textract (>=1.35.0,<1.36.0)", "mypy-boto3-timestream-influxdb (>=1.35.0,<1.36.0)", "mypy-boto3-timestream-query (>=1.35.0,<1.36.0)", "mypy-boto3-timestream-write (>=1.35.0,<1.36.0)", "mypy-boto3-tnb (>=1.35.0,<1.36.0)", "mypy-boto3-transcribe (>=1.35.0,<1.36.0)", "mypy-boto3-transfer (>=1.35.0,<1.36.0)", "mypy-boto3-translate (>=1.35.0,<1.36.0)", "mypy-boto3-trustedadvisor (>=1.35.0,<1.36.0)", "mypy-boto3-verifiedpermissions (>=1.35.0,<1.36.0)", "mypy-boto3-voice-id (>=1.35.0,<1.36.0)", "mypy-boto3-vpc-lattice (>=1.35.0,<1.36.0)", "mypy-boto3-waf (>=1.35.0,<1.36.0)", "mypy-boto3-waf-regional (>=1.35.0,<1.36.0)", "mypy-boto3-wafv2 (>=1.35.0,<1.36.0)", "mypy-boto3-wellarchitected (>=1.35.0,<1.36.0)", "mypy-boto3-wisdom (>=1.35.0,<1.36.0)", "mypy-boto3-workdocs (>=1.35.0,<1.36.0)", "mypy-boto3-workmail (>=1.35.0,<1.36.0)", "mypy-boto3-workmailmessageflow (>=1.35.0,<1.36.0)", "mypy-boto3-workspaces (>=1.35.0,<1.36.0)", "mypy-boto3-workspaces-thin-client (>=1.35.0,<1.36.0)", "mypy-boto3-workspaces-web (>=1.35.0,<1.36.0)", "mypy-boto3-xray (>=1.35.0,<1.36.0)"] amp = ["mypy-boto3-amp (>=1.35.0,<1.36.0)"] amplify = ["mypy-boto3-amplify (>=1.35.0,<1.36.0)"] amplifybackend = ["mypy-boto3-amplifybackend (>=1.35.0,<1.36.0)"] @@ -175,12 +175,14 @@ backup = ["mypy-boto3-backup (>=1.35.0,<1.36.0)"] backup-gateway = ["mypy-boto3-backup-gateway (>=1.35.0,<1.36.0)"] batch = ["mypy-boto3-batch (>=1.35.0,<1.36.0)"] bcm-data-exports = ["mypy-boto3-bcm-data-exports (>=1.35.0,<1.36.0)"] +bcm-pricing-calculator = ["mypy-boto3-bcm-pricing-calculator (>=1.35.0,<1.36.0)"] bedrock = ["mypy-boto3-bedrock (>=1.35.0,<1.36.0)"] bedrock-agent = ["mypy-boto3-bedrock-agent (>=1.35.0,<1.36.0)"] bedrock-agent-runtime = ["mypy-boto3-bedrock-agent-runtime (>=1.35.0,<1.36.0)"] bedrock-runtime = ["mypy-boto3-bedrock-runtime (>=1.35.0,<1.36.0)"] +billing = ["mypy-boto3-billing (>=1.35.0,<1.36.0)"] billingconductor = ["mypy-boto3-billingconductor (>=1.35.0,<1.36.0)"] -boto3 = ["boto3 (==1.35.41)", "botocore (==1.35.41)"] +boto3 = ["boto3 (==1.35.71)", "botocore (==1.35.71)"] braket = ["mypy-boto3-braket (>=1.35.0,<1.36.0)"] budgets = ["mypy-boto3-budgets (>=1.35.0,<1.36.0)"] ce = ["mypy-boto3-ce (>=1.35.0,<1.36.0)"] @@ -228,6 +230,7 @@ config = ["mypy-boto3-config (>=1.35.0,<1.36.0)"] connect = ["mypy-boto3-connect (>=1.35.0,<1.36.0)"] connect-contact-lens = ["mypy-boto3-connect-contact-lens (>=1.35.0,<1.36.0)"] connectcampaigns = ["mypy-boto3-connectcampaigns (>=1.35.0,<1.36.0)"] +connectcampaignsv2 = ["mypy-boto3-connectcampaignsv2 (>=1.35.0,<1.36.0)"] connectcases = ["mypy-boto3-connectcases (>=1.35.0,<1.36.0)"] connectparticipant = ["mypy-boto3-connectparticipant (>=1.35.0,<1.36.0)"] controlcatalog = ["mypy-boto3-controlcatalog (>=1.35.0,<1.36.0)"] @@ -291,6 +294,9 @@ freetier = ["mypy-boto3-freetier (>=1.35.0,<1.36.0)"] fsx = ["mypy-boto3-fsx (>=1.35.0,<1.36.0)"] full = ["boto3-stubs-full"] gamelift = ["mypy-boto3-gamelift (>=1.35.0,<1.36.0)"] +geo-maps = ["mypy-boto3-geo-maps (>=1.35.0,<1.36.0)"] +geo-places = ["mypy-boto3-geo-places (>=1.35.0,<1.36.0)"] +geo-routes = ["mypy-boto3-geo-routes (>=1.35.0,<1.36.0)"] glacier = ["mypy-boto3-glacier (>=1.35.0,<1.36.0)"] globalaccelerator = ["mypy-boto3-globalaccelerator (>=1.35.0,<1.36.0)"] glue = ["mypy-boto3-glue (>=1.35.0,<1.36.0)"] @@ -397,8 +403,10 @@ neptunedata = ["mypy-boto3-neptunedata (>=1.35.0,<1.36.0)"] network-firewall = ["mypy-boto3-network-firewall (>=1.35.0,<1.36.0)"] networkmanager = ["mypy-boto3-networkmanager (>=1.35.0,<1.36.0)"] networkmonitor = ["mypy-boto3-networkmonitor (>=1.35.0,<1.36.0)"] -nimble = ["mypy-boto3-nimble (>=1.35.0,<1.36.0)"] +notifications = ["mypy-boto3-notifications (>=1.35.0,<1.36.0)"] +notificationscontacts = ["mypy-boto3-notificationscontacts (>=1.35.0,<1.36.0)"] oam = ["mypy-boto3-oam (>=1.35.0,<1.36.0)"] +observabilityadmin = ["mypy-boto3-observabilityadmin (>=1.35.0,<1.36.0)"] omics = ["mypy-boto3-omics (>=1.35.0,<1.36.0)"] opensearch = ["mypy-boto3-opensearch (>=1.35.0,<1.36.0)"] opensearchserverless = ["mypy-boto3-opensearchserverless (>=1.35.0,<1.36.0)"] @@ -408,6 +416,7 @@ organizations = ["mypy-boto3-organizations (>=1.35.0,<1.36.0)"] osis = ["mypy-boto3-osis (>=1.35.0,<1.36.0)"] outposts = ["mypy-boto3-outposts (>=1.35.0,<1.36.0)"] panorama = ["mypy-boto3-panorama (>=1.35.0,<1.36.0)"] +partnercentral-selling = ["mypy-boto3-partnercentral-selling (>=1.35.0,<1.36.0)"] payment-cryptography = ["mypy-boto3-payment-cryptography (>=1.35.0,<1.36.0)"] payment-cryptography-data = ["mypy-boto3-payment-cryptography-data (>=1.35.0,<1.36.0)"] pca-connector-ad = ["mypy-boto3-pca-connector-ad (>=1.35.0,<1.36.0)"] @@ -533,13 +542,13 @@ xray = ["mypy-boto3-xray (>=1.35.0,<1.36.0)"] [[package]] name = "botocore" -version = "1.35.41" +version = "1.35.71" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.35.41-py3-none-any.whl", hash = "sha256:915c4d81e3a0be3b793c1e2efdf19af1d0a9cd4a2d8de08ee18216c14d67764b"}, - {file = "botocore-1.35.41.tar.gz", hash = "sha256:8a09a32136df8768190a6c92f0240cd59c30deb99c89026563efadbbed41fa00"}, + {file = "botocore-1.35.71-py3-none-any.whl", hash = "sha256:fc46e7ab1df3cef66dfba1633f4da77c75e07365b36f03bd64a3793634be8fc1"}, + {file = "botocore-1.35.71.tar.gz", hash = "sha256:f9fa058e0393660c3fe53c1e044751beb64b586def0bd2212448a7c328b0cbba"}, ] [package.dependencies] @@ -552,13 +561,13 @@ crt = ["awscrt (==0.22.0)"] [[package]] name = "botocore-stubs" -version = "1.35.41" +version = "1.35.71" description = "Type annotations and code completion for botocore" optional = false python-versions = ">=3.8" files = [ - {file = "botocore_stubs-1.35.41-py3-none-any.whl", hash = "sha256:99e8f0e20266b2abc0e095ef19e8e628a926c25c4a0edbfd25978f484677bac6"}, - {file = "botocore_stubs-1.35.41.tar.gz", hash = "sha256:62e369aed694471eaf72305cd2f33c356337d49637a5fcc17fc2ef237e8f517f"}, + {file = "botocore_stubs-1.35.71-py3-none-any.whl", hash = "sha256:7e938bb169c28faf05ce14e67bb0b5e5583092ab6ccc9d3d68d698530edb6584"}, + {file = "botocore_stubs-1.35.71.tar.gz", hash = "sha256:c5f7208b20ae19400fa73eb569017f1e372990f7a5505a72116ed6420904f666"}, ] [package.dependencies] @@ -730,18 +739,18 @@ files = [ [[package]] name = "duckduckgo-search" -version = "6.3.0" +version = "6.3.7" description = "Search for words, documents, images, news, maps and text translation using the DuckDuckGo.com search engine." optional = false python-versions = ">=3.8" files = [ - {file = "duckduckgo_search-6.3.0-py3-none-any.whl", hash = "sha256:9a231a7b325226811cf7d35a240f3f501e718ae10a1aa0a638cabc80e129dfe7"}, - {file = "duckduckgo_search-6.3.0.tar.gz", hash = "sha256:e9f56955569325a7d9cacda2488ca78bf6629a459e74415892bee560b664f5eb"}, + {file = "duckduckgo_search-6.3.7-py3-none-any.whl", hash = "sha256:6a831a27977751e8928222f04c99a5d069ff80e2a7c78b699c9b9ac6cb48c41b"}, + {file = "duckduckgo_search-6.3.7.tar.gz", hash = "sha256:53d84966429a6377647e2a1ea7224b657575c7a4d506729bdb837e4ee12915ed"}, ] [package.dependencies] click = ">=8.1.7" -primp = ">=0.6.3" +primp = ">=0.8.1" [package.extras] dev = ["mypy (>=1.11.1)", "pytest (>=8.3.1)", "pytest-asyncio (>=0.23.8)", "ruff (>=0.6.1)"] @@ -767,18 +776,18 @@ gmpy2 = ["gmpy2"] [[package]] name = "fastapi" -version = "0.115.2" +version = "0.115.5" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" optional = false python-versions = ">=3.8" files = [ - {file = "fastapi-0.115.2-py3-none-any.whl", hash = "sha256:61704c71286579cc5a598763905928f24ee98bfcc07aabe84cfefb98812bbc86"}, - {file = "fastapi-0.115.2.tar.gz", hash = "sha256:3995739e0b09fa12f984bce8fa9ae197b35d433750d3d312422d846e283697ee"}, + {file = "fastapi-0.115.5-py3-none-any.whl", hash = "sha256:596b95adbe1474da47049e802f9a65ab2ffa9c2b07e7efee70eb8a66c9f2f796"}, + {file = "fastapi-0.115.5.tar.gz", hash = "sha256:0e7a4d0dc0d01c68df21887cce0945e72d3c48b9f4f79dfe7a7d53aa08fbb289"}, ] [package.dependencies] pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" -starlette = ">=0.37.2,<0.41.0" +starlette = ">=0.40.0,<0.42.0" typing-extensions = ">=4.8.0" [package.extras] @@ -889,13 +898,13 @@ reports = ["lxml"] [[package]] name = "mypy-boto3-bedrock" -version = "1.35.30" -description = "Type annotations for boto3.Bedrock 1.35.30 service generated with mypy-boto3-builder 8.1.2" +version = "1.35.51" +description = "Type annotations for boto3.Bedrock 1.35.51 service generated with mypy-boto3-builder 8.1.4" optional = false python-versions = ">=3.8" files = [ - {file = "mypy_boto3_bedrock-1.35.30-py3-none-any.whl", hash = "sha256:f10e4a69b247b782c410ccdc207950ced7c4af9f62ae8d22e6738d65007ec562"}, - {file = "mypy_boto3_bedrock-1.35.30.tar.gz", hash = "sha256:3356690d47359e0070d7135ab9e23df76095b3c870b0aa61149ec7a31e0e8b4a"}, + {file = "mypy_boto3_bedrock-1.35.51-py3-none-any.whl", hash = "sha256:231d524a2952a23f74684ab4709e773e2703252485cf80db116d20324f38db31"}, + {file = "mypy_boto3_bedrock-1.35.51.tar.gz", hash = "sha256:62218c48a00462283ae24f43a4589ed7422fe21bf607befd333809b3383b4431"}, ] [package.dependencies] @@ -903,13 +912,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-bedrock-agent-runtime" -version = "1.35.32" -description = "Type annotations for boto3.AgentsforBedrockRuntime 1.35.32 service generated with mypy-boto3-builder 8.1.2" +version = "1.35.70" +description = "Type annotations for boto3 AgentsforBedrockRuntime 1.35.70 service generated with mypy-boto3-builder 8.3.1" optional = false python-versions = ">=3.8" files = [ - {file = "mypy_boto3_bedrock_agent_runtime-1.35.32-py3-none-any.whl", hash = "sha256:199b1c456801892d4e4719e399a46d589069ec813652b759cd6fef5d94af5bf5"}, - {file = "mypy_boto3_bedrock_agent_runtime-1.35.32.tar.gz", hash = "sha256:5ae95baad65d3e03fd27648aeaf3388d67f5c91a559b6b05780adcb383dd2b7e"}, + {file = "mypy_boto3_bedrock_agent_runtime-1.35.70-py3-none-any.whl", hash = "sha256:f14529419bf90b2599d7836fb95d65e8dd5662d2d58f17de5927a9fc0c861251"}, + {file = "mypy_boto3_bedrock_agent_runtime-1.35.70.tar.gz", hash = "sha256:d69b182aaae563327b4f7d9c859df48faf50f920a2a1574082d4c2dc5cf9984c"}, ] [package.dependencies] @@ -917,13 +926,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-bedrock-runtime" -version = "1.35.32" -description = "Type annotations for boto3.BedrockRuntime 1.35.32 service generated with mypy-boto3-builder 8.1.2" +version = "1.35.56" +description = "Type annotations for boto3.BedrockRuntime 1.35.56 service generated with mypy-boto3-builder 8.2.0" optional = false python-versions = ">=3.8" files = [ - {file = "mypy_boto3_bedrock_runtime-1.35.32-py3-none-any.whl", hash = "sha256:b847cadf34f47829a604c22d941cd1a173cb42ca4594ddb11f55edd3506f19f1"}, - {file = "mypy_boto3_bedrock_runtime-1.35.32.tar.gz", hash = "sha256:6965ff8d33206197387efff74de0868354049abee87ec243a366b8cdf4534547"}, + {file = "mypy_boto3_bedrock_runtime-1.35.56-py3-none-any.whl", hash = "sha256:418689db8cfce7127b83e8d3a0856cc249025d3aea05abaddd99df57b8162bbc"}, + {file = "mypy_boto3_bedrock_runtime-1.35.56.tar.gz", hash = "sha256:07670a32841050ddf7ad55d07d00daede9eadabbe809424a915227e6880b1d06"}, ] [package.dependencies] @@ -942,13 +951,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -995,19 +1004,20 @@ type = ["mypy (>=1.11.2)"] [[package]] name = "primp" -version = "0.6.3" +version = "0.8.1" description = "HTTP client that can impersonate web browsers, mimicking their headers and `TLS/JA3/JA4/HTTP2` fingerprints" optional = false python-versions = ">=3.8" files = [ - {file = "primp-0.6.3-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bdbe6a7cdaaf5c9ed863432a941f4a75bd4c6ff626cbc8d32fc232793c70ba06"}, - {file = "primp-0.6.3-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:eeb53eb987bdcbcd85740633470255cab887d921df713ffa12a36a13366c9cdb"}, - {file = "primp-0.6.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78da53d3c92a8e3f05bd3286ac76c291f1b6fe5e08ea63b7ba92b0f9141800bb"}, - {file = "primp-0.6.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:86337b44deecdac752bd8112909987fc9fa9b894f30191c80a164dc8f895da53"}, - {file = "primp-0.6.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d3cd9a22b97f3eae42b2a5fb99f00480daf4cd6d9b139e05b0ffb03f7cc037f3"}, - {file = "primp-0.6.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7732bec917e2d3c48a31cdb92e1250f4ad6203a1aa4f802bd9abd84f2286a1e0"}, - {file = "primp-0.6.3-cp38-abi3-win_amd64.whl", hash = "sha256:1e4113c34b86c676ae321af185f03a372caef3ee009f1682c2d62e30ec87348c"}, - {file = "primp-0.6.3.tar.gz", hash = "sha256:17d30ebe26864defad5232dbbe1372e80483940012356e1f68846bb182282039"}, + {file = "primp-0.8.1-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:8294db817701ad76b6a186c16e22cc49d36fac5986647a83657ad4a58ddeee42"}, + {file = "primp-0.8.1-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:e8117531dcdb0dbcf9855fdbac73febdde5967ca0332a2c05b5961d2fbcfe749"}, + {file = "primp-0.8.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:993cc4284e8c5c858254748f078e872ba250c9339d64398dc000a8f9cffadda3"}, + {file = "primp-0.8.1-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4a27ac642be5c616fc5f139a5ad391dcd0c5964ace56fe6cf31cbffb972a7480"}, + {file = "primp-0.8.1-cp38-abi3-manylinux_2_34_armv7l.whl", hash = "sha256:e8483b8d9eec9fc43d77bb448555466030f29cdd99d9375eb75155e9f832e5bd"}, + {file = "primp-0.8.1-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:92f5f8267216252cfb27f2149811e14682bb64f0c5d37f00d218d1592e02f0b9"}, + {file = "primp-0.8.1-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:98f7f3a9481c55c56e7eff9024f29e16379a87d5b0a1b683e145dd8fcbdcc46b"}, + {file = "primp-0.8.1-cp38-abi3-win_amd64.whl", hash = "sha256:6f0018a26be787431504e32548b296a278abbe85da43bcbaf2d4982ac3dcd332"}, + {file = "primp-0.8.1.tar.gz", hash = "sha256:ddf05754a7b70d59df8a014a8585e418f9c04e0b69065bab6633f4a9b92bad93"}, ] [package.extras] @@ -1037,19 +1047,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.2" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e"}, + {file = "pydantic-2.10.2.tar.gz", hash = "sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.1" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1057,100 +1067,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.1" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206"}, + {file = "pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c"}, + {file = "pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc"}, + {file = "pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9"}, + {file = "pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5"}, + {file = "pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae"}, + {file = "pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c"}, + {file = "pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16"}, + {file = "pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23"}, + {file = "pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05"}, + {file = "pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337"}, + {file = "pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:5897bec80a09b4084aee23f9b73a9477a46c3304ad1d2d07acca19723fb1de62"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d0165ab2914379bd56908c02294ed8405c252250668ebcb438a55494c69f44ab"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b9af86e1d8e4cfc82c2022bfaa6f459381a50b94a29e95dcdda8442d6d83864"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f6c8a66741c5f5447e047ab0ba7a1c61d1e95580d64bce852e3df1f895c4067"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a42d6a8156ff78981f8aa56eb6394114e0dedb217cf8b729f438f643608cbcd"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64c65f40b4cd8b0e049a8edde07e38b476da7e3aaebe63287c899d2cff253fa5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdcf339322a3fae5cbd504edcefddd5a50d9ee00d968696846f089b4432cf78"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf99c8404f008750c846cb4ac4667b798a9f7de673ff719d705d9b2d6de49c5f"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f1edcea27918d748c7e5e4d917297b2a0ab80cad10f86631e488b7cddf76a36"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:159cac0a3d096f79ab6a44d77a961917219707e2a130739c64d4dd46281f5c2a"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:029d9757eb621cc6e1848fa0b0310310de7301057f623985698ed7ebb014391b"}, + {file = "pydantic_core-2.27.1-cp38-none-win32.whl", hash = "sha256:a28af0695a45f7060e6f9b7092558a928a28553366519f64083c63a44f70e618"}, + {file = "pydantic_core-2.27.1-cp38-none-win_amd64.whl", hash = "sha256:2d4567c850905d5eaaed2f7a404e61012a51caf288292e016360aa2b96ff38d4"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:e9386266798d64eeb19dd3677051f5705bf873e98e15897ddb7d76f477131967"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4228b5b646caa73f119b1ae756216b59cc6e2267201c27d3912b592c5e323b60"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3dfe500de26c52abe0477dde16192ac39c98f05bf2d80e76102d394bd13854"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aee66be87825cdf72ac64cb03ad4c15ffef4143dbf5c113f64a5ff4f81477bf9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b748c44bb9f53031c8cbc99a8a061bc181c1000c60a30f55393b6e9c45cc5bd"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ca038c7f6a0afd0b2448941b6ef9d5e1949e999f9e5517692eb6da58e9d44be"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e0bd57539da59a3e4671b90a502da9a28c72322a4f17866ba3ac63a82c4498e"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac6c2c45c847bbf8f91930d88716a0fb924b51e0c6dad329b793d670ec5db792"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b94d4ba43739bbe8b0ce4262bcc3b7b9f31459ad120fb595627eaeb7f9b9ca01"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:00e6424f4b26fe82d44577b4c842d7df97c20be6439e8e685d0d715feceb9fb9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:38de0a70160dd97540335b7ad3a74571b24f1dc3ed33f815f0880682e6880131"}, + {file = "pydantic_core-2.27.1-cp39-none-win32.whl", hash = "sha256:7ccebf51efc61634f6c2344da73e366c75e735960b5654b63d7e6f69a5885fa3"}, + {file = "pydantic_core-2.27.1-cp39-none-win_amd64.whl", hash = "sha256:a57847b090d7892f123726202b7daa20df6694cbd583b67a592e856bff603d6c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5fde892e6c697ce3e30c61b239330fc5d569a71fefd4eb6512fc6caec9dd9e2f"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:816f5aa087094099fff7edabb5e01cc370eb21aa1a1d44fe2d2aefdfb5599b31"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c10c309e18e443ddb108f0ef64e8729363adbfd92d6d57beec680f6261556f3"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98476c98b02c8e9b2eec76ac4156fd006628b1b2d0ef27e548ffa978393fd154"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c3027001c28434e7ca5a6e1e527487051136aa81803ac812be51802150d880dd"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7699b1df36a48169cdebda7ab5a2bac265204003f153b4bd17276153d997670a"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1c39b07d90be6b48968ddc8c19e7585052088fd7ec8d568bb31ff64c70ae3c97"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:46ccfe3032b3915586e469d4972973f893c0a2bb65669194a5bdea9bacc088c2"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:62ba45e21cf6571d7f716d903b5b7b6d2617e2d5d67c0923dc47b9d41369f840"}, + {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, ] [package.dependencies] @@ -1265,13 +1286,13 @@ pyasn1 = ">=0.1.3" [[package]] name = "s3transfer" -version = "0.10.3" +version = "0.10.4" description = "An Amazon S3 Transfer Manager" optional = false python-versions = ">=3.8" files = [ - {file = "s3transfer-0.10.3-py3-none-any.whl", hash = "sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d"}, - {file = "s3transfer-0.10.3.tar.gz", hash = "sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c"}, + {file = "s3transfer-0.10.4-py3-none-any.whl", hash = "sha256:244a76a24355363a68164241438de1b72f8781664920260c48465896b712a41e"}, + {file = "s3transfer-0.10.4.tar.gz", hash = "sha256:29edc09801743c21eb5ecbc617a152df41d3c287f67b615f73e5f750583666a7"}, ] [package.dependencies] @@ -1318,13 +1339,13 @@ files = [ [[package]] name = "starlette" -version = "0.40.0" +version = "0.41.3" description = "The little ASGI library that shines." optional = false python-versions = ">=3.8" files = [ - {file = "starlette-0.40.0-py3-none-any.whl", hash = "sha256:c494a22fae73805376ea6bf88439783ecfba9aac88a43911b48c653437e784c4"}, - {file = "starlette-0.40.0.tar.gz", hash = "sha256:1a3139688fb298ce5e2d661d37046a66ad996ce94be4d4983be019a23a04ea35"}, + {file = "starlette-0.41.3-py3-none-any.whl", hash = "sha256:44cedb2b7c77a9de33a8b74b2b90e9f50d11fcf25d8270ea525ad71a25374ff7"}, + {file = "starlette-0.41.3.tar.gz", hash = "sha256:0e4ab3d16522a255be6b28260b938eae2482f98ce5cc934cb08dce8dc3ba5835"}, ] [package.dependencies] @@ -1350,24 +1371,24 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "types-awscrt" -version = "0.22.0" +version = "0.23.1" description = "Type annotations and code completion for awscrt" optional = false python-versions = ">=3.8" files = [ - {file = "types_awscrt-0.22.0-py3-none-any.whl", hash = "sha256:b2c196bbd3226bab42d80fae13c34548de9ddc195f5a366d79c15d18e5897aa9"}, - {file = "types_awscrt-0.22.0.tar.gz", hash = "sha256:67a660c90bad360c339f6a79310cc17094d12472042c7ca5a41450aaf5fc9a54"}, + {file = "types_awscrt-0.23.1-py3-none-any.whl", hash = "sha256:0d362a5d62d68ca4216f458172f41c1123ec04791d68364de8ee8b61b528b262"}, + {file = "types_awscrt-0.23.1.tar.gz", hash = "sha256:a20b425dabb258bc3d07a5e7de503fd9558dd1542d72de796e74e402c6d493b2"}, ] [[package]] name = "types-requests" -version = "2.32.0.20240914" +version = "2.32.0.20241016" description = "Typing stubs for requests" optional = false python-versions = ">=3.8" files = [ - {file = "types-requests-2.32.0.20240914.tar.gz", hash = "sha256:2850e178db3919d9bf809e434eef65ba49d0e7e33ac92d588f4a5e295fffd405"}, - {file = "types_requests-2.32.0.20240914-py3-none-any.whl", hash = "sha256:59c2f673eb55f32a99b2894faf6020e1a9f4a402ad0f192bfee0b64469054310"}, + {file = "types-requests-2.32.0.20241016.tar.gz", hash = "sha256:0d9cad2f27515d0e3e3da7134a1b6f28fb97129d86b867f24d9c726452634d95"}, + {file = "types_requests-2.32.0.20241016-py3-none-any.whl", hash = "sha256:4195d62d6d3e043a4eaaf08ff8a62184584d2e8684e9d2aa178c7915a7da3747"}, ] [package.dependencies] @@ -1386,13 +1407,13 @@ files = [ [[package]] name = "types-s3transfer" -version = "0.10.3" +version = "0.10.4" description = "Type annotations and code completion for s3transfer" optional = false python-versions = ">=3.8" files = [ - {file = "types_s3transfer-0.10.3-py3-none-any.whl", hash = "sha256:d34c5a82f531af95bb550927136ff5b737a1ed3087f90a59d545591dfde5b4cc"}, - {file = "types_s3transfer-0.10.3.tar.gz", hash = "sha256:f761b2876ac4c208e6c6b75cdf5f6939009768be9950c545b11b0225e7703ee7"}, + {file = "types_s3transfer-0.10.4-py3-none-any.whl", hash = "sha256:22ac1aabc98f9d7f2928eb3fb4d5c02bf7435687f0913345a97dd3b84d0c217d"}, + {file = "types_s3transfer-0.10.4.tar.gz", hash = "sha256:03123477e3064c81efe712bf9d372c7c72f2790711431f9baa59cf96ea607267"}, ] [[package]] @@ -1425,13 +1446,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "uvicorn" -version = "0.23.2" +version = "0.32.1" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.8" files = [ - {file = "uvicorn-0.23.2-py3-none-any.whl", hash = "sha256:1f9be6558f01239d4fdf22ef8126c39cb1ad0addf76c40e760549d2c2f43ab53"}, - {file = "uvicorn-0.23.2.tar.gz", hash = "sha256:4d3cc12d7727ba72b64d12d3cc7743124074c0a69f7b201512fc50c3e3f1569a"}, + {file = "uvicorn-0.32.1-py3-none-any.whl", hash = "sha256:82ad92fd58da0d12af7482ecdb5f2470a04c9c9a53ced65b9bbb4a205377602e"}, + {file = "uvicorn-0.32.1.tar.gz", hash = "sha256:ee9519c246a72b1c084cea8d3b44ed6026e78a4a309cbedae9c37e4cb9fbb175"}, ] [package.dependencies] @@ -1439,9 +1460,9 @@ click = ">=7.0" h11 = ">=0.8" [package.extras] -standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] +standard = ["colorama (>=0.4)", "httptools (>=0.6.3)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] [metadata] lock-version = "2.0" python-versions = ">=3.11,<3.13" -content-hash = "9a58568f29f268870b28c16abb4d818df34f836c6a7b5ccfc6764ec4e43bfb88" +content-hash = "3dd87314ea88fc4ce17abbfcb1a3f6fe8384e859db8edfb489a4b089ca8d2565" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 7768cc8ef..00bdcb81b 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -6,7 +6,7 @@ python = ">=3.11,<3.13" fastapi = ">=0.109.1,<1" requests = "^2.32.0" types-requests = "^2.31.0" -pydantic = "^2.4.0" +pydantic = "^2.10.2" pyhumps = "^3.8.0" uvicorn = ">=0.23.1,<1" python-ulid = "^1.1.0" diff --git a/backend/tests/test_repositories/test_conversation.py b/backend/tests/test_repositories/test_conversation.py index 9a2b50af4..cbc072b18 100644 --- a/backend/tests/test_repositories/test_conversation.py +++ b/backend/tests/test_repositories/test_conversation.py @@ -1,6 +1,9 @@ -import sys import base64 +import json +import os +import sys import unittest +from unittest.mock import MagicMock, patch sys.path.append(".") @@ -23,15 +26,16 @@ store_bot, ) from app.repositories.models.conversation import ( - SimpleMessageModel, ChunkModel, FeedbackModel, - TextContentModel, ImageContentModel, + SimpleMessageModel, + TextContentModel, ToolUseContentModel, ToolUseContentModelBody, ) from app.repositories.models.custom_bot import ( + ActiveModelsModel, AgentModel, AgentToolModel, BotModel, @@ -123,6 +127,33 @@ class TestConversationRepository(unittest.TestCase): + def setUp(self): + self.patcher1 = patch("boto3.resource") + self.patcher2 = patch("app.repositories.conversation.s3_client") + self.mock_boto3_resource = self.patcher1.start() + self.mock_s3_client = self.patcher2.start() + + self.mock_table = MagicMock() + self.mock_boto3_resource.return_value.Table.return_value = self.mock_table + + # Set up environment variables + os.environ["CONVERSATION_TABLE_NAME"] = "test-table" + os.environ["CONVERSATION_BUCKET_NAME"] = "test-bucket" + os.environ["LARGE_MESSAGE_BUCKET"] = "test-large-message-bucket" + os.environ["BEDROCK_REGION"] = "us-east-1" + + self.title_updated = False + self.feedback_updated = False + self.conversation_deleted = False + + def tearDown(self): + self.patcher1.stop() + self.patcher2.stop() + os.environ.pop("CONVERSATION_TABLE_NAME", None) + os.environ.pop("CONVERSATION_BUCKET_NAME", None) + os.environ.pop("LARGE_MESSAGE_BUCKET", None) + os.environ.pop("BEDROCK_REGION", None) + def test_store_and_find_conversation(self): conversation = ConversationModel( id="1", @@ -184,6 +215,66 @@ def test_store_and_find_conversation(self): should_continue=False, ) + # Mock the responses + self.mock_table.put_item.return_value = { + "ResponseMetadata": {"HTTPStatusCode": 200} + } + + def mock_query_side_effect(**kwargs): + if self.conversation_deleted: + return {"Items": []} + + if "IndexName" in kwargs and kwargs["IndexName"] == "SKIndex": + message_map = conversation.model_dump()["message_map"] + if self.feedback_updated: + message_map["a"]["feedback"] = { + "thumbs_up": True, + "category": "Good", + "comment": "The response is pretty good.", + } + return { + "Items": [ + { + "PK": "user", + "SK": "user#CONV#1", + "Title": ( + "Updated title" + if self.title_updated + else "Test Conversation" + ), + "CreateTime": 1627984879.9, + "TotalPrice": 100, + "LastMessageId": "x", + "MessageMap": json.dumps(message_map), + "IsLargeMessage": False, + "ShouldContinue": False, + } + ] + } + return { + "Items": ( + [] + if self.conversation_deleted + else [ + { + "PK": "user", + "SK": "user#CONV#1", + "Title": "Test Conversation", + "CreateTime": 1627984879.9, + "TotalPrice": 100, + "LastMessageId": "x", + "MessageMap": json.dumps( + conversation.model_dump()["message_map"] + ), + "IsLargeMessage": False, + "ShouldContinue": False, + } + ] + ) + } + + self.mock_table.query.side_effect = mock_query_side_effect + # Test storing conversation response = store_conversation("user", conversation) self.assertIsNotNone(response) @@ -197,6 +288,8 @@ def test_store_and_find_conversation(self): user_id="user", conversation_id="1" ) self.assertEqual(found_conversation.id, "1") + self.assertEqual(found_conversation.title, "Test Conversation") + message_map = found_conversation.message_map # Assert whether the message map is correctly reconstructed self.assertEqual(message_map["a"].role, "user") @@ -228,11 +321,17 @@ def test_store_and_find_conversation(self): self.assertEqual( message_map["a"].thinking_log[0].content[0].body.name, "internet_search" # type: ignore ) + self.assertEqual(found_conversation.message_map["a"].content[0].body, "Hello") self.assertEqual( message_map["a"].thinking_log[0].content[0].body.input["query"], "Google news" # type: ignore ) # Test update title + self.title_updated = True + self.mock_table.update_item.return_value = { + "Attributes": {"Title": "Updated title"}, + "ResponseMetadata": {"HTTPStatusCode": 200}, + } response = change_conversation_title( user_id="user", conversation_id="1", @@ -245,6 +344,7 @@ def test_store_and_find_conversation(self): # Test give a feedback self.assertIsNone(found_conversation.message_map["a"].feedback) + self.feedback_updated = True response = update_feedback( user_id="user", conversation_id="1", @@ -263,6 +363,7 @@ def test_store_and_find_conversation(self): self.assertEqual(feedback.comment, "The response is pretty good.") # type: ignore # Test deleting conversation by id + self.conversation_deleted = True delete_conversation_by_id(user_id="user", conversation_id="1") with self.assertRaises(RecordNotFoundError): find_conversation_by_id("user", "1") @@ -293,7 +394,7 @@ def test_store_and_find_large_conversation(self): used_chunks=None, thinking_log=None, ) - for i in range(10) # Create 10 large messages + for i in range(10) } large_conversation = ConversationModel( @@ -307,7 +408,80 @@ def test_store_and_find_large_conversation(self): should_continue=False, ) - # Test storing large conversation with a small threshold + # Mock responses + self.mock_table.put_item.return_value = { + "ResponseMetadata": {"HTTPStatusCode": 200} + } + self.mock_s3_client.put_object.return_value = { + "ResponseMetadata": {"HTTPStatusCode": 200} + } + + def mock_query_side_effect(**kwargs): + if self.conversation_deleted: + return {"Items": []} + + if "IndexName" in kwargs and kwargs["IndexName"] == "SKIndex": + return { + "Items": [ + { + "PK": "user", + "SK": "user#CONV#2", + "Title": "Large Conversation", + "CreateTime": 1627984879.9, + "TotalPrice": 200, + "LastMessageId": "msg_9", + "IsLargeMessage": True, + "LargeMessagePath": "user/2/message_map.json", + "MessageMap": json.dumps( + { + "system": { + "role": "system", + "content": [ + { + "content_type": "text", + "body": "Hello", + "media_type": None, + } + ], + "model": "claude-instant-v1", + "children": [], + "parent": None, + "create_time": 1627984879.9, + "feedback": None, + "used_chunks": None, + "thinking_log": None, + } + } + ), + "ShouldContinue": False, + } + ] + } + return {"Items": []} + + self.mock_table.query.side_effect = mock_query_side_effect + + message_map_json = json.dumps( + { + k: { + "role": v.role, + "content": [c.model_dump() for c in v.content], + "model": v.model, + "children": v.children, + "parent": v.parent, + "create_time": v.create_time, + "feedback": v.feedback, + "used_chunks": v.used_chunks, + "thinking_log": v.thinking_log, + } + for k, v in large_message_map.items() + } + ) + self.mock_s3_client.get_object.return_value = { + "Body": MagicMock(read=lambda: message_map_json.encode()) + } + + # Test storing large conversation response = store_conversation("user", large_conversation, threshold=1) self.assertIsNotNone(response) @@ -321,14 +495,12 @@ def test_store_and_find_large_conversation(self): self.assertEqual(found_conversation.last_message_id, "msg_9") self.assertEqual(found_conversation.bot_id, None) self.assertEqual(found_conversation.should_continue, False) - - message_map = found_conversation.message_map - self.assertEqual(len(message_map), 10) + self.assertEqual(len(found_conversation.message_map), 10) for i in range(10): message_id = f"msg_{i}" - self.assertIn(message_id, message_map) - message = message_map[message_id] + self.assertIn(message_id, found_conversation.message_map) + message = found_conversation.message_map[message_id] self.assertEqual(message.role, "user") self.assertEqual(len(message.content), 1) self.assertEqual(message.content[0].content_type, "text") @@ -339,6 +511,7 @@ def test_store_and_find_large_conversation(self): self.assertEqual(message.create_time, 1627984879.9) # Test deleting large conversation + self.conversation_deleted = True delete_conversation_by_id(user_id="user", conversation_id="2") with self.assertRaises(RecordNotFoundError): find_conversation_by_id("user", "2") @@ -350,8 +523,27 @@ def test_store_and_find_large_conversation(self): class TestConversationBotRepository(unittest.TestCase): - def setUp(self) -> None: - conversation1 = ConversationModel( + def setUp(self): + self.patcher = patch("boto3.resource") + self.mock_boto3_resource = self.patcher.start() + + self.mock_table = MagicMock() + self.mock_boto3_resource.return_value.Table.return_value = self.mock_table + + # Set up environment variables + os.environ["CONVERSATION_TABLE_NAME"] = "test-table" + os.environ["CONVERSATION_BUCKET_NAME"] = "test-bucket" + + self.active_models = ActiveModelsModel( + claude3_sonnet_v1=True, + claude3_haiku_v1=True, + claude3_opus_v1=True, + claude3_5_sonnet_v1=True, + claude3_5_sonnet_v2=True, + claude3_5_haiku_v1=True, + ) + + self.conversation1 = ConversationModel( id="1", create_time=1627984879.9, title="Test Conversation", @@ -385,7 +577,8 @@ def setUp(self) -> None: bot_id=None, should_continue=False, ) - conversation2 = ConversationModel( + + self.conversation2 = ConversationModel( id="2", create_time=1627984879.9, title="Test Conversation", @@ -419,7 +612,8 @@ def setUp(self) -> None: bot_id="1", should_continue=False, ) - bot1 = BotModel( + + self.bot1 = BotModel( id="1", title="Test Bot", instruction="Test Bot Prompt", @@ -460,8 +654,10 @@ def setUp(self) -> None: ], bedrock_knowledge_base=None, bedrock_guardrails=None, + active_models=self.active_models, ) - bot2 = BotModel( + + self.bot2 = BotModel( id="2", title="Test Bot", instruction="Test Bot Prompt", @@ -502,25 +698,79 @@ def setUp(self) -> None: ], bedrock_knowledge_base=None, bedrock_guardrails=None, + active_models=self.active_models, # Added the missing field ) - store_conversation("user", conversation1) - store_bot("user", bot1) - store_bot("user", bot2) - store_conversation("user", conversation2) + store_conversation("user", self.conversation1) + store_bot("user", self.bot1) + store_bot("user", self.bot2) + store_conversation("user", self.conversation2) + + def tearDown(self): + self.patcher.stop() + os.environ.pop("CONVERSATION_TABLE_NAME", None) + os.environ.pop("CONVERSATION_BUCKET_NAME", None) def test_only_conversation_is_fetched(self): + self.mock_table.query.return_value = { + "Items": [ + { + "PK": "user", + "SK": "user#CONV#1", + "Title": "Test Conversation", + "CreateTime": 1627984879.9, + "MessageMap": json.dumps( + { + "system": { + "role": "system", + "content": [ + { + "content_type": "text", + "body": "Hello", + "media_type": None, + } + ], + "model": "claude-instant-v1", + "children": [], + "parent": None, + "create_time": 1627984879.9, + "feedback": None, + "used_chunks": None, + "thinking_log": None, + } + } + ), + "BotId": None, + } + ] + } conversations = find_conversation_by_user_id("user") - self.assertEqual(len(conversations), 2) + self.assertEqual(len(conversations), 1) def test_only_bot_is_fetched(self): + self.mock_table.query.return_value = { + "Items": [ + { + "PK": "user", + "SK": "user#BOT#1", + "Title": "Test Bot", + "Description": "Test Bot Description", + "CreateTime": 1627984879.9, + "LastBotUsed": 1627984879.9, + "IsPinned": False, + "SyncStatus": "RUNNING", + "BedrockKnowledgeBase": None, + } + ] + } bots = find_private_bots_by_user_id("user") - self.assertEqual(len(bots), 2) + self.assertEqual(len(bots), 1) + - def tearDown(self) -> None: - delete_conversation_by_user_id("user") - delete_bot_by_id("user", "1") - delete_bot_by_id("user", "2") +def tearDown(self) -> None: + delete_conversation_by_user_id("user") + delete_bot_by_id("user", "1") + delete_bot_by_id("user", "2") if __name__ == "__main__": diff --git a/backend/tests/test_repositories/test_custom_bot.py b/backend/tests/test_repositories/test_custom_bot.py index ba4605401..cd317f71c 100644 --- a/backend/tests/test_repositories/test_custom_bot.py +++ b/backend/tests/test_repositories/test_custom_bot.py @@ -22,6 +22,7 @@ update_knowledge_base_id, ) from app.repositories.models.custom_bot import ( + ActiveModelsModel, AgentModel, AgentToolModel, BotAliasModel, @@ -299,6 +300,7 @@ def test_update_bot(self): guardrail_arn="arn:aws:guardrail", guardrail_version="v1", ), + active_models=ActiveModelsModel(), ) bot = find_private_bot_by_id("user1", "1") @@ -388,6 +390,7 @@ def setUp(self) -> None: conversation_quick_starters=[ ConversationQuickStarterModel(title="QS title", example="QS example") ], + active_models=ActiveModelsModel(), ) alias2 = BotAliasModel( id="alias2", @@ -404,6 +407,7 @@ def setUp(self) -> None: conversation_quick_starters=[ ConversationQuickStarterModel(title="QS title", example="QS example") ], + active_models=ActiveModelsModel(), ) store_bot("user1", bot1) store_bot("user1", bot2) @@ -471,6 +475,7 @@ def setUp(self) -> None: conversation_quick_starters=[ ConversationQuickStarterModel(title="QS title", example="QS example") ], + active_models=ActiveModelsModel(), ) store_bot("user1", bot1) store_bot("user1", bot2) @@ -507,6 +512,7 @@ def test_update_bot_visibility(self): sync_status_reason="", display_retrieved_chunks=True, conversation_quick_starters=[], + active_models=ActiveModelsModel(), ) bots = fetch_all_bots_by_user_id("user1", limit=3) self.assertEqual(len(bots), 3) diff --git a/backend/tests/test_repositories/utils/bot_factory.py b/backend/tests/test_repositories/utils/bot_factory.py index 46a7d103f..95c848df1 100644 --- a/backend/tests/test_repositories/utils/bot_factory.py +++ b/backend/tests/test_repositories/utils/bot_factory.py @@ -5,6 +5,7 @@ from app.repositories.models.custom_bot import ( + ActiveModelsModel, AgentModel, AgentToolModel, BedrockGuardrailsModel, @@ -73,6 +74,7 @@ def create_test_private_bot( ), bedrock_knowledge_base=bedrock_knowledge_base, bedrock_guardrails=bedrock_guardrails, + active_models=ActiveModelsModel(), ) @@ -127,4 +129,5 @@ def create_test_public_bot( ), bedrock_knowledge_base=bedrock_knowledge_base, bedrock_guardrails=bedrock_guardrails, + active_models=ActiveModelsModel(), ) diff --git a/backend/tests/test_usecases/utils/bot_factory.py b/backend/tests/test_usecases/utils/bot_factory.py index 9fe8f0d05..40e4c8668 100644 --- a/backend/tests/test_usecases/utils/bot_factory.py +++ b/backend/tests/test_usecases/utils/bot_factory.py @@ -5,6 +5,7 @@ from app.agents.tools.internet_search import internet_search_tool from app.repositories.models.custom_bot import ( + ActiveModelsModel, AgentModel, AgentToolModel, BotAliasModel, @@ -77,6 +78,7 @@ def create_test_private_bot( conversation_quick_starters=[], bedrock_knowledge_base=bedrock_knowledge_base, bedrock_guardrails=bedrock_guardrails, + active_models=ActiveModelsModel(), ) @@ -131,6 +133,7 @@ def create_test_public_bot( conversation_quick_starters=[], bedrock_knowledge_base=bedrock_knowledge_base, bedrock_guardrails=bedrock_guardrails, + active_models=ActiveModelsModel(), ) @@ -148,6 +151,7 @@ def create_test_bot_alias(id, original_bot_id, is_pinned): has_knowledge=True, has_agent=False, conversation_quick_starters=[], + active_models=ActiveModelsModel(), ) diff --git a/frontend/src/@types/bot.d.ts b/frontend/src/@types/bot.d.ts index b2fd83418..9bb1a1b23 100644 --- a/frontend/src/@types/bot.d.ts +++ b/frontend/src/@types/bot.d.ts @@ -1,7 +1,11 @@ import { BedrockKnowledgeBase } from '../features/knowledgeBase/types'; - +import { Model } from './conversation'; export type BotKind = 'private' | 'mixed'; +type ActiveModels = { + [K in Model]: boolean; +}; + export type BotMeta = { id: string; title: string; @@ -74,12 +78,14 @@ export type BotDetails = BotMeta & { conversationQuickStarters: ConversationQuickStarter[]; bedrockGuardrails: GuardrailsParams; bedrockKnowledgeBase: BedrockKnowledgeBase; + activeModels: ActiveModels; }; export type BotSummary = BotMeta & { hasKnowledge: boolean; hasAgent: boolean; conversationQuickStarters: ConversationQuickStarter[]; + activeModels: ActiveModels; }; export type BotFile = { @@ -101,6 +107,7 @@ export type RegisterBotRequest = { conversationQuickStarters: ConversationQuickStarter[]; bedrockGuardrails?: GuardrailsParams; bedrockKnowledgeBase?: BedrockKnowledgeBase; + activeModels: ActiveModels; }; export type RegisterBotResponse = BotDetails; @@ -116,6 +123,7 @@ export type UpdateBotRequest = { conversationQuickStarters: ConversationQuickStarter[]; bedrockGuardrails?: GuardrailsParams; bedrockKnowledgeBase?: BedrockKnowledgeBase; + activeModels: ActiveModels; }; export type UpdateBotResponse = { @@ -128,6 +136,7 @@ export type UpdateBotResponse = { displayRetrievedChunks: boolean; conversationQuickStarters: ConversationQuickStarter[]; bedrockKnowledgeBase: BedrockKnowledgeBase; + activeModels: ActiveModels; }; export type UpdateBotPinnedRequest = { diff --git a/frontend/src/@types/conversation.d.ts b/frontend/src/@types/conversation.d.ts index 4bb7e3afe..c4b4184e2 100644 --- a/frontend/src/@types/conversation.d.ts +++ b/frontend/src/@types/conversation.d.ts @@ -1,19 +1,9 @@ +import { + AVAILABLE_MODEL_KEYS +} from '../constants/index' export type Role = 'system' | 'assistant' | 'user'; -export type Model = - | 'claude-instant-v1' - | 'claude-v2' - | 'claude-v3-opus' - | 'claude-v3-sonnet' - | 'claude-v3.5-sonnet' - | 'claude-v3.5-sonnet-v2' - | 'claude-v3-haiku' - | 'claude-v3.5-haiku' - | 'mistral-7b-instruct' - | 'mixtral-8x7b-instruct' - | 'mistral-large' - | 'amazon-nova-pro' - | 'amazon-nova-lite' - | 'amazon-nova-micro'; + +export type Model = (typeof AVAILABLE_MODEL_KEYS)[number]; export type Content = TextContent | ImageContent | AttachmentContent; @@ -65,7 +55,9 @@ export type AgentToolResultJsonContent = { json: { [key: string]: any }; // eslint-disable-line @typescript-eslint/no-explicit-any }; -export type AgentToolResultContent = AgentToolResultTextContent | AgentToolResultJsonContent; +export type AgentToolResultContent = + | AgentToolResultTextContent + | AgentToolResultJsonContent; export type ToolResultContentBody = { toolUseId: string; @@ -73,7 +65,10 @@ export type ToolResultContentBody = { status: 'success' | 'error'; }; -export type SimpleMessageContent = TextContent | ToolUseContent | ToolResultContent; +export type SimpleMessageContent = + | TextContent + | ToolUseContent + | ToolResultContent; export type SimpleMessage = { role: Role; @@ -109,7 +104,7 @@ export type PostMessageRequest = { parentMessageId: null | string; }; botId?: string; - continueGenerate?: bool; + continueGenerate?: boolean; }; export type PostMessageResponse = { diff --git a/frontend/src/components/SwitchBedrockModel.stories.tsx b/frontend/src/components/SwitchBedrockModel.stories.tsx index 42a9c1cbe..f8bcf92db 100644 --- a/frontend/src/components/SwitchBedrockModel.stories.tsx +++ b/frontend/src/components/SwitchBedrockModel.stories.tsx @@ -1,3 +1,14 @@ import SwitchBedrockModel from './SwitchBedrockModel'; +import { Model } from '../@types/conversation'; +import { AVAILABLE_MODEL_KEYS } from '../constants/index'; +import { ActiveModels } from '../@types/bot'; -export const Ideal = () => ; +export const Ideal = () => ( + [key, true]) + ) as ActiveModels + } + /> +); diff --git a/frontend/src/components/SwitchBedrockModel.tsx b/frontend/src/components/SwitchBedrockModel.tsx index b1548bd18..51f21d441 100644 --- a/frontend/src/components/SwitchBedrockModel.tsx +++ b/frontend/src/components/SwitchBedrockModel.tsx @@ -4,11 +4,33 @@ import { Popover, Transition } from '@headlessui/react'; import { Fragment } from 'react/jsx-runtime'; import { useMemo } from 'react'; import { PiCaretDown, PiCheck } from 'react-icons/pi'; +import { ActiveModels } from '../@types/bot'; +import { toCamelCase } from '../utils/StringUtils'; -type Props = BaseProps; +interface Props extends BaseProps { + activeModels: ActiveModels; + botId?: string | null; +} const SwitchBedrockModel: React.FC = (props) => { - const { availableModels, modelId, setModelId } = useModel(); + const { + availableModels: allModels, + modelId, + setModelId, + } = useModel(props.botId, props.activeModels); + + const availableModels = useMemo(() => { + return allModels.filter((model) => { + if (props.activeModels) { + return ( + props.activeModels[ + toCamelCase(model.modelId) as keyof ActiveModels + ] === true + ); + } + return true; + }); + }, [allModels, props.activeModels]); const modelName = useMemo(() => { return ( @@ -26,8 +48,7 @@ const SwitchBedrockModel: React.FC = (props) => { props.className ?? '' } group inline-flex w-auto whitespace-nowrap rounded border-aws-squid-ink/50 bg-aws-paper p-2 px-3 text-base hover:brightness-75`}>
- {modelName} - + {modelName}
@@ -39,13 +60,13 @@ const SwitchBedrockModel: React.FC = (props) => { leave="transition ease-in duration-150" leaveFrom="opacity-100 translate-y-0" leaveTo="opacity-0 translate-y-1"> - +
{availableModels.map((model) => (
{ setModelId(model.modelId); }}> @@ -60,17 +81,19 @@ const SwitchBedrockModel: React.FC = (props) => {
- {model.label} -
-
- {model.description} + {model.label}
+ {model.description && ( +
+ {model.description} +
+ )}
))}
-
+ )} diff --git a/frontend/src/constants/index.ts b/frontend/src/constants/index.ts index a404a9392..c6dc8ef63 100644 --- a/frontend/src/constants/index.ts +++ b/frontend/src/constants/index.ts @@ -100,3 +100,18 @@ export const GUARDRAILS_CONTECTUAL_GROUNDING_THRESHOLD = { MIN: 0, STEP: 0.01, }; + +export const AVAILABLE_MODEL_KEYS = [ + 'claude-v3-opus', + 'claude-v3-sonnet', + 'claude-v3.5-sonnet', + 'claude-v3.5-sonnet-v2', + 'claude-v3-haiku', + 'claude-v3.5-haiku', + 'mistral-7b-instruct', + 'mixtral-8x7b-instruct', + 'mistral-large', + 'amazon-nova-pro', + 'amazon-nova-lite', + 'amazon-nova-micro', +] as const; diff --git a/frontend/src/features/knowledgeBase/pages/BotKbEditPage.tsx b/frontend/src/features/knowledgeBase/pages/BotKbEditPage.tsx index 8af79f7fb..d094a88a7 100644 --- a/frontend/src/features/knowledgeBase/pages/BotKbEditPage.tsx +++ b/frontend/src/features/knowledgeBase/pages/BotKbEditPage.tsx @@ -13,7 +13,11 @@ import Alert from '../../../components/Alert'; import KnowledgeFileUploader from '../../../components/KnowledgeFileUploader'; import GenerationConfig from '../../../components/GenerationConfig'; import Select from '../../../components/Select'; -import { BotFile, ConversationQuickStarter } from '../../../@types/bot'; +import { + BotFile, + ConversationQuickStarter, + ActiveModels, +} from '../../../@types/bot'; import { ParsingModel } from '../types'; import { ulid } from 'ulid'; import { @@ -47,6 +51,8 @@ import { GUARDRAILS_FILTERS_THRESHOLD, GUARDRAILS_CONTECTUAL_GROUNDING_THRESHOLD, } from '../../../constants'; +import { Model } from '../../../@types/conversation'; +import { AVAILABLE_MODEL_KEYS } from '../../../constants/index' import { ChunkingStrategy, FixedSizeParams, @@ -58,14 +64,18 @@ import { SearchType, WebCrawlingScope, } from '../types'; +import { toCamelCase } from '../../../utils/StringUtils'; + +const MISTRAL_ENABLED: boolean = + import.meta.env.VITE_APP_ENABLE_MISTRAL === 'true'; const edgeGenerationParams = - import.meta.env.VITE_APP_ENABLE_MISTRAL === 'true' + MISTRAL_ENABLED === true ? EDGE_MISTRAL_GENERATION_PARAMS : EDGE_GENERATION_PARAMS; const defaultGenerationConfig = - import.meta.env.VITE_APP_ENABLE_MISTRAL === 'true' + MISTRAL_ENABLED === true ? DEFAULT_MISTRAL_GENERATION_CONFIG : DEFAULT_GENERATION_CONFIG; @@ -108,7 +118,8 @@ const BotKbEditPage: React.FC = () => { example: '', }, ]); - const [webCrawlingScope, setWebCrawlingScope] = useState('DEFAULT'); + const [webCrawlingScope, setWebCrawlingScope] = + useState('DEFAULT'); const [knowledgeBaseId, setKnowledgeBaseId] = useState(null); // Send null when creating a new bot const [embeddingsModel, setEmbeddingsModel] = @@ -123,7 +134,9 @@ const BotKbEditPage: React.FC = () => { const [relevanceThreshold, setRelevanceThreshold] = useState(0); const [guardrailArn, setGuardrailArn] = useState(''); const [guardrailVersion, setGuardrailVersion] = useState(''); - const [parsingModel, setParsingModel] = useState(undefined); + const [parsingModel, setParsingModel] = useState( + undefined + ); const [webCrawlingFilters, setWebCrawlingFilters] = useState<{ includePatterns: string[]; excludePatterns: string[]; @@ -132,21 +145,56 @@ const BotKbEditPage: React.FC = () => { excludePatterns: [''], }); + const [activeModels, setActiveModels] = useState(() => { + const initialState = AVAILABLE_MODEL_KEYS.reduce((acc: ActiveModels, key: Model) => { + acc[toCamelCase(key) as keyof ActiveModels] = true; + return acc; + }, {} as ActiveModels); + return initialState; + }); + + const activeModelsOptions: { + key: Model; + label: string; + description: string; + }[] = (() => { + const getMistralModels = () => + AVAILABLE_MODEL_KEYS.filter( + (key) => key.includes('mistral') || key.includes('mixtral') + ).map((key) => ({ + key: key as Model, + label: t(`model.${key}.label`) as string, + description: t(`model.${key}.description`) as string, + })); + + const getClaudeAndNovaModels = () => { + return AVAILABLE_MODEL_KEYS.filter( + (key) => key.includes('claude') || key.includes('nova') + ).map((key) => ({ + key: key as Model, + label: t(`model.${key}.label`) as string, + description: t(`model.${key}.description`) as string, + })); + }; + + return MISTRAL_ENABLED ? getMistralModels() : getClaudeAndNovaModels(); + })(); + const embeddingsModelOptions: { label: string; value: EmbeddingsModel; }[] = [ - { - label: t('knowledgeBaseSettings.embeddingModel.titan_v2.label'), - value: 'titan_v2', - }, - { - label: t( - 'knowledgeBaseSettings.embeddingModel.cohere_multilingual_v3.label' - ), - value: 'cohere_multilingual_v3', - }, - ]; + { + label: t('knowledgeBaseSettings.embeddingModel.titan_v2.label'), + value: 'titan_v2', + }, + { + label: t( + 'knowledgeBaseSettings.embeddingModel.cohere_multilingual_v3.label' + ), + value: 'cohere_multilingual_v3', + }, + ]; const [chunkingStrategy, setChunkingStrategy] = useState('default'); @@ -157,19 +205,31 @@ const BotKbEditPage: React.FC = () => { description: string; }[] = [ { - label: t('knowledgeBaseSettings.webCrawlerConfig.crawlingScope.default.label'), + label: t( + 'knowledgeBaseSettings.webCrawlerConfig.crawlingScope.default.label' + ), value: 'DEFAULT', - description: t('knowledgeBaseSettings.webCrawlerConfig.crawlingScope.default.hint'), + description: t( + 'knowledgeBaseSettings.webCrawlerConfig.crawlingScope.default.hint' + ), }, { - label: t('knowledgeBaseSettings.webCrawlerConfig.crawlingScope.subdomains.label'), + label: t( + 'knowledgeBaseSettings.webCrawlerConfig.crawlingScope.subdomains.label' + ), value: 'SUBDOMAINS', - description: t('knowledgeBaseSettings.webCrawlerConfig.crawlingScope.subdomains.hint'), + description: t( + 'knowledgeBaseSettings.webCrawlerConfig.crawlingScope.subdomains.hint' + ), }, { - label: t('knowledgeBaseSettings.webCrawlerConfig.crawlingScope.hostOnly.label'), + label: t( + 'knowledgeBaseSettings.webCrawlerConfig.crawlingScope.hostOnly.label' + ), value: 'HOST_ONLY', - description: t('knowledgeBaseSettings.webCrawlerConfig.crawlingScope.hostOnly.hint'), + description: t( + 'knowledgeBaseSettings.webCrawlerConfig.crawlingScope.hostOnly.hint' + ), }, ]; @@ -178,33 +238,35 @@ const BotKbEditPage: React.FC = () => { value: ChunkingStrategy; description: string; }[] = [ - { - label: t('knowledgeBaseSettings.chunkingStrategy.default.label'), - value: 'default', - description: t('knowledgeBaseSettings.chunkingStrategy.default.hint'), - }, - { - label: t('knowledgeBaseSettings.chunkingStrategy.fixed_size.label'), - value: 'fixed_size', - description: t('knowledgeBaseSettings.chunkingStrategy.fixed_size.hint'), - }, - { - label: t('knowledgeBaseSettings.chunkingStrategy.hierarchical.label'), - value: 'hierarchical', - description: t('knowledgeBaseSettings.chunkingStrategy.hierarchical.hint'), - }, - { - label: t('knowledgeBaseSettings.chunkingStrategy.semantic.label'), - value: 'semantic', - description: t('knowledgeBaseSettings.chunkingStrategy.semantic.hint'), - }, - { - label: t('knowledgeBaseSettings.chunkingStrategy.none.label'), - value: 'none', - description: t('knowledgeBaseSettings.chunkingStrategy.none.hint'), - }, - ]; - + { + label: t('knowledgeBaseSettings.chunkingStrategy.default.label'), + value: 'default', + description: t('knowledgeBaseSettings.chunkingStrategy.default.hint'), + }, + { + label: t('knowledgeBaseSettings.chunkingStrategy.fixed_size.label'), + value: 'fixed_size', + description: t('knowledgeBaseSettings.chunkingStrategy.fixed_size.hint'), + }, + { + label: t('knowledgeBaseSettings.chunkingStrategy.hierarchical.label'), + value: 'hierarchical', + description: t( + 'knowledgeBaseSettings.chunkingStrategy.hierarchical.hint' + ), + }, + { + label: t('knowledgeBaseSettings.chunkingStrategy.semantic.label'), + value: 'semantic', + description: t('knowledgeBaseSettings.chunkingStrategy.semantic.hint'), + }, + { + label: t('knowledgeBaseSettings.chunkingStrategy.none.label'), + value: 'none', + description: t('knowledgeBaseSettings.chunkingStrategy.none.hint'), + }, + ]; + const parsingModelOptions: { label: string; value: ParsingModel; @@ -218,12 +280,16 @@ const BotKbEditPage: React.FC = () => { { label: t('knowledgeBaseSettings.parsingModel.claude_3_sonnet_v1.label'), value: 'anthropic.claude-3-sonnet-v1', - description: t('knowledgeBaseSettings.parsingModel.claude_3_sonnet_v1.hint'), + description: t( + 'knowledgeBaseSettings.parsingModel.claude_3_sonnet_v1.hint' + ), }, { label: t('knowledgeBaseSettings.parsingModel.claude_3_haiku_v1.label'), value: 'anthropic.claude-3-haiku-v1', - description: t('knowledgeBaseSettings.parsingModel.claude_3_haiku_v1.hint'), + description: t( + 'knowledgeBaseSettings.parsingModel.claude_3_haiku_v1.hint' + ), }, ]; @@ -231,9 +297,8 @@ const BotKbEditPage: React.FC = () => { DEFAULT_FIXED_CHUNK_PARAMS ); - const [hierarchicalParams, setHierarchicalParams] = useState( - DEFAULT_HIERARCHICAL_CHUNK_PARAMS - ); + const [hierarchicalParams, setHierarchicalParams] = + useState(DEFAULT_HIERARCHICAL_CHUNK_PARAMS); const [semanticParams, setSemanticParams] = useState( DEFAULT_SEMANTIC_CHUNK_PARAMS @@ -254,28 +319,28 @@ const BotKbEditPage: React.FC = () => { value: string; description: string; }[] = [ - { - label: t('knowledgeBaseSettings.opensearchAnalyzer.icu.label'), - value: 'icu', - description: t('knowledgeBaseSettings.opensearchAnalyzer.icu.hint', { - tokenizer: OPENSEARCH_ANALYZER['icu'].analyzer!.tokenizer, - normalizer: OPENSEARCH_ANALYZER['icu'].analyzer!.characterFilters, - }), - }, - { - label: t('knowledgeBaseSettings.opensearchAnalyzer.kuromoji.label'), - value: 'kuromoji', - description: t('knowledgeBaseSettings.opensearchAnalyzer.kuromoji.hint', { - tokenizer: OPENSEARCH_ANALYZER['kuromoji'].analyzer!.tokenizer, - normalizer: OPENSEARCH_ANALYZER['icu'].analyzer!.characterFilters, - }), - }, - { - label: t('knowledgeBaseSettings.opensearchAnalyzer.none.label'), - value: 'none', - description: t('knowledgeBaseSettings.opensearchAnalyzer.none.hint'), - }, - ]; + { + label: t('knowledgeBaseSettings.opensearchAnalyzer.icu.label'), + value: 'icu', + description: t('knowledgeBaseSettings.opensearchAnalyzer.icu.hint', { + tokenizer: OPENSEARCH_ANALYZER['icu'].analyzer!.tokenizer, + normalizer: OPENSEARCH_ANALYZER['icu'].analyzer!.characterFilters, + }), + }, + { + label: t('knowledgeBaseSettings.opensearchAnalyzer.kuromoji.label'), + value: 'kuromoji', + description: t('knowledgeBaseSettings.opensearchAnalyzer.kuromoji.hint', { + tokenizer: OPENSEARCH_ANALYZER['kuromoji'].analyzer!.tokenizer, + normalizer: OPENSEARCH_ANALYZER['icu'].analyzer!.characterFilters, + }), + }, + { + label: t('knowledgeBaseSettings.opensearchAnalyzer.none.label'), + value: 'none', + description: t('knowledgeBaseSettings.opensearchAnalyzer.none.hint'), + }, + ]; const [searchParams, setSearchParams] = useState( DEFAULT_SEARCH_CONFIG @@ -286,17 +351,17 @@ const BotKbEditPage: React.FC = () => { value: SearchType; description: string; }[] = [ - { - label: t('searchSettings.searchType.hybrid.label'), - value: 'hybrid', - description: t('searchSettings.searchType.hybrid.hint'), - }, - { - label: t('searchSettings.searchType.semantic.label'), - value: 'semantic', - description: t('searchSettings.searchType.semantic.hint'), - }, - ]; + { + label: t('searchSettings.searchType.hybrid.label'), + value: 'hybrid', + description: t('searchSettings.searchType.hybrid.hint'), + }, + { + label: t('searchSettings.searchType.semantic.label'), + value: 'semantic', + description: t('searchSettings.searchType.semantic.hint'), + }, + ]; const { errorMessages, @@ -420,26 +485,43 @@ const BotKbEditPage: React.FC = () => { bot.conversationQuickStarters.length > 0 ? bot.conversationQuickStarters : [ - { - title: '', - example: '', - }, - ] + { + title: '', + example: '', + }, + ] ); setKnowledgeBaseId(bot.bedrockKnowledgeBase.knowledgeBaseId); setEmbeddingsModel(bot.bedrockKnowledgeBase!.embeddingsModel); - setChunkingStrategy(bot.bedrockKnowledgeBase!.chunkingConfiguration.chunkingStrategy); - if (bot.bedrockKnowledgeBase!.chunkingConfiguration.chunkingStrategy == 'fixed_size') { + setChunkingStrategy( + bot.bedrockKnowledgeBase!.chunkingConfiguration.chunkingStrategy + ); + if ( + bot.bedrockKnowledgeBase!.chunkingConfiguration.chunkingStrategy == + 'fixed_size' + ) { setFixedSizeParams( - (bot.bedrockKnowledgeBase!.chunkingConfiguration) as FixedSizeParams ?? DEFAULT_FIXED_CHUNK_PARAMS + (bot.bedrockKnowledgeBase! + .chunkingConfiguration as FixedSizeParams) ?? + DEFAULT_FIXED_CHUNK_PARAMS ); - } else if (bot.bedrockKnowledgeBase!.chunkingConfiguration.chunkingStrategy == 'hierarchical') { + } else if ( + bot.bedrockKnowledgeBase!.chunkingConfiguration.chunkingStrategy == + 'hierarchical' + ) { setHierarchicalParams( - (bot.bedrockKnowledgeBase!.chunkingConfiguration) as HierarchicalParams ?? DEFAULT_HIERARCHICAL_CHUNK_PARAMS + (bot.bedrockKnowledgeBase! + .chunkingConfiguration as HierarchicalParams) ?? + DEFAULT_HIERARCHICAL_CHUNK_PARAMS ); - } else if (bot.bedrockKnowledgeBase!.chunkingConfiguration.chunkingStrategy == 'semantic') { + } else if ( + bot.bedrockKnowledgeBase!.chunkingConfiguration.chunkingStrategy == + 'semantic' + ) { setSemanticParams( - (bot.bedrockKnowledgeBase!.chunkingConfiguration) as SemanticParams ?? DEFAULT_SEMANTIC_CHUNK_PARAMS + (bot.bedrockKnowledgeBase! + .chunkingConfiguration as SemanticParams) ?? + DEFAULT_SEMANTIC_CHUNK_PARAMS ); } @@ -487,11 +569,16 @@ const BotKbEditPage: React.FC = () => { : 0 ); setParsingModel(bot.bedrockKnowledgeBase.parsingModel); - setWebCrawlingScope(bot.bedrockKnowledgeBase.webCrawlingScope ?? 'DEFAULT'); + setWebCrawlingScope( + bot.bedrockKnowledgeBase.webCrawlingScope ?? 'DEFAULT' + ); setWebCrawlingFilters({ - includePatterns: bot.bedrockKnowledgeBase.webCrawlingFilters?.includePatterns || [''], - excludePatterns: bot.bedrockKnowledgeBase.webCrawlingFilters?.excludePatterns || [''], + includePatterns: bot.bedrockKnowledgeBase.webCrawlingFilters + ?.includePatterns || [''], + excludePatterns: bot.bedrockKnowledgeBase.webCrawlingFilters + ?.excludePatterns || [''], }); + setActiveModels(bot.activeModels); }) .finally(() => { setIsLoading(false); @@ -506,6 +593,15 @@ const BotKbEditPage: React.FC = () => { return pattern.test(syncErrorMessage); }, []); + const onChangeActiveModels = useCallback((key: string, value: boolean) => { + setActiveModels((prevState) => { + const camelKey = toCamelCase(key) as keyof ActiveModels; + const newState = { ...prevState }; + newState[camelKey] = value; + return newState; + }); + }, []); + const onChangeS3Url = useCallback( (s3Url: string, idx: number) => { setS3Urls( @@ -702,16 +798,22 @@ const BotKbEditPage: React.FC = () => { // Update maxTokens based on the selected embeddings model const maxEdgeFixed = EDGE_FIXED_CHUNK_PARAMS.maxTokens.MAX[value]; const maxEdgeSemantic = EDGE_SEMANTIC_CHUNK_PARAMS.maxTokens.MAX[value]; - if (chunkingStrategy == 'fixed_size' && fixedSizeParams.maxTokens > maxEdgeFixed) { + if ( + chunkingStrategy == 'fixed_size' && + fixedSizeParams.maxTokens > maxEdgeFixed + ) { setFixedSizeParams((params) => ({ ...params, maxTokens: maxEdgeFixed, - })) - } else if (chunkingStrategy == 'semantic' && semanticParams.maxTokens > maxEdgeSemantic) { + })); + } else if ( + chunkingStrategy == 'semantic' && + semanticParams.maxTokens > maxEdgeSemantic + ) { setSemanticParams((params) => ({ ...params, maxTokens: maxEdgeSemantic, - })) + })); } }, [chunkingStrategy, fixedSizeParams.maxTokens, semanticParams.maxTokens] @@ -773,7 +875,8 @@ const BotKbEditPage: React.FC = () => { ); return false; } else if ( - fixedSizeParams.maxTokens > EDGE_FIXED_CHUNK_PARAMS.maxTokens.MAX[embeddingsModel] + fixedSizeParams.maxTokens > + EDGE_FIXED_CHUNK_PARAMS.maxTokens.MAX[embeddingsModel] ) { setErrorMessages( 'fixedSizeParams.maxTokens', @@ -784,7 +887,10 @@ const BotKbEditPage: React.FC = () => { return false; } - if (fixedSizeParams.overlapPercentage < EDGE_FIXED_CHUNK_PARAMS.overlapPercentage.MIN) { + if ( + fixedSizeParams.overlapPercentage < + EDGE_FIXED_CHUNK_PARAMS.overlapPercentage.MIN + ) { setErrorMessages( 'fixedSizeParams.overlapPercentage', t('validation.minRange.message', { @@ -793,7 +899,8 @@ const BotKbEditPage: React.FC = () => { ); return false; } else if ( - fixedSizeParams.overlapPercentage > EDGE_FIXED_CHUNK_PARAMS.overlapPercentage.MAX + fixedSizeParams.overlapPercentage > + EDGE_FIXED_CHUNK_PARAMS.overlapPercentage.MAX ) { setErrorMessages( 'fixedSizeParams.overlapPercentage', @@ -804,7 +911,10 @@ const BotKbEditPage: React.FC = () => { return false; } } else if (chunkingStrategy === 'hierarchical') { - if (hierarchicalParams.overlapTokens < EDGE_HIERARCHICAL_CHUNK_PARAMS.overlapTokens.MIN) { + if ( + hierarchicalParams.overlapTokens < + EDGE_HIERARCHICAL_CHUNK_PARAMS.overlapTokens.MIN + ) { setErrorMessages( 'hierarchicalParams.overlapTokens', t('validation.minRange.message', { @@ -814,7 +924,10 @@ const BotKbEditPage: React.FC = () => { return false; } - if (hierarchicalParams.maxParentTokenSize < EDGE_HIERARCHICAL_CHUNK_PARAMS.maxParentTokenSize.MIN) { + if ( + hierarchicalParams.maxParentTokenSize < + EDGE_HIERARCHICAL_CHUNK_PARAMS.maxParentTokenSize.MIN + ) { setErrorMessages( 'hierarchicalParams.maxParentTokenSize', t('validation.minRange.message', { @@ -823,18 +936,24 @@ const BotKbEditPage: React.FC = () => { ); return false; } else if ( - hierarchicalParams.maxParentTokenSize > EDGE_HIERARCHICAL_CHUNK_PARAMS.maxParentTokenSize.MAX[embeddingsModel] + hierarchicalParams.maxParentTokenSize > + EDGE_HIERARCHICAL_CHUNK_PARAMS.maxParentTokenSize.MAX[embeddingsModel] ) { setErrorMessages( 'hierarchicalParams.maxParentTokenSize', t('validation.maxRange.message', { - size: EDGE_HIERARCHICAL_CHUNK_PARAMS.maxParentTokenSize.MAX[embeddingsModel], + size: EDGE_HIERARCHICAL_CHUNK_PARAMS.maxParentTokenSize.MAX[ + embeddingsModel + ], }) ); return false; } - if (hierarchicalParams.maxChildTokenSize < EDGE_HIERARCHICAL_CHUNK_PARAMS.maxChildTokenSize.MIN) { + if ( + hierarchicalParams.maxChildTokenSize < + EDGE_HIERARCHICAL_CHUNK_PARAMS.maxChildTokenSize.MIN + ) { setErrorMessages( 'hierarchicalParams.maxChildTokenSize', t('validation.minRange.message', { @@ -843,18 +962,24 @@ const BotKbEditPage: React.FC = () => { ); return false; } else if ( - hierarchicalParams.maxChildTokenSize > EDGE_HIERARCHICAL_CHUNK_PARAMS.maxChildTokenSize.MAX[embeddingsModel] + hierarchicalParams.maxChildTokenSize > + EDGE_HIERARCHICAL_CHUNK_PARAMS.maxChildTokenSize.MAX[embeddingsModel] ) { setErrorMessages( 'hierarchicalParams.maxChildTokenSize', t('validation.maxRange.message', { - size: EDGE_HIERARCHICAL_CHUNK_PARAMS.maxChildTokenSize.MAX[embeddingsModel], + size: EDGE_HIERARCHICAL_CHUNK_PARAMS.maxChildTokenSize.MAX[ + embeddingsModel + ], }) ); return false; } - if (hierarchicalParams.maxParentTokenSize < hierarchicalParams.maxChildTokenSize) { + if ( + hierarchicalParams.maxParentTokenSize < + hierarchicalParams.maxChildTokenSize + ) { setErrorMessages( 'hierarchicalParams.maxParentTokenSize', t('validation.parentTokenRange.message') @@ -871,7 +996,8 @@ const BotKbEditPage: React.FC = () => { ); return false; } else if ( - semanticParams.maxTokens > EDGE_SEMANTIC_CHUNK_PARAMS.maxTokens.MAX[embeddingsModel] + semanticParams.maxTokens > + EDGE_SEMANTIC_CHUNK_PARAMS.maxTokens.MAX[embeddingsModel] ) { setErrorMessages( 'semanticParams.maxTokens', @@ -882,7 +1008,9 @@ const BotKbEditPage: React.FC = () => { return false; } - if (semanticParams.bufferSize < EDGE_SEMANTIC_CHUNK_PARAMS.bufferSize.MIN) { + if ( + semanticParams.bufferSize < EDGE_SEMANTIC_CHUNK_PARAMS.bufferSize.MIN + ) { setErrorMessages( 'semanticParams.bufferSize', t('validation.minRange.message', { @@ -902,7 +1030,10 @@ const BotKbEditPage: React.FC = () => { return false; } - if (semanticParams.breakpointPercentileThreshold < EDGE_SEMANTIC_CHUNK_PARAMS.breakpointPercentileThreshold.MIN) { + if ( + semanticParams.breakpointPercentileThreshold < + EDGE_SEMANTIC_CHUNK_PARAMS.breakpointPercentileThreshold.MIN + ) { setErrorMessages( 'semanticParams.breakpointPercentileThreshold', t('validation.minRange.message', { @@ -911,7 +1042,8 @@ const BotKbEditPage: React.FC = () => { ); return false; } else if ( - semanticParams.breakpointPercentileThreshold > EDGE_SEMANTIC_CHUNK_PARAMS.breakpointPercentileThreshold.MAX + semanticParams.breakpointPercentileThreshold > + EDGE_SEMANTIC_CHUNK_PARAMS.breakpointPercentileThreshold.MAX ) { setErrorMessages( 'semanticParams.breakpointPercentileThreshold', @@ -1060,6 +1192,7 @@ const BotKbEditPage: React.FC = () => { guardrailArn: '', guardrailVersion: '', }, + activeModels, }) .then(() => { navigate('/bot/explore'); @@ -1104,6 +1237,7 @@ const BotKbEditPage: React.FC = () => { parsingModel, webCrawlingScope, webCrawlingFilters, + activeModels, ]); const onClickEdit = useCallback(() => { @@ -1181,6 +1315,7 @@ const BotKbEditPage: React.FC = () => { guardrailArn: guardrailArn, guardrailVersion: guardrailVersion, }, + activeModels, }) .then(() => { navigate('/bot/explore'); @@ -1231,6 +1366,7 @@ const BotKbEditPage: React.FC = () => { parsingModel, webCrawlingScope, webCrawlingFilters, + activeModels, ]); const [isOpenSamples, setIsOpenSamples] = useState(false); @@ -1403,9 +1539,7 @@ const BotKbEditPage: React.FC = () => { /> { onClickRemoveUrls(idx); }}> @@ -1428,10 +1562,11 @@ const BotKbEditPage: React.FC = () => { isDefaultShow={false} label={t('knowledgeBaseSettings.webCrawlerConfig.title')} className="py-2"> -