mirascope 1.0.5__py3-none-any.whl → 2.1.1__py3-none-any.whl

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 (632) hide show
  1. mirascope/__init__.py +6 -6
  2. mirascope/_stubs.py +384 -0
  3. mirascope/_utils.py +34 -0
  4. mirascope/api/__init__.py +14 -0
  5. mirascope/api/_generated/README.md +207 -0
  6. mirascope/api/_generated/__init__.py +444 -0
  7. mirascope/api/_generated/annotations/__init__.py +33 -0
  8. mirascope/api/_generated/annotations/client.py +506 -0
  9. mirascope/api/_generated/annotations/raw_client.py +1414 -0
  10. mirascope/api/_generated/annotations/types/__init__.py +31 -0
  11. mirascope/api/_generated/annotations/types/annotations_create_request_label.py +5 -0
  12. mirascope/api/_generated/annotations/types/annotations_create_response.py +48 -0
  13. mirascope/api/_generated/annotations/types/annotations_create_response_label.py +5 -0
  14. mirascope/api/_generated/annotations/types/annotations_get_response.py +48 -0
  15. mirascope/api/_generated/annotations/types/annotations_get_response_label.py +5 -0
  16. mirascope/api/_generated/annotations/types/annotations_list_request_label.py +5 -0
  17. mirascope/api/_generated/annotations/types/annotations_list_response.py +21 -0
  18. mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item.py +50 -0
  19. mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item_label.py +5 -0
  20. mirascope/api/_generated/annotations/types/annotations_update_request_label.py +5 -0
  21. mirascope/api/_generated/annotations/types/annotations_update_response.py +48 -0
  22. mirascope/api/_generated/annotations/types/annotations_update_response_label.py +5 -0
  23. mirascope/api/_generated/api_keys/__init__.py +17 -0
  24. mirascope/api/_generated/api_keys/client.py +530 -0
  25. mirascope/api/_generated/api_keys/raw_client.py +1236 -0
  26. mirascope/api/_generated/api_keys/types/__init__.py +15 -0
  27. mirascope/api/_generated/api_keys/types/api_keys_create_response.py +28 -0
  28. mirascope/api/_generated/api_keys/types/api_keys_get_response.py +27 -0
  29. mirascope/api/_generated/api_keys/types/api_keys_list_all_for_org_response_item.py +40 -0
  30. mirascope/api/_generated/api_keys/types/api_keys_list_response_item.py +27 -0
  31. mirascope/api/_generated/client.py +211 -0
  32. mirascope/api/_generated/core/__init__.py +52 -0
  33. mirascope/api/_generated/core/api_error.py +23 -0
  34. mirascope/api/_generated/core/client_wrapper.py +46 -0
  35. mirascope/api/_generated/core/datetime_utils.py +28 -0
  36. mirascope/api/_generated/core/file.py +67 -0
  37. mirascope/api/_generated/core/force_multipart.py +16 -0
  38. mirascope/api/_generated/core/http_client.py +543 -0
  39. mirascope/api/_generated/core/http_response.py +55 -0
  40. mirascope/api/_generated/core/jsonable_encoder.py +100 -0
  41. mirascope/api/_generated/core/pydantic_utilities.py +255 -0
  42. mirascope/api/_generated/core/query_encoder.py +58 -0
  43. mirascope/api/_generated/core/remove_none_from_dict.py +11 -0
  44. mirascope/api/_generated/core/request_options.py +35 -0
  45. mirascope/api/_generated/core/serialization.py +276 -0
  46. mirascope/api/_generated/docs/__init__.py +4 -0
  47. mirascope/api/_generated/docs/client.py +91 -0
  48. mirascope/api/_generated/docs/raw_client.py +178 -0
  49. mirascope/api/_generated/environment.py +9 -0
  50. mirascope/api/_generated/environments/__init__.py +23 -0
  51. mirascope/api/_generated/environments/client.py +649 -0
  52. mirascope/api/_generated/environments/raw_client.py +1567 -0
  53. mirascope/api/_generated/environments/types/__init__.py +25 -0
  54. mirascope/api/_generated/environments/types/environments_create_response.py +24 -0
  55. mirascope/api/_generated/environments/types/environments_get_analytics_response.py +60 -0
  56. mirascope/api/_generated/environments/types/environments_get_analytics_response_top_functions_item.py +24 -0
  57. mirascope/api/_generated/environments/types/environments_get_analytics_response_top_models_item.py +22 -0
  58. mirascope/api/_generated/environments/types/environments_get_response.py +24 -0
  59. mirascope/api/_generated/environments/types/environments_list_response_item.py +24 -0
  60. mirascope/api/_generated/environments/types/environments_update_response.py +24 -0
  61. mirascope/api/_generated/errors/__init__.py +25 -0
  62. mirascope/api/_generated/errors/bad_request_error.py +14 -0
  63. mirascope/api/_generated/errors/conflict_error.py +14 -0
  64. mirascope/api/_generated/errors/forbidden_error.py +11 -0
  65. mirascope/api/_generated/errors/internal_server_error.py +10 -0
  66. mirascope/api/_generated/errors/not_found_error.py +11 -0
  67. mirascope/api/_generated/errors/payment_required_error.py +15 -0
  68. mirascope/api/_generated/errors/service_unavailable_error.py +14 -0
  69. mirascope/api/_generated/errors/too_many_requests_error.py +15 -0
  70. mirascope/api/_generated/errors/unauthorized_error.py +11 -0
  71. mirascope/api/_generated/functions/__init__.py +39 -0
  72. mirascope/api/_generated/functions/client.py +647 -0
  73. mirascope/api/_generated/functions/raw_client.py +1890 -0
  74. mirascope/api/_generated/functions/types/__init__.py +53 -0
  75. mirascope/api/_generated/functions/types/functions_create_request_dependencies_value.py +20 -0
  76. mirascope/api/_generated/functions/types/functions_create_response.py +37 -0
  77. mirascope/api/_generated/functions/types/functions_create_response_dependencies_value.py +20 -0
  78. mirascope/api/_generated/functions/types/functions_find_by_hash_response.py +39 -0
  79. mirascope/api/_generated/functions/types/functions_find_by_hash_response_dependencies_value.py +20 -0
  80. mirascope/api/_generated/functions/types/functions_get_by_env_response.py +53 -0
  81. mirascope/api/_generated/functions/types/functions_get_by_env_response_dependencies_value.py +22 -0
  82. mirascope/api/_generated/functions/types/functions_get_response.py +37 -0
  83. mirascope/api/_generated/functions/types/functions_get_response_dependencies_value.py +20 -0
  84. mirascope/api/_generated/functions/types/functions_list_by_env_response.py +25 -0
  85. mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item.py +56 -0
  86. mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item_dependencies_value.py +22 -0
  87. mirascope/api/_generated/functions/types/functions_list_response.py +21 -0
  88. mirascope/api/_generated/functions/types/functions_list_response_functions_item.py +41 -0
  89. mirascope/api/_generated/functions/types/functions_list_response_functions_item_dependencies_value.py +20 -0
  90. mirascope/api/_generated/health/__init__.py +7 -0
  91. mirascope/api/_generated/health/client.py +92 -0
  92. mirascope/api/_generated/health/raw_client.py +175 -0
  93. mirascope/api/_generated/health/types/__init__.py +8 -0
  94. mirascope/api/_generated/health/types/health_check_response.py +22 -0
  95. mirascope/api/_generated/health/types/health_check_response_status.py +5 -0
  96. mirascope/api/_generated/organization_invitations/__init__.py +33 -0
  97. mirascope/api/_generated/organization_invitations/client.py +546 -0
  98. mirascope/api/_generated/organization_invitations/raw_client.py +1519 -0
  99. mirascope/api/_generated/organization_invitations/types/__init__.py +53 -0
  100. mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response.py +34 -0
  101. mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response_role.py +7 -0
  102. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_request_role.py +7 -0
  103. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response.py +48 -0
  104. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_role.py +7 -0
  105. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_status.py +7 -0
  106. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response.py +48 -0
  107. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_role.py +7 -0
  108. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_status.py +7 -0
  109. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item.py +48 -0
  110. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_role.py +7 -0
  111. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_status.py +7 -0
  112. mirascope/api/_generated/organization_memberships/__init__.py +19 -0
  113. mirascope/api/_generated/organization_memberships/client.py +302 -0
  114. mirascope/api/_generated/organization_memberships/raw_client.py +736 -0
  115. mirascope/api/_generated/organization_memberships/types/__init__.py +27 -0
  116. mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item.py +33 -0
  117. mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item_role.py +7 -0
  118. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_request_role.py +7 -0
  119. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response.py +31 -0
  120. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response_role.py +7 -0
  121. mirascope/api/_generated/organizations/__init__.py +51 -0
  122. mirascope/api/_generated/organizations/client.py +869 -0
  123. mirascope/api/_generated/organizations/raw_client.py +2593 -0
  124. mirascope/api/_generated/organizations/types/__init__.py +71 -0
  125. mirascope/api/_generated/organizations/types/organizations_create_payment_intent_response.py +24 -0
  126. mirascope/api/_generated/organizations/types/organizations_create_response.py +26 -0
  127. mirascope/api/_generated/organizations/types/organizations_create_response_role.py +5 -0
  128. mirascope/api/_generated/organizations/types/organizations_get_response.py +26 -0
  129. mirascope/api/_generated/organizations/types/organizations_get_response_role.py +5 -0
  130. mirascope/api/_generated/organizations/types/organizations_list_response_item.py +26 -0
  131. mirascope/api/_generated/organizations/types/organizations_list_response_item_role.py +5 -0
  132. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_request_target_plan.py +7 -0
  133. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response.py +47 -0
  134. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item.py +33 -0
  135. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item_resource.py +7 -0
  136. mirascope/api/_generated/organizations/types/organizations_router_balance_response.py +24 -0
  137. mirascope/api/_generated/organizations/types/organizations_subscription_response.py +53 -0
  138. mirascope/api/_generated/organizations/types/organizations_subscription_response_current_plan.py +7 -0
  139. mirascope/api/_generated/organizations/types/organizations_subscription_response_payment_method.py +26 -0
  140. mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change.py +34 -0
  141. mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change_target_plan.py +7 -0
  142. mirascope/api/_generated/organizations/types/organizations_update_response.py +26 -0
  143. mirascope/api/_generated/organizations/types/organizations_update_response_role.py +5 -0
  144. mirascope/api/_generated/organizations/types/organizations_update_subscription_request_target_plan.py +7 -0
  145. mirascope/api/_generated/organizations/types/organizations_update_subscription_response.py +35 -0
  146. mirascope/api/_generated/project_memberships/__init__.py +29 -0
  147. mirascope/api/_generated/project_memberships/client.py +528 -0
  148. mirascope/api/_generated/project_memberships/raw_client.py +1278 -0
  149. mirascope/api/_generated/project_memberships/types/__init__.py +33 -0
  150. mirascope/api/_generated/project_memberships/types/project_memberships_create_request_role.py +7 -0
  151. mirascope/api/_generated/project_memberships/types/project_memberships_create_response.py +35 -0
  152. mirascope/api/_generated/project_memberships/types/project_memberships_create_response_role.py +7 -0
  153. mirascope/api/_generated/project_memberships/types/project_memberships_get_response.py +33 -0
  154. mirascope/api/_generated/project_memberships/types/project_memberships_get_response_role.py +7 -0
  155. mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item.py +33 -0
  156. mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item_role.py +7 -0
  157. mirascope/api/_generated/project_memberships/types/project_memberships_update_request_role.py +7 -0
  158. mirascope/api/_generated/project_memberships/types/project_memberships_update_response.py +35 -0
  159. mirascope/api/_generated/project_memberships/types/project_memberships_update_response_role.py +7 -0
  160. mirascope/api/_generated/projects/__init__.py +7 -0
  161. mirascope/api/_generated/projects/client.py +428 -0
  162. mirascope/api/_generated/projects/raw_client.py +1302 -0
  163. mirascope/api/_generated/projects/types/__init__.py +10 -0
  164. mirascope/api/_generated/projects/types/projects_create_response.py +25 -0
  165. mirascope/api/_generated/projects/types/projects_get_response.py +25 -0
  166. mirascope/api/_generated/projects/types/projects_list_response_item.py +25 -0
  167. mirascope/api/_generated/projects/types/projects_update_response.py +25 -0
  168. mirascope/api/_generated/reference.md +4987 -0
  169. mirascope/api/_generated/tags/__init__.py +19 -0
  170. mirascope/api/_generated/tags/client.py +504 -0
  171. mirascope/api/_generated/tags/raw_client.py +1288 -0
  172. mirascope/api/_generated/tags/types/__init__.py +17 -0
  173. mirascope/api/_generated/tags/types/tags_create_response.py +41 -0
  174. mirascope/api/_generated/tags/types/tags_get_response.py +41 -0
  175. mirascope/api/_generated/tags/types/tags_list_response.py +23 -0
  176. mirascope/api/_generated/tags/types/tags_list_response_tags_item.py +41 -0
  177. mirascope/api/_generated/tags/types/tags_update_response.py +41 -0
  178. mirascope/api/_generated/token_cost/__init__.py +7 -0
  179. mirascope/api/_generated/token_cost/client.py +160 -0
  180. mirascope/api/_generated/token_cost/raw_client.py +264 -0
  181. mirascope/api/_generated/token_cost/types/__init__.py +8 -0
  182. mirascope/api/_generated/token_cost/types/token_cost_calculate_request_usage.py +54 -0
  183. mirascope/api/_generated/token_cost/types/token_cost_calculate_response.py +52 -0
  184. mirascope/api/_generated/traces/__init__.py +97 -0
  185. mirascope/api/_generated/traces/client.py +1103 -0
  186. mirascope/api/_generated/traces/raw_client.py +2322 -0
  187. mirascope/api/_generated/traces/types/__init__.py +155 -0
  188. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item.py +29 -0
  189. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource.py +27 -0
  190. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item.py +23 -0
  191. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value.py +38 -0
  192. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_array_value.py +19 -0
  193. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value.py +22 -0
  194. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value_values_item.py +20 -0
  195. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item.py +29 -0
  196. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope.py +31 -0
  197. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item.py +23 -0
  198. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value.py +38 -0
  199. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_array_value.py +19 -0
  200. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value.py +22 -0
  201. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value_values_item.py +22 -0
  202. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item.py +48 -0
  203. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item.py +23 -0
  204. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value.py +38 -0
  205. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_array_value.py +19 -0
  206. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value.py +24 -0
  207. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value_values_item.py +22 -0
  208. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_status.py +20 -0
  209. mirascope/api/_generated/traces/types/traces_create_response.py +24 -0
  210. mirascope/api/_generated/traces/types/traces_create_response_partial_success.py +22 -0
  211. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response.py +60 -0
  212. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_functions_item.py +24 -0
  213. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_models_item.py +22 -0
  214. mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response.py +33 -0
  215. mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response_spans_item.py +88 -0
  216. mirascope/api/_generated/traces/types/traces_get_trace_detail_response.py +33 -0
  217. mirascope/api/_generated/traces/types/traces_get_trace_detail_response_spans_item.py +88 -0
  218. mirascope/api/_generated/traces/types/traces_list_by_function_hash_response.py +25 -0
  219. mirascope/api/_generated/traces/types/traces_list_by_function_hash_response_traces_item.py +44 -0
  220. mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item.py +26 -0
  221. mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item_operator.py +7 -0
  222. mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_by.py +7 -0
  223. mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_order.py +7 -0
  224. mirascope/api/_generated/traces/types/traces_search_by_env_response.py +26 -0
  225. mirascope/api/_generated/traces/types/traces_search_by_env_response_spans_item.py +50 -0
  226. mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item.py +26 -0
  227. mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item_operator.py +7 -0
  228. mirascope/api/_generated/traces/types/traces_search_request_sort_by.py +7 -0
  229. mirascope/api/_generated/traces/types/traces_search_request_sort_order.py +5 -0
  230. mirascope/api/_generated/traces/types/traces_search_response.py +26 -0
  231. mirascope/api/_generated/traces/types/traces_search_response_spans_item.py +50 -0
  232. mirascope/api/_generated/types/__init__.py +85 -0
  233. mirascope/api/_generated/types/already_exists_error.py +22 -0
  234. mirascope/api/_generated/types/already_exists_error_tag.py +5 -0
  235. mirascope/api/_generated/types/bad_request_error_body.py +50 -0
  236. mirascope/api/_generated/types/click_house_error.py +22 -0
  237. mirascope/api/_generated/types/database_error.py +22 -0
  238. mirascope/api/_generated/types/database_error_tag.py +5 -0
  239. mirascope/api/_generated/types/date.py +3 -0
  240. mirascope/api/_generated/types/http_api_decode_error.py +27 -0
  241. mirascope/api/_generated/types/http_api_decode_error_tag.py +5 -0
  242. mirascope/api/_generated/types/immutable_resource_error.py +22 -0
  243. mirascope/api/_generated/types/internal_server_error_body.py +49 -0
  244. mirascope/api/_generated/types/issue.py +38 -0
  245. mirascope/api/_generated/types/issue_tag.py +10 -0
  246. mirascope/api/_generated/types/not_found_error_body.py +22 -0
  247. mirascope/api/_generated/types/not_found_error_tag.py +5 -0
  248. mirascope/api/_generated/types/number_from_string.py +3 -0
  249. mirascope/api/_generated/types/permission_denied_error.py +22 -0
  250. mirascope/api/_generated/types/permission_denied_error_tag.py +5 -0
  251. mirascope/api/_generated/types/plan_limit_exceeded_error.py +32 -0
  252. mirascope/api/_generated/types/plan_limit_exceeded_error_tag.py +7 -0
  253. mirascope/api/_generated/types/pricing_unavailable_error.py +23 -0
  254. mirascope/api/_generated/types/property_key.py +7 -0
  255. mirascope/api/_generated/types/property_key_key.py +25 -0
  256. mirascope/api/_generated/types/property_key_key_tag.py +5 -0
  257. mirascope/api/_generated/types/rate_limit_error.py +31 -0
  258. mirascope/api/_generated/types/rate_limit_error_tag.py +5 -0
  259. mirascope/api/_generated/types/service_unavailable_error_body.py +24 -0
  260. mirascope/api/_generated/types/service_unavailable_error_tag.py +7 -0
  261. mirascope/api/_generated/types/stripe_error.py +20 -0
  262. mirascope/api/_generated/types/subscription_past_due_error.py +31 -0
  263. mirascope/api/_generated/types/subscription_past_due_error_tag.py +7 -0
  264. mirascope/api/_generated/types/unauthorized_error_body.py +21 -0
  265. mirascope/api/_generated/types/unauthorized_error_tag.py +5 -0
  266. mirascope/api/client.py +255 -0
  267. mirascope/api/settings.py +99 -0
  268. mirascope/llm/__init__.py +316 -0
  269. mirascope/llm/calls/__init__.py +17 -0
  270. mirascope/llm/calls/calls.py +348 -0
  271. mirascope/llm/calls/decorator.py +268 -0
  272. mirascope/llm/content/__init__.py +71 -0
  273. mirascope/llm/content/audio.py +173 -0
  274. mirascope/llm/content/document.py +94 -0
  275. mirascope/llm/content/image.py +206 -0
  276. mirascope/llm/content/text.py +47 -0
  277. mirascope/llm/content/thought.py +58 -0
  278. mirascope/llm/content/tool_call.py +69 -0
  279. mirascope/llm/content/tool_output.py +43 -0
  280. mirascope/llm/context/__init__.py +6 -0
  281. mirascope/llm/context/_utils.py +41 -0
  282. mirascope/llm/context/context.py +24 -0
  283. mirascope/llm/exceptions.py +360 -0
  284. mirascope/llm/formatting/__init__.py +39 -0
  285. mirascope/llm/formatting/format.py +291 -0
  286. mirascope/llm/formatting/from_call_args.py +30 -0
  287. mirascope/llm/formatting/output_parser.py +178 -0
  288. mirascope/llm/formatting/partial.py +131 -0
  289. mirascope/llm/formatting/primitives.py +192 -0
  290. mirascope/llm/formatting/types.py +83 -0
  291. mirascope/llm/mcp/__init__.py +5 -0
  292. mirascope/llm/mcp/mcp_client.py +130 -0
  293. mirascope/llm/messages/__init__.py +35 -0
  294. mirascope/llm/messages/_utils.py +34 -0
  295. mirascope/llm/messages/message.py +190 -0
  296. mirascope/llm/models/__init__.py +21 -0
  297. mirascope/llm/models/models.py +1339 -0
  298. mirascope/llm/models/params.py +72 -0
  299. mirascope/llm/models/thinking_config.py +61 -0
  300. mirascope/llm/prompts/__init__.py +34 -0
  301. mirascope/llm/prompts/_utils.py +31 -0
  302. mirascope/llm/prompts/decorator.py +215 -0
  303. mirascope/llm/prompts/prompts.py +484 -0
  304. mirascope/llm/prompts/protocols.py +65 -0
  305. mirascope/llm/providers/__init__.py +65 -0
  306. mirascope/llm/providers/anthropic/__init__.py +11 -0
  307. mirascope/llm/providers/anthropic/_utils/__init__.py +27 -0
  308. mirascope/llm/providers/anthropic/_utils/beta_decode.py +297 -0
  309. mirascope/llm/providers/anthropic/_utils/beta_encode.py +272 -0
  310. mirascope/llm/providers/anthropic/_utils/decode.py +326 -0
  311. mirascope/llm/providers/anthropic/_utils/encode.py +431 -0
  312. mirascope/llm/providers/anthropic/_utils/errors.py +46 -0
  313. mirascope/llm/providers/anthropic/beta_provider.py +338 -0
  314. mirascope/llm/providers/anthropic/model_id.py +23 -0
  315. mirascope/llm/providers/anthropic/model_info.py +87 -0
  316. mirascope/llm/providers/anthropic/provider.py +440 -0
  317. mirascope/llm/providers/base/__init__.py +14 -0
  318. mirascope/llm/providers/base/_utils.py +248 -0
  319. mirascope/llm/providers/base/base_provider.py +1463 -0
  320. mirascope/llm/providers/base/kwargs.py +12 -0
  321. mirascope/llm/providers/google/__init__.py +6 -0
  322. mirascope/llm/providers/google/_utils/__init__.py +17 -0
  323. mirascope/llm/providers/google/_utils/decode.py +357 -0
  324. mirascope/llm/providers/google/_utils/encode.py +418 -0
  325. mirascope/llm/providers/google/_utils/errors.py +50 -0
  326. mirascope/llm/providers/google/message.py +7 -0
  327. mirascope/llm/providers/google/model_id.py +22 -0
  328. mirascope/llm/providers/google/model_info.py +63 -0
  329. mirascope/llm/providers/google/provider.py +456 -0
  330. mirascope/llm/providers/mirascope/__init__.py +5 -0
  331. mirascope/llm/providers/mirascope/_utils.py +73 -0
  332. mirascope/llm/providers/mirascope/provider.py +313 -0
  333. mirascope/llm/providers/mlx/__init__.py +9 -0
  334. mirascope/llm/providers/mlx/_utils.py +141 -0
  335. mirascope/llm/providers/mlx/encoding/__init__.py +8 -0
  336. mirascope/llm/providers/mlx/encoding/base.py +69 -0
  337. mirascope/llm/providers/mlx/encoding/transformers.py +146 -0
  338. mirascope/llm/providers/mlx/mlx.py +242 -0
  339. mirascope/llm/providers/mlx/model_id.py +17 -0
  340. mirascope/llm/providers/mlx/provider.py +416 -0
  341. mirascope/llm/providers/model_id.py +16 -0
  342. mirascope/llm/providers/ollama/__init__.py +7 -0
  343. mirascope/llm/providers/ollama/provider.py +71 -0
  344. mirascope/llm/providers/openai/__init__.py +15 -0
  345. mirascope/llm/providers/openai/_utils/__init__.py +5 -0
  346. mirascope/llm/providers/openai/_utils/errors.py +46 -0
  347. mirascope/llm/providers/openai/completions/__init__.py +7 -0
  348. mirascope/llm/providers/openai/completions/_utils/__init__.py +18 -0
  349. mirascope/llm/providers/openai/completions/_utils/decode.py +252 -0
  350. mirascope/llm/providers/openai/completions/_utils/encode.py +390 -0
  351. mirascope/llm/providers/openai/completions/_utils/feature_info.py +50 -0
  352. mirascope/llm/providers/openai/completions/base_provider.py +522 -0
  353. mirascope/llm/providers/openai/completions/provider.py +28 -0
  354. mirascope/llm/providers/openai/model_id.py +31 -0
  355. mirascope/llm/providers/openai/model_info.py +303 -0
  356. mirascope/llm/providers/openai/provider.py +405 -0
  357. mirascope/llm/providers/openai/responses/__init__.py +5 -0
  358. mirascope/llm/providers/openai/responses/_utils/__init__.py +15 -0
  359. mirascope/llm/providers/openai/responses/_utils/decode.py +289 -0
  360. mirascope/llm/providers/openai/responses/_utils/encode.py +399 -0
  361. mirascope/llm/providers/openai/responses/provider.py +472 -0
  362. mirascope/llm/providers/openrouter/__init__.py +5 -0
  363. mirascope/llm/providers/openrouter/provider.py +67 -0
  364. mirascope/llm/providers/provider_id.py +26 -0
  365. mirascope/llm/providers/provider_registry.py +305 -0
  366. mirascope/llm/providers/together/__init__.py +7 -0
  367. mirascope/llm/providers/together/provider.py +40 -0
  368. mirascope/llm/responses/__init__.py +66 -0
  369. mirascope/llm/responses/_utils.py +146 -0
  370. mirascope/llm/responses/base_response.py +103 -0
  371. mirascope/llm/responses/base_stream_response.py +824 -0
  372. mirascope/llm/responses/finish_reason.py +28 -0
  373. mirascope/llm/responses/response.py +362 -0
  374. mirascope/llm/responses/root_response.py +248 -0
  375. mirascope/llm/responses/stream_response.py +577 -0
  376. mirascope/llm/responses/streams.py +363 -0
  377. mirascope/llm/responses/usage.py +139 -0
  378. mirascope/llm/tools/__init__.py +71 -0
  379. mirascope/llm/tools/_utils.py +34 -0
  380. mirascope/llm/tools/decorator.py +184 -0
  381. mirascope/llm/tools/protocols.py +96 -0
  382. mirascope/llm/tools/provider_tools.py +18 -0
  383. mirascope/llm/tools/tool_schema.py +321 -0
  384. mirascope/llm/tools/toolkit.py +178 -0
  385. mirascope/llm/tools/tools.py +263 -0
  386. mirascope/llm/tools/types.py +112 -0
  387. mirascope/llm/tools/web_search_tool.py +32 -0
  388. mirascope/llm/types/__init__.py +22 -0
  389. mirascope/llm/types/dataclass.py +9 -0
  390. mirascope/llm/types/jsonable.py +44 -0
  391. mirascope/llm/types/type_vars.py +19 -0
  392. mirascope/ops/__init__.py +129 -0
  393. mirascope/ops/_internal/__init__.py +5 -0
  394. mirascope/ops/_internal/closure.py +1172 -0
  395. mirascope/ops/_internal/configuration.py +177 -0
  396. mirascope/ops/_internal/context.py +76 -0
  397. mirascope/ops/_internal/exporters/__init__.py +26 -0
  398. mirascope/ops/_internal/exporters/exporters.py +362 -0
  399. mirascope/ops/_internal/exporters/processors.py +104 -0
  400. mirascope/ops/_internal/exporters/types.py +165 -0
  401. mirascope/ops/_internal/exporters/utils.py +66 -0
  402. mirascope/ops/_internal/instrumentation/__init__.py +28 -0
  403. mirascope/ops/_internal/instrumentation/llm/__init__.py +8 -0
  404. mirascope/ops/_internal/instrumentation/llm/common.py +500 -0
  405. mirascope/ops/_internal/instrumentation/llm/cost.py +190 -0
  406. mirascope/ops/_internal/instrumentation/llm/encode.py +238 -0
  407. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/__init__.py +38 -0
  408. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_input_messages.py +31 -0
  409. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_output_messages.py +38 -0
  410. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_system_instructions.py +18 -0
  411. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/shared.py +100 -0
  412. mirascope/ops/_internal/instrumentation/llm/llm.py +161 -0
  413. mirascope/ops/_internal/instrumentation/llm/model.py +1777 -0
  414. mirascope/ops/_internal/instrumentation/llm/response.py +521 -0
  415. mirascope/ops/_internal/instrumentation/llm/serialize.py +324 -0
  416. mirascope/ops/_internal/instrumentation/providers/__init__.py +29 -0
  417. mirascope/ops/_internal/instrumentation/providers/anthropic.py +78 -0
  418. mirascope/ops/_internal/instrumentation/providers/base.py +179 -0
  419. mirascope/ops/_internal/instrumentation/providers/google_genai.py +85 -0
  420. mirascope/ops/_internal/instrumentation/providers/openai.py +82 -0
  421. mirascope/ops/_internal/propagation.py +198 -0
  422. mirascope/ops/_internal/protocols.py +133 -0
  423. mirascope/ops/_internal/session.py +139 -0
  424. mirascope/ops/_internal/spans.py +232 -0
  425. mirascope/ops/_internal/traced_calls.py +389 -0
  426. mirascope/ops/_internal/traced_functions.py +528 -0
  427. mirascope/ops/_internal/tracing.py +353 -0
  428. mirascope/ops/_internal/types.py +13 -0
  429. mirascope/ops/_internal/utils.py +131 -0
  430. mirascope/ops/_internal/versioned_calls.py +512 -0
  431. mirascope/ops/_internal/versioned_functions.py +357 -0
  432. mirascope/ops/_internal/versioning.py +303 -0
  433. mirascope/ops/exceptions.py +21 -0
  434. mirascope-2.1.1.dist-info/METADATA +231 -0
  435. mirascope-2.1.1.dist-info/RECORD +437 -0
  436. {mirascope-1.0.5.dist-info → mirascope-2.1.1.dist-info}/WHEEL +1 -1
  437. {mirascope-1.0.5.dist-info → mirascope-2.1.1.dist-info}/licenses/LICENSE +1 -1
  438. mirascope/beta/__init__.py +0 -0
  439. mirascope/beta/openai/__init__.py +0 -5
  440. mirascope/beta/openai/parse.py +0 -129
  441. mirascope/beta/rag/__init__.py +0 -24
  442. mirascope/beta/rag/base/__init__.py +0 -22
  443. mirascope/beta/rag/base/chunkers/__init__.py +0 -2
  444. mirascope/beta/rag/base/chunkers/base_chunker.py +0 -37
  445. mirascope/beta/rag/base/chunkers/text_chunker.py +0 -33
  446. mirascope/beta/rag/base/config.py +0 -8
  447. mirascope/beta/rag/base/document.py +0 -11
  448. mirascope/beta/rag/base/embedders.py +0 -35
  449. mirascope/beta/rag/base/embedding_params.py +0 -18
  450. mirascope/beta/rag/base/embedding_response.py +0 -30
  451. mirascope/beta/rag/base/query_results.py +0 -7
  452. mirascope/beta/rag/base/vectorstore_params.py +0 -18
  453. mirascope/beta/rag/base/vectorstores.py +0 -37
  454. mirascope/beta/rag/chroma/__init__.py +0 -11
  455. mirascope/beta/rag/chroma/types.py +0 -57
  456. mirascope/beta/rag/chroma/vectorstores.py +0 -97
  457. mirascope/beta/rag/cohere/__init__.py +0 -11
  458. mirascope/beta/rag/cohere/embedders.py +0 -87
  459. mirascope/beta/rag/cohere/embedding_params.py +0 -29
  460. mirascope/beta/rag/cohere/embedding_response.py +0 -29
  461. mirascope/beta/rag/cohere/py.typed +0 -0
  462. mirascope/beta/rag/openai/__init__.py +0 -11
  463. mirascope/beta/rag/openai/embedders.py +0 -144
  464. mirascope/beta/rag/openai/embedding_params.py +0 -18
  465. mirascope/beta/rag/openai/embedding_response.py +0 -14
  466. mirascope/beta/rag/openai/py.typed +0 -0
  467. mirascope/beta/rag/pinecone/__init__.py +0 -19
  468. mirascope/beta/rag/pinecone/types.py +0 -143
  469. mirascope/beta/rag/pinecone/vectorstores.py +0 -148
  470. mirascope/beta/rag/weaviate/__init__.py +0 -6
  471. mirascope/beta/rag/weaviate/types.py +0 -92
  472. mirascope/beta/rag/weaviate/vectorstores.py +0 -103
  473. mirascope/core/__init__.py +0 -55
  474. mirascope/core/anthropic/__init__.py +0 -21
  475. mirascope/core/anthropic/_call.py +0 -71
  476. mirascope/core/anthropic/_utils/__init__.py +0 -16
  477. mirascope/core/anthropic/_utils/_calculate_cost.py +0 -63
  478. mirascope/core/anthropic/_utils/_convert_message_params.py +0 -54
  479. mirascope/core/anthropic/_utils/_get_json_output.py +0 -34
  480. mirascope/core/anthropic/_utils/_handle_stream.py +0 -89
  481. mirascope/core/anthropic/_utils/_setup_call.py +0 -76
  482. mirascope/core/anthropic/call_params.py +0 -36
  483. mirascope/core/anthropic/call_response.py +0 -158
  484. mirascope/core/anthropic/call_response_chunk.py +0 -104
  485. mirascope/core/anthropic/dynamic_config.py +0 -26
  486. mirascope/core/anthropic/py.typed +0 -0
  487. mirascope/core/anthropic/stream.py +0 -140
  488. mirascope/core/anthropic/tool.py +0 -77
  489. mirascope/core/base/__init__.py +0 -40
  490. mirascope/core/base/_call_factory.py +0 -323
  491. mirascope/core/base/_create.py +0 -167
  492. mirascope/core/base/_extract.py +0 -139
  493. mirascope/core/base/_partial.py +0 -63
  494. mirascope/core/base/_utils/__init__.py +0 -64
  495. mirascope/core/base/_utils/_base_type.py +0 -17
  496. mirascope/core/base/_utils/_convert_base_model_to_base_tool.py +0 -45
  497. mirascope/core/base/_utils/_convert_base_type_to_base_tool.py +0 -24
  498. mirascope/core/base/_utils/_convert_function_to_base_tool.py +0 -126
  499. mirascope/core/base/_utils/_default_tool_docstring.py +0 -6
  500. mirascope/core/base/_utils/_extract_tool_return.py +0 -36
  501. mirascope/core/base/_utils/_format_template.py +0 -29
  502. mirascope/core/base/_utils/_get_audio_type.py +0 -18
  503. mirascope/core/base/_utils/_get_fn_args.py +0 -14
  504. mirascope/core/base/_utils/_get_image_type.py +0 -26
  505. mirascope/core/base/_utils/_get_metadata.py +0 -17
  506. mirascope/core/base/_utils/_get_possible_user_message_param.py +0 -21
  507. mirascope/core/base/_utils/_get_prompt_template.py +0 -25
  508. mirascope/core/base/_utils/_get_template_values.py +0 -52
  509. mirascope/core/base/_utils/_get_template_variables.py +0 -38
  510. mirascope/core/base/_utils/_json_mode_content.py +0 -15
  511. mirascope/core/base/_utils/_parse_content_template.py +0 -157
  512. mirascope/core/base/_utils/_parse_prompt_messages.py +0 -51
  513. mirascope/core/base/_utils/_protocols.py +0 -215
  514. mirascope/core/base/_utils/_setup_call.py +0 -64
  515. mirascope/core/base/_utils/_setup_extract_tool.py +0 -24
  516. mirascope/core/base/call_params.py +0 -6
  517. mirascope/core/base/call_response.py +0 -189
  518. mirascope/core/base/call_response_chunk.py +0 -91
  519. mirascope/core/base/dynamic_config.py +0 -55
  520. mirascope/core/base/message_param.py +0 -61
  521. mirascope/core/base/metadata.py +0 -13
  522. mirascope/core/base/prompt.py +0 -415
  523. mirascope/core/base/stream.py +0 -365
  524. mirascope/core/base/structured_stream.py +0 -251
  525. mirascope/core/base/tool.py +0 -126
  526. mirascope/core/base/toolkit.py +0 -146
  527. mirascope/core/cohere/__init__.py +0 -21
  528. mirascope/core/cohere/_call.py +0 -71
  529. mirascope/core/cohere/_utils/__init__.py +0 -16
  530. mirascope/core/cohere/_utils/_calculate_cost.py +0 -39
  531. mirascope/core/cohere/_utils/_convert_message_params.py +0 -31
  532. mirascope/core/cohere/_utils/_get_json_output.py +0 -31
  533. mirascope/core/cohere/_utils/_handle_stream.py +0 -33
  534. mirascope/core/cohere/_utils/_setup_call.py +0 -89
  535. mirascope/core/cohere/call_params.py +0 -57
  536. mirascope/core/cohere/call_response.py +0 -167
  537. mirascope/core/cohere/call_response_chunk.py +0 -101
  538. mirascope/core/cohere/dynamic_config.py +0 -24
  539. mirascope/core/cohere/py.typed +0 -0
  540. mirascope/core/cohere/stream.py +0 -113
  541. mirascope/core/cohere/tool.py +0 -92
  542. mirascope/core/gemini/__init__.py +0 -21
  543. mirascope/core/gemini/_call.py +0 -71
  544. mirascope/core/gemini/_utils/__init__.py +0 -16
  545. mirascope/core/gemini/_utils/_calculate_cost.py +0 -8
  546. mirascope/core/gemini/_utils/_convert_message_params.py +0 -74
  547. mirascope/core/gemini/_utils/_get_json_output.py +0 -33
  548. mirascope/core/gemini/_utils/_handle_stream.py +0 -33
  549. mirascope/core/gemini/_utils/_setup_call.py +0 -68
  550. mirascope/core/gemini/call_params.py +0 -28
  551. mirascope/core/gemini/call_response.py +0 -173
  552. mirascope/core/gemini/call_response_chunk.py +0 -85
  553. mirascope/core/gemini/dynamic_config.py +0 -26
  554. mirascope/core/gemini/stream.py +0 -121
  555. mirascope/core/gemini/tool.py +0 -104
  556. mirascope/core/groq/__init__.py +0 -21
  557. mirascope/core/groq/_call.py +0 -71
  558. mirascope/core/groq/_utils/__init__.py +0 -16
  559. mirascope/core/groq/_utils/_calculate_cost.py +0 -68
  560. mirascope/core/groq/_utils/_convert_message_params.py +0 -23
  561. mirascope/core/groq/_utils/_get_json_output.py +0 -27
  562. mirascope/core/groq/_utils/_handle_stream.py +0 -121
  563. mirascope/core/groq/_utils/_setup_call.py +0 -67
  564. mirascope/core/groq/call_params.py +0 -51
  565. mirascope/core/groq/call_response.py +0 -160
  566. mirascope/core/groq/call_response_chunk.py +0 -89
  567. mirascope/core/groq/dynamic_config.py +0 -26
  568. mirascope/core/groq/py.typed +0 -0
  569. mirascope/core/groq/stream.py +0 -136
  570. mirascope/core/groq/tool.py +0 -79
  571. mirascope/core/litellm/__init__.py +0 -6
  572. mirascope/core/litellm/_call.py +0 -73
  573. mirascope/core/litellm/_utils/__init__.py +0 -5
  574. mirascope/core/litellm/_utils/_setup_call.py +0 -46
  575. mirascope/core/litellm/py.typed +0 -0
  576. mirascope/core/mistral/__init__.py +0 -21
  577. mirascope/core/mistral/_call.py +0 -69
  578. mirascope/core/mistral/_utils/__init__.py +0 -16
  579. mirascope/core/mistral/_utils/_calculate_cost.py +0 -47
  580. mirascope/core/mistral/_utils/_convert_message_params.py +0 -23
  581. mirascope/core/mistral/_utils/_get_json_output.py +0 -28
  582. mirascope/core/mistral/_utils/_handle_stream.py +0 -121
  583. mirascope/core/mistral/_utils/_setup_call.py +0 -86
  584. mirascope/core/mistral/call_params.py +0 -36
  585. mirascope/core/mistral/call_response.py +0 -156
  586. mirascope/core/mistral/call_response_chunk.py +0 -84
  587. mirascope/core/mistral/dynamic_config.py +0 -24
  588. mirascope/core/mistral/py.typed +0 -0
  589. mirascope/core/mistral/stream.py +0 -117
  590. mirascope/core/mistral/tool.py +0 -77
  591. mirascope/core/openai/__init__.py +0 -21
  592. mirascope/core/openai/_call.py +0 -71
  593. mirascope/core/openai/_utils/__init__.py +0 -16
  594. mirascope/core/openai/_utils/_calculate_cost.py +0 -110
  595. mirascope/core/openai/_utils/_convert_message_params.py +0 -53
  596. mirascope/core/openai/_utils/_get_json_output.py +0 -27
  597. mirascope/core/openai/_utils/_handle_stream.py +0 -125
  598. mirascope/core/openai/_utils/_setup_call.py +0 -62
  599. mirascope/core/openai/call_params.py +0 -54
  600. mirascope/core/openai/call_response.py +0 -162
  601. mirascope/core/openai/call_response_chunk.py +0 -90
  602. mirascope/core/openai/dynamic_config.py +0 -26
  603. mirascope/core/openai/py.typed +0 -0
  604. mirascope/core/openai/stream.py +0 -148
  605. mirascope/core/openai/tool.py +0 -79
  606. mirascope/core/py.typed +0 -0
  607. mirascope/integrations/__init__.py +0 -20
  608. mirascope/integrations/_middleware_factory.py +0 -277
  609. mirascope/integrations/langfuse/__init__.py +0 -3
  610. mirascope/integrations/langfuse/_utils.py +0 -114
  611. mirascope/integrations/langfuse/_with_langfuse.py +0 -71
  612. mirascope/integrations/logfire/__init__.py +0 -3
  613. mirascope/integrations/logfire/_utils.py +0 -188
  614. mirascope/integrations/logfire/_with_logfire.py +0 -60
  615. mirascope/integrations/otel/__init__.py +0 -5
  616. mirascope/integrations/otel/_utils.py +0 -268
  617. mirascope/integrations/otel/_with_hyperdx.py +0 -61
  618. mirascope/integrations/otel/_with_otel.py +0 -60
  619. mirascope/integrations/tenacity.py +0 -50
  620. mirascope/py.typed +0 -0
  621. mirascope/v0/__init__.py +0 -43
  622. mirascope/v0/anthropic.py +0 -54
  623. mirascope/v0/base/__init__.py +0 -12
  624. mirascope/v0/base/calls.py +0 -118
  625. mirascope/v0/base/extractors.py +0 -122
  626. mirascope/v0/base/ops_utils.py +0 -207
  627. mirascope/v0/base/prompts.py +0 -48
  628. mirascope/v0/base/types.py +0 -14
  629. mirascope/v0/base/utils.py +0 -21
  630. mirascope/v0/openai.py +0 -54
  631. mirascope-1.0.5.dist-info/METADATA +0 -519
  632. mirascope-1.0.5.dist-info/RECORD +0 -198
@@ -0,0 +1,440 @@
1
+ """Anthropic client implementation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Sequence
6
+ from typing import TYPE_CHECKING
7
+ from typing_extensions import Unpack
8
+
9
+ from anthropic import Anthropic, AsyncAnthropic
10
+
11
+ from ...context import Context, DepsT
12
+ from ...formatting import FormatSpec, FormattableT, resolve_format
13
+ from ...messages import Message
14
+ from ...responses import (
15
+ AsyncContextResponse,
16
+ AsyncContextStreamResponse,
17
+ AsyncResponse,
18
+ AsyncStreamResponse,
19
+ ContextResponse,
20
+ ContextStreamResponse,
21
+ Response,
22
+ StreamResponse,
23
+ )
24
+ from ...tools import (
25
+ AnyToolSchema,
26
+ AsyncContextToolkit,
27
+ AsyncToolkit,
28
+ BaseToolkit,
29
+ ContextToolkit,
30
+ Toolkit,
31
+ )
32
+ from ..base import BaseProvider, _utils as _base_utils
33
+ from . import _utils
34
+ from .beta_provider import AnthropicBetaProvider
35
+ from .model_id import AnthropicModelId, model_name
36
+ from .model_info import MODELS_WITHOUT_STRICT_STRUCTURED_OUTPUTS
37
+
38
+ if TYPE_CHECKING:
39
+ from ...models import Params
40
+
41
+
42
+ def _should_use_beta(
43
+ model_id: AnthropicModelId,
44
+ format: FormatSpec[FormattableT] | None,
45
+ tools: BaseToolkit[AnyToolSchema],
46
+ ) -> bool:
47
+ """Determine whether to use the beta API based on format mode or strict tools.
48
+
49
+ If the format resolves to strict mode, or any tools have strict=True,
50
+ and the model plausibly has strict structured output support, then we
51
+ will use the beta provider.
52
+ """
53
+ if model_name(model_id) in MODELS_WITHOUT_STRICT_STRUCTURED_OUTPUTS:
54
+ return False
55
+
56
+ # Check if format requires strict mode
57
+ resolved = resolve_format(format, default_mode=_utils.DEFAULT_FORMAT_MODE)
58
+ if resolved is not None and resolved.mode == "strict":
59
+ return True
60
+
61
+ return _base_utils.has_strict_tools(tools.tools)
62
+
63
+
64
+ class AnthropicProvider(BaseProvider[Anthropic]):
65
+ """The client for the Anthropic LLM model."""
66
+
67
+ id = "anthropic"
68
+ default_scope = "anthropic/"
69
+ error_map = _utils.ANTHROPIC_ERROR_MAP
70
+ _beta_provider: AnthropicBetaProvider
71
+
72
+ def __init__(
73
+ self, *, api_key: str | None = None, base_url: str | None = None
74
+ ) -> None:
75
+ """Initialize the Anthropic client."""
76
+ self.client = Anthropic(api_key=api_key, base_url=base_url)
77
+ self.async_client = AsyncAnthropic(api_key=api_key, base_url=base_url)
78
+ self._beta_provider = AnthropicBetaProvider(api_key=api_key, base_url=base_url)
79
+
80
+ def get_error_status(self, e: Exception) -> int | None:
81
+ """Extract HTTP status code from Anthropic exception."""
82
+ return getattr(e, "status_code", None)
83
+
84
+ def _call(
85
+ self,
86
+ *,
87
+ model_id: AnthropicModelId,
88
+ messages: Sequence[Message],
89
+ toolkit: Toolkit,
90
+ format: FormatSpec[FormattableT] | None = None,
91
+ **params: Unpack[Params],
92
+ ) -> Response | Response[FormattableT]:
93
+ """Generate an `llm.Response` by synchronously calling the Anthropic Messages API."""
94
+ if _should_use_beta(model_id, format, toolkit):
95
+ return self._beta_provider.call(
96
+ model_id=model_id,
97
+ messages=messages,
98
+ toolkit=toolkit,
99
+ format=format,
100
+ **params,
101
+ )
102
+
103
+ input_messages, resolved_format, kwargs = _utils.encode_request(
104
+ model_id=model_id,
105
+ messages=messages,
106
+ tools=toolkit,
107
+ format=format,
108
+ params=params,
109
+ )
110
+ anthropic_response = self.client.messages.create(**kwargs)
111
+ include_thoughts = _utils.get_include_thoughts(params)
112
+ assistant_message, finish_reason, usage = _utils.decode_response(
113
+ anthropic_response, model_id, include_thoughts=include_thoughts
114
+ )
115
+ return Response(
116
+ raw=anthropic_response,
117
+ provider_id="anthropic",
118
+ model_id=model_id,
119
+ provider_model_name=model_name(model_id),
120
+ params=params,
121
+ tools=toolkit,
122
+ input_messages=input_messages,
123
+ assistant_message=assistant_message,
124
+ finish_reason=finish_reason,
125
+ usage=usage,
126
+ format=resolved_format,
127
+ )
128
+
129
+ def _context_call(
130
+ self,
131
+ *,
132
+ ctx: Context[DepsT],
133
+ model_id: AnthropicModelId,
134
+ messages: Sequence[Message],
135
+ toolkit: ContextToolkit[DepsT],
136
+ format: FormatSpec[FormattableT] | None = None,
137
+ **params: Unpack[Params],
138
+ ) -> ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]:
139
+ """Generate an `llm.ContextResponse` by synchronously calling the Anthropic Messages API."""
140
+ if _should_use_beta(model_id, format, toolkit):
141
+ return self._beta_provider.context_call(
142
+ ctx=ctx,
143
+ model_id=model_id,
144
+ messages=messages,
145
+ toolkit=toolkit,
146
+ format=format,
147
+ **params,
148
+ )
149
+
150
+ input_messages, resolved_format, kwargs = _utils.encode_request(
151
+ model_id=model_id,
152
+ messages=messages,
153
+ tools=toolkit,
154
+ format=format,
155
+ params=params,
156
+ )
157
+ anthropic_response = self.client.messages.create(**kwargs)
158
+ include_thoughts = _utils.get_include_thoughts(params)
159
+ assistant_message, finish_reason, usage = _utils.decode_response(
160
+ anthropic_response, model_id, include_thoughts=include_thoughts
161
+ )
162
+ return ContextResponse(
163
+ raw=anthropic_response,
164
+ provider_id="anthropic",
165
+ model_id=model_id,
166
+ provider_model_name=model_name(model_id),
167
+ params=params,
168
+ tools=toolkit,
169
+ input_messages=input_messages,
170
+ assistant_message=assistant_message,
171
+ finish_reason=finish_reason,
172
+ usage=usage,
173
+ format=resolved_format,
174
+ )
175
+
176
+ async def _call_async(
177
+ self,
178
+ *,
179
+ model_id: AnthropicModelId,
180
+ messages: Sequence[Message],
181
+ toolkit: AsyncToolkit,
182
+ format: FormatSpec[FormattableT] | None = None,
183
+ **params: Unpack[Params],
184
+ ) -> AsyncResponse | AsyncResponse[FormattableT]:
185
+ """Generate an `llm.AsyncResponse` by asynchronously calling the Anthropic Messages API."""
186
+ if _should_use_beta(model_id, format, toolkit):
187
+ return await self._beta_provider.call_async(
188
+ model_id=model_id,
189
+ messages=messages,
190
+ toolkit=toolkit,
191
+ format=format,
192
+ **params,
193
+ )
194
+
195
+ input_messages, resolved_format, kwargs = _utils.encode_request(
196
+ model_id=model_id,
197
+ messages=messages,
198
+ tools=toolkit,
199
+ format=format,
200
+ params=params,
201
+ )
202
+ anthropic_response = await self.async_client.messages.create(**kwargs)
203
+ include_thoughts = _utils.get_include_thoughts(params)
204
+ assistant_message, finish_reason, usage = _utils.decode_response(
205
+ anthropic_response, model_id, include_thoughts=include_thoughts
206
+ )
207
+ return AsyncResponse(
208
+ raw=anthropic_response,
209
+ provider_id="anthropic",
210
+ model_id=model_id,
211
+ provider_model_name=model_name(model_id),
212
+ params=params,
213
+ tools=toolkit,
214
+ input_messages=input_messages,
215
+ assistant_message=assistant_message,
216
+ finish_reason=finish_reason,
217
+ usage=usage,
218
+ format=resolved_format,
219
+ )
220
+
221
+ async def _context_call_async(
222
+ self,
223
+ *,
224
+ ctx: Context[DepsT],
225
+ model_id: AnthropicModelId,
226
+ messages: Sequence[Message],
227
+ toolkit: AsyncContextToolkit[DepsT],
228
+ format: FormatSpec[FormattableT] | None = None,
229
+ **params: Unpack[Params],
230
+ ) -> AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT]:
231
+ """Generate an `llm.AsyncContextResponse` by asynchronously calling the Anthropic Messages API."""
232
+ if _should_use_beta(model_id, format, toolkit):
233
+ return await self._beta_provider.context_call_async(
234
+ ctx=ctx,
235
+ model_id=model_id,
236
+ messages=messages,
237
+ toolkit=toolkit,
238
+ format=format,
239
+ **params,
240
+ )
241
+
242
+ input_messages, resolved_format, kwargs = _utils.encode_request(
243
+ model_id=model_id,
244
+ messages=messages,
245
+ tools=toolkit,
246
+ format=format,
247
+ params=params,
248
+ )
249
+ anthropic_response = await self.async_client.messages.create(**kwargs)
250
+ include_thoughts = _utils.get_include_thoughts(params)
251
+ assistant_message, finish_reason, usage = _utils.decode_response(
252
+ anthropic_response, model_id, include_thoughts=include_thoughts
253
+ )
254
+ return AsyncContextResponse(
255
+ raw=anthropic_response,
256
+ provider_id="anthropic",
257
+ model_id=model_id,
258
+ provider_model_name=model_name(model_id),
259
+ params=params,
260
+ tools=toolkit,
261
+ input_messages=input_messages,
262
+ assistant_message=assistant_message,
263
+ finish_reason=finish_reason,
264
+ usage=usage,
265
+ format=resolved_format,
266
+ )
267
+
268
+ def _stream(
269
+ self,
270
+ *,
271
+ model_id: AnthropicModelId,
272
+ messages: Sequence[Message],
273
+ toolkit: Toolkit,
274
+ format: FormatSpec[FormattableT] | None = None,
275
+ **params: Unpack[Params],
276
+ ) -> StreamResponse | StreamResponse[FormattableT]:
277
+ """Generate an `llm.StreamResponse` by synchronously streaming from the Anthropic Messages API."""
278
+ if _should_use_beta(model_id, format, toolkit):
279
+ return self._beta_provider.stream(
280
+ model_id=model_id,
281
+ messages=messages,
282
+ toolkit=toolkit,
283
+ format=format,
284
+ **params,
285
+ )
286
+
287
+ input_messages, resolved_format, kwargs = _utils.encode_request(
288
+ model_id=model_id,
289
+ messages=messages,
290
+ tools=toolkit,
291
+ format=format,
292
+ params=params,
293
+ )
294
+ anthropic_stream = self.client.messages.stream(**kwargs)
295
+ include_thoughts = _utils.get_include_thoughts(params)
296
+ chunk_iterator = _utils.decode_stream(
297
+ anthropic_stream, include_thoughts=include_thoughts
298
+ )
299
+ return StreamResponse(
300
+ provider_id="anthropic",
301
+ model_id=model_id,
302
+ provider_model_name=model_name(model_id),
303
+ params=params,
304
+ tools=toolkit,
305
+ input_messages=input_messages,
306
+ chunk_iterator=chunk_iterator,
307
+ format=resolved_format,
308
+ )
309
+
310
+ def _context_stream(
311
+ self,
312
+ *,
313
+ ctx: Context[DepsT],
314
+ model_id: AnthropicModelId,
315
+ messages: Sequence[Message],
316
+ toolkit: ContextToolkit[DepsT],
317
+ format: FormatSpec[FormattableT] | None = None,
318
+ **params: Unpack[Params],
319
+ ) -> ContextStreamResponse[DepsT] | ContextStreamResponse[DepsT, FormattableT]:
320
+ """Generate an `llm.ContextStreamResponse` by synchronously streaming from the Anthropic Messages API."""
321
+ if _should_use_beta(model_id, format, toolkit):
322
+ return self._beta_provider.context_stream(
323
+ ctx=ctx,
324
+ model_id=model_id,
325
+ messages=messages,
326
+ toolkit=toolkit,
327
+ format=format,
328
+ **params,
329
+ )
330
+
331
+ input_messages, resolved_format, kwargs = _utils.encode_request(
332
+ model_id=model_id,
333
+ messages=messages,
334
+ tools=toolkit,
335
+ format=format,
336
+ params=params,
337
+ )
338
+ anthropic_stream = self.client.messages.stream(**kwargs)
339
+ include_thoughts = _utils.get_include_thoughts(params)
340
+ chunk_iterator = _utils.decode_stream(
341
+ anthropic_stream, include_thoughts=include_thoughts
342
+ )
343
+ return ContextStreamResponse(
344
+ provider_id="anthropic",
345
+ model_id=model_id,
346
+ provider_model_name=model_name(model_id),
347
+ params=params,
348
+ tools=toolkit,
349
+ input_messages=input_messages,
350
+ chunk_iterator=chunk_iterator,
351
+ format=resolved_format,
352
+ )
353
+
354
+ async def _stream_async(
355
+ self,
356
+ *,
357
+ model_id: AnthropicModelId,
358
+ messages: Sequence[Message],
359
+ toolkit: AsyncToolkit,
360
+ format: FormatSpec[FormattableT] | None = None,
361
+ **params: Unpack[Params],
362
+ ) -> AsyncStreamResponse | AsyncStreamResponse[FormattableT]:
363
+ """Generate an `llm.AsyncStreamResponse` by asynchronously streaming from the Anthropic Messages API."""
364
+ if _should_use_beta(model_id, format, toolkit):
365
+ return await self._beta_provider.stream_async(
366
+ model_id=model_id,
367
+ messages=messages,
368
+ toolkit=toolkit,
369
+ format=format,
370
+ **params,
371
+ )
372
+ input_messages, resolved_format, kwargs = _utils.encode_request(
373
+ model_id=model_id,
374
+ messages=messages,
375
+ tools=toolkit,
376
+ format=format,
377
+ params=params,
378
+ )
379
+ anthropic_stream = self.async_client.messages.stream(**kwargs)
380
+ include_thoughts = _utils.get_include_thoughts(params)
381
+ chunk_iterator = _utils.decode_async_stream(
382
+ anthropic_stream, include_thoughts=include_thoughts
383
+ )
384
+ return AsyncStreamResponse(
385
+ provider_id="anthropic",
386
+ model_id=model_id,
387
+ provider_model_name=model_name(model_id),
388
+ params=params,
389
+ tools=toolkit,
390
+ input_messages=input_messages,
391
+ chunk_iterator=chunk_iterator,
392
+ format=resolved_format,
393
+ )
394
+
395
+ async def _context_stream_async(
396
+ self,
397
+ *,
398
+ ctx: Context[DepsT],
399
+ model_id: AnthropicModelId,
400
+ messages: Sequence[Message],
401
+ toolkit: AsyncContextToolkit[DepsT],
402
+ format: FormatSpec[FormattableT] | None = None,
403
+ **params: Unpack[Params],
404
+ ) -> (
405
+ AsyncContextStreamResponse[DepsT]
406
+ | AsyncContextStreamResponse[DepsT, FormattableT]
407
+ ):
408
+ """Generate an `llm.AsyncContextStreamResponse` by asynchronously streaming from the Anthropic Messages API."""
409
+ if _should_use_beta(model_id, format, toolkit):
410
+ return await self._beta_provider.context_stream_async(
411
+ ctx=ctx,
412
+ model_id=model_id,
413
+ messages=messages,
414
+ toolkit=toolkit,
415
+ format=format,
416
+ **params,
417
+ )
418
+
419
+ input_messages, resolved_format, kwargs = _utils.encode_request(
420
+ model_id=model_id,
421
+ messages=messages,
422
+ tools=toolkit,
423
+ format=format,
424
+ params=params,
425
+ )
426
+ anthropic_stream = self.async_client.messages.stream(**kwargs)
427
+ include_thoughts = _utils.get_include_thoughts(params)
428
+ chunk_iterator = _utils.decode_async_stream(
429
+ anthropic_stream, include_thoughts=include_thoughts
430
+ )
431
+ return AsyncContextStreamResponse(
432
+ provider_id="anthropic",
433
+ model_id=model_id,
434
+ provider_model_name=model_name(model_id),
435
+ params=params,
436
+ tools=toolkit,
437
+ input_messages=input_messages,
438
+ chunk_iterator=chunk_iterator,
439
+ format=resolved_format,
440
+ )
@@ -0,0 +1,14 @@
1
+ """Base client interfaces and types."""
2
+
3
+ from . import _utils
4
+ from .base_provider import BaseProvider, Provider, ProviderErrorMap
5
+ from .kwargs import BaseKwargs, KwargsT
6
+
7
+ __all__ = [
8
+ "BaseKwargs",
9
+ "BaseProvider",
10
+ "KwargsT",
11
+ "Provider",
12
+ "ProviderErrorMap",
13
+ "_utils",
14
+ ]
@@ -0,0 +1,248 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from collections.abc import Generator, Sequence
5
+ from contextlib import contextmanager
6
+ from typing import TYPE_CHECKING, TypeAlias, cast, get_type_hints
7
+
8
+ from ...content import Text
9
+ from ...messages import AssistantMessage, Message, SystemMessage, UserMessage
10
+ from ...models.params import (
11
+ Params, # Import directly from params.py to avoid circular dependency
12
+ )
13
+ from ...tools import AnyToolSchema, ProviderTool, ToolSchema
14
+ from ..provider_id import ProviderId
15
+
16
+ if TYPE_CHECKING:
17
+ from ...models import ThinkingConfig
18
+ from ..model_id import ModelId
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+ SystemMessageContent: TypeAlias = str | None
23
+
24
+
25
+ def get_include_thoughts(params: Params) -> bool:
26
+ """Extract include_thoughts from params thinking config."""
27
+ thinking_config = params.get("thinking")
28
+ return (thinking_config or {}).get("include_thoughts", False)
29
+
30
+
31
+ def has_strict_tools(tools: Sequence[AnyToolSchema | ProviderTool]) -> bool:
32
+ """Check if any tools have strict=True explicitly set.
33
+
34
+ Args:
35
+ tools: The tools to check
36
+
37
+ Returns:
38
+ True if any tool has strict=True, False otherwise
39
+ """
40
+ return any(isinstance(tool, ToolSchema) and tool.strict is True for tool in tools)
41
+
42
+
43
+ def ensure_additional_properties_false(obj: object) -> None:
44
+ """Recursively adds additionalProperties = False to a schema, required for strict mode."""
45
+ if isinstance(obj, dict):
46
+ obj = cast(dict[str, object], obj)
47
+ if obj.get("type") == "object" and "additionalProperties" not in obj:
48
+ obj["additionalProperties"] = False
49
+ for value in obj.values():
50
+ ensure_additional_properties_false(value)
51
+ elif isinstance(obj, list):
52
+ obj = cast(list[object], obj)
53
+ for item in obj:
54
+ ensure_additional_properties_false(item)
55
+
56
+
57
+ def ensure_all_properties_required(obj: object) -> None:
58
+ """Recursively ensures all properties are in required array, needed for OpenAI strict mode.
59
+
60
+ OpenAI's strict mode requires that all properties in an object schema are listed
61
+ in the 'required' array, even if they have default values.
62
+ """
63
+ if isinstance(obj, dict):
64
+ obj = cast(dict[str, object], obj)
65
+ if obj.get("type") == "object" and "properties" in obj:
66
+ properties = obj.get("properties")
67
+ if isinstance(properties, dict):
68
+ property_keys = cast(dict[str, object], properties)
69
+ obj["required"] = list(property_keys.keys())
70
+ for value in obj.values():
71
+ ensure_all_properties_required(value)
72
+ elif isinstance(obj, list):
73
+ obj = cast(list[object], obj)
74
+ for item in obj:
75
+ ensure_all_properties_required(item)
76
+
77
+
78
+ def add_system_instructions(
79
+ messages: Sequence[Message], additional_system_instructions: str
80
+ ) -> Sequence[Message]:
81
+ """Add system instructions to a sequence of messages.
82
+
83
+ If the first message is a system message, appends the additional instructions
84
+ to it with a newline separator. If the instructions already exist at the end
85
+ of the system message, returns the original messages unchanged. Otherwise,
86
+ creates a new system message at the beginning of the sequence.
87
+
88
+ Args:
89
+ messages: The sequence of messages to modify.
90
+ additional_system_instructions: The system instructions to add.
91
+
92
+ Returns:
93
+ A new sequence of messages with the system instructions added.
94
+ """
95
+ if messages and messages[0].role == "system":
96
+ if messages[0].content.text.endswith(additional_system_instructions):
97
+ return messages
98
+ modified = Text(
99
+ text=messages[0].content.text + "\n" + additional_system_instructions
100
+ )
101
+ return [SystemMessage(role="system", content=modified), *messages[1:]]
102
+ else:
103
+ return [
104
+ SystemMessage(
105
+ role="system", content=Text(text=additional_system_instructions)
106
+ ),
107
+ *messages,
108
+ ]
109
+
110
+
111
+ def extract_system_message(
112
+ messages: Sequence[Message],
113
+ ) -> tuple[SystemMessageContent, Sequence[UserMessage | AssistantMessage]]:
114
+ """Extract the system message(s) from a list of Messages.
115
+
116
+ This takes a list of messages, and returns the list of messages with
117
+ all system messages removed, as well as the textual contents of the first message,
118
+ if that message was a system message. If there are any system messages that are
119
+ not the first message, they will be dropped, and a warning will be emitted.
120
+
121
+ This is intended for use in clients where the system message is not included in the
122
+ input messages, but passed as an additional argument or metadata.
123
+ """
124
+ system_message_content: SystemMessageContent = None
125
+ remaining_messages: list[UserMessage | AssistantMessage] = []
126
+
127
+ for i, message in enumerate(messages):
128
+ if message.role == "system":
129
+ if i == 0:
130
+ system_message_content = message.content.text
131
+ else:
132
+ logging.warning(
133
+ "Skipping system message at index %d because it is not the first message",
134
+ i,
135
+ )
136
+ else:
137
+ remaining_messages.append(message)
138
+
139
+ return system_message_content, remaining_messages
140
+
141
+
142
+ class SafeParamsAccessor:
143
+ """A wrapper around Params that tracks which parameters have been accessed."""
144
+
145
+ def __init__(self, params: Params) -> None:
146
+ self._params = params
147
+ self._unaccessed = set(get_type_hints(Params).keys())
148
+
149
+ @property
150
+ def temperature(self) -> float | None:
151
+ """Access the temperature parameter."""
152
+ self._unaccessed.discard("temperature")
153
+ return self._params.get("temperature")
154
+
155
+ @property
156
+ def max_tokens(self) -> int | None:
157
+ """Access the max_tokens parameter."""
158
+ self._unaccessed.discard("max_tokens")
159
+ return self._params.get("max_tokens")
160
+
161
+ @property
162
+ def top_p(self) -> float | None:
163
+ """Access the top_p parameter."""
164
+ self._unaccessed.discard("top_p")
165
+ return self._params.get("top_p")
166
+
167
+ @property
168
+ def top_k(self) -> int | None:
169
+ """Access the top_k parameter."""
170
+ self._unaccessed.discard("top_k")
171
+ return self._params.get("top_k")
172
+
173
+ @property
174
+ def seed(self) -> int | None:
175
+ """Access the seed parameter."""
176
+ self._unaccessed.discard("seed")
177
+ return self._params.get("seed")
178
+
179
+ @property
180
+ def stop_sequences(self) -> list[str] | None:
181
+ """Access the stop_sequences parameter."""
182
+ self._unaccessed.discard("stop_sequences")
183
+ return self._params.get("stop_sequences")
184
+
185
+ @property
186
+ def thinking(self) -> ThinkingConfig | None:
187
+ """Access the thinking parameter."""
188
+ self._unaccessed.discard("thinking")
189
+ return self._params.get("thinking")
190
+
191
+ def emit_warning_for_unused_param(
192
+ self,
193
+ param_name: str,
194
+ param_value: object,
195
+ provider_id: ProviderId,
196
+ model_id: ModelId | None = None,
197
+ ) -> None:
198
+ unsupported_by = f"provider: {provider_id}"
199
+ if model_id:
200
+ unsupported_by += f" with model_id: {model_id}"
201
+ logger.warning(
202
+ f"Skipping unsupported parameter: {param_name}={param_value} ({unsupported_by})"
203
+ )
204
+
205
+ def check_access_integrity(self, unsupported_params: list[str]) -> None:
206
+ """Verify that all used parameters have been accessed, and none of the unsupported have been."""
207
+ assert self._unaccessed == set(unsupported_params), (
208
+ "Mismatch between unsupported and unaccessed params"
209
+ )
210
+
211
+
212
+ @contextmanager
213
+ def ensure_all_params_accessed(
214
+ *,
215
+ params: Params,
216
+ provider_id: ProviderId,
217
+ unsupported_params: list[str] | None = None,
218
+ ) -> Generator[SafeParamsAccessor, None, None]:
219
+ """Context manager that ensures all parameters are accessed.
220
+
221
+ Yields a wrapper around params that tracks which parameters have been accessed.
222
+ On context exit, raises a `RuntimeError` if any parameters were not accessed.
223
+
224
+ Args:
225
+ params: The parameters to wrap
226
+ provider: The provider that is accessing these params (required for logging)
227
+ unsupported_params: A list of params keys it does not support, for auto-warning
228
+ of unsupported params as boilerplate reduction. Or None, to disable this
229
+ optional feature.
230
+
231
+ Yields:
232
+ A SafeParamsAccessor instance if params is not None, else None
233
+
234
+ Raises:
235
+ RuntimeError: If any parameters were not accessed before context exit
236
+ """
237
+
238
+ accessor = SafeParamsAccessor(params)
239
+ unsupported_params = unsupported_params or []
240
+ for unsupported in unsupported_params:
241
+ if (val := params.get(unsupported)) is not None:
242
+ accessor.emit_warning_for_unused_param(
243
+ unsupported, val, provider_id=provider_id
244
+ )
245
+ try:
246
+ yield accessor
247
+ finally:
248
+ accessor.check_access_integrity(unsupported_params=unsupported_params)