mirascope 2.0.0a5__py3-none-any.whl → 2.0.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 (349) hide show
  1. mirascope/__init__.py +10 -1
  2. mirascope/_stubs.py +363 -0
  3. mirascope/api/__init__.py +8 -0
  4. mirascope/api/_generated/__init__.py +285 -2
  5. mirascope/api/_generated/annotations/__init__.py +33 -0
  6. mirascope/api/_generated/annotations/client.py +506 -0
  7. mirascope/api/_generated/annotations/raw_client.py +1414 -0
  8. mirascope/api/_generated/annotations/types/__init__.py +31 -0
  9. mirascope/api/_generated/annotations/types/annotations_create_request_label.py +5 -0
  10. mirascope/api/_generated/annotations/types/annotations_create_response.py +48 -0
  11. mirascope/api/_generated/annotations/types/annotations_create_response_label.py +5 -0
  12. mirascope/api/_generated/annotations/types/annotations_get_response.py +48 -0
  13. mirascope/api/_generated/annotations/types/annotations_get_response_label.py +5 -0
  14. mirascope/api/_generated/annotations/types/annotations_list_request_label.py +5 -0
  15. mirascope/api/_generated/annotations/types/annotations_list_response.py +21 -0
  16. mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item.py +50 -0
  17. mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item_label.py +5 -0
  18. mirascope/api/_generated/annotations/types/annotations_update_request_label.py +5 -0
  19. mirascope/api/_generated/annotations/types/annotations_update_response.py +48 -0
  20. mirascope/api/_generated/annotations/types/annotations_update_response_label.py +5 -0
  21. mirascope/api/_generated/api_keys/__init__.py +12 -2
  22. mirascope/api/_generated/api_keys/client.py +77 -0
  23. mirascope/api/_generated/api_keys/raw_client.py +422 -39
  24. mirascope/api/_generated/api_keys/types/__init__.py +7 -1
  25. mirascope/api/_generated/api_keys/types/api_keys_create_response.py +4 -12
  26. mirascope/api/_generated/api_keys/types/api_keys_get_response.py +4 -12
  27. mirascope/api/_generated/api_keys/types/api_keys_list_all_for_org_response_item.py +40 -0
  28. mirascope/api/_generated/api_keys/types/api_keys_list_response_item.py +4 -12
  29. mirascope/api/_generated/client.py +42 -0
  30. mirascope/api/_generated/core/client_wrapper.py +2 -14
  31. mirascope/api/_generated/core/datetime_utils.py +1 -3
  32. mirascope/api/_generated/core/file.py +2 -5
  33. mirascope/api/_generated/core/http_client.py +36 -112
  34. mirascope/api/_generated/core/jsonable_encoder.py +1 -3
  35. mirascope/api/_generated/core/pydantic_utilities.py +19 -74
  36. mirascope/api/_generated/core/query_encoder.py +1 -3
  37. mirascope/api/_generated/core/serialization.py +4 -10
  38. mirascope/api/_generated/docs/client.py +2 -6
  39. mirascope/api/_generated/docs/raw_client.py +51 -5
  40. mirascope/api/_generated/environment.py +3 -3
  41. mirascope/api/_generated/environments/__init__.py +6 -0
  42. mirascope/api/_generated/environments/client.py +117 -0
  43. mirascope/api/_generated/environments/raw_client.py +530 -51
  44. mirascope/api/_generated/environments/types/__init__.py +10 -0
  45. mirascope/api/_generated/environments/types/environments_create_response.py +1 -3
  46. mirascope/api/_generated/environments/types/environments_get_analytics_response.py +60 -0
  47. mirascope/api/_generated/environments/types/environments_get_analytics_response_top_functions_item.py +24 -0
  48. mirascope/api/_generated/environments/types/environments_get_analytics_response_top_models_item.py +22 -0
  49. mirascope/api/_generated/environments/types/environments_get_response.py +1 -3
  50. mirascope/api/_generated/environments/types/environments_list_response_item.py +1 -3
  51. mirascope/api/_generated/environments/types/environments_update_response.py +1 -3
  52. mirascope/api/_generated/errors/__init__.py +8 -0
  53. mirascope/api/_generated/errors/bad_request_error.py +1 -2
  54. mirascope/api/_generated/errors/conflict_error.py +1 -2
  55. mirascope/api/_generated/errors/forbidden_error.py +1 -5
  56. mirascope/api/_generated/errors/internal_server_error.py +1 -6
  57. mirascope/api/_generated/errors/not_found_error.py +1 -5
  58. mirascope/api/_generated/errors/payment_required_error.py +15 -0
  59. mirascope/api/_generated/errors/service_unavailable_error.py +14 -0
  60. mirascope/api/_generated/errors/too_many_requests_error.py +15 -0
  61. mirascope/api/_generated/errors/unauthorized_error.py +11 -0
  62. mirascope/api/_generated/functions/__init__.py +39 -0
  63. mirascope/api/_generated/functions/client.py +647 -0
  64. mirascope/api/_generated/functions/raw_client.py +1890 -0
  65. mirascope/api/_generated/functions/types/__init__.py +53 -0
  66. mirascope/api/_generated/functions/types/functions_create_request_dependencies_value.py +20 -0
  67. mirascope/api/_generated/functions/types/functions_create_response.py +37 -0
  68. mirascope/api/_generated/functions/types/functions_create_response_dependencies_value.py +20 -0
  69. mirascope/api/_generated/functions/types/functions_find_by_hash_response.py +39 -0
  70. mirascope/api/_generated/functions/types/functions_find_by_hash_response_dependencies_value.py +20 -0
  71. mirascope/api/_generated/functions/types/functions_get_by_env_response.py +53 -0
  72. mirascope/api/_generated/functions/types/functions_get_by_env_response_dependencies_value.py +22 -0
  73. mirascope/api/_generated/functions/types/functions_get_response.py +37 -0
  74. mirascope/api/_generated/functions/types/functions_get_response_dependencies_value.py +20 -0
  75. mirascope/api/_generated/functions/types/functions_list_by_env_response.py +25 -0
  76. mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item.py +56 -0
  77. mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item_dependencies_value.py +22 -0
  78. mirascope/api/_generated/functions/types/functions_list_response.py +21 -0
  79. mirascope/api/_generated/functions/types/functions_list_response_functions_item.py +41 -0
  80. mirascope/api/_generated/functions/types/functions_list_response_functions_item_dependencies_value.py +20 -0
  81. mirascope/api/_generated/health/client.py +2 -6
  82. mirascope/api/_generated/health/raw_client.py +51 -5
  83. mirascope/api/_generated/health/types/health_check_response.py +1 -3
  84. mirascope/api/_generated/organization_invitations/__init__.py +33 -0
  85. mirascope/api/_generated/organization_invitations/client.py +546 -0
  86. mirascope/api/_generated/organization_invitations/raw_client.py +1519 -0
  87. mirascope/api/_generated/organization_invitations/types/__init__.py +53 -0
  88. mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response.py +34 -0
  89. mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response_role.py +7 -0
  90. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_request_role.py +7 -0
  91. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response.py +48 -0
  92. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_role.py +7 -0
  93. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_status.py +7 -0
  94. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response.py +48 -0
  95. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_role.py +7 -0
  96. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_status.py +7 -0
  97. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item.py +48 -0
  98. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_role.py +7 -0
  99. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_status.py +7 -0
  100. mirascope/api/_generated/organization_memberships/__init__.py +19 -0
  101. mirascope/api/_generated/organization_memberships/client.py +302 -0
  102. mirascope/api/_generated/organization_memberships/raw_client.py +736 -0
  103. mirascope/api/_generated/organization_memberships/types/__init__.py +27 -0
  104. mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item.py +33 -0
  105. mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item_role.py +7 -0
  106. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_request_role.py +7 -0
  107. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response.py +31 -0
  108. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response_role.py +7 -0
  109. mirascope/api/_generated/organizations/__init__.py +26 -0
  110. mirascope/api/_generated/organizations/client.py +465 -0
  111. mirascope/api/_generated/organizations/raw_client.py +1799 -108
  112. mirascope/api/_generated/organizations/types/__init__.py +48 -0
  113. mirascope/api/_generated/organizations/types/organizations_create_payment_intent_response.py +24 -0
  114. mirascope/api/_generated/organizations/types/organizations_create_response.py +4 -3
  115. mirascope/api/_generated/organizations/types/organizations_create_response_role.py +1 -3
  116. mirascope/api/_generated/organizations/types/organizations_get_response.py +4 -3
  117. mirascope/api/_generated/organizations/types/organizations_get_response_role.py +1 -3
  118. mirascope/api/_generated/organizations/types/organizations_list_response_item.py +4 -3
  119. mirascope/api/_generated/organizations/types/organizations_list_response_item_role.py +1 -3
  120. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_request_target_plan.py +7 -0
  121. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response.py +47 -0
  122. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item.py +33 -0
  123. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item_resource.py +7 -0
  124. mirascope/api/_generated/organizations/types/organizations_router_balance_response.py +24 -0
  125. mirascope/api/_generated/organizations/types/organizations_subscription_response.py +53 -0
  126. mirascope/api/_generated/organizations/types/organizations_subscription_response_current_plan.py +7 -0
  127. mirascope/api/_generated/organizations/types/organizations_subscription_response_payment_method.py +26 -0
  128. mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change.py +34 -0
  129. mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change_target_plan.py +7 -0
  130. mirascope/api/_generated/organizations/types/organizations_update_response.py +4 -3
  131. mirascope/api/_generated/organizations/types/organizations_update_response_role.py +1 -3
  132. mirascope/api/_generated/organizations/types/organizations_update_subscription_request_target_plan.py +7 -0
  133. mirascope/api/_generated/organizations/types/organizations_update_subscription_response.py +35 -0
  134. mirascope/api/_generated/project_memberships/__init__.py +25 -0
  135. mirascope/api/_generated/project_memberships/client.py +437 -0
  136. mirascope/api/_generated/project_memberships/raw_client.py +1039 -0
  137. mirascope/api/_generated/project_memberships/types/__init__.py +29 -0
  138. mirascope/api/_generated/project_memberships/types/project_memberships_create_request_role.py +7 -0
  139. mirascope/api/_generated/project_memberships/types/project_memberships_create_response.py +35 -0
  140. mirascope/api/_generated/project_memberships/types/project_memberships_create_response_role.py +7 -0
  141. mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item.py +33 -0
  142. mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item_role.py +7 -0
  143. mirascope/api/_generated/project_memberships/types/project_memberships_update_request_role.py +7 -0
  144. mirascope/api/_generated/project_memberships/types/project_memberships_update_response.py +35 -0
  145. mirascope/api/_generated/project_memberships/types/project_memberships_update_response_role.py +7 -0
  146. mirascope/api/_generated/projects/__init__.py +2 -12
  147. mirascope/api/_generated/projects/client.py +17 -71
  148. mirascope/api/_generated/projects/raw_client.py +295 -51
  149. mirascope/api/_generated/projects/types/__init__.py +1 -6
  150. mirascope/api/_generated/projects/types/projects_create_response.py +3 -9
  151. mirascope/api/_generated/projects/types/projects_get_response.py +3 -9
  152. mirascope/api/_generated/projects/types/projects_list_response_item.py +3 -9
  153. mirascope/api/_generated/projects/types/projects_update_response.py +3 -9
  154. mirascope/api/_generated/reference.md +3619 -182
  155. mirascope/api/_generated/tags/__init__.py +19 -0
  156. mirascope/api/_generated/tags/client.py +504 -0
  157. mirascope/api/_generated/tags/raw_client.py +1288 -0
  158. mirascope/api/_generated/tags/types/__init__.py +17 -0
  159. mirascope/api/_generated/tags/types/tags_create_response.py +41 -0
  160. mirascope/api/_generated/tags/types/tags_get_response.py +41 -0
  161. mirascope/api/_generated/tags/types/tags_list_response.py +23 -0
  162. mirascope/api/_generated/tags/types/tags_list_response_tags_item.py +41 -0
  163. mirascope/api/_generated/tags/types/tags_update_response.py +41 -0
  164. mirascope/api/_generated/token_cost/__init__.py +7 -0
  165. mirascope/api/_generated/token_cost/client.py +160 -0
  166. mirascope/api/_generated/token_cost/raw_client.py +264 -0
  167. mirascope/api/_generated/token_cost/types/__init__.py +8 -0
  168. mirascope/api/_generated/token_cost/types/token_cost_calculate_request_usage.py +54 -0
  169. mirascope/api/_generated/token_cost/types/token_cost_calculate_response.py +52 -0
  170. mirascope/api/_generated/traces/__init__.py +42 -0
  171. mirascope/api/_generated/traces/client.py +941 -0
  172. mirascope/api/_generated/traces/raw_client.py +2177 -23
  173. mirascope/api/_generated/traces/types/__init__.py +60 -0
  174. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item.py +4 -11
  175. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource.py +2 -6
  176. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item.py +1 -3
  177. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value.py +8 -24
  178. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_array_value.py +2 -6
  179. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value.py +3 -9
  180. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value_values_item.py +2 -6
  181. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item.py +3 -9
  182. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope.py +4 -8
  183. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item.py +2 -6
  184. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value.py +8 -24
  185. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_array_value.py +2 -6
  186. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value.py +3 -9
  187. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value_values_item.py +1 -3
  188. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item.py +6 -18
  189. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item.py +3 -9
  190. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value.py +8 -24
  191. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_array_value.py +2 -6
  192. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value.py +2 -6
  193. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value_values_item.py +1 -3
  194. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_status.py +2 -6
  195. mirascope/api/_generated/traces/types/traces_create_response.py +2 -5
  196. mirascope/api/_generated/traces/types/traces_create_response_partial_success.py +3 -9
  197. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response.py +60 -0
  198. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_functions_item.py +24 -0
  199. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_models_item.py +22 -0
  200. mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response.py +33 -0
  201. mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response_spans_item.py +88 -0
  202. mirascope/api/_generated/traces/types/traces_get_trace_detail_response.py +33 -0
  203. mirascope/api/_generated/traces/types/traces_get_trace_detail_response_spans_item.py +88 -0
  204. mirascope/api/_generated/traces/types/traces_list_by_function_hash_response.py +25 -0
  205. mirascope/api/_generated/traces/types/traces_list_by_function_hash_response_traces_item.py +44 -0
  206. mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item.py +26 -0
  207. mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item_operator.py +7 -0
  208. mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_by.py +7 -0
  209. mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_order.py +7 -0
  210. mirascope/api/_generated/traces/types/traces_search_by_env_response.py +26 -0
  211. mirascope/api/_generated/traces/types/traces_search_by_env_response_spans_item.py +50 -0
  212. mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item.py +26 -0
  213. mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item_operator.py +7 -0
  214. mirascope/api/_generated/traces/types/traces_search_request_sort_by.py +7 -0
  215. mirascope/api/_generated/traces/types/traces_search_request_sort_order.py +5 -0
  216. mirascope/api/_generated/traces/types/traces_search_response.py +26 -0
  217. mirascope/api/_generated/traces/types/traces_search_response_spans_item.py +50 -0
  218. mirascope/api/_generated/types/__init__.py +48 -0
  219. mirascope/api/_generated/types/already_exists_error.py +1 -3
  220. mirascope/api/_generated/types/bad_request_error_body.py +50 -0
  221. mirascope/api/_generated/types/click_house_error.py +22 -0
  222. mirascope/api/_generated/types/database_error.py +1 -3
  223. mirascope/api/_generated/types/date.py +3 -0
  224. mirascope/api/_generated/types/http_api_decode_error.py +1 -3
  225. mirascope/api/_generated/types/immutable_resource_error.py +22 -0
  226. mirascope/api/_generated/types/internal_server_error_body.py +49 -0
  227. mirascope/api/_generated/types/issue.py +1 -3
  228. mirascope/api/_generated/types/issue_tag.py +1 -8
  229. mirascope/api/_generated/types/not_found_error_body.py +1 -3
  230. mirascope/api/_generated/types/number_from_string.py +3 -0
  231. mirascope/api/_generated/types/permission_denied_error.py +1 -3
  232. mirascope/api/_generated/types/permission_denied_error_tag.py +1 -3
  233. mirascope/api/_generated/types/plan_limit_exceeded_error.py +32 -0
  234. mirascope/api/_generated/types/plan_limit_exceeded_error_tag.py +7 -0
  235. mirascope/api/_generated/types/pricing_unavailable_error.py +23 -0
  236. mirascope/api/_generated/types/property_key_key.py +1 -3
  237. mirascope/api/_generated/types/rate_limit_error.py +31 -0
  238. mirascope/api/_generated/types/rate_limit_error_tag.py +5 -0
  239. mirascope/api/_generated/types/service_unavailable_error_body.py +24 -0
  240. mirascope/api/_generated/types/service_unavailable_error_tag.py +7 -0
  241. mirascope/api/_generated/types/stripe_error.py +20 -0
  242. mirascope/api/_generated/types/subscription_past_due_error.py +31 -0
  243. mirascope/api/_generated/types/subscription_past_due_error_tag.py +7 -0
  244. mirascope/api/_generated/types/unauthorized_error_body.py +21 -0
  245. mirascope/api/_generated/types/unauthorized_error_tag.py +5 -0
  246. mirascope/api/settings.py +19 -1
  247. mirascope/llm/__init__.py +55 -8
  248. mirascope/llm/calls/__init__.py +2 -1
  249. mirascope/llm/calls/calls.py +3 -1
  250. mirascope/llm/calls/decorator.py +21 -7
  251. mirascope/llm/content/tool_call.py +6 -0
  252. mirascope/llm/content/tool_output.py +22 -5
  253. mirascope/llm/exceptions.py +284 -71
  254. mirascope/llm/formatting/__init__.py +19 -2
  255. mirascope/llm/formatting/format.py +219 -30
  256. mirascope/llm/formatting/output_parser.py +178 -0
  257. mirascope/llm/formatting/partial.py +80 -7
  258. mirascope/llm/formatting/primitives.py +192 -0
  259. mirascope/llm/formatting/types.py +21 -64
  260. mirascope/llm/mcp/__init__.py +2 -2
  261. mirascope/llm/mcp/mcp_client.py +130 -0
  262. mirascope/llm/messages/__init__.py +3 -0
  263. mirascope/llm/messages/_utils.py +34 -0
  264. mirascope/llm/models/__init__.py +5 -0
  265. mirascope/llm/models/models.py +137 -69
  266. mirascope/llm/{providers/base → models}/params.py +16 -37
  267. mirascope/llm/models/thinking_config.py +61 -0
  268. mirascope/llm/prompts/_utils.py +0 -32
  269. mirascope/llm/prompts/decorator.py +16 -5
  270. mirascope/llm/prompts/prompts.py +131 -68
  271. mirascope/llm/providers/__init__.py +18 -2
  272. mirascope/llm/providers/anthropic/__init__.py +3 -21
  273. mirascope/llm/providers/anthropic/_utils/__init__.py +2 -0
  274. mirascope/llm/providers/anthropic/_utils/beta_decode.py +22 -11
  275. mirascope/llm/providers/anthropic/_utils/beta_encode.py +75 -25
  276. mirascope/llm/providers/anthropic/_utils/decode.py +22 -11
  277. mirascope/llm/providers/anthropic/_utils/encode.py +82 -20
  278. mirascope/llm/providers/anthropic/_utils/errors.py +2 -2
  279. mirascope/llm/providers/anthropic/beta_provider.py +64 -18
  280. mirascope/llm/providers/anthropic/provider.py +91 -33
  281. mirascope/llm/providers/base/__init__.py +0 -2
  282. mirascope/llm/providers/base/_utils.py +55 -11
  283. mirascope/llm/providers/base/base_provider.py +116 -37
  284. mirascope/llm/providers/google/__init__.py +2 -17
  285. mirascope/llm/providers/google/_utils/__init__.py +2 -0
  286. mirascope/llm/providers/google/_utils/decode.py +37 -15
  287. mirascope/llm/providers/google/_utils/encode.py +127 -19
  288. mirascope/llm/providers/google/_utils/errors.py +3 -2
  289. mirascope/llm/providers/google/model_info.py +1 -0
  290. mirascope/llm/providers/google/provider.py +68 -19
  291. mirascope/llm/providers/mirascope/__init__.py +5 -0
  292. mirascope/llm/providers/mirascope/_utils.py +73 -0
  293. mirascope/llm/providers/mirascope/provider.py +349 -0
  294. mirascope/llm/providers/mlx/__init__.py +2 -17
  295. mirascope/llm/providers/mlx/_utils.py +8 -3
  296. mirascope/llm/providers/mlx/encoding/base.py +5 -2
  297. mirascope/llm/providers/mlx/encoding/transformers.py +5 -2
  298. mirascope/llm/providers/mlx/mlx.py +23 -6
  299. mirascope/llm/providers/mlx/provider.py +42 -13
  300. mirascope/llm/providers/ollama/__init__.py +1 -13
  301. mirascope/llm/providers/openai/_utils/errors.py +2 -2
  302. mirascope/llm/providers/openai/completions/__init__.py +2 -20
  303. mirascope/llm/providers/openai/completions/_utils/decode.py +14 -3
  304. mirascope/llm/providers/openai/completions/_utils/encode.py +35 -28
  305. mirascope/llm/providers/openai/completions/base_provider.py +40 -11
  306. mirascope/llm/providers/openai/provider.py +40 -10
  307. mirascope/llm/providers/openai/responses/__init__.py +1 -17
  308. mirascope/llm/providers/openai/responses/_utils/__init__.py +2 -0
  309. mirascope/llm/providers/openai/responses/_utils/decode.py +21 -8
  310. mirascope/llm/providers/openai/responses/_utils/encode.py +59 -19
  311. mirascope/llm/providers/openai/responses/provider.py +56 -18
  312. mirascope/llm/providers/provider_id.py +1 -0
  313. mirascope/llm/providers/provider_registry.py +96 -19
  314. mirascope/llm/providers/together/__init__.py +1 -13
  315. mirascope/llm/responses/__init__.py +6 -1
  316. mirascope/llm/responses/_utils.py +102 -12
  317. mirascope/llm/responses/base_response.py +5 -2
  318. mirascope/llm/responses/base_stream_response.py +139 -45
  319. mirascope/llm/responses/response.py +2 -1
  320. mirascope/llm/responses/root_response.py +89 -17
  321. mirascope/llm/responses/stream_response.py +6 -9
  322. mirascope/llm/tools/decorator.py +17 -8
  323. mirascope/llm/tools/tool_schema.py +43 -10
  324. mirascope/llm/tools/toolkit.py +35 -27
  325. mirascope/llm/tools/tools.py +123 -30
  326. mirascope/ops/__init__.py +64 -109
  327. mirascope/ops/_internal/configuration.py +82 -31
  328. mirascope/ops/_internal/exporters/exporters.py +64 -11
  329. mirascope/ops/_internal/instrumentation/llm/common.py +530 -0
  330. mirascope/ops/_internal/instrumentation/llm/cost.py +190 -0
  331. mirascope/ops/_internal/instrumentation/llm/encode.py +1 -1
  332. mirascope/ops/_internal/instrumentation/llm/llm.py +116 -1243
  333. mirascope/ops/_internal/instrumentation/llm/model.py +1798 -0
  334. mirascope/ops/_internal/instrumentation/llm/response.py +521 -0
  335. mirascope/ops/_internal/instrumentation/llm/serialize.py +300 -0
  336. mirascope/ops/_internal/protocols.py +83 -1
  337. mirascope/ops/_internal/traced_calls.py +4 -0
  338. mirascope/ops/_internal/traced_functions.py +141 -12
  339. mirascope/ops/_internal/tracing.py +78 -1
  340. mirascope/ops/_internal/utils.py +52 -4
  341. mirascope/ops/_internal/versioned_functions.py +54 -43
  342. {mirascope-2.0.0a5.dist-info → mirascope-2.0.1.dist-info}/METADATA +14 -13
  343. mirascope-2.0.1.dist-info/RECORD +423 -0
  344. {mirascope-2.0.0a5.dist-info → mirascope-2.0.1.dist-info}/licenses/LICENSE +1 -1
  345. mirascope/llm/formatting/_utils.py +0 -78
  346. mirascope/llm/mcp/client.py +0 -118
  347. mirascope/llm/providers/_missing_import_stubs.py +0 -49
  348. mirascope-2.0.0a5.dist-info/RECORD +0 -265
  349. {mirascope-2.0.0a5.dist-info → mirascope-2.0.1.dist-info}/WHEEL +0 -0
@@ -14,8 +14,12 @@ from .tools import AsyncContextTool, AsyncTool, ContextTool, Tool
14
14
  class ToolDecorator:
15
15
  """Protocol for the tool decorator."""
16
16
 
17
- strict: bool
18
- """Whether to use strict tool calling, if supported by the provider."""
17
+ strict: bool | None = None
18
+ """Whether to use strict tool calling, if supported by the provider.
19
+
20
+ If set to None, then it will use the provider's default setting (usually the
21
+ strictest possible).
22
+ """
19
23
 
20
24
  @overload
21
25
  def __call__( # pyright:ignore[reportOverlappingOverload]
@@ -62,15 +66,19 @@ class ToolDecorator:
62
66
  is_async = _tool_utils.is_async_tool_fn(fn)
63
67
 
64
68
  if is_context and is_async:
65
- return AsyncContextTool[DepsT, JsonableCovariantT, P](
69
+ return AsyncContextTool[DepsT, JsonableCovariantT, P].from_function(
66
70
  fn, strict=self.strict
67
71
  )
68
72
  elif is_context:
69
- return ContextTool[DepsT, JsonableCovariantT, P](fn, strict=self.strict)
73
+ return ContextTool[DepsT, JsonableCovariantT, P].from_function(
74
+ fn, strict=self.strict
75
+ )
70
76
  elif is_async:
71
- return AsyncTool[P, JsonableCovariantT](fn, strict=self.strict)
77
+ return AsyncTool[P, JsonableCovariantT].from_function(
78
+ fn, strict=self.strict
79
+ )
72
80
  else:
73
- return Tool[P, JsonableCovariantT](fn, strict=self.strict)
81
+ return Tool[P, JsonableCovariantT].from_function(fn, strict=self.strict)
74
82
 
75
83
 
76
84
  @overload
@@ -102,7 +110,7 @@ def tool(__fn: ToolFn[P, JsonableCovariantT]) -> Tool[P, JsonableCovariantT]:
102
110
 
103
111
 
104
112
  @overload
105
- def tool(*, strict: bool = False) -> ToolDecorator:
113
+ def tool(*, strict: bool | None = None) -> ToolDecorator:
106
114
  """Overload for setting non-default arguments."""
107
115
  ...
108
116
 
@@ -114,7 +122,7 @@ def tool(
114
122
  | AsyncToolFn[P, JsonableCovariantT]
115
123
  | None = None,
116
124
  *,
117
- strict: bool = False,
125
+ strict: bool | None = None,
118
126
  ) -> (
119
127
  ContextTool[DepsT, JsonableCovariantT, P]
120
128
  | AsyncContextTool[DepsT, JsonableCovariantT, P]
@@ -133,6 +141,7 @@ def tool(
133
141
 
134
142
  Args:
135
143
  strict: Whether the tool should use strict mode when supported by the model.
144
+ If None, uses provider's default (usually as strict as possible).
136
145
 
137
146
  Returns:
138
147
  A decorator function that converts the function into a Tool or ContextTool.
@@ -157,8 +157,12 @@ class ToolSchema(Generic[ToolFnT]):
157
157
  it should **not be modified** after the ToolSchema is created.
158
158
  """
159
159
 
160
- strict: bool
161
- """Whether the tool should use strict mode when supported by the model."""
160
+ strict: bool | None
161
+ """Whether the tool should use strict mode when supported by the model.
162
+
163
+ If set to None, will use the provider's default setting (usually as strict as
164
+ possible).
165
+ """
162
166
 
163
167
  def __hash__(self) -> int:
164
168
  if not hasattr(self, "_hash"):
@@ -175,10 +179,36 @@ class ToolSchema(Generic[ToolFnT]):
175
179
  def __init__(
176
180
  self,
177
181
  fn: ToolFnT,
182
+ name: str,
183
+ description: str,
184
+ parameters: ToolParameterSchema,
178
185
  *,
179
- strict: bool = False,
180
- is_context_tool: bool = False,
186
+ strict: bool | None = None,
181
187
  ) -> None:
188
+ """Create a `ToolSchema` with the provided values.
189
+
190
+ Args:
191
+ fn: The function that implements the tool's functionality
192
+ name: The name of the tool
193
+ description: Description of what the tool does
194
+ parameters: JSON Schema describing the parameters accepted by the tool
195
+ strict: Whether the tool should use strict mode when supported.
196
+ If None, uses provider's default (usually as strict as possible).
197
+ """
198
+ self.fn = fn
199
+ self.name = name
200
+ self.description = description
201
+ self.parameters = parameters
202
+ self.strict = strict
203
+
204
+ @classmethod
205
+ def from_function(
206
+ cls,
207
+ fn: AnyToolFn,
208
+ *,
209
+ strict: bool | None = None,
210
+ is_context_tool: bool = False,
211
+ ) -> ToolSchema[AnyToolFn]:
182
212
  """Create a `ToolSchema` by inspecting a function and its docstring.
183
213
 
184
214
  Uses Pydantic's create_model to dynamically build a model from the function
@@ -187,7 +217,8 @@ class ToolSchema(Generic[ToolFnT]):
187
217
 
188
218
  Args:
189
219
  fn: The function to extract schema from
190
- strict: Whether the tool should use strict mode when supported
220
+ strict: Whether the tool should use strict mode when supported.
221
+ If None, uses provider's default (usually as strict as possible).
191
222
  is_context_tool: Whether this is a context tool (skips the context parameter)
192
223
 
193
224
  Returns:
@@ -264,11 +295,13 @@ class ToolSchema(Generic[ToolFnT]):
264
295
  if "$defs" in schema:
265
296
  parameters.defs = schema["$defs"]
266
297
 
267
- self.fn = fn
268
- self.name = name
269
- self.description = description
270
- self.parameters = parameters
271
- self.strict = strict
298
+ return cls(
299
+ fn=cast(ToolFnT, fn),
300
+ name=name,
301
+ description=description,
302
+ parameters=parameters,
303
+ strict=strict,
304
+ )
272
305
 
273
306
  def can_execute(self, tool_call: ToolCall) -> bool:
274
307
  """Check if a `ToolCall` can be executed by tools with this `ToolSchema`.
@@ -60,7 +60,7 @@ class BaseToolkit(Generic[ToolSchemaT]):
60
60
  """
61
61
  tool = self.tools_dict.get(tool_call.name, None)
62
62
  if not tool:
63
- raise ToolNotFoundError(f"Tool not found in toolkit: {tool_call.name}")
63
+ raise ToolNotFoundError(tool_call.name)
64
64
  return tool
65
65
 
66
66
 
@@ -75,12 +75,14 @@ class Toolkit(BaseToolkit[Tool]):
75
75
 
76
76
  Returns:
77
77
  The output from executing the `Tool`.
78
-
79
- Raises:
80
- ToolNotFoundError: If the requested tool is not found.
81
78
  """
82
- tool = self.get(tool_call)
83
- return tool.execute(tool_call)
79
+ try:
80
+ tool = self.get(tool_call)
81
+ return tool.execute(tool_call)
82
+ except ToolNotFoundError as e:
83
+ return ToolOutput(
84
+ id=tool_call.id, result=str(e), error=e, name=tool_call.name
85
+ )
84
86
 
85
87
 
86
88
  class AsyncToolkit(BaseToolkit[AsyncTool]):
@@ -94,12 +96,14 @@ class AsyncToolkit(BaseToolkit[AsyncTool]):
94
96
 
95
97
  Returns:
96
98
  The output from executing the `AsyncTool`.
97
-
98
- Raises:
99
- ToolNotFoundError: If the requested tool is not found.
100
99
  """
101
- tool = self.get(tool_call)
102
- return await tool.execute(tool_call)
100
+ try:
101
+ tool = self.get(tool_call)
102
+ return await tool.execute(tool_call)
103
+ except ToolNotFoundError as e:
104
+ return ToolOutput(
105
+ id=tool_call.id, result=str(e), error=e, name=tool_call.name
106
+ )
103
107
 
104
108
 
105
109
  class ContextToolkit(BaseToolkit[Tool | ContextTool[DepsT]], Generic[DepsT]):
@@ -114,15 +118,17 @@ class ContextToolkit(BaseToolkit[Tool | ContextTool[DepsT]], Generic[DepsT]):
114
118
 
115
119
  Returns:
116
120
  The output from executing the `ContextTool`.
117
-
118
- Raises:
119
- ToolNotFoundError: If the requested tool is not found.
120
121
  """
121
- tool = self.get(tool_call)
122
- if isinstance(tool, ContextTool):
123
- return tool.execute(ctx, tool_call)
124
- else:
125
- return tool.execute(tool_call)
122
+ try:
123
+ tool = self.get(tool_call)
124
+ if isinstance(tool, ContextTool):
125
+ return tool.execute(ctx, tool_call)
126
+ else:
127
+ return tool.execute(tool_call)
128
+ except ToolNotFoundError as e:
129
+ return ToolOutput(
130
+ id=tool_call.id, result=str(e), error=e, name=tool_call.name
131
+ )
126
132
 
127
133
 
128
134
  class AsyncContextToolkit(
@@ -141,12 +147,14 @@ class AsyncContextToolkit(
141
147
 
142
148
  Returns:
143
149
  The output from executing the `AsyncContextTool`.
144
-
145
- Raises:
146
- ToolNotFoundError: If the requested tool is not found.
147
150
  """
148
- tool = self.get(tool_call)
149
- if isinstance(tool, AsyncContextTool):
150
- return await tool.execute(ctx, tool_call)
151
- else:
152
- return await tool.execute(tool_call)
151
+ try:
152
+ tool = self.get(tool_call)
153
+ if isinstance(tool, AsyncContextTool):
154
+ return await tool.execute(ctx, tool_call)
155
+ else:
156
+ return await tool.execute(tool_call)
157
+ except ToolNotFoundError as e:
158
+ return ToolOutput(
159
+ id=tool_call.id, result=str(e), error=e, name=tool_call.name
160
+ )
@@ -9,6 +9,7 @@ from typing_extensions import TypeVar
9
9
 
10
10
  from ..content import ToolCall, ToolOutput
11
11
  from ..context import Context, DepsT
12
+ from ..exceptions import ToolError, ToolExecutionError
12
13
  from ..types import AnyP, JsonableCovariantT
13
14
  from .protocols import (
14
15
  AsyncContextToolFn,
@@ -40,10 +41,28 @@ class Tool(
40
41
  This class is not instantiated directly but created by the `@tool()` decorator.
41
42
  """
42
43
 
43
- def __init__(
44
- self, fn: ToolFn[AnyP, JsonableCovariantT], *, strict: bool = False
45
- ) -> None:
46
- super().__init__(fn, strict=strict, is_context_tool=False)
44
+ @classmethod
45
+ def from_function( # pyright: ignore[reportIncompatibleMethodOverride]
46
+ cls, fn: ToolFn[AnyP, JsonableCovariantT], *, strict: bool | None = None
47
+ ) -> Tool[AnyP, JsonableCovariantT]:
48
+ """Create a `Tool` by inspecting a function and its docstring.
49
+
50
+ Args:
51
+ fn: The function to extract schema from
52
+ strict: Whether the tool should use strict mode when supported.
53
+ If None, uses provider's default (usually as strict as possible).
54
+
55
+ Returns:
56
+ a `Tool` representing the function
57
+ """
58
+ schema = ToolSchema.from_function(fn, strict=strict, is_context_tool=False)
59
+ return cls(
60
+ fn=cast(ToolFn[AnyP, JsonableCovariantT], schema.fn),
61
+ name=schema.name,
62
+ description=schema.description,
63
+ parameters=schema.parameters,
64
+ strict=schema.strict,
65
+ )
47
66
 
48
67
  def __call__(self, *args: AnyP.args, **kwargs: AnyP.kwargs) -> JsonableCovariantT:
49
68
  """Call the underlying function directly."""
@@ -51,10 +70,15 @@ class Tool(
51
70
 
52
71
  def execute(self, tool_call: ToolCall) -> ToolOutput[JsonableCovariantT]:
53
72
  """Execute the tool using an LLM-provided `ToolCall`."""
54
- kwargs_from_json = json.loads(tool_call.args)
55
73
  kwargs_callable = cast(KwargsCallable[JsonableCovariantT], self.fn)
56
- result = kwargs_callable(**kwargs_from_json)
57
- return ToolOutput(id=tool_call.id, value=result, name=self.name)
74
+ error: ToolError | None = None
75
+ try:
76
+ kwargs_from_json = json.loads(tool_call.args)
77
+ result = kwargs_callable(**kwargs_from_json)
78
+ except Exception as e:
79
+ result = str(e)
80
+ error = ToolExecutionError(e)
81
+ return ToolOutput(id=tool_call.id, result=result, error=error, name=self.name)
58
82
 
59
83
 
60
84
  class AsyncTool(
@@ -69,10 +93,28 @@ class AsyncTool(
69
93
  This class is not instantiated directly but created by the `@tool()` decorator.
70
94
  """
71
95
 
72
- def __init__(
73
- self, fn: AsyncToolFn[AnyP, JsonableCovariantT], *, strict: bool = False
74
- ) -> None:
75
- super().__init__(fn, strict=strict, is_context_tool=False)
96
+ @classmethod
97
+ def from_function( # pyright: ignore[reportIncompatibleMethodOverride]
98
+ cls, fn: AsyncToolFn[AnyP, JsonableCovariantT], *, strict: bool | None = None
99
+ ) -> AsyncTool[AnyP, JsonableCovariantT]:
100
+ """Create an `AsyncTool` by inspecting a function and its docstring.
101
+
102
+ Args:
103
+ fn: The function to extract schema from
104
+ strict: Whether the tool should use strict mode when supported.
105
+ If None, uses provider's default (usually as strict as possible).
106
+
107
+ Returns:
108
+ an `AsyncTool` representing the function
109
+ """
110
+ schema = ToolSchema.from_function(fn, strict=strict, is_context_tool=False)
111
+ return cls(
112
+ fn=cast(AsyncToolFn[AnyP, JsonableCovariantT], schema.fn),
113
+ name=schema.name,
114
+ description=schema.description,
115
+ parameters=schema.parameters,
116
+ strict=schema.strict,
117
+ )
76
118
 
77
119
  def __call__(
78
120
  self, *args: AnyP.args, **kwargs: AnyP.kwargs
@@ -82,10 +124,15 @@ class AsyncTool(
82
124
 
83
125
  async def execute(self, tool_call: ToolCall) -> ToolOutput[JsonableCovariantT]:
84
126
  """Execute the async tool using an LLM-provided `ToolCall`."""
85
- kwargs_from_json = json.loads(tool_call.args)
86
127
  kwargs_callable = cast(AsyncKwargsCallable[JsonableCovariantT], self.fn)
87
- result = await kwargs_callable(**kwargs_from_json)
88
- return ToolOutput(id=tool_call.id, value=result, name=self.name)
128
+ error: ToolError | None = None
129
+ try:
130
+ kwargs_from_json = json.loads(tool_call.args)
131
+ result = await kwargs_callable(**kwargs_from_json)
132
+ except Exception as e:
133
+ result = str(e)
134
+ error = ToolExecutionError(e)
135
+ return ToolOutput(id=tool_call.id, result=result, error=error, name=self.name)
89
136
 
90
137
 
91
138
  class ContextTool(
@@ -100,13 +147,31 @@ class ContextTool(
100
147
  This class is not instantiated directly but created by the `@tool()` decorator.
101
148
  """
102
149
 
103
- def __init__(
104
- self,
150
+ @classmethod
151
+ def from_function( # pyright: ignore[reportIncompatibleMethodOverride]
152
+ cls,
105
153
  fn: ContextToolFn[DepsT, AnyP, JsonableCovariantT],
106
154
  *,
107
- strict: bool = False,
108
- ) -> None:
109
- super().__init__(fn, strict=strict, is_context_tool=True)
155
+ strict: bool | None = None,
156
+ ) -> ContextTool[DepsT, JsonableCovariantT, AnyP]:
157
+ """Create a `ContextTool` by inspecting a function and its docstring.
158
+
159
+ Args:
160
+ fn: The function to extract schema from
161
+ strict: Whether the tool should use strict mode when supported.
162
+ If None, uses provider's default (usually as strict as possible).
163
+
164
+ Returns:
165
+ a `ContextTool` representing the function
166
+ """
167
+ schema = ToolSchema.from_function(fn, strict=strict, is_context_tool=True)
168
+ return cls(
169
+ fn=cast(ContextToolFn[DepsT, AnyP, JsonableCovariantT], schema.fn),
170
+ name=schema.name,
171
+ description=schema.description,
172
+ parameters=schema.parameters,
173
+ strict=schema.strict,
174
+ )
110
175
 
111
176
  def __call__(
112
177
  self,
@@ -121,12 +186,17 @@ class ContextTool(
121
186
  self, ctx: Context[DepsT], tool_call: ToolCall
122
187
  ) -> ToolOutput[JsonableCovariantT]:
123
188
  """Execute the context tool using an LLM-provided `ToolCall`."""
124
- kwargs_from_json = json.loads(tool_call.args)
125
189
  kwargs_callable = cast(
126
190
  ContextKwargsCallable[DepsT, JsonableCovariantT], self.fn
127
191
  )
128
- result = kwargs_callable(ctx, **kwargs_from_json)
129
- return ToolOutput(id=tool_call.id, value=result, name=self.name)
192
+ error: ToolError | None = None
193
+ try:
194
+ kwargs_from_json = json.loads(tool_call.args)
195
+ result = kwargs_callable(ctx, **kwargs_from_json)
196
+ except Exception as e:
197
+ result = str(e)
198
+ error = ToolExecutionError(e)
199
+ return ToolOutput(id=tool_call.id, result=result, error=error, name=self.name)
130
200
 
131
201
 
132
202
  class AsyncContextTool(
@@ -141,13 +211,31 @@ class AsyncContextTool(
141
211
  This class is not instantiated directly but created by the `@tool()` decorator.
142
212
  """
143
213
 
144
- def __init__(
145
- self,
214
+ @classmethod
215
+ def from_function( # pyright: ignore[reportIncompatibleMethodOverride]
216
+ cls,
146
217
  fn: AsyncContextToolFn[DepsT, AnyP, JsonableCovariantT],
147
218
  *,
148
- strict: bool = False,
149
- ) -> None:
150
- super().__init__(fn, strict=strict, is_context_tool=True)
219
+ strict: bool | None = None,
220
+ ) -> AsyncContextTool[DepsT, JsonableCovariantT, AnyP]:
221
+ """Create an `AsyncContextTool` by inspecting a function and its docstring.
222
+
223
+ Args:
224
+ fn: The function to extract schema from
225
+ strict: Whether the tool should use strict mode when supported.
226
+ If None, uses provider's default (usually as strict as possible).
227
+
228
+ Returns:
229
+ an `AsyncContextTool` representing the function
230
+ """
231
+ schema = ToolSchema.from_function(fn, strict=strict, is_context_tool=True)
232
+ return cls(
233
+ fn=cast(AsyncContextToolFn[DepsT, AnyP, JsonableCovariantT], schema.fn),
234
+ name=schema.name,
235
+ description=schema.description,
236
+ parameters=schema.parameters,
237
+ strict=schema.strict,
238
+ )
151
239
 
152
240
  def __call__(
153
241
  self,
@@ -162,9 +250,14 @@ class AsyncContextTool(
162
250
  self, ctx: Context[DepsT], tool_call: ToolCall
163
251
  ) -> ToolOutput[JsonableCovariantT]:
164
252
  """Execute the async context tool using an LLM-provided `ToolCall`."""
165
- kwargs_from_json = json.loads(tool_call.args)
166
253
  kwargs_callable = cast(
167
254
  AsyncJsonKwargsCallable[DepsT, JsonableCovariantT], self.fn
168
255
  )
169
- result = await kwargs_callable(ctx, **kwargs_from_json)
170
- return ToolOutput(id=tool_call.id, value=result, name=self.name)
256
+ error: ToolError | None = None
257
+ try:
258
+ kwargs_from_json = json.loads(tool_call.args)
259
+ result = await kwargs_callable(ctx, **kwargs_from_json)
260
+ except Exception as e:
261
+ result = str(e)
262
+ error = ToolExecutionError(e)
263
+ return ToolOutput(id=tool_call.id, result=result, error=error, name=self.name)
mirascope/ops/__init__.py CHANGED
@@ -2,122 +2,76 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- try:
6
- from ._internal.configuration import configure, tracer_context
7
- from ._internal.context import propagated_context
8
- from ._internal.instrumentation.llm import (
9
- instrument_llm,
10
- uninstrument_llm,
11
- )
12
- from ._internal.propagation import (
13
- ContextPropagator,
14
- PropagatorFormat,
15
- extract_context,
16
- get_propagator,
17
- inject_context,
18
- reset_propagator,
19
- )
20
- from ._internal.session import (
21
- SESSION_HEADER_NAME,
22
- SessionContext,
23
- current_session,
24
- extract_session_id,
25
- session,
26
- )
27
- from ._internal.spans import Span, span
28
- from ._internal.traced_calls import (
29
- TracedAsyncCall,
30
- TracedAsyncContextCall,
31
- TracedCall,
32
- TracedContextCall,
33
- )
34
- from ._internal.traced_functions import (
35
- AsyncTrace,
36
- AsyncTracedFunction,
37
- Trace,
38
- TracedFunction,
39
- )
40
- from ._internal.tracing import (
41
- TraceDecorator,
42
- trace,
43
- )
44
- from ._internal.versioned_calls import (
45
- VersionedAsyncCall,
46
- VersionedAsyncContextCall,
47
- VersionedCall,
48
- VersionedContextCall,
49
- )
50
- from ._internal.versioned_functions import (
51
- AsyncVersionedFunction,
52
- VersionedFunction,
53
- VersionInfo,
54
- )
55
- from ._internal.versioning import (
56
- VersionDecorator,
57
- version,
58
- )
59
- from .exceptions import ClosureComputationError
5
+ from .._stubs import stub_module_if_missing
60
6
 
61
- except ImportError: # pragma: no cover
62
- # TODO: refactor alongside other import error handling improvements
63
- from collections.abc import Callable
64
-
65
- def _create_otel_import_error_stub(name: str) -> Callable[..., None]:
66
- """Create a stub that raises ImportError with helpful message."""
67
-
68
- def _raise_not_installed() -> None:
69
- raise ImportError(
70
- f"The 'opentelemetry' packages are required to use {name}. "
71
- "Install them with: `uv add 'mirascope[otel]'`."
72
- )
73
-
74
- return _raise_not_installed
75
-
76
- propagated_context = _create_otel_import_error_stub("propagated_context")
77
- instrument_llm = _create_otel_import_error_stub("instrument_llm")
78
- uninstrument_llm = _create_otel_import_error_stub("uninstrument_llm")
79
- ContextPropagator = _create_otel_import_error_stub("ContextPropagator")
80
- PropagatorFormat = str
81
- extract_context = _create_otel_import_error_stub("extract_context")
82
- get_propagator = _create_otel_import_error_stub("get_propagator")
83
- inject_context = _create_otel_import_error_stub("inject_context")
84
- reset_propagator = _create_otel_import_error_stub("reset_propagator")
85
- SESSION_HEADER_NAME = "X-Mirascope-Session-ID"
86
- SessionContext = _create_otel_import_error_stub("SessionContext")
87
- current_session = _create_otel_import_error_stub("current_session")
88
- extract_session_id = _create_otel_import_error_stub("extract_session_id")
89
- session = _create_otel_import_error_stub("session")
90
- Span = _create_otel_import_error_stub("Span")
91
- span = _create_otel_import_error_stub("span")
92
- AsyncTrace = _create_otel_import_error_stub("AsyncTrace")
93
- AsyncTracedFunction = _create_otel_import_error_stub("AsyncTracedFunction")
94
- Trace = _create_otel_import_error_stub("Trace")
95
- TraceDecorator = _create_otel_import_error_stub("TraceDecorator")
96
- TracedAsyncCall = _create_otel_import_error_stub("TracedAsyncCall")
97
- TracedAsyncContextCall = _create_otel_import_error_stub("TracedAsyncContextCall")
98
- TracedCall = _create_otel_import_error_stub("TracedCall")
99
- TracedContextCall = _create_otel_import_error_stub("TracedContextCall")
100
- TracedFunction = _create_otel_import_error_stub("TracedFunction")
101
- trace = _create_otel_import_error_stub("trace")
102
- configure = _create_otel_import_error_stub("configure")
103
- tracer_context = _create_otel_import_error_stub("tracer_context")
104
- AsyncVersionedFunction = _create_otel_import_error_stub("AsyncVersionedFunction")
105
- VersionDecorator = _create_otel_import_error_stub("VersionDecorator")
106
- VersionedAsyncCall = _create_otel_import_error_stub("VersionedAsyncCall")
107
- VersionedAsyncContextCall = _create_otel_import_error_stub(
108
- "VersionedAsyncContextCall"
109
- )
110
- VersionedCall = _create_otel_import_error_stub("VersionedCall")
111
- VersionedContextCall = _create_otel_import_error_stub("VersionedContextCall")
112
- VersionedFunction = _create_otel_import_error_stub("VersionedFunction")
113
- VersionInfo = _create_otel_import_error_stub("VersionInfo")
114
- version = _create_otel_import_error_stub("version")
7
+ # Stub modules for missing optional dependencies BEFORE importing
8
+ # This must happen before any imports from these modules
9
+ stub_module_if_missing("mirascope.ops", "ops")
115
10
 
11
+ # Now imports work regardless of which packages are installed
12
+ # ruff: noqa: E402
13
+ from ._internal.configuration import configure, tracer_context
14
+ from ._internal.context import propagated_context
15
+ from ._internal.instrumentation.llm import (
16
+ instrument_llm,
17
+ uninstrument_llm,
18
+ )
19
+ from ._internal.propagation import (
20
+ ContextPropagator,
21
+ PropagatorFormat,
22
+ extract_context,
23
+ get_propagator,
24
+ inject_context,
25
+ reset_propagator,
26
+ )
27
+ from ._internal.session import (
28
+ SESSION_HEADER_NAME,
29
+ SessionContext,
30
+ current_session,
31
+ extract_session_id,
32
+ session,
33
+ )
34
+ from ._internal.spans import Span, span
35
+ from ._internal.traced_calls import (
36
+ TracedAsyncCall,
37
+ TracedAsyncContextCall,
38
+ TracedCall,
39
+ TracedContextCall,
40
+ )
41
+ from ._internal.traced_functions import (
42
+ AsyncTrace,
43
+ AsyncTracedFunction,
44
+ AsyncTracedSpanFunction,
45
+ Trace,
46
+ TracedFunction,
47
+ TracedSpanFunction,
48
+ )
49
+ from ._internal.tracing import (
50
+ TraceDecorator,
51
+ trace,
52
+ )
53
+ from ._internal.versioned_calls import (
54
+ VersionedAsyncCall,
55
+ VersionedAsyncContextCall,
56
+ VersionedCall,
57
+ VersionedContextCall,
58
+ )
59
+ from ._internal.versioned_functions import (
60
+ AsyncVersionedFunction,
61
+ VersionedFunction,
62
+ VersionInfo,
63
+ )
64
+ from ._internal.versioning import (
65
+ VersionDecorator,
66
+ version,
67
+ )
68
+ from .exceptions import ClosureComputationError
116
69
 
117
70
  __all__ = [
118
71
  "SESSION_HEADER_NAME",
119
72
  "AsyncTrace",
120
73
  "AsyncTracedFunction",
74
+ "AsyncTracedSpanFunction",
121
75
  "AsyncVersionedFunction",
122
76
  "ClosureComputationError",
123
77
  "ContextPropagator",
@@ -131,6 +85,7 @@ __all__ = [
131
85
  "TracedCall",
132
86
  "TracedContextCall",
133
87
  "TracedFunction",
88
+ "TracedSpanFunction",
134
89
  "VersionDecorator",
135
90
  "VersionInfo",
136
91
  "VersionedAsyncCall",