mirascope 2.0.0__py3-none-any.whl → 2.0.0a1__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 (443) hide show
  1. mirascope/__init__.py +2 -11
  2. mirascope/graphs/__init__.py +22 -0
  3. mirascope/graphs/finite_state_machine.py +625 -0
  4. mirascope/llm/__init__.py +15 -96
  5. mirascope/llm/agents/__init__.py +15 -0
  6. mirascope/llm/agents/agent.py +97 -0
  7. mirascope/llm/agents/agent_template.py +45 -0
  8. mirascope/llm/agents/decorator.py +176 -0
  9. mirascope/llm/calls/__init__.py +1 -2
  10. mirascope/llm/calls/base_call.py +33 -0
  11. mirascope/llm/calls/calls.py +58 -84
  12. mirascope/llm/calls/decorator.py +120 -140
  13. mirascope/llm/clients/__init__.py +34 -0
  14. mirascope/llm/clients/_missing_import_stubs.py +47 -0
  15. mirascope/llm/clients/anthropic/__init__.py +25 -0
  16. mirascope/llm/{providers/openai/completions → clients/anthropic}/_utils/__init__.py +0 -2
  17. mirascope/llm/{providers → clients}/anthropic/_utils/decode.py +22 -66
  18. mirascope/llm/clients/anthropic/_utils/encode.py +243 -0
  19. mirascope/llm/clients/anthropic/clients.py +819 -0
  20. mirascope/llm/clients/anthropic/model_ids.py +8 -0
  21. mirascope/llm/{providers → clients}/base/__init__.py +5 -4
  22. mirascope/llm/{providers → clients}/base/_utils.py +17 -78
  23. mirascope/llm/{providers/base/base_provider.py → clients/base/client.py} +145 -468
  24. mirascope/llm/{models → clients/base}/params.py +37 -16
  25. mirascope/llm/clients/google/__init__.py +20 -0
  26. mirascope/llm/{providers/openai/responses → clients/google}/_utils/__init__.py +0 -2
  27. mirascope/llm/{providers → clients}/google/_utils/decode.py +22 -98
  28. mirascope/llm/{providers → clients}/google/_utils/encode.py +46 -168
  29. mirascope/llm/clients/google/clients.py +853 -0
  30. mirascope/llm/clients/google/model_ids.py +15 -0
  31. mirascope/llm/clients/openai/__init__.py +25 -0
  32. mirascope/llm/clients/openai/completions/__init__.py +28 -0
  33. mirascope/llm/{providers/google → clients/openai/completions}/_utils/__init__.py +0 -4
  34. mirascope/llm/{providers → clients}/openai/completions/_utils/decode.py +9 -74
  35. mirascope/llm/{providers → clients}/openai/completions/_utils/encode.py +52 -70
  36. mirascope/llm/clients/openai/completions/_utils/model_features.py +81 -0
  37. mirascope/llm/clients/openai/completions/clients.py +833 -0
  38. mirascope/llm/clients/openai/completions/model_ids.py +8 -0
  39. mirascope/llm/clients/openai/responses/__init__.py +26 -0
  40. mirascope/llm/clients/openai/responses/_utils/__init__.py +13 -0
  41. mirascope/llm/{providers → clients}/openai/responses/_utils/decode.py +14 -80
  42. mirascope/llm/{providers → clients}/openai/responses/_utils/encode.py +41 -92
  43. mirascope/llm/clients/openai/responses/_utils/model_features.py +87 -0
  44. mirascope/llm/clients/openai/responses/clients.py +832 -0
  45. mirascope/llm/clients/openai/responses/model_ids.py +8 -0
  46. mirascope/llm/clients/openai/shared/__init__.py +7 -0
  47. mirascope/llm/clients/openai/shared/_utils.py +55 -0
  48. mirascope/llm/clients/providers.py +175 -0
  49. mirascope/llm/content/__init__.py +2 -3
  50. mirascope/llm/content/tool_call.py +0 -6
  51. mirascope/llm/content/tool_output.py +5 -22
  52. mirascope/llm/context/_utils.py +6 -19
  53. mirascope/llm/exceptions.py +43 -298
  54. mirascope/llm/formatting/__init__.py +2 -19
  55. mirascope/llm/formatting/_utils.py +74 -0
  56. mirascope/llm/formatting/format.py +30 -219
  57. mirascope/llm/formatting/from_call_args.py +2 -2
  58. mirascope/llm/formatting/partial.py +7 -80
  59. mirascope/llm/formatting/types.py +64 -21
  60. mirascope/llm/mcp/__init__.py +2 -2
  61. mirascope/llm/mcp/client.py +118 -0
  62. mirascope/llm/messages/__init__.py +0 -3
  63. mirascope/llm/messages/message.py +5 -13
  64. mirascope/llm/models/__init__.py +2 -7
  65. mirascope/llm/models/models.py +139 -315
  66. mirascope/llm/prompts/__init__.py +12 -13
  67. mirascope/llm/prompts/_utils.py +43 -14
  68. mirascope/llm/prompts/decorator.py +204 -144
  69. mirascope/llm/prompts/protocols.py +59 -25
  70. mirascope/llm/responses/__init__.py +1 -9
  71. mirascope/llm/responses/_utils.py +12 -102
  72. mirascope/llm/responses/base_response.py +6 -18
  73. mirascope/llm/responses/base_stream_response.py +50 -173
  74. mirascope/llm/responses/finish_reason.py +0 -1
  75. mirascope/llm/responses/response.py +13 -34
  76. mirascope/llm/responses/root_response.py +29 -100
  77. mirascope/llm/responses/stream_response.py +31 -40
  78. mirascope/llm/tools/__init__.py +2 -9
  79. mirascope/llm/tools/_utils.py +3 -12
  80. mirascope/llm/tools/decorator.py +16 -25
  81. mirascope/llm/tools/protocols.py +4 -4
  82. mirascope/llm/tools/tool_schema.py +19 -87
  83. mirascope/llm/tools/toolkit.py +27 -35
  84. mirascope/llm/tools/tools.py +41 -135
  85. {mirascope-2.0.0.dist-info → mirascope-2.0.0a1.dist-info}/METADATA +13 -90
  86. mirascope-2.0.0a1.dist-info/RECORD +102 -0
  87. {mirascope-2.0.0.dist-info → mirascope-2.0.0a1.dist-info}/WHEEL +1 -1
  88. {mirascope-2.0.0.dist-info → mirascope-2.0.0a1.dist-info}/licenses/LICENSE +1 -1
  89. mirascope/_stubs.py +0 -363
  90. mirascope/api/__init__.py +0 -14
  91. mirascope/api/_generated/README.md +0 -207
  92. mirascope/api/_generated/__init__.py +0 -440
  93. mirascope/api/_generated/annotations/__init__.py +0 -33
  94. mirascope/api/_generated/annotations/client.py +0 -506
  95. mirascope/api/_generated/annotations/raw_client.py +0 -1414
  96. mirascope/api/_generated/annotations/types/__init__.py +0 -31
  97. mirascope/api/_generated/annotations/types/annotations_create_request_label.py +0 -5
  98. mirascope/api/_generated/annotations/types/annotations_create_response.py +0 -48
  99. mirascope/api/_generated/annotations/types/annotations_create_response_label.py +0 -5
  100. mirascope/api/_generated/annotations/types/annotations_get_response.py +0 -48
  101. mirascope/api/_generated/annotations/types/annotations_get_response_label.py +0 -5
  102. mirascope/api/_generated/annotations/types/annotations_list_request_label.py +0 -5
  103. mirascope/api/_generated/annotations/types/annotations_list_response.py +0 -21
  104. mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item.py +0 -50
  105. mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item_label.py +0 -5
  106. mirascope/api/_generated/annotations/types/annotations_update_request_label.py +0 -5
  107. mirascope/api/_generated/annotations/types/annotations_update_response.py +0 -48
  108. mirascope/api/_generated/annotations/types/annotations_update_response_label.py +0 -5
  109. mirascope/api/_generated/api_keys/__init__.py +0 -17
  110. mirascope/api/_generated/api_keys/client.py +0 -530
  111. mirascope/api/_generated/api_keys/raw_client.py +0 -1236
  112. mirascope/api/_generated/api_keys/types/__init__.py +0 -15
  113. mirascope/api/_generated/api_keys/types/api_keys_create_response.py +0 -28
  114. mirascope/api/_generated/api_keys/types/api_keys_get_response.py +0 -27
  115. mirascope/api/_generated/api_keys/types/api_keys_list_all_for_org_response_item.py +0 -40
  116. mirascope/api/_generated/api_keys/types/api_keys_list_response_item.py +0 -27
  117. mirascope/api/_generated/client.py +0 -211
  118. mirascope/api/_generated/core/__init__.py +0 -52
  119. mirascope/api/_generated/core/api_error.py +0 -23
  120. mirascope/api/_generated/core/client_wrapper.py +0 -46
  121. mirascope/api/_generated/core/datetime_utils.py +0 -28
  122. mirascope/api/_generated/core/file.py +0 -67
  123. mirascope/api/_generated/core/force_multipart.py +0 -16
  124. mirascope/api/_generated/core/http_client.py +0 -543
  125. mirascope/api/_generated/core/http_response.py +0 -55
  126. mirascope/api/_generated/core/jsonable_encoder.py +0 -100
  127. mirascope/api/_generated/core/pydantic_utilities.py +0 -255
  128. mirascope/api/_generated/core/query_encoder.py +0 -58
  129. mirascope/api/_generated/core/remove_none_from_dict.py +0 -11
  130. mirascope/api/_generated/core/request_options.py +0 -35
  131. mirascope/api/_generated/core/serialization.py +0 -276
  132. mirascope/api/_generated/docs/__init__.py +0 -4
  133. mirascope/api/_generated/docs/client.py +0 -91
  134. mirascope/api/_generated/docs/raw_client.py +0 -178
  135. mirascope/api/_generated/environment.py +0 -9
  136. mirascope/api/_generated/environments/__init__.py +0 -23
  137. mirascope/api/_generated/environments/client.py +0 -649
  138. mirascope/api/_generated/environments/raw_client.py +0 -1567
  139. mirascope/api/_generated/environments/types/__init__.py +0 -25
  140. mirascope/api/_generated/environments/types/environments_create_response.py +0 -24
  141. mirascope/api/_generated/environments/types/environments_get_analytics_response.py +0 -60
  142. mirascope/api/_generated/environments/types/environments_get_analytics_response_top_functions_item.py +0 -24
  143. mirascope/api/_generated/environments/types/environments_get_analytics_response_top_models_item.py +0 -22
  144. mirascope/api/_generated/environments/types/environments_get_response.py +0 -24
  145. mirascope/api/_generated/environments/types/environments_list_response_item.py +0 -24
  146. mirascope/api/_generated/environments/types/environments_update_response.py +0 -24
  147. mirascope/api/_generated/errors/__init__.py +0 -25
  148. mirascope/api/_generated/errors/bad_request_error.py +0 -14
  149. mirascope/api/_generated/errors/conflict_error.py +0 -14
  150. mirascope/api/_generated/errors/forbidden_error.py +0 -11
  151. mirascope/api/_generated/errors/internal_server_error.py +0 -10
  152. mirascope/api/_generated/errors/not_found_error.py +0 -11
  153. mirascope/api/_generated/errors/payment_required_error.py +0 -15
  154. mirascope/api/_generated/errors/service_unavailable_error.py +0 -14
  155. mirascope/api/_generated/errors/too_many_requests_error.py +0 -15
  156. mirascope/api/_generated/errors/unauthorized_error.py +0 -11
  157. mirascope/api/_generated/functions/__init__.py +0 -39
  158. mirascope/api/_generated/functions/client.py +0 -647
  159. mirascope/api/_generated/functions/raw_client.py +0 -1890
  160. mirascope/api/_generated/functions/types/__init__.py +0 -53
  161. mirascope/api/_generated/functions/types/functions_create_request_dependencies_value.py +0 -20
  162. mirascope/api/_generated/functions/types/functions_create_response.py +0 -37
  163. mirascope/api/_generated/functions/types/functions_create_response_dependencies_value.py +0 -20
  164. mirascope/api/_generated/functions/types/functions_find_by_hash_response.py +0 -39
  165. mirascope/api/_generated/functions/types/functions_find_by_hash_response_dependencies_value.py +0 -20
  166. mirascope/api/_generated/functions/types/functions_get_by_env_response.py +0 -53
  167. mirascope/api/_generated/functions/types/functions_get_by_env_response_dependencies_value.py +0 -22
  168. mirascope/api/_generated/functions/types/functions_get_response.py +0 -37
  169. mirascope/api/_generated/functions/types/functions_get_response_dependencies_value.py +0 -20
  170. mirascope/api/_generated/functions/types/functions_list_by_env_response.py +0 -25
  171. mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item.py +0 -56
  172. mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item_dependencies_value.py +0 -22
  173. mirascope/api/_generated/functions/types/functions_list_response.py +0 -21
  174. mirascope/api/_generated/functions/types/functions_list_response_functions_item.py +0 -41
  175. mirascope/api/_generated/functions/types/functions_list_response_functions_item_dependencies_value.py +0 -20
  176. mirascope/api/_generated/health/__init__.py +0 -7
  177. mirascope/api/_generated/health/client.py +0 -92
  178. mirascope/api/_generated/health/raw_client.py +0 -175
  179. mirascope/api/_generated/health/types/__init__.py +0 -8
  180. mirascope/api/_generated/health/types/health_check_response.py +0 -22
  181. mirascope/api/_generated/health/types/health_check_response_status.py +0 -5
  182. mirascope/api/_generated/organization_invitations/__init__.py +0 -33
  183. mirascope/api/_generated/organization_invitations/client.py +0 -546
  184. mirascope/api/_generated/organization_invitations/raw_client.py +0 -1519
  185. mirascope/api/_generated/organization_invitations/types/__init__.py +0 -53
  186. mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response.py +0 -34
  187. mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response_role.py +0 -7
  188. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_request_role.py +0 -7
  189. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response.py +0 -48
  190. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_role.py +0 -7
  191. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_status.py +0 -7
  192. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response.py +0 -48
  193. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_role.py +0 -7
  194. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_status.py +0 -7
  195. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item.py +0 -48
  196. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_role.py +0 -7
  197. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_status.py +0 -7
  198. mirascope/api/_generated/organization_memberships/__init__.py +0 -19
  199. mirascope/api/_generated/organization_memberships/client.py +0 -302
  200. mirascope/api/_generated/organization_memberships/raw_client.py +0 -736
  201. mirascope/api/_generated/organization_memberships/types/__init__.py +0 -27
  202. mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item.py +0 -33
  203. mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item_role.py +0 -7
  204. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_request_role.py +0 -7
  205. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response.py +0 -31
  206. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response_role.py +0 -7
  207. mirascope/api/_generated/organizations/__init__.py +0 -51
  208. mirascope/api/_generated/organizations/client.py +0 -869
  209. mirascope/api/_generated/organizations/raw_client.py +0 -2593
  210. mirascope/api/_generated/organizations/types/__init__.py +0 -71
  211. mirascope/api/_generated/organizations/types/organizations_create_payment_intent_response.py +0 -24
  212. mirascope/api/_generated/organizations/types/organizations_create_response.py +0 -26
  213. mirascope/api/_generated/organizations/types/organizations_create_response_role.py +0 -5
  214. mirascope/api/_generated/organizations/types/organizations_get_response.py +0 -26
  215. mirascope/api/_generated/organizations/types/organizations_get_response_role.py +0 -5
  216. mirascope/api/_generated/organizations/types/organizations_list_response_item.py +0 -26
  217. mirascope/api/_generated/organizations/types/organizations_list_response_item_role.py +0 -5
  218. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_request_target_plan.py +0 -7
  219. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response.py +0 -47
  220. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item.py +0 -33
  221. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item_resource.py +0 -7
  222. mirascope/api/_generated/organizations/types/organizations_router_balance_response.py +0 -24
  223. mirascope/api/_generated/organizations/types/organizations_subscription_response.py +0 -53
  224. mirascope/api/_generated/organizations/types/organizations_subscription_response_current_plan.py +0 -7
  225. mirascope/api/_generated/organizations/types/organizations_subscription_response_payment_method.py +0 -26
  226. mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change.py +0 -34
  227. mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change_target_plan.py +0 -7
  228. mirascope/api/_generated/organizations/types/organizations_update_response.py +0 -26
  229. mirascope/api/_generated/organizations/types/organizations_update_response_role.py +0 -5
  230. mirascope/api/_generated/organizations/types/organizations_update_subscription_request_target_plan.py +0 -7
  231. mirascope/api/_generated/organizations/types/organizations_update_subscription_response.py +0 -35
  232. mirascope/api/_generated/project_memberships/__init__.py +0 -25
  233. mirascope/api/_generated/project_memberships/client.py +0 -437
  234. mirascope/api/_generated/project_memberships/raw_client.py +0 -1039
  235. mirascope/api/_generated/project_memberships/types/__init__.py +0 -29
  236. mirascope/api/_generated/project_memberships/types/project_memberships_create_request_role.py +0 -7
  237. mirascope/api/_generated/project_memberships/types/project_memberships_create_response.py +0 -35
  238. mirascope/api/_generated/project_memberships/types/project_memberships_create_response_role.py +0 -7
  239. mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item.py +0 -33
  240. mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item_role.py +0 -7
  241. mirascope/api/_generated/project_memberships/types/project_memberships_update_request_role.py +0 -7
  242. mirascope/api/_generated/project_memberships/types/project_memberships_update_response.py +0 -35
  243. mirascope/api/_generated/project_memberships/types/project_memberships_update_response_role.py +0 -7
  244. mirascope/api/_generated/projects/__init__.py +0 -7
  245. mirascope/api/_generated/projects/client.py +0 -428
  246. mirascope/api/_generated/projects/raw_client.py +0 -1302
  247. mirascope/api/_generated/projects/types/__init__.py +0 -10
  248. mirascope/api/_generated/projects/types/projects_create_response.py +0 -25
  249. mirascope/api/_generated/projects/types/projects_get_response.py +0 -25
  250. mirascope/api/_generated/projects/types/projects_list_response_item.py +0 -25
  251. mirascope/api/_generated/projects/types/projects_update_response.py +0 -25
  252. mirascope/api/_generated/reference.md +0 -4915
  253. mirascope/api/_generated/tags/__init__.py +0 -19
  254. mirascope/api/_generated/tags/client.py +0 -504
  255. mirascope/api/_generated/tags/raw_client.py +0 -1288
  256. mirascope/api/_generated/tags/types/__init__.py +0 -17
  257. mirascope/api/_generated/tags/types/tags_create_response.py +0 -41
  258. mirascope/api/_generated/tags/types/tags_get_response.py +0 -41
  259. mirascope/api/_generated/tags/types/tags_list_response.py +0 -23
  260. mirascope/api/_generated/tags/types/tags_list_response_tags_item.py +0 -41
  261. mirascope/api/_generated/tags/types/tags_update_response.py +0 -41
  262. mirascope/api/_generated/token_cost/__init__.py +0 -7
  263. mirascope/api/_generated/token_cost/client.py +0 -160
  264. mirascope/api/_generated/token_cost/raw_client.py +0 -264
  265. mirascope/api/_generated/token_cost/types/__init__.py +0 -8
  266. mirascope/api/_generated/token_cost/types/token_cost_calculate_request_usage.py +0 -54
  267. mirascope/api/_generated/token_cost/types/token_cost_calculate_response.py +0 -52
  268. mirascope/api/_generated/traces/__init__.py +0 -97
  269. mirascope/api/_generated/traces/client.py +0 -1103
  270. mirascope/api/_generated/traces/raw_client.py +0 -2322
  271. mirascope/api/_generated/traces/types/__init__.py +0 -155
  272. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item.py +0 -29
  273. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource.py +0 -27
  274. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item.py +0 -23
  275. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value.py +0 -38
  276. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_array_value.py +0 -19
  277. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value.py +0 -22
  278. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value_values_item.py +0 -20
  279. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item.py +0 -29
  280. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope.py +0 -31
  281. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item.py +0 -23
  282. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value.py +0 -38
  283. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_array_value.py +0 -19
  284. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value.py +0 -22
  285. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value_values_item.py +0 -22
  286. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item.py +0 -48
  287. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item.py +0 -23
  288. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value.py +0 -38
  289. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_array_value.py +0 -19
  290. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value.py +0 -24
  291. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value_values_item.py +0 -22
  292. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_status.py +0 -20
  293. mirascope/api/_generated/traces/types/traces_create_response.py +0 -24
  294. mirascope/api/_generated/traces/types/traces_create_response_partial_success.py +0 -22
  295. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response.py +0 -60
  296. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_functions_item.py +0 -24
  297. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_models_item.py +0 -22
  298. mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response.py +0 -33
  299. mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response_spans_item.py +0 -88
  300. mirascope/api/_generated/traces/types/traces_get_trace_detail_response.py +0 -33
  301. mirascope/api/_generated/traces/types/traces_get_trace_detail_response_spans_item.py +0 -88
  302. mirascope/api/_generated/traces/types/traces_list_by_function_hash_response.py +0 -25
  303. mirascope/api/_generated/traces/types/traces_list_by_function_hash_response_traces_item.py +0 -44
  304. mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item.py +0 -26
  305. mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item_operator.py +0 -7
  306. mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_by.py +0 -7
  307. mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_order.py +0 -7
  308. mirascope/api/_generated/traces/types/traces_search_by_env_response.py +0 -26
  309. mirascope/api/_generated/traces/types/traces_search_by_env_response_spans_item.py +0 -50
  310. mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item.py +0 -26
  311. mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item_operator.py +0 -7
  312. mirascope/api/_generated/traces/types/traces_search_request_sort_by.py +0 -7
  313. mirascope/api/_generated/traces/types/traces_search_request_sort_order.py +0 -5
  314. mirascope/api/_generated/traces/types/traces_search_response.py +0 -26
  315. mirascope/api/_generated/traces/types/traces_search_response_spans_item.py +0 -50
  316. mirascope/api/_generated/types/__init__.py +0 -85
  317. mirascope/api/_generated/types/already_exists_error.py +0 -22
  318. mirascope/api/_generated/types/already_exists_error_tag.py +0 -5
  319. mirascope/api/_generated/types/bad_request_error_body.py +0 -50
  320. mirascope/api/_generated/types/click_house_error.py +0 -22
  321. mirascope/api/_generated/types/database_error.py +0 -22
  322. mirascope/api/_generated/types/database_error_tag.py +0 -5
  323. mirascope/api/_generated/types/date.py +0 -3
  324. mirascope/api/_generated/types/http_api_decode_error.py +0 -27
  325. mirascope/api/_generated/types/http_api_decode_error_tag.py +0 -5
  326. mirascope/api/_generated/types/immutable_resource_error.py +0 -22
  327. mirascope/api/_generated/types/internal_server_error_body.py +0 -49
  328. mirascope/api/_generated/types/issue.py +0 -38
  329. mirascope/api/_generated/types/issue_tag.py +0 -10
  330. mirascope/api/_generated/types/not_found_error_body.py +0 -22
  331. mirascope/api/_generated/types/not_found_error_tag.py +0 -5
  332. mirascope/api/_generated/types/number_from_string.py +0 -3
  333. mirascope/api/_generated/types/permission_denied_error.py +0 -22
  334. mirascope/api/_generated/types/permission_denied_error_tag.py +0 -5
  335. mirascope/api/_generated/types/plan_limit_exceeded_error.py +0 -32
  336. mirascope/api/_generated/types/plan_limit_exceeded_error_tag.py +0 -7
  337. mirascope/api/_generated/types/pricing_unavailable_error.py +0 -23
  338. mirascope/api/_generated/types/property_key.py +0 -7
  339. mirascope/api/_generated/types/property_key_key.py +0 -25
  340. mirascope/api/_generated/types/property_key_key_tag.py +0 -5
  341. mirascope/api/_generated/types/rate_limit_error.py +0 -31
  342. mirascope/api/_generated/types/rate_limit_error_tag.py +0 -5
  343. mirascope/api/_generated/types/service_unavailable_error_body.py +0 -24
  344. mirascope/api/_generated/types/service_unavailable_error_tag.py +0 -7
  345. mirascope/api/_generated/types/stripe_error.py +0 -20
  346. mirascope/api/_generated/types/subscription_past_due_error.py +0 -31
  347. mirascope/api/_generated/types/subscription_past_due_error_tag.py +0 -7
  348. mirascope/api/_generated/types/unauthorized_error_body.py +0 -21
  349. mirascope/api/_generated/types/unauthorized_error_tag.py +0 -5
  350. mirascope/api/client.py +0 -255
  351. mirascope/api/settings.py +0 -99
  352. mirascope/llm/formatting/output_parser.py +0 -178
  353. mirascope/llm/formatting/primitives.py +0 -192
  354. mirascope/llm/mcp/mcp_client.py +0 -130
  355. mirascope/llm/messages/_utils.py +0 -34
  356. mirascope/llm/models/thinking_config.py +0 -61
  357. mirascope/llm/prompts/prompts.py +0 -487
  358. mirascope/llm/providers/__init__.py +0 -62
  359. mirascope/llm/providers/anthropic/__init__.py +0 -11
  360. mirascope/llm/providers/anthropic/_utils/__init__.py +0 -27
  361. mirascope/llm/providers/anthropic/_utils/beta_decode.py +0 -282
  362. mirascope/llm/providers/anthropic/_utils/beta_encode.py +0 -266
  363. mirascope/llm/providers/anthropic/_utils/encode.py +0 -418
  364. mirascope/llm/providers/anthropic/_utils/errors.py +0 -46
  365. mirascope/llm/providers/anthropic/beta_provider.py +0 -374
  366. mirascope/llm/providers/anthropic/model_id.py +0 -23
  367. mirascope/llm/providers/anthropic/model_info.py +0 -87
  368. mirascope/llm/providers/anthropic/provider.py +0 -479
  369. mirascope/llm/providers/google/__init__.py +0 -6
  370. mirascope/llm/providers/google/_utils/errors.py +0 -50
  371. mirascope/llm/providers/google/model_id.py +0 -22
  372. mirascope/llm/providers/google/model_info.py +0 -63
  373. mirascope/llm/providers/google/provider.py +0 -492
  374. mirascope/llm/providers/mirascope/__init__.py +0 -5
  375. mirascope/llm/providers/mirascope/_utils.py +0 -73
  376. mirascope/llm/providers/mirascope/provider.py +0 -349
  377. mirascope/llm/providers/mlx/__init__.py +0 -9
  378. mirascope/llm/providers/mlx/_utils.py +0 -141
  379. mirascope/llm/providers/mlx/encoding/__init__.py +0 -8
  380. mirascope/llm/providers/mlx/encoding/base.py +0 -72
  381. mirascope/llm/providers/mlx/encoding/transformers.py +0 -150
  382. mirascope/llm/providers/mlx/mlx.py +0 -254
  383. mirascope/llm/providers/mlx/model_id.py +0 -17
  384. mirascope/llm/providers/mlx/provider.py +0 -452
  385. mirascope/llm/providers/model_id.py +0 -16
  386. mirascope/llm/providers/ollama/__init__.py +0 -7
  387. mirascope/llm/providers/ollama/provider.py +0 -71
  388. mirascope/llm/providers/openai/__init__.py +0 -15
  389. mirascope/llm/providers/openai/_utils/__init__.py +0 -5
  390. mirascope/llm/providers/openai/_utils/errors.py +0 -46
  391. mirascope/llm/providers/openai/completions/__init__.py +0 -7
  392. mirascope/llm/providers/openai/completions/base_provider.py +0 -542
  393. mirascope/llm/providers/openai/completions/provider.py +0 -22
  394. mirascope/llm/providers/openai/model_id.py +0 -31
  395. mirascope/llm/providers/openai/model_info.py +0 -303
  396. mirascope/llm/providers/openai/provider.py +0 -441
  397. mirascope/llm/providers/openai/responses/__init__.py +0 -5
  398. mirascope/llm/providers/openai/responses/provider.py +0 -513
  399. mirascope/llm/providers/provider_id.py +0 -24
  400. mirascope/llm/providers/provider_registry.py +0 -299
  401. mirascope/llm/providers/together/__init__.py +0 -7
  402. mirascope/llm/providers/together/provider.py +0 -40
  403. mirascope/llm/responses/usage.py +0 -95
  404. mirascope/ops/__init__.py +0 -111
  405. mirascope/ops/_internal/__init__.py +0 -5
  406. mirascope/ops/_internal/closure.py +0 -1169
  407. mirascope/ops/_internal/configuration.py +0 -177
  408. mirascope/ops/_internal/context.py +0 -76
  409. mirascope/ops/_internal/exporters/__init__.py +0 -26
  410. mirascope/ops/_internal/exporters/exporters.py +0 -395
  411. mirascope/ops/_internal/exporters/processors.py +0 -104
  412. mirascope/ops/_internal/exporters/types.py +0 -165
  413. mirascope/ops/_internal/exporters/utils.py +0 -29
  414. mirascope/ops/_internal/instrumentation/__init__.py +0 -8
  415. mirascope/ops/_internal/instrumentation/llm/__init__.py +0 -8
  416. mirascope/ops/_internal/instrumentation/llm/common.py +0 -530
  417. mirascope/ops/_internal/instrumentation/llm/cost.py +0 -190
  418. mirascope/ops/_internal/instrumentation/llm/encode.py +0 -238
  419. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/__init__.py +0 -38
  420. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_input_messages.py +0 -31
  421. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_output_messages.py +0 -38
  422. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_system_instructions.py +0 -18
  423. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/shared.py +0 -100
  424. mirascope/ops/_internal/instrumentation/llm/llm.py +0 -161
  425. mirascope/ops/_internal/instrumentation/llm/model.py +0 -1798
  426. mirascope/ops/_internal/instrumentation/llm/response.py +0 -521
  427. mirascope/ops/_internal/instrumentation/llm/serialize.py +0 -300
  428. mirascope/ops/_internal/propagation.py +0 -198
  429. mirascope/ops/_internal/protocols.py +0 -133
  430. mirascope/ops/_internal/session.py +0 -139
  431. mirascope/ops/_internal/spans.py +0 -232
  432. mirascope/ops/_internal/traced_calls.py +0 -375
  433. mirascope/ops/_internal/traced_functions.py +0 -523
  434. mirascope/ops/_internal/tracing.py +0 -353
  435. mirascope/ops/_internal/types.py +0 -13
  436. mirascope/ops/_internal/utils.py +0 -123
  437. mirascope/ops/_internal/versioned_calls.py +0 -512
  438. mirascope/ops/_internal/versioned_functions.py +0 -357
  439. mirascope/ops/_internal/versioning.py +0 -303
  440. mirascope/ops/exceptions.py +0 -21
  441. mirascope-2.0.0.dist-info/RECORD +0 -423
  442. /mirascope/llm/{providers → clients}/base/kwargs.py +0 -0
  443. /mirascope/llm/{providers → clients}/google/message.py +0 -0
@@ -0,0 +1,47 @@
1
+ """Utilities for handling optional provider dependencies."""
2
+
3
+ from collections.abc import Callable
4
+
5
+
6
+ def create_import_error_stub(
7
+ package_name: str, client_name: str
8
+ ) -> Callable: # pragma: no cover
9
+ """Create a stub that raises ImportError when called.
10
+
11
+ Args:
12
+ package_name: The package/extra name (e.g., "anthropic", "openai", "google")
13
+ client_name: The client name for the error message (e.g., "AnthropicClient")
14
+
15
+ Returns:
16
+ A callable that raises `ImportError` with helpful message.
17
+ """
18
+
19
+ def _raise_not_installed() -> None:
20
+ raise ImportError(
21
+ f"The '{package_name}' package is required to use {client_name}. "
22
+ f"Install it with: `uv add 'mirascope[{package_name}]'`. "
23
+ "Or use `uv add 'mirascope[all]'` to support all providers."
24
+ )
25
+
26
+ return _raise_not_installed
27
+
28
+
29
+ def create_client_stub(package_name: str, client_name: str) -> type: # pragma: no cover
30
+ """Create a stub client class that raises ImportError when instantiated.
31
+
32
+ Args:
33
+ package_name: The package/extra name (e.g., "anthropic", "openai", "google")
34
+ client_name: The client name for the error message (e.g., "AnthropicClient")
35
+
36
+ Returns:
37
+ A stub class that raises `ImportError` on instantiation.
38
+ """
39
+ error_fn = create_import_error_stub(package_name, client_name)
40
+
41
+ class _ClientStub:
42
+ """Stub client that raises `ImportError` when instantiated."""
43
+
44
+ def __init__(self) -> None:
45
+ error_fn()
46
+
47
+ return _ClientStub
@@ -0,0 +1,25 @@
1
+ """Anthropic client implementation."""
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ if TYPE_CHECKING:
6
+ from .clients import AnthropicClient, client, get_client
7
+ from .model_ids import AnthropicModelId
8
+ else:
9
+ try:
10
+ from .clients import AnthropicClient, client, get_client
11
+ from .model_ids import AnthropicModelId
12
+ except ImportError: # pragma: no cover
13
+ from .._missing_import_stubs import create_client_stub, create_import_error_stub
14
+
15
+ AnthropicClient = create_client_stub("anthropic", "AnthropicClient")
16
+ AnthropicModelId = str
17
+ client = create_import_error_stub("anthropic", "AnthropicClient")
18
+ get_client = create_import_error_stub("anthropic", "AnthropicClient")
19
+
20
+ __all__ = [
21
+ "AnthropicClient",
22
+ "AnthropicModelId",
23
+ "client",
24
+ "get_client",
25
+ ]
@@ -2,7 +2,6 @@ from .decode import (
2
2
  decode_async_stream,
3
3
  decode_response,
4
4
  decode_stream,
5
- model_name,
6
5
  )
7
6
  from .encode import encode_request
8
7
 
@@ -11,5 +10,4 @@ __all__ = [
11
10
  "decode_response",
12
11
  "decode_stream",
13
12
  "encode_request",
14
- "model_name",
15
13
  ]
@@ -1,11 +1,10 @@
1
- """Standard Anthropic response decoding."""
1
+ """Anthropic response decoding."""
2
2
 
3
3
  import json
4
4
  from typing import Any, TypeAlias, cast
5
5
 
6
6
  from anthropic import types as anthropic_types
7
7
  from anthropic.lib.streaming import AsyncMessageStreamManager, MessageStreamManager
8
- from anthropic.types.beta import BetaUsage
9
8
 
10
9
  from ....content import (
11
10
  AssistantContentPart,
@@ -30,10 +29,8 @@ from ....responses import (
30
29
  FinishReasonChunk,
31
30
  RawMessageChunk,
32
31
  RawStreamEventChunk,
33
- Usage,
34
- UsageDeltaChunk,
35
32
  )
36
- from ..model_id import AnthropicModelId, model_name
33
+ from ..model_ids import AnthropicModelId
37
34
 
38
35
  ANTHROPIC_FINISH_REASON_MAP = {
39
36
  "max_tokens": FinishReason.MAX_TOKENS,
@@ -61,40 +58,15 @@ def _decode_assistant_content(
61
58
  )
62
59
 
63
60
 
64
- def decode_usage(
65
- usage: anthropic_types.Usage | BetaUsage,
66
- ) -> Usage:
67
- """Convert Anthropic Usage (or BetaUsage) to Mirascope Usage."""
68
-
69
- cache_read_tokens = usage.cache_read_input_tokens or 0
70
- cache_write_tokens = usage.cache_creation_input_tokens or 0
71
- input_tokens = usage.input_tokens + cache_read_tokens + cache_write_tokens
72
- output_tokens = usage.output_tokens
73
- return Usage(
74
- input_tokens=input_tokens,
75
- output_tokens=output_tokens,
76
- cache_read_tokens=cache_read_tokens,
77
- cache_write_tokens=cache_write_tokens,
78
- reasoning_tokens=0,
79
- raw=usage,
80
- )
81
-
82
-
83
61
  def decode_response(
84
62
  response: anthropic_types.Message,
85
63
  model_id: AnthropicModelId,
86
- *,
87
- include_thoughts: bool,
88
- ) -> tuple[AssistantMessage, FinishReason | None, Usage]:
89
- """Convert Anthropic message to mirascope AssistantMessage and usage."""
90
- content = [_decode_assistant_content(part) for part in response.content]
91
- if not include_thoughts:
92
- content = [part for part in content if part.type != "thought"]
64
+ ) -> tuple[AssistantMessage, FinishReason | None]:
65
+ """Convert Anthropic message to mirascope AssistantMessage."""
93
66
  assistant_message = AssistantMessage(
94
- content=content,
95
- provider_id="anthropic",
67
+ content=[_decode_assistant_content(part) for part in response.content],
68
+ provider="anthropic",
96
69
  model_id=model_id,
97
- provider_model_name=model_name(model_id),
98
70
  raw_message={
99
71
  "role": response.role,
100
72
  "content": [part.model_dump() for part in response.content],
@@ -105,14 +77,14 @@ def decode_response(
105
77
  if response.stop_reason
106
78
  else None
107
79
  )
108
- usage = decode_usage(response.usage)
109
- return assistant_message, finish_reason, usage
80
+ return assistant_message, finish_reason
110
81
 
111
82
 
112
83
  ContentBlock: TypeAlias = (
113
84
  anthropic_types.TextBlockParam
114
85
  | anthropic_types.ThinkingBlockParam
115
86
  | anthropic_types.ToolUseBlockParam
87
+ | anthropic_types.ThinkingBlockParam
116
88
  | anthropic_types.RedactedThinkingBlockParam
117
89
  )
118
90
 
@@ -120,11 +92,10 @@ ContentBlock: TypeAlias = (
120
92
  class _AnthropicChunkProcessor:
121
93
  """Processes Anthropic stream events and maintains state across events."""
122
94
 
123
- def __init__(self, *, include_thoughts: bool) -> None:
95
+ def __init__(self) -> None:
124
96
  self.current_block_param: ContentBlock | None = None
125
97
  self.accumulated_tool_json: str = ""
126
98
  self.accumulated_blocks: list[ContentBlock] = []
127
- self.include_thoughts = include_thoughts
128
99
 
129
100
  def process_event(
130
101
  self, event: anthropic_types.RawMessageStreamEvent
@@ -159,8 +130,7 @@ class _AnthropicChunkProcessor:
159
130
  "thinking": "",
160
131
  "signature": "",
161
132
  }
162
- if self.include_thoughts:
163
- yield ThoughtStartChunk()
133
+ yield ThoughtStartChunk()
164
134
  elif content_block.type == "redacted_thinking": # pragma: no cover
165
135
  self.current_block_param = {
166
136
  "type": "redacted_thinking",
@@ -187,17 +157,14 @@ class _AnthropicChunkProcessor:
187
157
  f"Received input_json_delta for {self.current_block_param['type']} block"
188
158
  )
189
159
  self.accumulated_tool_json += delta.partial_json
190
- yield ToolCallChunk(
191
- id=self.current_block_param["id"], delta=delta.partial_json
192
- )
160
+ yield ToolCallChunk(delta=delta.partial_json)
193
161
  elif delta.type == "thinking_delta":
194
162
  if self.current_block_param["type"] != "thinking": # pragma: no cover
195
163
  raise RuntimeError(
196
164
  f"Received thinking_delta for {self.current_block_param['type']} block"
197
165
  )
198
166
  self.current_block_param["thinking"] += delta.thinking
199
- if self.include_thoughts:
200
- yield ThoughtChunk(delta=delta.thinking)
167
+ yield ThoughtChunk(delta=delta.thinking)
201
168
  elif delta.type == "signature_delta":
202
169
  if self.current_block_param["type"] != "thinking": # pragma: no cover
203
170
  raise RuntimeError(
@@ -227,10 +194,9 @@ class _AnthropicChunkProcessor:
227
194
  if self.accumulated_tool_json
228
195
  else {}
229
196
  )
230
- yield ToolCallEndChunk(id=self.current_block_param["id"])
197
+ yield ToolCallEndChunk()
231
198
  elif block_type == "thinking":
232
- if self.include_thoughts:
233
- yield ThoughtEndChunk()
199
+ yield ThoughtEndChunk()
234
200
  else:
235
201
  raise NotImplementedError
236
202
 
@@ -243,16 +209,6 @@ class _AnthropicChunkProcessor:
243
209
  if finish_reason is not None:
244
210
  yield FinishReasonChunk(finish_reason=finish_reason)
245
211
 
246
- # Emit usage delta
247
- usage = event.usage
248
- yield UsageDeltaChunk(
249
- input_tokens=usage.input_tokens or 0,
250
- output_tokens=usage.output_tokens,
251
- cache_read_tokens=usage.cache_read_input_tokens or 0,
252
- cache_write_tokens=usage.cache_creation_input_tokens or 0,
253
- reasoning_tokens=0,
254
- )
255
-
256
212
  def raw_message_chunk(self) -> RawMessageChunk:
257
213
  return RawMessageChunk(
258
214
  raw_message=cast(
@@ -266,23 +222,23 @@ class _AnthropicChunkProcessor:
266
222
 
267
223
 
268
224
  def decode_stream(
269
- anthropic_stream_manager: MessageStreamManager, *, include_thoughts: bool
225
+ anthropic_stream_manager: MessageStreamManager,
270
226
  ) -> ChunkIterator:
271
- """Returns a ChunkIterator converted from an Anthropic MessageStreamManager."""
272
- processor = _AnthropicChunkProcessor(include_thoughts=include_thoughts)
227
+ """Returns a ChunkIterator converted from an Anthropic MessageStreamManager"""
228
+ processor = _AnthropicChunkProcessor()
273
229
  with anthropic_stream_manager as stream:
274
- for event in stream._raw_stream: # pyright: ignore[reportPrivateUsage]
230
+ for event in stream._raw_stream:
275
231
  yield from processor.process_event(event)
276
232
  yield processor.raw_message_chunk()
277
233
 
278
234
 
279
235
  async def decode_async_stream(
280
- anthropic_stream_manager: AsyncMessageStreamManager, *, include_thoughts: bool
236
+ anthropic_stream_manager: AsyncMessageStreamManager,
281
237
  ) -> AsyncChunkIterator:
282
- """Returns an AsyncChunkIterator converted from an Anthropic MessageStreamManager."""
283
- processor = _AnthropicChunkProcessor(include_thoughts=include_thoughts)
238
+ """Returns an AsyncChunkIterator converted from an Anthropic MessageStreamManager"""
239
+ processor = _AnthropicChunkProcessor()
284
240
  async with anthropic_stream_manager as stream:
285
- async for event in stream._raw_stream: # pyright: ignore[reportPrivateUsage]
241
+ async for event in stream._raw_stream:
286
242
  for item in processor.process_event(event):
287
243
  yield item
288
244
  yield processor.raw_message_chunk()
@@ -0,0 +1,243 @@
1
+ """Anthropic message encoding and request preparation."""
2
+
3
+ import json
4
+ from collections.abc import Sequence
5
+ from functools import lru_cache
6
+ from typing import Literal, TypedDict, cast
7
+ from typing_extensions import Required
8
+
9
+ from anthropic import Omit, types as anthropic_types
10
+
11
+ from ....content import ContentPart, ImageMimeType
12
+ from ....exceptions import FeatureNotSupportedError, FormattingModeNotSupportedError
13
+ from ....formatting import (
14
+ Format,
15
+ FormattableT,
16
+ _utils as _formatting_utils,
17
+ resolve_format,
18
+ )
19
+ from ....messages import AssistantMessage, Message, UserMessage
20
+ from ....tools import FORMAT_TOOL_NAME, BaseToolkit, ToolSchema
21
+ from ...base import Params, _utils as _base_utils
22
+ from ..model_ids import AnthropicModelId
23
+
24
+ DEFAULT_MAX_TOKENS = 16000
25
+
26
+ AnthropicImageMimeType = Literal["image/jpeg", "image/png", "image/gif", "image/webp"]
27
+
28
+
29
+ def encode_image_mime_type(
30
+ mime_type: ImageMimeType,
31
+ ) -> AnthropicImageMimeType:
32
+ """Convert an ImageMimeType into anthropic supported mime type"""
33
+ if mime_type in ("image/jpeg", "image/png", "image/gif", "image/webp"):
34
+ return mime_type
35
+ raise FeatureNotSupportedError(
36
+ feature=f"Image with mime_type: {mime_type}", provider="anthropic"
37
+ ) # pragma: no cover
38
+
39
+
40
+ class MessageCreateKwargs(TypedDict, total=False):
41
+ """Kwargs for Anthropic Message.create method."""
42
+
43
+ model: Required[str]
44
+ max_tokens: Required[int]
45
+ messages: Sequence[anthropic_types.MessageParam]
46
+ system: str | Omit
47
+ tools: Sequence[anthropic_types.ToolParam] | Omit
48
+ tool_choice: anthropic_types.ToolChoiceParam | Omit
49
+ temperature: float | Omit
50
+ top_p: float | Omit
51
+ top_k: int | Omit
52
+ stop_sequences: list[str] | Omit
53
+ thinking: anthropic_types.ThinkingConfigParam | Omit
54
+
55
+
56
+ def _encode_content(
57
+ content: Sequence[ContentPart], encode_thoughts: bool
58
+ ) -> str | Sequence[anthropic_types.ContentBlockParam]:
59
+ """Convert mirascope content to Anthropic content format."""
60
+
61
+ if len(content) == 1 and content[0].type == "text":
62
+ return content[0].text
63
+
64
+ blocks: list[anthropic_types.ContentBlockParam] = []
65
+
66
+ for part in content:
67
+ if part.type == "text":
68
+ blocks.append(anthropic_types.TextBlockParam(type="text", text=part.text))
69
+ elif part.type == "image":
70
+ source: (
71
+ anthropic_types.Base64ImageSourceParam
72
+ | anthropic_types.URLImageSourceParam
73
+ )
74
+ if part.source.type == "base64_image_source":
75
+ source = anthropic_types.Base64ImageSourceParam(
76
+ type="base64",
77
+ media_type=encode_image_mime_type(part.source.mime_type),
78
+ data=part.source.data,
79
+ )
80
+ else: # url_image_source
81
+ source = anthropic_types.URLImageSourceParam(
82
+ type="url",
83
+ url=part.source.url,
84
+ )
85
+ blocks.append(anthropic_types.ImageBlockParam(type="image", source=source))
86
+ elif part.type == "audio":
87
+ raise FeatureNotSupportedError(
88
+ "audio input",
89
+ "anthropic",
90
+ message="Anthropic does not support audio inputs.",
91
+ )
92
+ elif part.type == "tool_output":
93
+ blocks.append(
94
+ anthropic_types.ToolResultBlockParam(
95
+ type="tool_result",
96
+ tool_use_id=part.id,
97
+ content=str(part.value),
98
+ )
99
+ )
100
+ elif part.type == "tool_call":
101
+ blocks.append(
102
+ anthropic_types.ToolUseBlockParam(
103
+ type="tool_use",
104
+ id=part.id,
105
+ name=part.name,
106
+ input=json.loads(part.args),
107
+ )
108
+ )
109
+ elif part.type == "thought":
110
+ if encode_thoughts:
111
+ blocks.append(
112
+ anthropic_types.TextBlockParam(
113
+ type="text", text="**Thinking:** " + part.thought
114
+ )
115
+ )
116
+ else:
117
+ raise NotImplementedError(f"Unsupported content type: {part.type}")
118
+
119
+ return blocks
120
+
121
+
122
+ def _encode_message(
123
+ message: UserMessage | AssistantMessage,
124
+ model_id: AnthropicModelId,
125
+ encode_thoughts: bool,
126
+ ) -> anthropic_types.MessageParam:
127
+ """Convert user or assistant `Message`s to Anthropic `MessageParam` format.
128
+
129
+ Args:
130
+ messages: A Sequence containing `UserMessage`s or `AssistantMessage`s
131
+ model_id: The Anthropic model ID being used
132
+
133
+ Returns:
134
+ A Sequence of converted Anthropic `MessageParam`
135
+ """
136
+
137
+ if (
138
+ message.role == "assistant"
139
+ and message.provider == "anthropic"
140
+ and message.model_id == model_id
141
+ and message.raw_message
142
+ and not encode_thoughts
143
+ ):
144
+ return cast(anthropic_types.MessageParam, message.raw_message)
145
+ return {
146
+ "role": message.role,
147
+ "content": _encode_content(message.content, encode_thoughts),
148
+ }
149
+
150
+
151
+ @lru_cache(maxsize=128)
152
+ def _convert_tool_to_tool_param(tool: ToolSchema) -> anthropic_types.ToolParam:
153
+ """Convert a single Mirascope tool to Anthropic tool format with caching."""
154
+ schema_dict = tool.parameters.model_dump(by_alias=True, exclude_none=True)
155
+ schema_dict["type"] = "object"
156
+ return anthropic_types.ToolParam(
157
+ name=tool.name,
158
+ description=tool.description,
159
+ input_schema=schema_dict,
160
+ )
161
+
162
+
163
+ def encode_request(
164
+ *,
165
+ model_id: AnthropicModelId,
166
+ messages: Sequence[Message],
167
+ tools: Sequence[ToolSchema] | BaseToolkit | None,
168
+ format: type[FormattableT] | Format[FormattableT] | None,
169
+ params: Params,
170
+ ) -> tuple[Sequence[Message], Format[FormattableT] | None, MessageCreateKwargs]:
171
+ """Prepares a request for the `Anthropic.messages.create` method."""
172
+ kwargs: MessageCreateKwargs = MessageCreateKwargs(
173
+ {
174
+ "model": model_id,
175
+ "max_tokens": DEFAULT_MAX_TOKENS,
176
+ }
177
+ )
178
+ encode_thoughts = False
179
+
180
+ with _base_utils.ensure_all_params_accessed(
181
+ params=params, provider="anthropic", unsupported_params=["seed"]
182
+ ) as param_accessor:
183
+ if param_accessor.temperature is not None:
184
+ kwargs["temperature"] = param_accessor.temperature
185
+ if param_accessor.max_tokens is not None:
186
+ kwargs["max_tokens"] = param_accessor.max_tokens
187
+ if param_accessor.top_p is not None:
188
+ kwargs["top_p"] = param_accessor.top_p
189
+ if param_accessor.top_k is not None:
190
+ kwargs["top_k"] = param_accessor.top_k
191
+ if param_accessor.stop_sequences is not None:
192
+ kwargs["stop_sequences"] = param_accessor.stop_sequences
193
+ if param_accessor.thinking is not None:
194
+ if param_accessor.thinking:
195
+ # Set budget to 50% of max_tokens with minimum of 1024
196
+ budget_tokens = max(1024, kwargs["max_tokens"] // 2)
197
+ kwargs["thinking"] = {"type": "enabled", "budget_tokens": budget_tokens}
198
+ else:
199
+ kwargs["thinking"] = {"type": "disabled"}
200
+ if param_accessor.encode_thoughts_as_text:
201
+ encode_thoughts = True
202
+
203
+ tools = tools.tools if isinstance(tools, BaseToolkit) else tools or []
204
+ anthropic_tools = [_convert_tool_to_tool_param(tool) for tool in tools]
205
+ format = resolve_format(format, default_mode="tool")
206
+ if format is not None:
207
+ if format.mode == "strict":
208
+ raise FormattingModeNotSupportedError(
209
+ formatting_mode="strict", provider="anthropic"
210
+ )
211
+ elif format.mode == "tool":
212
+ format_tool_schema = _formatting_utils.create_tool_schema(format)
213
+ anthropic_tools.append(_convert_tool_to_tool_param(format_tool_schema))
214
+ if tools:
215
+ kwargs["tool_choice"] = {"type": "any"}
216
+ else:
217
+ kwargs["tool_choice"] = {
218
+ "type": "tool",
219
+ "name": FORMAT_TOOL_NAME,
220
+ "disable_parallel_tool_use": True,
221
+ }
222
+
223
+ if format.formatting_instructions:
224
+ messages = _base_utils.add_system_instructions(
225
+ messages, format.formatting_instructions
226
+ )
227
+
228
+ if anthropic_tools:
229
+ kwargs["tools"] = anthropic_tools
230
+
231
+ system_message_content, remaining_messages = _base_utils.extract_system_message(
232
+ messages
233
+ )
234
+
235
+ kwargs["messages"] = [
236
+ _encode_message(remaining_message, model_id, encode_thoughts)
237
+ for remaining_message in remaining_messages
238
+ ]
239
+
240
+ if system_message_content:
241
+ kwargs["system"] = system_message_content
242
+
243
+ return messages, format, kwargs