hammad-python 0.0.20__tar.gz → 0.0.22__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 (258) hide show
  1. {hammad_python-0.0.20 → hammad_python-0.0.22}/PKG-INFO +1 -1
  2. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/agents/agent.py +386 -47
  3. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/agents/types/agent_response.py +39 -5
  4. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/agents/types/agent_stream.py +92 -7
  5. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/model.py +17 -0
  6. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/types/language_model_response.py +5 -2
  7. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/types/tools.py +2 -0
  8. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/logging/logger.py +8 -0
  9. {hammad_python-0.0.20 → hammad_python-0.0.22}/pyproject.toml +2 -3
  10. {hammad_python-0.0.20 → hammad_python-0.0.22}/uv.lock +231 -14
  11. hammad_python-0.0.20/.python-version +0 -1
  12. hammad_python-0.0.20/deprecated/hammad/__init__.py +0 -1
  13. hammad_python-0.0.20/deprecated/hammad/ai/__init__.py +0 -1
  14. hammad_python-0.0.20/deprecated/hammad/ai/_utils.py +0 -142
  15. hammad_python-0.0.20/deprecated/hammad/ai/completions/__init__.py +0 -45
  16. hammad_python-0.0.20/deprecated/hammad/ai/completions/client.py +0 -684
  17. hammad_python-0.0.20/deprecated/hammad/ai/completions/create.py +0 -710
  18. hammad_python-0.0.20/deprecated/hammad/ai/completions/settings.py +0 -100
  19. hammad_python-0.0.20/deprecated/hammad/ai/completions/types.py +0 -792
  20. hammad_python-0.0.20/deprecated/hammad/ai/completions/utils.py +0 -486
  21. hammad_python-0.0.20/deprecated/hammad/ai/embeddings/__init__.py +0 -35
  22. hammad_python-0.0.20/deprecated/hammad/ai/embeddings/client/__init__.py +0 -1
  23. hammad_python-0.0.20/deprecated/hammad/ai/embeddings/client/base_embeddings_client.py +0 -26
  24. hammad_python-0.0.20/deprecated/hammad/ai/embeddings/client/fastembed_text_embeddings_client.py +0 -200
  25. hammad_python-0.0.20/deprecated/hammad/ai/embeddings/client/litellm_embeddings_client.py +0 -288
  26. hammad_python-0.0.20/deprecated/hammad/ai/embeddings/create.py +0 -159
  27. hammad_python-0.0.20/deprecated/hammad/ai/embeddings/types.py +0 -69
  28. hammad_python-0.0.20/deprecated/hammad/cache/__init__.py +0 -40
  29. hammad_python-0.0.20/deprecated/hammad/cli/__init__.py +0 -33
  30. hammad_python-0.0.20/deprecated/hammad/cli/animations.py +0 -573
  31. hammad_python-0.0.20/deprecated/hammad/cli/plugins.py +0 -777
  32. hammad_python-0.0.20/deprecated/hammad/cli/styles/__init__.py +0 -55
  33. hammad_python-0.0.20/deprecated/hammad/cli/styles/utils.py +0 -480
  34. hammad_python-0.0.20/deprecated/hammad/data/__init__.py +0 -54
  35. hammad_python-0.0.20/deprecated/hammad/data/collections/__init__.py +0 -34
  36. hammad_python-0.0.20/deprecated/hammad/data/collections/base_collection.py +0 -58
  37. hammad_python-0.0.20/deprecated/hammad/data/collections/collection.py +0 -452
  38. hammad_python-0.0.20/deprecated/hammad/data/collections/searchable_collection.py +0 -556
  39. hammad_python-0.0.20/deprecated/hammad/data/collections/vector_collection.py +0 -596
  40. hammad_python-0.0.20/deprecated/hammad/data/configurations/__init__.py +0 -35
  41. hammad_python-0.0.20/deprecated/hammad/data/configurations/configuration.py +0 -564
  42. hammad_python-0.0.20/deprecated/hammad/data/databases/__init__.py +0 -21
  43. hammad_python-0.0.20/deprecated/hammad/data/databases/database.py +0 -916
  44. hammad_python-0.0.20/deprecated/hammad/data/models/__init__.py +0 -33
  45. hammad_python-0.0.20/deprecated/hammad/data/models/base/__init__.py +0 -35
  46. hammad_python-0.0.20/deprecated/hammad/data/models/base/fields.py +0 -546
  47. hammad_python-0.0.20/deprecated/hammad/data/models/base/model.py +0 -1078
  48. hammad_python-0.0.20/deprecated/hammad/data/models/base/utils.py +0 -280
  49. hammad_python-0.0.20/deprecated/hammad/data/models/pydantic/__init__.py +0 -55
  50. hammad_python-0.0.20/deprecated/hammad/data/models/pydantic/converters.py +0 -632
  51. hammad_python-0.0.20/deprecated/hammad/data/models/pydantic/models/__init__.py +0 -28
  52. hammad_python-0.0.20/deprecated/hammad/data/models/pydantic/models/arbitrary_model.py +0 -46
  53. hammad_python-0.0.20/deprecated/hammad/data/models/pydantic/models/cacheable_model.py +0 -79
  54. hammad_python-0.0.20/deprecated/hammad/data/models/pydantic/models/fast_model.py +0 -318
  55. hammad_python-0.0.20/deprecated/hammad/data/models/pydantic/models/function_model.py +0 -176
  56. hammad_python-0.0.20/deprecated/hammad/data/models/pydantic/models/subscriptable_model.py +0 -63
  57. hammad_python-0.0.20/deprecated/hammad/data/types/__init__.py +0 -39
  58. hammad_python-0.0.20/deprecated/hammad/data/types/file.py +0 -358
  59. hammad_python-0.0.20/deprecated/hammad/data/types/multimodal/__init__.py +0 -24
  60. hammad_python-0.0.20/deprecated/hammad/data/types/multimodal/audio.py +0 -96
  61. hammad_python-0.0.20/deprecated/hammad/data/types/multimodal/image.py +0 -80
  62. hammad_python-0.0.20/deprecated/hammad/formatting/__init__.py +0 -38
  63. hammad_python-0.0.20/deprecated/hammad/formatting/json/__init__.py +0 -21
  64. hammad_python-0.0.20/deprecated/hammad/formatting/json/converters.py +0 -152
  65. hammad_python-0.0.20/deprecated/hammad/formatting/text/__init__.py +0 -63
  66. hammad_python-0.0.20/deprecated/hammad/formatting/yaml/__init__.py +0 -26
  67. hammad_python-0.0.20/deprecated/hammad/logging/__init__.py +0 -35
  68. hammad_python-0.0.20/deprecated/hammad/logging/decorators.py +0 -834
  69. hammad_python-0.0.20/deprecated/hammad/logging/logger.py +0 -954
  70. hammad_python-0.0.20/deprecated/hammad/mcp/__init__.py +0 -50
  71. hammad_python-0.0.20/deprecated/hammad/mcp/client/__init__.py +0 -1
  72. hammad_python-0.0.20/deprecated/hammad/mcp/client/client.py +0 -523
  73. hammad_python-0.0.20/deprecated/hammad/mcp/client/client_service.py +0 -393
  74. hammad_python-0.0.20/deprecated/hammad/mcp/servers/__init__.py +0 -1
  75. hammad_python-0.0.20/deprecated/hammad/performance/__init__.py +0 -36
  76. hammad_python-0.0.20/deprecated/hammad/performance/imports.py +0 -231
  77. hammad_python-0.0.20/deprecated/hammad/performance/runtime/__init__.py +0 -32
  78. hammad_python-0.0.20/deprecated/hammad/performance/runtime/decorators.py +0 -142
  79. hammad_python-0.0.20/deprecated/hammad/performance/runtime/run.py +0 -299
  80. hammad_python-0.0.20/deprecated/hammad/service/__init__.py +0 -49
  81. hammad_python-0.0.20/deprecated/hammad/service/create.py +0 -532
  82. hammad_python-0.0.20/deprecated/hammad/service/decorators.py +0 -285
  83. hammad_python-0.0.20/deprecated/hammad/typing/__init__.py +0 -407
  84. hammad_python-0.0.20/deprecated/hammad/web/__init__.py +0 -43
  85. hammad_python-0.0.20/deprecated/hammad/web/http/client.py +0 -944
  86. hammad_python-0.0.20/deprecated/hammad/web/models.py +0 -245
  87. hammad_python-0.0.20/deprecated/hammad/web/search/client.py +0 -988
  88. hammad_python-0.0.20/deprecated/hammad/web/utils.py +0 -472
  89. hammad_python-0.0.20/deprecated/tests/ai/completions/test_ai_completions_create.py +0 -244
  90. hammad_python-0.0.20/deprecated/tests/ai/completions/test_ai_completions_types.py +0 -585
  91. hammad_python-0.0.20/deprecated/tests/cache/test_performance_cache.py +0 -182
  92. hammad_python-0.0.20/deprecated/tests/cli/test_cli_plugins_animate.py +0 -134
  93. hammad_python-0.0.20/deprecated/tests/cli/test_cli_plugins_input.py +0 -227
  94. hammad_python-0.0.20/deprecated/tests/cli/test_cli_plugins_print.py +0 -181
  95. hammad_python-0.0.20/deprecated/tests/cli/test_cli_styles_utils.py +0 -125
  96. hammad_python-0.0.20/deprecated/tests/data/collections/test_data_collections_searchable_collection.py +0 -308
  97. hammad_python-0.0.20/deprecated/tests/data/collections/test_data_collections_vector_collection.py +0 -495
  98. hammad_python-0.0.20/deprecated/tests/data/configuration/test_data_configuration.py +0 -0
  99. hammad_python-0.0.20/deprecated/tests/data/databases/test_data_databases_database.py +0 -725
  100. hammad_python-0.0.20/deprecated/tests/data/models/base/test_data_models_base_fields.py +0 -468
  101. hammad_python-0.0.20/deprecated/tests/data/models/base/test_data_models_base_model.py +0 -841
  102. hammad_python-0.0.20/deprecated/tests/data/models/pydantic/test_models_pydantic_converters.py +0 -270
  103. hammad_python-0.0.20/deprecated/tests/data/models/pydantic/test_models_pydantic_models.py +0 -288
  104. hammad_python-0.0.20/deprecated/tests/data/types/test_data_types_text.py +0 -523
  105. hammad_python-0.0.20/deprecated/tests/formatting/json/test_json_converters.py +0 -134
  106. hammad_python-0.0.20/deprecated/tests/formatting/text/test_text_utils_converters.py +0 -140
  107. hammad_python-0.0.20/deprecated/tests/formatting/text/test_text_utils_markdown_converters.py +0 -338
  108. hammad_python-0.0.20/deprecated/tests/logging/test_logging_decorators.py +0 -534
  109. hammad_python-0.0.20/deprecated/tests/logging/test_logging_logger.py +0 -237
  110. hammad_python-0.0.20/deprecated/tests/mcp/test_mcp_client_services.py +0 -404
  111. hammad_python-0.0.20/deprecated/tests/mcp/test_mcp_server_services.py +0 -555
  112. hammad_python-0.0.20/deprecated/tests/performance/runtime/test_performance_runtime_decorators.py +0 -66
  113. hammad_python-0.0.20/deprecated/tests/performance/runtime/test_performance_runtime_run.py +0 -98
  114. hammad_python-0.0.20/deprecated/tests/service/test_service_create_service.py +0 -177
  115. hammad_python-0.0.20/deprecated/tests/service/test_service_serve_decorator.py +0 -175
  116. hammad_python-0.0.20/deprecated/tests/service/test_service_serve_mcp_decorator.py +0 -204
  117. hammad_python-0.0.20/deprecated/tests/typing/test_typing_utils.py +0 -243
  118. hammad_python-0.0.20/deprecated/tests/web/test_web_toolkits_http_toolkit.py +0 -369
  119. hammad_python-0.0.20/deprecated/tests/web/test_web_toolkits_openapi_toolkit.py +0 -586
  120. hammad_python-0.0.20/deprecated/tests/web/test_web_utils.py +0 -364
  121. hammad_python-0.0.20/hammad/cache/base_cache.py +0 -181
  122. hammad_python-0.0.20/hammad/cache/cache.py +0 -169
  123. hammad_python-0.0.20/hammad/cache/decorators.py +0 -261
  124. hammad_python-0.0.20/hammad/cache/file_cache.py +0 -80
  125. hammad_python-0.0.20/hammad/cache/ttl_cache.py +0 -74
  126. hammad_python-0.0.20/hammad/cli/styles/settings.py +0 -139
  127. hammad_python-0.0.20/hammad/cli/styles/types.py +0 -358
  128. hammad_python-0.0.20/hammad/data/types/text.py +0 -1066
  129. hammad_python-0.0.20/hammad/formatting/text/converters.py +0 -723
  130. hammad_python-0.0.20/hammad/formatting/text/markdown.py +0 -131
  131. hammad_python-0.0.20/hammad/formatting/yaml/converters.py +0 -5
  132. hammad_python-0.0.20/hammad/mcp/client/settings.py +0 -178
  133. hammad_python-0.0.20/hammad/mcp/servers/launcher.py +0 -1161
  134. hammad_python-0.0.20/hammad/py.typed +0 -0
  135. hammad_python-0.0.20/hammad/web/http/__init__.py +0 -1
  136. hammad_python-0.0.20/hammad/web/openapi/__init__.py +0 -1
  137. hammad_python-0.0.20/hammad/web/openapi/client.py +0 -740
  138. hammad_python-0.0.20/hammad/web/search/__init__.py +0 -1
  139. {hammad_python-0.0.20 → hammad_python-0.0.22}/.gitignore +0 -0
  140. {hammad_python-0.0.20 → hammad_python-0.0.22}/LICENSE +0 -0
  141. {hammad_python-0.0.20 → hammad_python-0.0.22}/README.md +0 -0
  142. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/__init__.py +0 -0
  143. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/_internal.py +0 -0
  144. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/cache/__init__.py +0 -0
  145. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/cache/base_cache.py +0 -0
  146. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/cache/cache.py +0 -0
  147. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/cache/decorators.py +0 -0
  148. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/cache/file_cache.py +0 -0
  149. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/cache/ttl_cache.py +0 -0
  150. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/cli/__init__.py +0 -0
  151. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/cli/_runner.py +0 -0
  152. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/cli/animations.py +0 -0
  153. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/cli/plugins.py +0 -0
  154. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/cli/styles/__init__.py +0 -0
  155. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/cli/styles/settings.py +0 -0
  156. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/cli/styles/types.py +0 -0
  157. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/cli/styles/utils.py +0 -0
  158. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/__init__.py +0 -0
  159. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/collections/__init__.py +0 -0
  160. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/collections/collection.py +0 -0
  161. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/collections/indexes/__init__.py +0 -0
  162. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/collections/indexes/qdrant/__init__.py +0 -0
  163. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/collections/indexes/qdrant/index.py +0 -0
  164. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/collections/indexes/qdrant/settings.py +0 -0
  165. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/collections/indexes/qdrant/utils.py +0 -0
  166. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/collections/indexes/tantivy/__init__.py +0 -0
  167. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/collections/indexes/tantivy/index.py +0 -0
  168. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/collections/indexes/tantivy/settings.py +0 -0
  169. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/collections/indexes/tantivy/utils.py +0 -0
  170. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/configurations/__init__.py +0 -0
  171. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/configurations/configuration.py +0 -0
  172. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/models/__init__.py +0 -0
  173. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/models/extensions/__init__.py +0 -0
  174. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/models/extensions/pydantic/__init__.py +0 -0
  175. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/models/extensions/pydantic/converters.py +0 -0
  176. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/models/fields.py +0 -0
  177. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/models/model.py +0 -0
  178. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/models/utils.py +0 -0
  179. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/sql/__init__.py +0 -0
  180. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/sql/database.py +0 -0
  181. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/sql/types.py +0 -0
  182. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/types/__init__.py +0 -0
  183. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/types/file.py +0 -0
  184. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/types/multimodal/__init__.py +0 -0
  185. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/types/multimodal/audio.py +0 -0
  186. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/data/types/multimodal/image.py +0 -0
  187. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/data/types/text.py +0 -0
  188. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/formatting/__init__.py +0 -0
  189. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/formatting/json/__init__.py +0 -0
  190. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/formatting/json/converters.py +0 -0
  191. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/formatting/text/__init__.py +0 -0
  192. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/formatting/text/converters.py +0 -0
  193. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/formatting/text/markdown.py +0 -0
  194. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/formatting/yaml/__init__.py +0 -0
  195. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/formatting/yaml/converters.py +0 -0
  196. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/__init__.py +0 -0
  197. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/agents/__init__.py +0 -0
  198. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/agents/run.py +0 -0
  199. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/agents/types/__init__.py +0 -0
  200. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/agents/types/agent_context.py +0 -0
  201. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/agents/types/agent_event.py +0 -0
  202. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/agents/types/agent_hooks.py +0 -0
  203. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/agents/types/agent_messages.py +0 -0
  204. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/__init__.py +0 -0
  205. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/embeddings/__init__.py +0 -0
  206. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/embeddings/model.py +0 -0
  207. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/embeddings/run.py +0 -0
  208. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/embeddings/types/__init__.py +0 -0
  209. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/embeddings/types/embedding_model_name.py +0 -0
  210. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/embeddings/types/embedding_model_response.py +0 -0
  211. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/embeddings/types/embedding_model_run_params.py +0 -0
  212. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/embeddings/types/embedding_model_settings.py +0 -0
  213. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/__init__.py +0 -0
  214. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/run.py +0 -0
  215. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/types/__init__.py +0 -0
  216. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/types/language_model_instructor_mode.py +0 -0
  217. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/types/language_model_messages.py +0 -0
  218. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/types/language_model_name.py +0 -0
  219. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/types/language_model_request.py +0 -0
  220. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/types/language_model_response_chunk.py +0 -0
  221. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/types/language_model_settings.py +0 -0
  222. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/types/language_model_stream.py +0 -0
  223. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/utils/__init__.py +0 -0
  224. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/utils/requests.py +0 -0
  225. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/language/utils/structured_outputs.py +0 -0
  226. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/model_provider.py +0 -0
  227. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/multimodal.py +0 -0
  228. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/models/reranking.py +0 -0
  229. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/types/__init__.py +0 -0
  230. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/types/base.py +0 -0
  231. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/genai/types/history.py +0 -0
  232. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/logging/__init__.py +0 -0
  233. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/logging/decorators.py +0 -0
  234. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/mcp/__init__.py +0 -0
  235. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/mcp/client/__init__.py +0 -0
  236. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/mcp/client/client.py +0 -0
  237. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/mcp/client/client_service.py +0 -0
  238. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/mcp/client/settings.py +0 -0
  239. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/mcp/servers/__init__.py +0 -0
  240. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/mcp/servers/launcher.py +0 -0
  241. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/py.typed +0 -0
  242. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/runtime/__init__.py +0 -0
  243. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/runtime/decorators.py +0 -0
  244. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/runtime/run.py +0 -0
  245. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/service/__init__.py +0 -0
  246. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/service/create.py +0 -0
  247. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/service/decorators.py +0 -0
  248. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/typing/__init__.py +0 -0
  249. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/web/__init__.py +0 -0
  250. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/web/http/__init__.py +0 -0
  251. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/web/http/client.py +0 -0
  252. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/web/models.py +0 -0
  253. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/web/openapi/__init__.py +0 -0
  254. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/web/openapi/client.py +0 -0
  255. {hammad_python-0.0.20/deprecated → hammad_python-0.0.22}/hammad/web/search/__init__.py +0 -0
  256. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/web/search/client.py +0 -0
  257. {hammad_python-0.0.20 → hammad_python-0.0.22}/hammad/web/utils.py +0 -0
  258. {hammad_python-0.0.20 → hammad_python-0.0.22}/mkdocs.yml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hammad-python
3
- Version: 0.0.20
3
+ Version: 0.0.22
4
4
  Author-email: Hammad Saeed <hammadaidev@gmail.com>
5
5
  License: MIT License
6
6
 
@@ -19,6 +19,8 @@ from dataclasses import dataclass, field
19
19
  from enum import Enum
20
20
  import json
21
21
 
22
+ from ...logging.logger import _get_internal_logger
23
+
22
24
  from ..types.base import BaseGenAIModel, BaseGenAIModelSettings
23
25
  from ..models.language.model import LanguageModel
24
26
  from ..models.language.types import (
@@ -53,6 +55,9 @@ if TYPE_CHECKING:
53
55
  T = TypeVar("T")
54
56
 
55
57
 
58
+ logger = _get_internal_logger(__name__)
59
+
60
+
56
61
  @dataclass
57
62
  class AgentSettings:
58
63
  """Settings object that controls the default behavior of an agent's run."""
@@ -253,6 +258,43 @@ class Agent(BaseGenAIModel, Generic[T]):
253
258
  context_format: Literal["json", "python", "markdown"] = "json",
254
259
  **kwargs: Any,
255
260
  ):
261
+ """Create a new AI agent with specified capabilities and behavior.
262
+
263
+ An agent is an intelligent assistant that can use tools, follow instructions,
264
+ and maintain context across conversations. It combines a language model with
265
+ additional capabilities like tool execution and structured output generation.
266
+
267
+ Args:
268
+ name: A human-readable name for the agent (default: "agent")
269
+ instructions: System instructions that define the agent's behavior and personality
270
+ model: The language model to use - either a LanguageModel instance or model name string
271
+ description: Optional description of what the agent does
272
+ tools: List of tools/functions the agent can call, or a single callable
273
+ settings: AgentSettings object to customize default behavior
274
+ instructor_mode: Mode for structured output generation
275
+ context_updates: When to update context - "before", "after", or both
276
+ context_confirm: Whether to confirm context updates with the user
277
+ context_strategy: How to select context updates - "selective" or "all"
278
+ context_max_retries: Maximum attempts for context update operations
279
+ context_confirm_instructions: Custom instructions for context confirmation
280
+ context_selection_instructions: Custom instructions for context selection
281
+ context_update_instructions: Custom instructions for context updates
282
+ context_format: Format for context display - "json", "python", or "markdown"
283
+ **kwargs: Additional parameters passed to the underlying language model
284
+
285
+ Example:
286
+ Basic agent:
287
+ >>> agent = Agent(name="assistant", instructions="You are helpful")
288
+
289
+ Agent with tools:
290
+ >>> def calculator(x: int, y: int) -> int:
291
+ ... return x + y
292
+ >>> agent = Agent(tools=[calculator])
293
+
294
+ Agent with custom settings:
295
+ >>> settings = AgentSettings(max_steps=5)
296
+ >>> agent = Agent(settings=settings, model="gpt-4")
297
+ """
256
298
  # Initialize BaseGenAIModel with basic parameters
257
299
  super().__init__(
258
300
  model=model if isinstance(model, str) else model.model, **kwargs
@@ -297,17 +339,65 @@ class Agent(BaseGenAIModel, Generic[T]):
297
339
  """Get the underlying language model."""
298
340
  return self._language_model
299
341
 
342
+ def _get_effective_context_settings(
343
+ self,
344
+ context_updates: Optional[
345
+ Union[List[Literal["before", "after"]], Literal["before", "after"]]
346
+ ] = None,
347
+ context_confirm: Optional[bool] = None,
348
+ context_strategy: Optional[Literal["selective", "all"]] = None,
349
+ context_max_retries: Optional[int] = None,
350
+ context_confirm_instructions: Optional[str] = None,
351
+ context_selection_instructions: Optional[str] = None,
352
+ context_update_instructions: Optional[str] = None,
353
+ context_format: Optional[Literal["json", "python", "markdown"]] = None,
354
+ ) -> dict:
355
+ """Get effective context settings, using provided parameters or defaults."""
356
+ return {
357
+ "context_updates": context_updates
358
+ if context_updates is not None
359
+ else self.context_updates,
360
+ "context_confirm": context_confirm
361
+ if context_confirm is not None
362
+ else self.context_confirm,
363
+ "context_strategy": context_strategy
364
+ if context_strategy is not None
365
+ else self.context_strategy,
366
+ "context_max_retries": context_max_retries
367
+ if context_max_retries is not None
368
+ else self.context_max_retries,
369
+ "context_confirm_instructions": context_confirm_instructions
370
+ if context_confirm_instructions is not None
371
+ else self.context_confirm_instructions,
372
+ "context_selection_instructions": context_selection_instructions
373
+ if context_selection_instructions is not None
374
+ else self.context_selection_instructions,
375
+ "context_update_instructions": context_update_instructions
376
+ if context_update_instructions is not None
377
+ else self.context_update_instructions,
378
+ "context_format": context_format
379
+ if context_format is not None
380
+ else self.context_format,
381
+ }
382
+
300
383
  def _should_update_context(
301
- self, context: AgentContext, timing: Literal["before", "after"]
384
+ self,
385
+ context: AgentContext,
386
+ timing: Literal["before", "after"],
387
+ context_updates=None,
302
388
  ) -> bool:
303
389
  """Determine if context should be updated based on timing and configuration."""
304
- if not self.context_updates:
390
+ effective_context_updates = (
391
+ context_updates if context_updates is not None else self.context_updates
392
+ )
393
+
394
+ if not effective_context_updates:
305
395
  return False
306
396
 
307
- if isinstance(self.context_updates, str):
308
- return self.context_updates == timing
397
+ if isinstance(effective_context_updates, str):
398
+ return effective_context_updates == timing
309
399
  else:
310
- return timing in self.context_updates
400
+ return timing in effective_context_updates
311
401
 
312
402
  def _create_context_confirm_model(self):
313
403
  """Create IsUpdateRequired model for context confirmation."""
@@ -334,18 +424,60 @@ class Agent(BaseGenAIModel, Generic[T]):
334
424
  if field_name:
335
425
  # Single field update
336
426
  if isinstance(context, BaseModel):
337
- field_type = context.model_fields[field_name].annotation
427
+ field_type = context.__class__.model_fields[field_name].annotation
428
+ field_info = context.__class__.model_fields[field_name]
429
+ description = getattr(
430
+ field_info, "description", f"Update the {field_name} field"
431
+ )
338
432
  elif isinstance(context, dict):
339
433
  field_type = type(context[field_name])
434
+ description = f"Update the {field_name} field"
340
435
  else:
341
436
  field_type = Any
437
+ description = f"Update the {field_name} field"
342
438
 
343
439
  return create_model(
344
- field_name.capitalize(), **{field_name: (field_type, ...)}
440
+ f"Update{field_name.capitalize()}",
441
+ **{field_name: (field_type, Field(description=description))},
345
442
  )
346
443
  else:
347
- # All fields update
348
- return create_model("Update", updates=(Dict[str, Any], ...))
444
+ # All fields update - create a model with the exact same fields as the context
445
+ if isinstance(context, BaseModel):
446
+ # Create a model with the same fields as the context
447
+ field_definitions = {}
448
+ for field_name, field_info in context.model_fields.items():
449
+ field_type = field_info.annotation
450
+ current_value = getattr(context, field_name)
451
+ description = getattr(
452
+ field_info, "description", f"Current value: {current_value}"
453
+ )
454
+ field_definitions[field_name] = (
455
+ field_type,
456
+ Field(description=description),
457
+ )
458
+
459
+ return create_model("ContextUpdate", **field_definitions)
460
+ elif isinstance(context, dict):
461
+ # Create a model with the same keys as the dict
462
+ field_definitions = {}
463
+ for key, value in context.items():
464
+ field_type = type(value)
465
+ description = f"Current value: {value}"
466
+ field_definitions[key] = (
467
+ field_type,
468
+ Field(description=description),
469
+ )
470
+
471
+ return create_model("ContextUpdate", **field_definitions)
472
+ else:
473
+ # Fallback to generic updates
474
+ return create_model(
475
+ "ContextUpdate",
476
+ updates=(
477
+ Dict[str, Any],
478
+ Field(description="Dictionary of field updates"),
479
+ ),
480
+ )
349
481
 
350
482
  def _perform_context_update(
351
483
  self,
@@ -353,20 +485,42 @@ class Agent(BaseGenAIModel, Generic[T]):
353
485
  model: LanguageModel,
354
486
  current_messages: List[Dict[str, Any]],
355
487
  timing: Literal["before", "after"],
488
+ effective_settings: Optional[dict] = None,
356
489
  ) -> AgentContext:
357
490
  """Perform context update with retries and error handling."""
358
491
  updated_context = context
359
492
 
360
- for attempt in range(self.context_max_retries):
493
+ # Use effective settings or defaults
494
+ if effective_settings is None:
495
+ effective_settings = {
496
+ "context_confirm": self.context_confirm,
497
+ "context_strategy": self.context_strategy,
498
+ "context_max_retries": self.context_max_retries,
499
+ "context_confirm_instructions": self.context_confirm_instructions,
500
+ "context_selection_instructions": self.context_selection_instructions,
501
+ "context_update_instructions": self.context_update_instructions,
502
+ "context_format": self.context_format,
503
+ }
504
+
505
+ for attempt in range(effective_settings["context_max_retries"]):
361
506
  try:
362
507
  # Check if update is needed (if confirmation is enabled)
363
- if self.context_confirm:
508
+ if effective_settings["context_confirm"]:
364
509
  confirm_model = self._create_context_confirm_model()
365
- confirm_instructions = f"Based on the conversation, determine if the context should be updated {timing} processing."
366
- if self.context_confirm_instructions:
367
- confirm_instructions += (
368
- f"\n\n{self.context_confirm_instructions}"
369
- )
510
+
511
+ # Create detailed instructions with context structure
512
+ context_structure = _format_context_for_instructions(
513
+ updated_context, effective_settings["context_format"]
514
+ )
515
+ confirm_instructions = f"""Based on the conversation, determine if the context should be updated {timing} processing.
516
+
517
+ Current context structure:
518
+ {context_structure}
519
+
520
+ Should the context be updated based on the new information provided in the conversation?"""
521
+
522
+ if effective_settings["context_confirm_instructions"]:
523
+ confirm_instructions += f"\n\nAdditional instructions: {effective_settings['context_confirm_instructions']}"
370
524
 
371
525
  confirm_response = model.run(
372
526
  messages=current_messages
@@ -379,16 +533,25 @@ class Agent(BaseGenAIModel, Generic[T]):
379
533
  return updated_context
380
534
 
381
535
  # Perform the update based on strategy
382
- if self.context_strategy == "selective":
536
+ if effective_settings["context_strategy"] == "selective":
383
537
  # Get fields to update
384
538
  selection_model = self._create_context_selection_model(
385
539
  updated_context
386
540
  )
387
- selection_instructions = f"Select which fields in the context should be updated {timing} processing."
388
- if self.context_selection_instructions:
389
- selection_instructions += (
390
- f"\n\n{self.context_selection_instructions}"
391
- )
541
+
542
+ # Create detailed instructions with context structure
543
+ context_structure = _format_context_for_instructions(
544
+ updated_context, effective_settings["context_format"]
545
+ )
546
+ selection_instructions = f"""Select which fields in the context should be updated {timing} processing based on the conversation.
547
+
548
+ Current context structure:
549
+ {context_structure}
550
+
551
+ Choose only the fields that need to be updated based on the new information provided in the conversation."""
552
+
553
+ if effective_settings["context_selection_instructions"]:
554
+ selection_instructions += f"\n\nAdditional instructions: {effective_settings['context_selection_instructions']}"
392
555
 
393
556
  selection_response = model.run(
394
557
  messages=current_messages
@@ -403,13 +566,21 @@ class Agent(BaseGenAIModel, Generic[T]):
403
566
  field_model = self._create_context_update_model(
404
567
  updated_context, field_name
405
568
  )
406
- field_instructions = (
407
- f"Update the {field_name} field in the context."
569
+ # Get current field value for context
570
+ current_value = (
571
+ getattr(updated_context, field_name)
572
+ if isinstance(updated_context, BaseModel)
573
+ else updated_context.get(field_name)
408
574
  )
409
- if self.context_update_instructions:
410
- field_instructions += (
411
- f"\n\n{self.context_update_instructions}"
412
- )
575
+
576
+ field_instructions = f"""Update the {field_name} field in the context based on the conversation.
577
+
578
+ Current value of {field_name}: {current_value}
579
+
580
+ Please provide the new value for {field_name} based on the information from the conversation."""
581
+
582
+ if effective_settings["context_update_instructions"]:
583
+ field_instructions += f"\n\nAdditional instructions: {effective_settings['context_update_instructions']}"
413
584
 
414
585
  field_response = model.run(
415
586
  messages=current_messages
@@ -429,9 +600,20 @@ class Agent(BaseGenAIModel, Generic[T]):
429
600
  else: # strategy == "all"
430
601
  # Update all fields at once
431
602
  update_model = self._create_context_update_model(updated_context)
432
- update_instructions = f"Update the context {timing} processing."
433
- if self.context_update_instructions:
434
- update_instructions += f"\n\n{self.context_update_instructions}"
603
+
604
+ # Create detailed instructions with context structure
605
+ context_structure = _format_context_for_instructions(
606
+ updated_context, effective_settings["context_format"]
607
+ )
608
+ update_instructions = f"""Update the context {timing} processing based on the conversation.
609
+
610
+ Current context structure:
611
+ {context_structure}
612
+
613
+ Please update the appropriate fields based on the conversation. Only update fields that need to be changed based on the new information provided."""
614
+
615
+ if effective_settings["context_update_instructions"]:
616
+ update_instructions += f"\n\nAdditional instructions: {effective_settings['context_update_instructions']}"
435
617
 
436
618
  update_response = model.run(
437
619
  messages=current_messages
@@ -441,9 +623,26 @@ class Agent(BaseGenAIModel, Generic[T]):
441
623
  )
442
624
 
443
625
  # Apply the updates
444
- updated_context = _update_context_object(
445
- updated_context, update_response.output.updates
446
- )
626
+ if hasattr(update_response.output, "updates"):
627
+ # Legacy fallback for generic updates
628
+ updated_context = _update_context_object(
629
+ updated_context, update_response.output.updates
630
+ )
631
+ else:
632
+ # New approach - extract field values directly from the response
633
+ updates_dict = {}
634
+ for field_name in (
635
+ context.model_fields.keys()
636
+ if isinstance(context, BaseModel)
637
+ else context.keys()
638
+ ):
639
+ if hasattr(update_response.output, field_name):
640
+ updates_dict[field_name] = getattr(
641
+ update_response.output, field_name
642
+ )
643
+ updated_context = _update_context_object(
644
+ updated_context, updates_dict
645
+ )
447
646
 
448
647
  # Trigger context update hooks
449
648
  self.hook_manager.trigger_hooks("context_update", updated_context)
@@ -490,10 +689,20 @@ class Agent(BaseGenAIModel, Generic[T]):
490
689
  max_steps: Optional[int] = None,
491
690
  context: Optional[AgentContext] = None,
492
691
  output_type: Optional[Type[T]] = None,
692
+ context_updates: Optional[
693
+ Union[List[Literal["before", "after"]], Literal["before", "after"]]
694
+ ] = None,
695
+ context_confirm: Optional[bool] = None,
696
+ context_strategy: Optional[Literal["selective", "all"]] = None,
697
+ context_max_retries: Optional[int] = None,
698
+ context_confirm_instructions: Optional[str] = None,
699
+ context_selection_instructions: Optional[str] = None,
700
+ context_update_instructions: Optional[str] = None,
701
+ context_format: Optional[Literal["json", "python", "markdown"]] = None,
493
702
  *,
494
703
  stream: Literal[False] = False,
495
704
  **kwargs: Any,
496
- ) -> AgentResponse[T]: ...
705
+ ) -> AgentResponse[T, AgentContext]: ...
497
706
 
498
707
  @overload
499
708
  def run(
@@ -503,10 +712,20 @@ class Agent(BaseGenAIModel, Generic[T]):
503
712
  max_steps: Optional[int] = None,
504
713
  context: Optional[AgentContext] = None,
505
714
  output_type: Optional[Type[T]] = None,
715
+ context_updates: Optional[
716
+ Union[List[Literal["before", "after"]], Literal["before", "after"]]
717
+ ] = None,
718
+ context_confirm: Optional[bool] = None,
719
+ context_strategy: Optional[Literal["selective", "all"]] = None,
720
+ context_max_retries: Optional[int] = None,
721
+ context_confirm_instructions: Optional[str] = None,
722
+ context_selection_instructions: Optional[str] = None,
723
+ context_update_instructions: Optional[str] = None,
724
+ context_format: Optional[Literal["json", "python", "markdown"]] = None,
506
725
  *,
507
726
  stream: Literal[True],
508
727
  **kwargs: Any,
509
- ) -> AgentStream[T]: ...
728
+ ) -> AgentStream[T, AgentContext]: ...
510
729
 
511
730
  def run(
512
731
  self,
@@ -515,9 +734,19 @@ class Agent(BaseGenAIModel, Generic[T]):
515
734
  max_steps: Optional[int] = None,
516
735
  context: Optional[AgentContext] = None,
517
736
  output_type: Optional[Type[T]] = None,
737
+ context_updates: Optional[
738
+ Union[List[Literal["before", "after"]], Literal["before", "after"]]
739
+ ] = None,
740
+ context_confirm: Optional[bool] = None,
741
+ context_strategy: Optional[Literal["selective", "all"]] = None,
742
+ context_max_retries: Optional[int] = None,
743
+ context_confirm_instructions: Optional[str] = None,
744
+ context_selection_instructions: Optional[str] = None,
745
+ context_update_instructions: Optional[str] = None,
746
+ context_format: Optional[Literal["json", "python", "markdown"]] = None,
518
747
  stream: bool = False,
519
748
  **kwargs: Any,
520
- ) -> Union[AgentResponse[T], AgentStream[T]]:
749
+ ) -> Union[AgentResponse[T, AgentContext], AgentStream[T, AgentContext]]:
521
750
  """Runs this agent and returns a final agent response or stream.
522
751
 
523
752
  You can override defaults assigned to this agent from this function directly.
@@ -614,6 +843,18 @@ class Agent(BaseGenAIModel, Generic[T]):
614
843
  if max_steps is None:
615
844
  max_steps = self.settings.max_steps
616
845
 
846
+ # Get effective context settings
847
+ effective_context_settings = self._get_effective_context_settings(
848
+ context_updates=context_updates,
849
+ context_confirm=context_confirm,
850
+ context_strategy=context_strategy,
851
+ context_max_retries=context_max_retries,
852
+ context_confirm_instructions=context_confirm_instructions,
853
+ context_selection_instructions=context_selection_instructions,
854
+ context_update_instructions=context_update_instructions,
855
+ context_format=context_format,
856
+ )
857
+
617
858
  # Parse initial messages
618
859
  parsed_messages = parse_messages(messages)
619
860
  current_messages = parsed_messages.copy()
@@ -621,6 +862,18 @@ class Agent(BaseGenAIModel, Generic[T]):
621
862
 
622
863
  # RUN MAIN AGENTIC LOOP
623
864
  for step in range(max_steps):
865
+ # Update context before processing if configured
866
+ if context and self._should_update_context(
867
+ context, "before", effective_context_settings["context_updates"]
868
+ ):
869
+ context = self._perform_context_update(
870
+ context=context,
871
+ model=working_model,
872
+ current_messages=current_messages,
873
+ timing="before",
874
+ effective_settings=effective_context_settings,
875
+ )
876
+
624
877
  # Format messages with instructions and context for first step only
625
878
  if step == 0:
626
879
  formatted_messages = self._format_messages_with_context(
@@ -640,9 +893,7 @@ class Agent(BaseGenAIModel, Generic[T]):
640
893
  # Get language model response
641
894
  response = working_model.run(
642
895
  messages=formatted_messages,
643
- tools=[tool.model_dump() for tool in self.tools]
644
- if self.tools
645
- else None,
896
+ tools=[tool.to_dict() for tool in self.tools] if self.tools else None,
646
897
  **model_kwargs,
647
898
  )
648
899
 
@@ -663,6 +914,17 @@ class Agent(BaseGenAIModel, Generic[T]):
663
914
  steps.append(response)
664
915
  else:
665
916
  # No tool calls - this is the final step
917
+ # Update context after processing if configured
918
+ if context and self._should_update_context(
919
+ context, "after", effective_context_settings["context_updates"]
920
+ ):
921
+ context = self._perform_context_update(
922
+ context=context,
923
+ model=working_model,
924
+ current_messages=current_messages,
925
+ timing="after",
926
+ effective_settings=effective_context_settings,
927
+ )
666
928
  return _create_agent_response_from_language_model_response(
667
929
  response=response, steps=steps, context=context
668
930
  )
@@ -680,6 +942,18 @@ class Agent(BaseGenAIModel, Generic[T]):
680
942
  **model_kwargs,
681
943
  )
682
944
 
945
+ # Update context after processing if configured
946
+ if context and self._should_update_context(
947
+ context, "after", effective_context_settings["context_updates"]
948
+ ):
949
+ context = self._perform_context_update(
950
+ context=context,
951
+ model=working_model,
952
+ current_messages=current_messages,
953
+ timing="after",
954
+ effective_settings=effective_context_settings,
955
+ )
956
+
683
957
  return _create_agent_response_from_language_model_response(
684
958
  response=final_response, steps=steps, context=context
685
959
  )
@@ -691,8 +965,18 @@ class Agent(BaseGenAIModel, Generic[T]):
691
965
  max_steps: Optional[int] = None,
692
966
  context: Optional[AgentContext] = None,
693
967
  output_type: Optional[Type[T]] = None,
968
+ context_updates: Optional[
969
+ Union[List[Literal["before", "after"]], Literal["before", "after"]]
970
+ ] = None,
971
+ context_confirm: Optional[bool] = None,
972
+ context_strategy: Optional[Literal["selective", "all"]] = None,
973
+ context_max_retries: Optional[int] = None,
974
+ context_confirm_instructions: Optional[str] = None,
975
+ context_selection_instructions: Optional[str] = None,
976
+ context_update_instructions: Optional[str] = None,
977
+ context_format: Optional[Literal["json", "python", "markdown"]] = None,
694
978
  **kwargs: Any,
695
- ) -> AgentResponse[T]:
979
+ ) -> AgentResponse[T, AgentContext]:
696
980
  """Runs this agent asynchronously and returns a final agent response.
697
981
 
698
982
  You can override defaults assigned to this agent from this function directly.
@@ -772,6 +1056,18 @@ class Agent(BaseGenAIModel, Generic[T]):
772
1056
  if max_steps is None:
773
1057
  max_steps = self.settings.max_steps
774
1058
 
1059
+ # Get effective context settings
1060
+ effective_context_settings = self._get_effective_context_settings(
1061
+ context_updates=context_updates,
1062
+ context_confirm=context_confirm,
1063
+ context_strategy=context_strategy,
1064
+ context_max_retries=context_max_retries,
1065
+ context_confirm_instructions=context_confirm_instructions,
1066
+ context_selection_instructions=context_selection_instructions,
1067
+ context_update_instructions=context_update_instructions,
1068
+ context_format=context_format,
1069
+ )
1070
+
775
1071
  # Parse initial messages
776
1072
  parsed_messages = parse_messages(messages)
777
1073
  current_messages = parsed_messages.copy()
@@ -779,6 +1075,18 @@ class Agent(BaseGenAIModel, Generic[T]):
779
1075
 
780
1076
  # RUN MAIN AGENTIC LOOP
781
1077
  for step in range(max_steps):
1078
+ # Update context before processing if configured
1079
+ if context and self._should_update_context(
1080
+ context, "before", effective_context_settings["context_updates"]
1081
+ ):
1082
+ context = self._perform_context_update(
1083
+ context=context,
1084
+ model=working_model,
1085
+ current_messages=current_messages,
1086
+ timing="before",
1087
+ effective_settings=effective_context_settings,
1088
+ )
1089
+
782
1090
  # Format messages with instructions and context for first step only
783
1091
  if step == 0:
784
1092
  formatted_messages = self._format_messages_with_context(
@@ -798,9 +1106,7 @@ class Agent(BaseGenAIModel, Generic[T]):
798
1106
  # Get language model response
799
1107
  response = await working_model.async_run(
800
1108
  messages=formatted_messages,
801
- tools=[tool.model_dump() for tool in self.tools]
802
- if self.tools
803
- else None,
1109
+ tools=[tool.to_dict() for tool in self.tools] if self.tools else None,
804
1110
  **model_kwargs,
805
1111
  )
806
1112
 
@@ -821,6 +1127,17 @@ class Agent(BaseGenAIModel, Generic[T]):
821
1127
  steps.append(response)
822
1128
  else:
823
1129
  # No tool calls - this is the final step
1130
+ # Update context after processing if configured
1131
+ if context and self._should_update_context(
1132
+ context, "after", effective_context_settings["context_updates"]
1133
+ ):
1134
+ context = self._perform_context_update(
1135
+ context=context,
1136
+ model=working_model,
1137
+ current_messages=current_messages,
1138
+ timing="after",
1139
+ effective_settings=effective_context_settings,
1140
+ )
824
1141
  return _create_agent_response_from_language_model_response(
825
1142
  response=response, steps=steps, context=context
826
1143
  )
@@ -838,6 +1155,18 @@ class Agent(BaseGenAIModel, Generic[T]):
838
1155
  **model_kwargs,
839
1156
  )
840
1157
 
1158
+ # Update context after processing if configured
1159
+ if context and self._should_update_context(
1160
+ context, "after", effective_context_settings["context_updates"]
1161
+ ):
1162
+ context = self._perform_context_update(
1163
+ context=context,
1164
+ model=working_model,
1165
+ current_messages=current_messages,
1166
+ timing="after",
1167
+ effective_settings=effective_context_settings,
1168
+ )
1169
+
841
1170
  return _create_agent_response_from_language_model_response(
842
1171
  response=final_response, steps=steps, context=context
843
1172
  )
@@ -850,7 +1179,7 @@ class Agent(BaseGenAIModel, Generic[T]):
850
1179
  context: Optional[AgentContext] = None,
851
1180
  output_type: Optional[Type[T]] = None,
852
1181
  **kwargs: Any,
853
- ) -> AgentStream[T]:
1182
+ ) -> AgentStream[T, AgentContext]:
854
1183
  """Create a stream that yields agent steps.
855
1184
 
856
1185
  Args:
@@ -882,8 +1211,18 @@ class Agent(BaseGenAIModel, Generic[T]):
882
1211
  max_steps: Optional[int] = None,
883
1212
  context: Optional[AgentContext] = None,
884
1213
  output_type: Optional[Type[T]] = None,
1214
+ context_updates: Optional[
1215
+ Union[List[Literal["before", "after"]], Literal["before", "after"]]
1216
+ ] = None,
1217
+ context_confirm: Optional[bool] = None,
1218
+ context_strategy: Optional[Literal["selective", "all"]] = None,
1219
+ context_max_retries: Optional[int] = None,
1220
+ context_confirm_instructions: Optional[str] = None,
1221
+ context_selection_instructions: Optional[str] = None,
1222
+ context_update_instructions: Optional[str] = None,
1223
+ context_format: Optional[Literal["json", "python", "markdown"]] = None,
885
1224
  **kwargs: Any,
886
- ) -> AgentStream[T]:
1225
+ ) -> AgentStream[T, AgentContext]:
887
1226
  """Iterate over agent steps, yielding each step response.
888
1227
 
889
1228
  You can override defaults assigned to this agent from this function directly.
@@ -986,7 +1325,7 @@ class Agent(BaseGenAIModel, Generic[T]):
986
1325
  context: Optional[AgentContext] = None,
987
1326
  output_type: Optional[Type[T]] = None,
988
1327
  **kwargs: Any,
989
- ) -> AgentStream[T]:
1328
+ ) -> AgentStream[T, AgentContext]:
990
1329
  """Async iterate over agent steps, yielding each step response.
991
1330
 
992
1331
  Args: