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,360 @@
1
+ """Mirascope llm exception hierarchy for unified error handling across providers."""
2
+
3
+ import json
4
+ from typing import TYPE_CHECKING
5
+
6
+ from pydantic import ValidationError
7
+
8
+ if TYPE_CHECKING:
9
+ from .providers import ModelId, ProviderId
10
+
11
+
12
+ class Error(Exception):
13
+ """Base exception for all Mirascope LLM errors."""
14
+
15
+
16
+ class ProviderError(Error):
17
+ """Base class for errors that originate from a provider SDK.
18
+
19
+ This wraps exceptions from provider libraries (OpenAI, Anthropic, etc.)
20
+ and provides a unified interface for error handling.
21
+ """
22
+
23
+ provider: "ProviderId"
24
+ """The provider that raised this error."""
25
+
26
+ original_exception: Exception | None
27
+ """The original exception from the provider SDK, if available."""
28
+
29
+ def __init__(
30
+ self,
31
+ message: str,
32
+ provider: "ProviderId",
33
+ original_exception: Exception | None = None,
34
+ ) -> None:
35
+ super().__init__(message)
36
+ self.provider = provider
37
+ self.original_exception = original_exception
38
+ if original_exception is not None:
39
+ self.__cause__ = original_exception
40
+
41
+
42
+ class APIError(ProviderError):
43
+ """Base class for HTTP-level API errors."""
44
+
45
+ status_code: int | None
46
+ """The HTTP status code, if available."""
47
+
48
+ def __init__(
49
+ self,
50
+ message: str,
51
+ provider: "ProviderId",
52
+ status_code: int | None = None,
53
+ original_exception: Exception | None = None,
54
+ ) -> None:
55
+ super().__init__(message, provider, original_exception)
56
+ self.status_code = status_code
57
+
58
+
59
+ class AuthenticationError(APIError):
60
+ """Raised for authentication failures (401, invalid API keys)."""
61
+
62
+ def __init__(
63
+ self,
64
+ message: str,
65
+ provider: "ProviderId",
66
+ status_code: int | None = None,
67
+ original_exception: Exception | None = None,
68
+ ) -> None:
69
+ super().__init__(
70
+ message,
71
+ provider,
72
+ status_code=status_code or 401,
73
+ original_exception=original_exception,
74
+ )
75
+
76
+
77
+ class PermissionError(APIError):
78
+ """Raised for permission/authorization failures (403)."""
79
+
80
+ def __init__(
81
+ self,
82
+ message: str,
83
+ provider: "ProviderId",
84
+ status_code: int | None = None,
85
+ original_exception: Exception | None = None,
86
+ ) -> None:
87
+ super().__init__(
88
+ message,
89
+ provider,
90
+ status_code=status_code or 403,
91
+ original_exception=original_exception,
92
+ )
93
+
94
+
95
+ class BadRequestError(APIError):
96
+ """Raised for malformed requests (400, 422)."""
97
+
98
+ def __init__(
99
+ self,
100
+ message: str,
101
+ provider: "ProviderId",
102
+ status_code: int | None = None,
103
+ original_exception: Exception | None = None,
104
+ ) -> None:
105
+ super().__init__(
106
+ message,
107
+ provider,
108
+ status_code=status_code or 400,
109
+ original_exception=original_exception,
110
+ )
111
+
112
+
113
+ class NotFoundError(APIError):
114
+ """Raised when requested resource is not found (404)."""
115
+
116
+ def __init__(
117
+ self,
118
+ message: str,
119
+ provider: "ProviderId",
120
+ status_code: int | None = None,
121
+ original_exception: Exception | None = None,
122
+ ) -> None:
123
+ super().__init__(
124
+ message,
125
+ provider,
126
+ status_code=status_code or 404,
127
+ original_exception=original_exception,
128
+ )
129
+
130
+
131
+ class RateLimitError(APIError):
132
+ """Raised when rate limits are exceeded (429)."""
133
+
134
+ def __init__(
135
+ self,
136
+ message: str,
137
+ provider: "ProviderId",
138
+ status_code: int | None = None,
139
+ original_exception: Exception | None = None,
140
+ ) -> None:
141
+ super().__init__(
142
+ message,
143
+ provider,
144
+ status_code=status_code or 429,
145
+ original_exception=original_exception,
146
+ )
147
+
148
+
149
+ class ServerError(APIError):
150
+ """Raised for server-side errors (500+)."""
151
+
152
+ def __init__(
153
+ self,
154
+ message: str,
155
+ provider: "ProviderId",
156
+ status_code: int | None = None,
157
+ original_exception: Exception | None = None,
158
+ ) -> None:
159
+ super().__init__(
160
+ message,
161
+ provider,
162
+ status_code=status_code or 500,
163
+ original_exception=original_exception,
164
+ )
165
+
166
+
167
+ class ConnectionError(ProviderError):
168
+ """Raised when unable to connect to the API (network issues, timeouts)."""
169
+
170
+
171
+ class TimeoutError(ProviderError):
172
+ """Raised when requests timeout or deadline exceeded."""
173
+
174
+
175
+ class ResponseValidationError(ProviderError):
176
+ """Raised when API response fails validation.
177
+
178
+ This wraps the APIResponseValidationErrors that OpenAI and Anthropic both return.
179
+ """
180
+
181
+
182
+ class ToolError(Error):
183
+ """Base class for errors that occur during tool execution."""
184
+
185
+
186
+ class ToolExecutionError(ToolError):
187
+ """Raised if an uncaught exception is thrown while executing a tool."""
188
+
189
+ tool_exception: Exception
190
+ """The exception that was thrown while executing the tool."""
191
+
192
+ def __init__(self, tool_exception: Exception | str) -> None:
193
+ if isinstance(tool_exception, str):
194
+ # Support string for snapshot reconstruction
195
+ message = tool_exception
196
+ tool_exception = ValueError(message)
197
+ else:
198
+ message = str(tool_exception)
199
+ super().__init__(message)
200
+ self.tool_exception = tool_exception
201
+ self.__cause__ = tool_exception
202
+
203
+ def __eq__(self, other: object) -> bool:
204
+ if not isinstance(other, ToolExecutionError):
205
+ return False
206
+ # Needed for snapshot tests.
207
+ return str(self) == str(other)
208
+
209
+
210
+ class ToolNotFoundError(ToolError):
211
+ """Raised if a tool call does not match any registered tool."""
212
+
213
+ tool_name: str
214
+ """The name of the tool that was not found."""
215
+
216
+ def __init__(self, tool_name: str) -> None:
217
+ super().__init__(f"Tool '{tool_name}' not found in registered tools")
218
+ self.tool_name = tool_name
219
+
220
+ def __repr__(self) -> str:
221
+ return f"ToolNotFoundError({self.tool_name!r})"
222
+
223
+ def __eq__(self, other: object) -> bool:
224
+ if not isinstance(other, ToolNotFoundError):
225
+ return NotImplemented
226
+ return self.tool_name == other.tool_name
227
+
228
+ def __hash__(self) -> int:
229
+ return hash((type(self), self.tool_name))
230
+
231
+
232
+ class ParseError(Error):
233
+ """Raised when response.parse() fails to parse the response content.
234
+
235
+ This wraps errors from JSON extraction, JSON parsing, Pydantic validation,
236
+ or custom OutputParser functions.
237
+ """
238
+
239
+ original_exception: Exception
240
+ """The original exception that caused the parse failure."""
241
+
242
+ def __init__(
243
+ self,
244
+ message: str,
245
+ original_exception: Exception,
246
+ ) -> None:
247
+ super().__init__(message)
248
+ self.original_exception = original_exception
249
+ self.__cause__ = original_exception
250
+
251
+ def retry_message(self) -> str:
252
+ """Generate a message suitable for retrying with the LLM.
253
+
254
+ Returns a user-friendly message describing what went wrong,
255
+ suitable for including in a retry prompt.
256
+ """
257
+
258
+ if isinstance(self.original_exception, ValidationError):
259
+ return (
260
+ f"Your response failed schema validation:\n"
261
+ f"{self.original_exception}\n\n"
262
+ "Please correct these issues and respond again."
263
+ )
264
+ elif isinstance(self.original_exception, json.JSONDecodeError):
265
+ # JSON syntax error
266
+ return (
267
+ "Your response could not be parsed because no valid JSON object "
268
+ "was found. Please ensure your response contains a JSON object "
269
+ "with opening '{' and closing '}' braces."
270
+ )
271
+ else:
272
+ # ValueError from JSON extraction, or OutputParser error
273
+ return (
274
+ f"Your response could not be parsed: {self.original_exception}\n\n"
275
+ "Please ensure your response matches the expected format."
276
+ )
277
+
278
+ def __eq__(self, other: object) -> bool:
279
+ if not isinstance(other, ParseError):
280
+ return False
281
+ return str(self) == str(other)
282
+
283
+
284
+ class FeatureNotSupportedError(Error):
285
+ """Raised if a Mirascope feature is unsupported by chosen provider.
286
+
287
+ If compatibility is model-specific, then `model_id` should be specified.
288
+ If the feature is not supported by the provider at all, then it may be `None`.
289
+ """
290
+
291
+ provider_id: "ProviderId"
292
+ model_id: "ModelId | None"
293
+ feature: str
294
+
295
+ def __init__(
296
+ self,
297
+ feature: str,
298
+ provider_id: "ProviderId",
299
+ model_id: "ModelId | None" = None,
300
+ message: str | None = None,
301
+ ) -> None:
302
+ if message is None:
303
+ model_msg = f" for model '{model_id}'" if model_id is not None else ""
304
+ message = f"Feature '{feature}' is not supported by provider '{provider_id}'{model_msg}"
305
+ super().__init__(message)
306
+ self.feature = feature
307
+ self.provider_id = provider_id
308
+ self.model_id = model_id
309
+
310
+
311
+ class NoRegisteredProviderError(Error):
312
+ """Raised when no provider is registered for a given model_id."""
313
+
314
+ model_id: str
315
+
316
+ def __init__(self, model_id: str) -> None:
317
+ message = (
318
+ f"No provider registered for model '{model_id}'. "
319
+ f"Use llm.register_provider() to register a provider for this model."
320
+ )
321
+ super().__init__(message)
322
+ self.model_id = model_id
323
+
324
+
325
+ class MissingAPIKeyError(Error):
326
+ """Raised when no API key is available for a provider.
327
+
328
+ This error is raised during auto-registration when the required API key
329
+ environment variable is not set. If a Mirascope fallback is available,
330
+ the error message will suggest using MIRASCOPE_API_KEY as an alternative.
331
+ """
332
+
333
+ provider_id: str
334
+ """The provider that requires an API key."""
335
+
336
+ env_var: str
337
+ """The environment variable that should contain the API key."""
338
+
339
+ def __init__(
340
+ self,
341
+ provider_id: str,
342
+ env_var: str,
343
+ has_mirascope_fallback: bool = False,
344
+ ) -> None:
345
+ if has_mirascope_fallback:
346
+ message = (
347
+ f"No API key found for {provider_id}. Either:\n"
348
+ f" 1. Set {env_var} environment variable, or\n"
349
+ f" 2. Set MIRASCOPE_API_KEY for cross-provider support "
350
+ f"via Mirascope Router\n"
351
+ f" (Learn more: https://mirascope.com/docs/router)"
352
+ )
353
+ else:
354
+ message = (
355
+ f"No API key found for {provider_id}. "
356
+ f"Set the {env_var} environment variable."
357
+ )
358
+ super().__init__(message)
359
+ self.provider_id = provider_id
360
+ self.env_var = env_var
@@ -0,0 +1,39 @@
1
+ """Response formatting interfaces for structuring LLM outputs.
2
+
3
+ This module provides a way to define structured output formats for LLM responses.
4
+ The `@format` decorator can be applied to classes to specify how LLM
5
+ outputs should be structured and parsed.
6
+
7
+ The `@output_parser` decorator can be used to create custom parsers for non-JSON
8
+ formats like XML, YAML, CSV, or any custom text structure.
9
+ """
10
+
11
+ from .format import Format, format, resolve_format
12
+ from .from_call_args import FromCallArgs
13
+ from .output_parser import OutputParser, is_output_parser, output_parser
14
+ from .partial import Partial
15
+ from .primitives import (
16
+ PrimitiveType,
17
+ PrimitiveWrapperModel,
18
+ create_wrapper_model,
19
+ is_primitive_type,
20
+ )
21
+ from .types import FormatSpec, FormattableT, FormattingMode
22
+
23
+ __all__ = [
24
+ "Format",
25
+ "FormatSpec",
26
+ "FormattableT",
27
+ "FormattingMode",
28
+ "FromCallArgs",
29
+ "OutputParser",
30
+ "Partial",
31
+ "PrimitiveType",
32
+ "PrimitiveWrapperModel",
33
+ "create_wrapper_model",
34
+ "format",
35
+ "is_output_parser",
36
+ "is_primitive_type",
37
+ "output_parser",
38
+ "resolve_format",
39
+ ]
@@ -0,0 +1,291 @@
1
+ """The `llm.format` decorator for defining response formats as classes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import inspect
6
+ import json
7
+ from dataclasses import dataclass
8
+ from typing import Any, Generic, cast
9
+
10
+ from ..tools import FORMAT_TOOL_NAME, ToolFn, ToolParameterSchema, ToolSchema
11
+ from ..types import NoneType
12
+ from .output_parser import OutputParser, is_output_parser
13
+ from .primitives import create_wrapper_model, is_primitive_type
14
+ from .types import FormatSpec, FormattableT, FormattingMode, HasFormattingInstructions
15
+
16
+ TOOL_MODE_INSTRUCTIONS = f"""Always respond to the user's query using the {FORMAT_TOOL_NAME} tool for structured output."""
17
+
18
+
19
+ JSON_MODE_INSTRUCTIONS = (
20
+ "Respond only with valid JSON that matches this exact schema:\n{json_schema}"
21
+ )
22
+
23
+
24
+ @dataclass(kw_only=True)
25
+ class Format(Generic[FormattableT]):
26
+ """Class representing a structured output format for LLM responses.
27
+
28
+ A `Format` contains metadata needed to describe a structured output type
29
+ to the LLM, including the expected schema. This class is not instantiated directly,
30
+ but is created by calling `llm.format`, or is automatically generated by LLM
31
+ providers when a `Formattable` is passed to a call method.
32
+
33
+ Example:
34
+
35
+ ```python
36
+ from mirascope import llm
37
+
38
+ class Book:
39
+ title: str
40
+ author: str
41
+
42
+ print(llm.format(Book, mode="tool"))
43
+ ```
44
+ """
45
+
46
+ name: str
47
+ """The name of the response format."""
48
+
49
+ description: str | None
50
+ """A description of the response format, if available."""
51
+
52
+ schema: dict[str, object]
53
+ """JSON schema representation of the structured output format."""
54
+
55
+ mode: FormattingMode
56
+ """The decorator-provided mode of the response format.
57
+
58
+ Determines how the LLM call may be modified in order to extract the expected format.
59
+ """
60
+
61
+ formattable: type[FormattableT] | OutputParser[FormattableT]
62
+ """The formattable type or custom output parser.
63
+
64
+ Can be one of:
65
+ - type[BaseModel]: A Pydantic model class for structured output
66
+ - PrimitiveType: A primitive type (str, int, list, etc.) for simple output
67
+ - OutputParser[FormattableT]: A custom parser created with @llm.output_parser
68
+
69
+ The type determines how the response will be parsed in response.parse().
70
+ OutputParser uses Any for the response type since it works with any response.
71
+ """
72
+
73
+ @property
74
+ def formatting_instructions(self) -> str | None:
75
+ """The formatting instructions that will be added to the LLM system prompt.
76
+
77
+ If the format has a custom `OutputParser`, its formatting instructions will be used.
78
+ Otherwise, if the format type has a `formatting_instructions` class method,
79
+ the output of that call will be used. Otherwise, instructions may be
80
+ auto-generated based on the formatting mode.
81
+ """
82
+ if is_output_parser(self.formattable) or isinstance(
83
+ self.formattable, HasFormattingInstructions
84
+ ):
85
+ return self.formattable.formatting_instructions()
86
+
87
+ if self.mode == "tool":
88
+ return TOOL_MODE_INSTRUCTIONS
89
+ elif self.mode == "json":
90
+ json_schema = json.dumps(self.schema, indent=2)
91
+ instructions = JSON_MODE_INSTRUCTIONS.format(json_schema=json_schema)
92
+ return inspect.cleandoc(instructions)
93
+ elif self.mode == "parser":
94
+ return None # pragma: no cover
95
+
96
+ def create_tool_schema(
97
+ self,
98
+ ) -> ToolSchema[ToolFn[..., None]]:
99
+ """Generate a `ToolSchema` for parsing this format.
100
+
101
+ Returns:
102
+ `ToolSchema` for the format tool
103
+ """
104
+
105
+ schema_dict: dict[str, Any] = self.schema.copy()
106
+ schema_dict["type"] = "object"
107
+
108
+ properties = schema_dict.get("properties")
109
+ if not properties or not isinstance(properties, dict):
110
+ properties = {} # pragma: no cover
111
+ properties = cast(dict[str, Any], properties)
112
+ required: list[str] = list(properties.keys())
113
+
114
+ description = (
115
+ f"Use this tool to extract data in {self.name} format for a final response."
116
+ )
117
+ if self.description:
118
+ description += "\n" + self.description
119
+
120
+ parameters = ToolParameterSchema(
121
+ properties=properties,
122
+ required=required,
123
+ additionalProperties=False,
124
+ )
125
+ if "$defs" in schema_dict and isinstance(schema_dict["$defs"], dict):
126
+ parameters.defs = schema_dict["$defs"]
127
+
128
+ def _unused_format_fn() -> None:
129
+ raise TypeError(
130
+ "Format tool function should not be called."
131
+ ) # pragma: no cover
132
+
133
+ return ToolSchema(
134
+ fn=cast(ToolFn[..., None], _unused_format_fn),
135
+ name=FORMAT_TOOL_NAME,
136
+ description=description,
137
+ parameters=parameters,
138
+ strict=None, # Provider determines whether to use strict mode.
139
+ )
140
+
141
+
142
+ def format(
143
+ formattable: type[FormattableT] | OutputParser[FormattableT] | None,
144
+ *,
145
+ mode: FormattingMode,
146
+ ) -> Format[FormattableT] | None:
147
+ """Returns a `Format` that describes structured output or custom parsing.
148
+
149
+ This function converts a Formattable type (e.g. Pydantic `BaseModel` or primitive type)
150
+ or an `OutputParser` into a `Format` object that describes how the output should be
151
+ formatted and parsed. Calling `llm.format` is optional, as all the APIs that expect
152
+ a `Format` can also take the Formattable type or `OutputParser` directly. However,
153
+ calling `llm.format` is necessary in order to specify the formatting mode for
154
+ `BaseModel`/primitive types.
155
+
156
+ Primitive types are automatically wrapped in a `BaseModel` with an "output" field
157
+ for schema generation, then unwrapped during parsing.
158
+
159
+ Args:
160
+ formattable: The type or parser to format:
161
+ - BaseModel type: Uses structured output with JSON schema
162
+ - Primitive type: Wrapped in schema for structured output
163
+ - OutputParser: Uses custom parsing with instructions
164
+ mode: The format mode to use (required):
165
+ - "strict": Use model strict structured outputs, or fail if unavailable.
166
+ - "tool": Use forced tool calling with a special tool that represents a
167
+ formatted response.
168
+ - "json": Use provider json mode if available, or modify prompt to request
169
+ json if not.
170
+ - "parser": Must be used for OutputParser types.
171
+
172
+ The Formattable type may provide custom formatting instructions via a
173
+ `formatting_instructions(cls)` classmethod. If that method is present, it will be called,
174
+ and the resulting instructions will automatically be appended to the system prompt.
175
+
176
+ If no formatting instructions are present, then Mirascope may auto-generate instructions
177
+ based on the active format mode. To disable this behavior and all prompt modification,
178
+ you can add the `formatting_instructions` classmethod and have it return `None`.
179
+
180
+ Returns:
181
+ A `Format` object describing the format type or parser.
182
+
183
+ Example:
184
+ Using with a BaseModel:
185
+
186
+ ```python
187
+ from pydantic import BaseModel
188
+ from mirascope import llm
189
+
190
+ class Book(BaseModel):
191
+ title: str
192
+ author: str
193
+
194
+ format = llm.format(Book, mode="strict")
195
+
196
+ @llm.call("openai/gpt-5-mini", format=format)
197
+ def recommend_book(genre: str):
198
+ return f"Recommend a {genre} book."
199
+
200
+ response = recommend_book("fantasy")
201
+ book: Book = response.parse()
202
+ ```
203
+
204
+ Example:
205
+
206
+ Using with an `OutputParser`:
207
+
208
+ ```python
209
+ @llm.output_parser(
210
+ formatting_instructions="Return XML: <book><title>...</title></book>"
211
+ )
212
+ def parse_book_xml(response: llm.AnyResponse) -> Book:
213
+ # ... parsing logic ...
214
+ return Book(...)
215
+
216
+ @llm.call("openai/gpt-5-mini", format=parse_book_xml)
217
+ def recommend_book(genre: str):
218
+ return f"Recommend a {genre} book."
219
+ ```
220
+ """
221
+ # TODO: Add caching or memoization to this function (e.g. functools.lru_cache)
222
+
223
+ if formattable is None or formattable is NoneType:
224
+ return None
225
+
226
+ if is_output_parser(formattable):
227
+ if mode != "parser":
228
+ raise ValueError(f"mode must be 'parser' for OutputParser, got '{mode}'")
229
+ return Format[Any](
230
+ name=formattable.__name__,
231
+ description=formattable.__doc__,
232
+ schema={},
233
+ mode="parser",
234
+ formattable=formattable,
235
+ )
236
+
237
+ if is_primitive_type(formattable):
238
+ wrapper_model = create_wrapper_model(formattable)
239
+ schema = wrapper_model.model_json_schema()
240
+ name = (
241
+ formattable.__name__
242
+ if hasattr(formattable, "__name__")
243
+ else str(formattable)
244
+ )
245
+
246
+ return Format[FormattableT](
247
+ name=name,
248
+ description=None,
249
+ schema=schema,
250
+ mode=mode,
251
+ formattable=formattable,
252
+ )
253
+
254
+ description = None
255
+ if formattable.__doc__:
256
+ description = inspect.cleandoc(formattable.__doc__)
257
+
258
+ schema = formattable.model_json_schema()
259
+
260
+ return Format[FormattableT](
261
+ name=formattable.__name__,
262
+ description=description,
263
+ schema=schema,
264
+ mode=mode,
265
+ formattable=formattable,
266
+ )
267
+
268
+
269
+ def resolve_format(
270
+ formattable: FormatSpec[FormattableT] | None,
271
+ default_mode: FormattingMode,
272
+ ) -> Format[FormattableT] | None:
273
+ """Resolve a `Format` (or None) from a possible `Format`, Formattable, or `OutputParser`.
274
+
275
+ Args:
276
+ formattable: The format specification:
277
+ - Format: Returned as-is
278
+ - BaseModel/primitive type: Converted to Format with default_mode
279
+ - OutputParser: Converted to Format with mode='parser'
280
+ default_mode: The mode to use for BaseModel/primitive types.
281
+
282
+ Returns:
283
+ A Format object or None.
284
+ """
285
+ if isinstance(formattable, Format):
286
+ return formattable
287
+
288
+ if is_output_parser(formattable):
289
+ return format(formattable, mode="parser")
290
+
291
+ return format(formattable, mode=default_mode)