language-model-common 3.0.4__tar.gz → 3.0.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. {language_model_common-3.0.4/language_model_common.egg-info → language_model_common-3.0.6}/PKG-INFO +2 -2
  2. language_model_common-3.0.6/VERSION +1 -0
  3. {language_model_common-3.0.4 → language_model_common-3.0.6/language_model_common.egg-info}/PKG-INFO +2 -2
  4. {language_model_common-3.0.4 → language_model_common-3.0.6}/language_model_common.egg-info/requires.txt +1 -1
  5. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/converters/langgraph_to_openai_converter.py +37 -12
  6. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/interceptors/types.py +22 -3
  7. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/mcp_client/langchain_adapter.py +73 -0
  8. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/mcp_client/tool_invocation.py +51 -7
  9. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/models/model_factory.py +30 -0
  10. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/environment/language_model_common_environment_variables.py +35 -0
  11. {language_model_common-3.0.4 → language_model_common-3.0.6}/pyproject.toml +1 -1
  12. language_model_common-3.0.4/VERSION +0 -1
  13. {language_model_common-3.0.4 → language_model_common-3.0.6}/LICENSE +0 -0
  14. {language_model_common-3.0.4 → language_model_common-3.0.6}/MANIFEST.in +0 -0
  15. {language_model_common-3.0.4 → language_model_common-3.0.6}/README.md +0 -0
  16. {language_model_common-3.0.4 → language_model_common-3.0.6}/language_model_common.egg-info/SOURCES.txt +0 -0
  17. {language_model_common-3.0.4 → language_model_common-3.0.6}/language_model_common.egg-info/dependency_links.txt +0 -0
  18. {language_model_common-3.0.4 → language_model_common-3.0.6}/language_model_common.egg-info/top_level.txt +0 -0
  19. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/__init__.py +0 -0
  20. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/auth/__init__.py +0 -0
  21. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/auth/authenticator/__init__.py +0 -0
  22. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/auth/exceptions/__init__.py +0 -0
  23. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/auth/models/__init__.py +0 -0
  24. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/aws/__init__.py +0 -0
  25. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/aws/aws_client_factory.py +0 -0
  26. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/__init__.py +0 -0
  27. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/config_reader/__init__.py +0 -0
  28. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/config_reader/config_reader.py +0 -0
  29. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/config_reader/file_config_reader.py +0 -0
  30. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/config_reader/github_directory_downloader.py +0 -0
  31. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/config_reader/github_directory_helper.py +0 -0
  32. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/config_reader/mcp_json_fetcher.py +0 -0
  33. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/config_reader/mcp_json_reader.py +0 -0
  34. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/config_reader/s3_config_reader.py +0 -0
  35. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/prompt_library/__init__.py +0 -0
  36. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/prompt_library/prompt_library_environment_variables.py +0 -0
  37. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/prompt_library/prompt_library_manager.py +0 -0
  38. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/prompt_library/prompt_store.py +0 -0
  39. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/schemas/__init__.py +0 -0
  40. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/schemas/config_schema.py +0 -0
  41. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/configs/schemas/mcp_json_schema.py +0 -0
  42. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/container/__init__.py +0 -0
  43. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/container/container_factory.py +0 -0
  44. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/context/__init__.py +0 -0
  45. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/context/request_context.py +0 -0
  46. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/converters/__init__.py +0 -0
  47. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/converters/history_cache_middleware.py +0 -0
  48. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/converters/stream_buffer.py +0 -0
  49. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/converters/stream_context_mixin.py +0 -0
  50. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/converters/stream_debug_output_manager.py +0 -0
  51. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/converters/streaming_formatters.py +0 -0
  52. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/converters/streaming_manager.py +0 -0
  53. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/converters/streaming_tool_node.py +0 -0
  54. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/converters/tool_event_handlers.py +0 -0
  55. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/exceptions/__init__.py +0 -0
  56. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/exceptions/bailey_exception.py +0 -0
  57. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/exceptions/rate_limit_exception.py +0 -0
  58. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/file_managers/__init__.py +0 -0
  59. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/file_managers/aws_s3_file_manager.py +0 -0
  60. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/file_managers/file_manager.py +0 -0
  61. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/file_managers/file_manager_factory.py +0 -0
  62. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/file_managers/file_writer.py +0 -0
  63. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/file_managers/local_file_manager.py +0 -0
  64. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/github/__init__.py +0 -0
  65. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/github/token_provider.py +0 -0
  66. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/graph/__init__.py +0 -0
  67. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/graph/graph_builder.py +0 -0
  68. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/history/__init__.py +0 -0
  69. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/history/context_compactor.py +0 -0
  70. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/history/conversation_history_manager.py +0 -0
  71. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/history/smart_history_manager.py +0 -0
  72. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/http/__init__.py +0 -0
  73. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/http/http_client_factory.py +0 -0
  74. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/image_generation/__init__.py +0 -0
  75. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/image_generation/aws_image_generator.py +0 -0
  76. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/image_generation/image_generator.py +0 -0
  77. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/image_generation/image_generator_factory.py +0 -0
  78. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/image_generation/managers/__init__.py +0 -0
  79. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/image_generation/managers/image_generation_manager.py +0 -0
  80. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/image_generation/openai_image_generator.py +0 -0
  81. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/image_generation/providers/__init__.py +0 -0
  82. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/image_generation/providers/base_image_generation_provider.py +0 -0
  83. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/image_generation/providers/image_generation_provider.py +0 -0
  84. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/markdown/__init__.py +0 -0
  85. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/markdown/html_to_markdown_converter.py +0 -0
  86. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/__init__.py +0 -0
  87. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/auth/__init__.py +0 -0
  88. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/callbacks.py +0 -0
  89. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/exceptions/__init__.py +0 -0
  90. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/interceptors/__init__.py +0 -0
  91. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/interceptors/tracing.py +0 -0
  92. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/interceptors/truncation.py +0 -0
  93. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/mcp_client/__init__.py +0 -0
  94. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/mcp_client/content_conversion.py +0 -0
  95. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/mcp_client/mcp_tool_list_store.py +0 -0
  96. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/mcp_client/server_card_discovery.py +0 -0
  97. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/mcp_client/session.py +0 -0
  98. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/mcp_client/session_pool.py +0 -0
  99. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mcp/mcp_client/tool_list_cache.py +0 -0
  100. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mocks/__init__.py +0 -0
  101. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mocks/mock_aws_client_factory.py +0 -0
  102. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mocks/mock_http_client_factory.py +0 -0
  103. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mocks/mock_image_generator.py +0 -0
  104. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/mocks/mock_image_generator_factory.py +0 -0
  105. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/models/__init__.py +0 -0
  106. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/models/bedrock_models.py +0 -0
  107. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/models/sanitizing_bedrock_converse.py +0 -0
  108. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/ocr/__init__.py +0 -0
  109. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/ocr/aws_ocr_extractor.py +0 -0
  110. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/ocr/ocr_extractor.py +0 -0
  111. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/ocr/ocr_extractor_factory.py +0 -0
  112. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/persistence/__init__.py +0 -0
  113. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/persistence/persistence_factory.py +0 -0
  114. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/pipeline/__init__.py +0 -0
  115. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/pipeline/context.py +0 -0
  116. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/pipeline/output/__init__.py +0 -0
  117. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/pipeline/pipeline.py +0 -0
  118. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/pipeline/step.py +0 -0
  119. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/pipeline/steps/__init__.py +0 -0
  120. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/py.typed +0 -0
  121. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/schema/__init__.py +0 -0
  122. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/schema/openai/__init__.py +0 -0
  123. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/schema/openai/completions.py +0 -0
  124. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/schema/openai/image_generation.py +0 -0
  125. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/schema/openai/responses.py +0 -0
  126. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/state/__init__.py +0 -0
  127. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/state/messages_state.py +0 -0
  128. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/structures/__init__.py +0 -0
  129. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/structures/openai/__init__.py +0 -0
  130. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/structures/openai/message/__init__.py +0 -0
  131. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/structures/openai/message/chat_completion_api_message_wrapper.py +0 -0
  132. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/structures/openai/message/chat_message_wrapper.py +0 -0
  133. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/structures/openai/message/responses_api_message_wrapper.py +0 -0
  134. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/structures/openai/request/__init__.py +0 -0
  135. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/structures/openai/request/chat_completion_api_request_wrapper.py +0 -0
  136. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/structures/openai/request/chat_request_wrapper.py +0 -0
  137. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/structures/openai/request/responses_api_request_wrapper.py +0 -0
  138. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/tools/__init__.py +0 -0
  139. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/tools/mcp/__init__.py +0 -0
  140. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/__init__.py +0 -0
  141. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/cache/__init__.py +0 -0
  142. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/cache/advisory_lock.py +0 -0
  143. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/cache/model_config_cache_store.py +0 -0
  144. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/chat_message_helpers.py +0 -0
  145. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/config_substitution.py +0 -0
  146. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/environment/__init__.py +0 -0
  147. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/header_reader/__init__.py +0 -0
  148. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/header_reader/header_reader.py +0 -0
  149. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/logger/__init__.py +0 -0
  150. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/logger/debug_configuration.py +0 -0
  151. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/logger/exception_formatter.py +0 -0
  152. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/logger/exception_logger.py +0 -0
  153. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/logger/log_levels.py +0 -0
  154. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/logger/logging_response.py +0 -0
  155. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/logger/logging_transport.py +0 -0
  156. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/message_preprocessing/__init__.py +0 -0
  157. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/message_preprocessing/composite_message_preprocessor.py +0 -0
  158. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/message_preprocessing/message_preprocessor.py +0 -0
  159. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/mongo_url_utils.py +0 -0
  160. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/openai/__init__.py +0 -0
  161. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/openai/responses_api_converter.py +0 -0
  162. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/request_information.py +0 -0
  163. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/s3_url.py +0 -0
  164. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/security/__init__.py +0 -0
  165. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/security/normalize.py +0 -0
  166. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/security/off_topic_detector.py +0 -0
  167. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/security/prompt_extraction_detector.py +0 -0
  168. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/security/prompt_sanitizer.py +0 -0
  169. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/security/url_validation.py +0 -0
  170. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/slash_command/__init__.py +0 -0
  171. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/slash_command/handlers/__init__.py +0 -0
  172. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/slash_command/handlers/debug_command_handler.py +0 -0
  173. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/slash_command/handlers/skill_command_handler.py +0 -0
  174. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/slash_command/slash_command_handler.py +0 -0
  175. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/slash_command/slash_command_parser.py +0 -0
  176. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/slash_command/slash_command_processor.py +0 -0
  177. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/text_humanizer.py +0 -0
  178. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/token_reducer/__init__.py +0 -0
  179. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/token_reducer/token_reducer.py +0 -0
  180. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/tool_display_name_mapper.py +0 -0
  181. {language_model_common-3.0.4 → language_model_common-3.0.6}/languagemodelcommon/utilities/url_parser.py +0 -0
  182. {language_model_common-3.0.4 → language_model_common-3.0.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: language-model-common
3
- Version: 3.0.4
3
+ Version: 3.0.6
4
4
  Summary: Provides the underlying framework to enhance langchain and add loading configurations
5
5
  Author-email: Imran Qureshi <imran.qureshi@bwell.com>
6
6
  License: Apache-2.0
@@ -21,7 +21,7 @@ Requires-Dist: openai>=2.5.0
21
21
  Requires-Dist: langchain-openai>=1.1.6
22
22
  Requires-Dist: langgraph>=1.0.0
23
23
  Requires-Dist: pydantic<3.0.0,>=2.0
24
- Requires-Dist: mcp>=1.27.2
24
+ Requires-Dist: mcp>=2.2.0
25
25
  Requires-Dist: langgraph-checkpoint>=3.0.0
26
26
  Requires-Dist: langgraph-checkpoint-mongodb>=0.3.1
27
27
  Requires-Dist: langgraph-store-mongodb>=0.1.0
@@ -0,0 +1 @@
1
+ 3.0.6
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: language-model-common
3
- Version: 3.0.4
3
+ Version: 3.0.6
4
4
  Summary: Provides the underlying framework to enhance langchain and add loading configurations
5
5
  Author-email: Imran Qureshi <imran.qureshi@bwell.com>
6
6
  License: Apache-2.0
@@ -21,7 +21,7 @@ Requires-Dist: openai>=2.5.0
21
21
  Requires-Dist: langchain-openai>=1.1.6
22
22
  Requires-Dist: langgraph>=1.0.0
23
23
  Requires-Dist: pydantic<3.0.0,>=2.0
24
- Requires-Dist: mcp>=1.27.2
24
+ Requires-Dist: mcp>=2.2.0
25
25
  Requires-Dist: langgraph-checkpoint>=3.0.0
26
26
  Requires-Dist: langgraph-checkpoint-mongodb>=0.3.1
27
27
  Requires-Dist: langgraph-store-mongodb>=0.1.0
@@ -8,7 +8,7 @@ openai>=2.5.0
8
8
  langchain-openai>=1.1.6
9
9
  langgraph>=1.0.0
10
10
  pydantic<3.0.0,>=2.0
11
- mcp>=1.27.2
11
+ mcp>=2.2.0
12
12
  langgraph-checkpoint>=3.0.0
13
13
  langgraph-checkpoint-mongodb>=0.3.1
14
14
  langgraph-store-mongodb>=0.1.0
@@ -139,6 +139,7 @@ class LangGraphToOpenAIConverter(StreamContextMixin):
139
139
 
140
140
  _RATE_LIMIT_PATTERNS: tuple[str, ...] = (
141
141
  "too many tokens",
142
+ "too many requests",
142
143
  "rate limit",
143
144
  "rate_limit",
144
145
  "error code: 429",
@@ -150,7 +151,12 @@ class LangGraphToOpenAIConverter(StreamContextMixin):
150
151
 
151
152
  Detects structurally rather than importing a specific vendor SDK: a
152
153
  ``status_code``/``code`` of 429, a class named ``*RateLimitError*``
153
- (Anthropic, OpenAI), or a recognizable message pattern.
154
+ (Anthropic, OpenAI) or ``*ThrottlingException*`` (boto3/botocore Bedrock
155
+ Converse client), or a recognizable message pattern. Covers both Bedrock
156
+ client paths language-model-common can construct (BAI-765) — the
157
+ Anthropic SDK's "too many tokens" wording and botocore's "too many
158
+ requests"/``ThrottlingException`` wording were previously handled by
159
+ separate, inconsistent checks in different call sites.
154
160
  """
155
161
  current: BaseException | None = exception
156
162
  while current is not None:
@@ -159,7 +165,10 @@ class LangGraphToOpenAIConverter(StreamContextMixin):
159
165
  or getattr(current, "code", None) == 429
160
166
  ):
161
167
  return True
162
- if "ratelimiterror" in current.__class__.__name__.lower():
168
+ class_name = current.__class__.__name__.lower()
169
+ if class_name.endswith("ratelimiterror") or class_name.endswith(
170
+ "throttlingexception"
171
+ ):
163
172
  return True
164
173
  msg = str(current).lower()
165
174
  if any(p in msg for p in LangGraphToOpenAIConverter._RATE_LIMIT_PATTERNS):
@@ -756,6 +765,18 @@ class LangGraphToOpenAIConverter(StreamContextMixin):
756
765
  config=config,
757
766
  )
758
767
  runtime_context = {"user_id": request_information.user_id}
768
+
769
+ # Deliberately no app-level retry-with-backoff here (unlike
770
+ # _stream_graph_with_messages_async's pre-first-token retry): a single
771
+ # ainvoke() call can span multiple graph steps (tool calls) with real
772
+ # side effects (e.g. writes via MCP tools), persisted through an
773
+ # optional checkpointer keyed by conversation_thread_id. Re-invoking
774
+ # the whole graph on a rate limit raised partway through a turn risks
775
+ # re-executing already-committed, non-idempotent tool calls (BAI-765
776
+ # review). Bedrock-level retry for a single throttled model call is
777
+ # instead handled at the SDK layer via ModelFactory's max_retries
778
+ # (see aws_bedrock_max_retries), which only retries the specific node
779
+ # that was throttled, not the whole graph.
759
780
  try:
760
781
  output: Dict[str, Any] = await compiled_state_graph.ainvoke(
761
782
  input=input_,
@@ -767,16 +788,16 @@ class LangGraphToOpenAIConverter(StreamContextMixin):
767
788
  logger.exception("AttributeError in throttling handling")
768
789
  raise
769
790
  except Exception as e:
770
- # Try to catch ThrottlingException dynamically
771
- if (
772
- hasattr(e, "__class__")
773
- and e.__class__.__name__ == "ThrottlingException"
774
- ):
775
- logger.exception("AWS ThrottlingException: %s", e)
791
+ if self._is_rate_limit_error(e):
792
+ logger.exception(
793
+ "Rate limited. request_id=%s error=%s",
794
+ request_information.request_id,
795
+ e,
796
+ )
776
797
  raise HTTPException(
777
798
  status_code=429,
778
799
  detail="AWS request throttled. Please try again later.",
779
- )
800
+ ) from e
780
801
  raise
781
802
  out_messages: List[AnyMessage] = output["messages"]
782
803
  return out_messages
@@ -898,14 +919,18 @@ class LangGraphToOpenAIConverter(StreamContextMixin):
898
919
  """Compute backoff delay for a rate-limit retry.
899
920
 
900
921
  Honors an upstream ``Retry-After`` hint when present; otherwise uses
901
- exponential backoff with full jitter based on the configured base delay.
922
+ exponential backoff with full jitter based on the configured base
923
+ delay. Both branches are clamped to rate_limit_max_backoff_seconds
924
+ (BAI-765 review) so an unreasonable/malicious upstream Retry-After
925
+ value can't hang a request-handling coroutine indefinitely.
902
926
  """
927
+ max_delay_seconds = self.environment_variables.rate_limit_max_backoff_seconds
903
928
  if retry_after_seconds is not None and retry_after_seconds > 0:
904
- return retry_after_seconds
929
+ return min(retry_after_seconds, max_delay_seconds)
905
930
  base_delay_seconds = (
906
931
  self.environment_variables.rate_limit_retry_base_delay_ms / 1000.0
907
932
  )
908
- exponential_delay = base_delay_seconds * (2**attempt)
933
+ exponential_delay = min(base_delay_seconds * (2**attempt), max_delay_seconds)
909
934
  # Full jitter: random point in [0, exponential_delay] avoids thundering herd.
910
935
  return random.uniform(0, exponential_delay)
911
936
 
@@ -7,17 +7,22 @@ from collections.abc import Awaitable, Callable
7
7
  from dataclasses import dataclass, replace
8
8
  from typing import Any, Protocol, Self, runtime_checkable
9
9
 
10
- from mcp.types import CallToolResult
10
+ from mcp.types import CallToolResult, InputRequiredResult, InputResponses
11
11
  from typing_extensions import NotRequired, TypedDict, Unpack
12
12
 
13
- # Result type — matches what interceptors and handlers return.
14
- MCPToolCallResult = CallToolResult
13
+ # Result type — matches what interceptors and handlers return. Widened for
14
+ # SEP-2322: a guard-tool-gated tool may return InputRequiredResult instead
15
+ # of a terminal CallToolResult.
16
+ MCPToolCallResult = CallToolResult | InputRequiredResult
15
17
 
16
18
 
17
19
  class _MCPToolCallRequestOverrides(TypedDict, total=False):
18
20
  name: NotRequired[str]
19
21
  args: NotRequired[dict[str, Any]]
20
22
  headers: NotRequired[dict[str, Any] | None]
23
+ input_responses: NotRequired["InputResponses | None"]
24
+ request_state: NotRequired[str | None]
25
+ allow_input_required: NotRequired[bool]
21
26
 
22
27
 
23
28
  @dataclass
@@ -28,6 +33,17 @@ class MCPToolCallRequest:
28
33
  name: Tool name to invoke.
29
34
  args: Tool arguments as key-value pairs.
30
35
  headers: HTTP headers for applicable transports.
36
+ input_responses: Answers to a prior call's InputRequiredResult
37
+ (SEP-2322 guard-tool retry). None on a first-round call.
38
+ request_state: Opaque state echoed from a prior InputRequiredResult.
39
+ Must be passed through byte-exact; never inspected here.
40
+ allow_input_required: Whether the caller is prepared to receive an
41
+ InputRequiredResult instead of a terminal CallToolResult.
42
+ Defaults to False so existing callers that don't handle
43
+ InputRequiredResult keep getting the pre-SEP-2322 behavior
44
+ (session.call_tool raises instead of returning one). Only
45
+ callers that actually check isinstance(result,
46
+ InputRequiredResult) should set this to True.
31
47
 
32
48
  Context fields (read-only, for routing/logging):
33
49
  server_name: Name of the MCP server handling the tool.
@@ -37,6 +53,9 @@ class MCPToolCallRequest:
37
53
  args: dict[str, Any]
38
54
  server_name: str
39
55
  headers: dict[str, Any] | None = None
56
+ input_responses: InputResponses | None = None
57
+ request_state: str | None = None
58
+ allow_input_required: bool = False
40
59
 
41
60
  def override(self, **overrides: Unpack[_MCPToolCallRequestOverrides]) -> Self:
42
61
  return replace(self, **overrides)
@@ -4,6 +4,7 @@ import re
4
4
  from typing import Any
5
5
 
6
6
  from langchain_core.tools import BaseTool, StructuredTool
7
+ from mcp.types import InputRequest, InputRequiredResult
7
8
  from mcp.types import Tool as MCPTool
8
9
 
9
10
  from languagemodelcommon.mcp.callbacks import Callbacks, CallbackContext, _MCPCallbacks
@@ -27,6 +28,68 @@ from languagemodelcommon.mcp.mcp_client.tool_list_cache import ToolListCache
27
28
  _INVALID_TOOL_NAME_CHARS = re.compile(r"[^a-zA-Z0-9_-]")
28
29
 
29
30
 
31
+ class MCPInputRequiredError(RuntimeError):
32
+ """Raised when an MCP tool call returns InputRequiredResult (SEP-2322
33
+ guard-tool ask) instead of a terminal CallToolResult.
34
+
35
+ Carries everything a caller needs to resubmit the *exact same* call via
36
+ ``call_mcp_tool_raw`` once it has collected an answer to
37
+ ``input_requests`` -- this package has no opinion on how that answer is
38
+ collected (a human-in-the-loop UI, a LangGraph ``interrupt()``, or
39
+ anything else); it only guarantees the retry leg has what it needs.
40
+
41
+ Deliberately a plain ``RuntimeError`` subclass, not ``BaseException``:
42
+ unlike mcp-fhir-agent's server-side ``ElicitationRequired`` (which must
43
+ survive broad `except Exception` handlers several call layers below the
44
+ tool function), this exception is raised directly at the LangChain tool
45
+ boundary with no intermediate layer *in this package* that could swallow
46
+ it -- this package makes no guarantee beyond its own boundary.
47
+
48
+ IMPORTANT -- this is the caller's responsibility, not something this
49
+ package can enforce: if you execute this tool's coroutine through a
50
+ framework that wraps tool execution in its own broad, default
51
+ exception-to-error-message conversion, that framework's handling sits
52
+ between this raise site and any "top-level catcher" you may have and
53
+ WILL swallow this exception before your code ever sees it. The primary
54
+ example is LangGraph's prebuilt ``ToolNode``, whose default
55
+ ``handle_tool_errors=True`` wraps every tool call in `except Exception`
56
+ and converts it to a generic error ``ToolMessage``, discarding
57
+ ``input_requests``/``request_state`` in the process. If you wire this
58
+ tool into a ``ToolNode``-style executor, you MUST catch
59
+ ``MCPInputRequiredError`` yourself at or before the point where that
60
+ framework invokes the tool -- do not rely on it propagating further up.
61
+ baileyai's ``wrap_tool_for_guard_tool_bridge``
62
+ (`baileyai/services/mcp/guard_tool_bridge.py`) is the correct pattern:
63
+ it catches ``MCPInputRequiredError`` immediately around its own
64
+ ``await tool.ainvoke(...)`` call, before ``ToolNode`` (or any other
65
+ framework-level handler) ever gets a chance to intercept it -- see the
66
+ companion baileyai ADR
67
+ (`adrs/006-mcp-guard-tool-elicitation-support.md`) for how it's
68
+ consumed.
69
+ """
70
+
71
+ def __init__(
72
+ self,
73
+ *,
74
+ tool_name: str,
75
+ arguments: dict[str, Any],
76
+ connection: "MCPConnectionConfig",
77
+ server_name: str | None,
78
+ input_requests: dict[str, InputRequest],
79
+ request_state: str | None,
80
+ ) -> None:
81
+ self.tool_name = tool_name
82
+ self.arguments = arguments
83
+ self.connection = connection
84
+ self.server_name = server_name
85
+ self.input_requests = input_requests
86
+ self.request_state = request_state
87
+ super().__init__(
88
+ f"MCP tool {tool_name!r} requires input before it can proceed "
89
+ f"(fields: {sorted(input_requests)})"
90
+ )
91
+
92
+
30
93
  def _sanitize_tool_name(name: str) -> str:
31
94
  """Replace characters that violate LLM provider tool-name constraints.
32
95
 
@@ -99,8 +162,18 @@ def mcp_tool_to_langchain_tool(
99
162
  args=arguments,
100
163
  server_name=server_name or "unknown",
101
164
  headers=None,
165
+ allow_input_required=True,
102
166
  )
103
167
  call_tool_result = await handler(request)
168
+ if isinstance(call_tool_result, InputRequiredResult):
169
+ raise MCPInputRequiredError(
170
+ tool_name=tool.name,
171
+ arguments=arguments,
172
+ connection=connection,
173
+ server_name=server_name,
174
+ input_requests=call_tool_result.input_requests or {},
175
+ request_state=call_tool_result.request_state,
176
+ )
104
177
  content = convert_call_tool_result(call_tool_result)
105
178
  return content, None
106
179
 
@@ -7,7 +7,7 @@ from collections.abc import Awaitable, Callable
7
7
  from typing import Any
8
8
 
9
9
  from langchain_core.callbacks.manager import adispatch_custom_event
10
- from mcp.types import CallToolResult
10
+ from mcp.types import CallToolResult, InputRequiredResult, InputResponses
11
11
  from pydantic import ValidationError
12
12
 
13
13
  from languagemodelcommon.mcp.callbacks import Callbacks, CallbackContext, _MCPCallbacks
@@ -231,19 +231,37 @@ async def _execute_tool_call_with_heartbeat(
231
231
  progress_callback: Any,
232
232
  server_name: str,
233
233
  heartbeat_interval_seconds: float,
234
- ) -> CallToolResult:
234
+ input_responses: InputResponses | None = None,
235
+ request_state: str | None = None,
236
+ allow_input_required: bool = False,
237
+ ) -> CallToolResult | InputRequiredResult:
235
238
  """Call ``session.call_tool``, emitting a synthetic ``mcp_tool_heartbeat``
236
239
  custom event every ``heartbeat_interval_seconds`` while the call is in
237
240
  flight, regardless of whether the tool reports real progress.
238
241
 
242
+ ``input_responses``/``request_state`` are SEP-2322 guard-tool retry
243
+ fields, forwarded byte-exact to ``session.call_tool``. When
244
+ ``allow_input_required`` is True, an ``InputRequiredResult`` is returned
245
+ to the caller instead of raising -- see ``ClientSession.call_tool``'s own
246
+ docstring for the raise-vs-return contract.
247
+
239
248
  Uses ``asyncio.shield`` so a heartbeat tick's wait_for timeout never
240
249
  cancels the underlying tool call -- only the local wait is abandoned and
241
250
  retried on the same call_task. If this coroutine itself is cancelled
242
251
  (e.g. the overall chat turn is aborted), the inner call_task is
243
252
  cancelled too rather than left running in the background.
244
253
  """
245
- call_task: "asyncio.Task[CallToolResult]" = asyncio.ensure_future(
246
- session.call_tool(name, arguments, progress_callback=progress_callback)
254
+ call_task: "asyncio.Task[CallToolResult | InputRequiredResult]" = (
255
+ asyncio.ensure_future(
256
+ session.call_tool(
257
+ name,
258
+ arguments,
259
+ progress_callback=progress_callback,
260
+ input_responses=input_responses,
261
+ request_state=request_state,
262
+ allow_input_required=allow_input_required,
263
+ )
264
+ )
247
265
  )
248
266
  elapsed_seconds = 0.0
249
267
  try:
@@ -350,6 +368,9 @@ def _make_execute_tool(
350
368
  progress_callback=mcp_callbacks.progress_callback,
351
369
  server_name=request.server_name,
352
370
  heartbeat_interval_seconds=heartbeat_interval_seconds,
371
+ input_responses=request.input_responses,
372
+ request_state=request.request_state,
373
+ allow_input_required=request.allow_input_required,
353
374
  )
354
375
  except Exception:
355
376
  await session_pool.evict(effective_config)
@@ -363,6 +384,7 @@ def _make_execute_tool(
363
384
  effective_config, mcp_callbacks=mcp_callbacks
364
385
  ) as session:
365
386
  await session.initialize()
387
+ result: CallToolResult | InputRequiredResult
366
388
  try:
367
389
  if await _tool_supports_tasks(
368
390
  session=session,
@@ -392,6 +414,9 @@ def _make_execute_tool(
392
414
  progress_callback=mcp_callbacks.progress_callback,
393
415
  server_name=request.server_name,
394
416
  heartbeat_interval_seconds=heartbeat_interval_seconds,
417
+ input_responses=request.input_responses,
418
+ request_state=request.request_state,
419
+ allow_input_required=request.allow_input_required,
395
420
  )
396
421
  else:
397
422
  result = await _execute_tool_call_with_heartbeat(
@@ -401,6 +426,9 @@ def _make_execute_tool(
401
426
  progress_callback=mcp_callbacks.progress_callback,
402
427
  server_name=request.server_name,
403
428
  heartbeat_interval_seconds=heartbeat_interval_seconds,
429
+ input_responses=request.input_responses,
430
+ request_state=request.request_state,
431
+ allow_input_required=request.allow_input_required,
404
432
  )
405
433
  except Exception as e:
406
434
  captured_exception = e
@@ -423,11 +451,24 @@ async def call_mcp_tool_raw(
423
451
  session_pool: McpSessionPool | None = None,
424
452
  tool_list_cache: ToolListCache | None = None,
425
453
  heartbeat_interval_seconds: float = 15.0,
426
- ) -> CallToolResult:
427
- """Call an MCP tool and return the raw CallToolResult.
454
+ input_responses: InputResponses | None = None,
455
+ request_state: str | None = None,
456
+ allow_input_required: bool = False,
457
+ ) -> MCPToolCallResult:
458
+ """Call an MCP tool and return the raw CallToolResult (or, for a
459
+ guard-tool-gated tool, an InputRequiredResult).
428
460
 
429
461
  This is used by the call_tool meta-tool to proxy calls without
430
- converting to LangChain format.
462
+ converting to LangChain format, and by callers resubmitting a SEP-2322
463
+ guard-tool answer (``input_responses``/``request_state``) directly,
464
+ bypassing the LangChain tool-call path entirely since the retry leg
465
+ isn't driven by a fresh LLM tool call.
466
+
467
+ ``allow_input_required`` defaults to False so existing callers that
468
+ don't handle ``InputRequiredResult`` keep getting the pre-SEP-2322
469
+ behavior: the underlying session raises rather than returning one.
470
+ Pass True only if the caller actually checks
471
+ ``isinstance(result, InputRequiredResult)``.
431
472
  """
432
473
  mcp_callbacks = (
433
474
  callbacks.to_mcp_format(
@@ -452,5 +493,8 @@ async def call_mcp_tool_raw(
452
493
  args=arguments,
453
494
  server_name=server_name,
454
495
  headers=None,
496
+ input_responses=input_responses,
497
+ request_state=request_state,
498
+ allow_input_required=allow_input_required,
455
499
  )
456
500
  return await handler(request)
@@ -199,6 +199,36 @@ class ModelFactory:
199
199
 
200
200
  model_parameters_dict = dict(model_parameters_dict)
201
201
 
202
+ if "max_retries" not in model_parameters_dict:
203
+ max_attempts = (
204
+ self._environment_variables.aws_bedrock_max_retries
205
+ if self._environment_variables
206
+ else None
207
+ )
208
+ if max_attempts is not None:
209
+ # aws_bedrock_max_retries returns boto3 max_attempts semantics
210
+ # (total attempts including the first, matching
211
+ # AwsClientFactory.create_bedrock_client's Converse client
212
+ # config), but ChatAnthropicBedrock's max_retries kwarg counts
213
+ # only retries *after* the first attempt. Convert so the same
214
+ # env var value yields the same total attempt count on both
215
+ # Bedrock client paths (BAI-765 review).
216
+ max_retries = max(0, max_attempts - 1)
217
+ model_parameters_dict["max_retries"] = max_retries
218
+ source_env_var = (
219
+ "AWS_BEDROCK_MAX_ATTEMPTS"
220
+ if os.environ.get("AWS_BEDROCK_MAX_ATTEMPTS")
221
+ else "AWS_BEDROCK_MAX_RETRIES"
222
+ )
223
+ logger.info(
224
+ "Using %s=%d (max_retries=%d) for Anthropic Bedrock client %s "
225
+ "(overriding langchain_aws's hardcoded default of 2; BAI-765)",
226
+ source_env_var,
227
+ max_attempts,
228
+ max_retries,
229
+ model_name,
230
+ )
231
+
202
232
  if "max_tokens" not in model_parameters_dict:
203
233
  resolved_max_tokens = self._resolve_anthropic_bedrock_max_tokens(
204
234
  model_name=model_name
@@ -264,6 +264,17 @@ class LanguageModelCommonEnvironmentVariables(
264
264
  """Base delay in milliseconds for rate-limit retry exponential backoff."""
265
265
  return int(os.environ.get("RATE_LIMIT_RETRY_BASE_DELAY_MS", "500"))
266
266
 
267
+ @property
268
+ def rate_limit_max_backoff_seconds(self) -> float:
269
+ """Upper bound on a single rate-limit retry delay, in seconds.
270
+
271
+ Applies to both the exponential-backoff and upstream Retry-After
272
+ branches of _compute_rate_limit_backoff, so an unreasonable or
273
+ malicious Retry-After header value can't hang a request-handling
274
+ coroutine indefinitely (BAI-765 review).
275
+ """
276
+ return float(os.environ.get("RATE_LIMIT_MAX_BACKOFF_SECONDS", "60"))
277
+
267
278
  @property
268
279
  def mongo_db_token_collection_name(self) -> Optional[str]:
269
280
  return os.environ.get("MONGO_DB_TOKEN_COLLECTION_NAME")
@@ -357,6 +368,30 @@ class LanguageModelCommonEnvironmentVariables(
357
368
  def aws_bedrock_retry_mode(self) -> str:
358
369
  return os.environ.get("AWS_BEDROCK_RETRY_MODE", "adaptive")
359
370
 
371
+ @property
372
+ def aws_bedrock_max_retries(self) -> Optional[int]:
373
+ """Max Bedrock call attempts, in boto3 max_attempts semantics (total
374
+ attempts including the first).
375
+
376
+ Shares AWS_BEDROCK_MAX_ATTEMPTS/AWS_BEDROCK_MAX_RETRIES with
377
+ AwsClientFactory.create_bedrock_client's boto3 retry config (BAI-765).
378
+ Despite this property's name, the returned value is *attempts*, not
379
+ *retries* — callers that hand it to an SDK using retries-after-first
380
+ semantics (e.g. ChatAnthropicBedrock's max_retries kwarg) must convert
381
+ it (max(0, value - 1)) to keep total attempt counts consistent across
382
+ Bedrock client paths (BAI-765 review). Returns None when unset so
383
+ callers keep the underlying SDK's own default instead of forcing one.
384
+ """
385
+ value = os.environ.get("AWS_BEDROCK_MAX_ATTEMPTS") or os.environ.get(
386
+ "AWS_BEDROCK_MAX_RETRIES"
387
+ )
388
+ if value is None or value.strip() == "":
389
+ return None
390
+ try:
391
+ return int(value)
392
+ except ValueError:
393
+ return None
394
+
360
395
  @property
361
396
  def aws_credentials_profile(self) -> Optional[str]:
362
397
  return os.environ.get("AWS_CREDENTIALS_PROFILE")
@@ -28,7 +28,7 @@ dependencies = [
28
28
  "langchain-openai>=1.1.6",
29
29
  "langgraph>=1.0.0",
30
30
  "pydantic>=2.0,<3.0.0",
31
- "mcp>=1.27.2",
31
+ "mcp>=2.2.0",
32
32
  "langgraph-checkpoint>=3.0.0",
33
33
  "langgraph-checkpoint-mongodb>=0.3.1",
34
34
  "langgraph-store-mongodb>=0.1.0",
@@ -1 +0,0 @@
1
- 3.0.4