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,232 @@
1
+ """Explicit span management utilities for `mirascope.ops`."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ from contextvars import Token
7
+ from typing import TYPE_CHECKING, Any
8
+
9
+ from opentelemetry import context as otel_context, trace as otel_trace
10
+ from opentelemetry.trace import (
11
+ SpanContext,
12
+ Status,
13
+ StatusCode,
14
+ format_span_id,
15
+ format_trace_id,
16
+ )
17
+ from opentelemetry.util.types import AttributeValue
18
+
19
+ from .session import current_session
20
+ from .utils import json_dumps
21
+
22
+ if TYPE_CHECKING:
23
+ from opentelemetry.context import Context
24
+
25
+ logger = logging.getLogger("mirascope.ops")
26
+ _warned_noop = False
27
+
28
+
29
+ class Span:
30
+ """Context-managed span for explicit tracing.
31
+
32
+ Creates a child span within the current trace context. Acts as a no-op
33
+ if tracing is not configured.
34
+ """
35
+
36
+ def __init__(self, name: str, **attributes: AttributeValue) -> None:
37
+ """Initialize a new span with the given name.
38
+
39
+ Args:
40
+ name: Name for the span.
41
+ **attributes: Initial attributes to set on the span.
42
+ """
43
+ self._name = name
44
+ self._initial_attributes = attributes
45
+ self._span: otel_trace.Span | None = None
46
+ self._token: Token[Context] | None = None
47
+ self._is_noop = True
48
+ self._finished = False
49
+
50
+ def __enter__(self) -> Span:
51
+ """Enter the span context.
52
+
53
+ Returns:
54
+ This span instance for use within the context.
55
+ """
56
+ tracer = otel_trace.get_tracer("mirascope.ops")
57
+ self._span = tracer.start_span(self._name)
58
+
59
+ if self._span.__class__.__name__ == "NonRecordingSpan":
60
+ self._is_noop = True
61
+ self._span = None
62
+ global _warned_noop
63
+ if not _warned_noop:
64
+ logger.warning(
65
+ f"mirascope tracing is not configured; Span('{self._name}') is a no-op."
66
+ )
67
+ _warned_noop = True
68
+ else:
69
+ self._is_noop = False
70
+ self._span.set_attribute("mirascope.type", "trace")
71
+
72
+ session_ctx = current_session()
73
+ if session_ctx is not None:
74
+ self._span.set_attribute("mirascope.ops.session.id", session_ctx.id)
75
+ if session_ctx.attributes is not None:
76
+ self._span.set_attribute(
77
+ "mirascope.ops.session.attributes",
78
+ json_dumps(session_ctx.attributes),
79
+ )
80
+
81
+ self._token = otel_context.attach(
82
+ otel_trace.set_span_in_context(self._span)
83
+ )
84
+
85
+ if self._initial_attributes:
86
+ self.set(**self._initial_attributes)
87
+
88
+ return self
89
+
90
+ def __exit__(
91
+ self,
92
+ exc_type: type[BaseException] | None,
93
+ exc: BaseException | None,
94
+ tb: Any, # noqa: ANN401
95
+ ) -> None:
96
+ """Exit the span context.
97
+
98
+ Args:
99
+ exc_type: Exception type if an exception was raised.
100
+ exc: Exception instance if an exception was raised.
101
+ tb: Traceback if an exception was raised.
102
+ """
103
+ if self._span and not self._finished:
104
+ if exc is not None:
105
+ self._span.record_exception(exc)
106
+ self._span.set_status(Status(StatusCode.ERROR))
107
+ self.finish()
108
+
109
+ def set(self, **attributes: AttributeValue) -> None:
110
+ """Set attributes on the current span.
111
+
112
+ Args:
113
+ **attributes: Key-value pairs to set as span attributes.
114
+ """
115
+ if self._span and not self._finished:
116
+ for key, value in attributes.items():
117
+ self._span.set_attribute(key, value)
118
+
119
+ def event(self, name: str, **attributes: AttributeValue) -> None:
120
+ """Record an event within the span.
121
+
122
+ Args:
123
+ name: Name of the event.
124
+ **attributes: Event attributes as key-value pairs.
125
+ """
126
+ if self._span and not self._finished:
127
+ self._span.add_event(name, attributes=attributes)
128
+
129
+ def debug(self, message: str, **additional_attributes: AttributeValue) -> None:
130
+ """Log a debug message within the span.
131
+
132
+ Args:
133
+ message: Debug message text.
134
+ **additional_attributes: Additional structured attributes for the log entry.
135
+ """
136
+ self.event("debug", level="debug", message=message, **additional_attributes)
137
+
138
+ def info(self, message: str, **additional_attributes: AttributeValue) -> None:
139
+ """Log an info message within the span.
140
+
141
+ Args:
142
+ message: Info message text.
143
+ **additional_attributes: Additional structured attributes for the log entry.
144
+ """
145
+ self.event("info", level="info", message=message, **additional_attributes)
146
+
147
+ def warning(self, message: str, **additional_attributes: AttributeValue) -> None:
148
+ """Log a warning message within the span.
149
+
150
+ Args:
151
+ message: Warning message text.
152
+ **additional_attributes: Additional structured attributes for the log entry.
153
+ """
154
+ self.event("warning", level="warning", message=message, **additional_attributes)
155
+
156
+ def error(self, message: str, **additional_attributes: AttributeValue) -> None:
157
+ """Log an error message within the span.
158
+
159
+ Args:
160
+ message: Error message text.
161
+ **additional_attributes: Additional structured attributes for the log entry.
162
+ """
163
+ self.event("error", level="error", message=message, **additional_attributes)
164
+ if self._span and not self._finished:
165
+ self._span.set_status(Status(StatusCode.ERROR))
166
+
167
+ def critical(self, message: str, **additional_attributes: AttributeValue) -> None:
168
+ """Log a critical message within the span.
169
+
170
+ Args:
171
+ message: Critical message text.
172
+ **additional_attributes: Additional structured attributes for the log entry.
173
+ """
174
+ self.event("critical", level="error", message=message, **additional_attributes)
175
+ if self._span and not self._finished:
176
+ self._span.set_status(Status(StatusCode.ERROR))
177
+
178
+ def finish(self) -> None:
179
+ """Explicitly finish the span."""
180
+ if not self._finished:
181
+ self._finished = True
182
+ if self._span:
183
+ self._span.end()
184
+ if self._token:
185
+ otel_context.detach(self._token)
186
+ self._token = None
187
+
188
+ @property
189
+ def span_id(self) -> str | None:
190
+ """Get the span ID if available.
191
+
192
+ Returns:
193
+ The span ID or None if not available.
194
+ """
195
+ if span_context := self.span_context:
196
+ return format_span_id(span_context.span_id)
197
+ return None
198
+
199
+ @property
200
+ def trace_id(self) -> str | None:
201
+ if span_context := self.span_context:
202
+ return format_trace_id(span_context.trace_id)
203
+ return None
204
+
205
+ @property
206
+ def is_noop(self) -> bool:
207
+ """Check if this is a no-op span.
208
+
209
+ Returns:
210
+ True if tracing is disabled, False otherwise.
211
+ """
212
+ return self._is_noop
213
+
214
+ @property
215
+ def span_context(self) -> SpanContext | None:
216
+ """Return the span context if available."""
217
+ if otel_span := self._span:
218
+ return otel_span.get_span_context()
219
+ return None
220
+
221
+
222
+ def span(name: str, **attributes: AttributeValue) -> Span:
223
+ """Create a new span context manager.
224
+
225
+ Args:
226
+ name: Name for the new span.
227
+ **attributes: Initial attributes to set on the span.
228
+
229
+ Returns:
230
+ A Span context manager that creates a child span when entered.
231
+ """
232
+ return Span(name, **attributes)
@@ -0,0 +1,389 @@
1
+ """Traced call wrappers for @ops.trace decorated @llm.call functions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from typing import Any, Generic, TypeVar
7
+ from typing_extensions import TypeIs
8
+
9
+ from ..._utils import copy_function_metadata
10
+ from ...llm.calls import AsyncCall, AsyncContextCall, Call, ContextCall
11
+ from ...llm.context import Context, DepsT
12
+ from ...llm.formatting import FormattableT
13
+ from ...llm.responses import (
14
+ AsyncContextResponse,
15
+ AsyncContextStreamResponse,
16
+ AsyncResponse,
17
+ AsyncStreamResponse,
18
+ ContextResponse,
19
+ ContextStreamResponse,
20
+ Response,
21
+ StreamResponse,
22
+ )
23
+ from ...llm.types import P
24
+ from .protocols import (
25
+ AsyncFunction,
26
+ AsyncSpanFunction,
27
+ R,
28
+ SyncFunction,
29
+ SyncSpanFunction,
30
+ )
31
+ from .traced_functions import (
32
+ AsyncTrace,
33
+ AsyncTracedContextFunction,
34
+ AsyncTracedFunction,
35
+ Trace,
36
+ TracedContextFunction,
37
+ TracedFunction,
38
+ )
39
+ from .utils import get_original_fn
40
+
41
+ CallT = TypeVar(
42
+ "CallT",
43
+ bound=Call[..., Any]
44
+ | AsyncCall[..., Any]
45
+ | ContextCall[..., Any, Any]
46
+ | AsyncContextCall[..., Any, Any],
47
+ )
48
+
49
+
50
+ def is_call_type(
51
+ fn: (
52
+ SyncFunction[P, R]
53
+ | AsyncFunction[P, R]
54
+ | SyncSpanFunction[P, R]
55
+ | AsyncSpanFunction[P, R]
56
+ | ContextCall[P, DepsT, FormattableT]
57
+ | AsyncContextCall[P, DepsT, FormattableT]
58
+ | Call[P, FormattableT]
59
+ | AsyncCall[P, FormattableT]
60
+ ),
61
+ ) -> TypeIs[
62
+ ContextCall[P, DepsT, FormattableT]
63
+ | AsyncContextCall[P, DepsT, FormattableT]
64
+ | Call[P, FormattableT]
65
+ | AsyncCall[P, FormattableT]
66
+ ]:
67
+ """Check if fn is any of the Call types."""
68
+ return isinstance(fn, Call | AsyncCall | ContextCall | AsyncContextCall)
69
+
70
+
71
+ def wrap_call(
72
+ fn: (
73
+ ContextCall[P, DepsT, FormattableT]
74
+ | AsyncContextCall[P, DepsT, FormattableT]
75
+ | Call[P, FormattableT]
76
+ | AsyncCall[P, FormattableT]
77
+ ),
78
+ tags: tuple[str, ...],
79
+ metadata: dict[str, str] | None = None,
80
+ ) -> (
81
+ TracedContextCall[P, DepsT, FormattableT]
82
+ | TracedAsyncContextCall[P, DepsT, FormattableT]
83
+ | TracedCall[P, FormattableT]
84
+ | TracedAsyncCall[P, FormattableT]
85
+ ):
86
+ """Wrap a Call object with the appropriate TracedCall type."""
87
+ metadata = metadata or {}
88
+ if isinstance(fn, AsyncContextCall):
89
+ return TracedAsyncContextCall(_call=fn, tags=tags, metadata=metadata)
90
+ elif isinstance(fn, ContextCall):
91
+ return TracedContextCall(_call=fn, tags=tags, metadata=metadata)
92
+ elif isinstance(fn, AsyncCall):
93
+ return TracedAsyncCall(_call=fn, tags=tags, metadata=metadata)
94
+ else:
95
+ return TracedCall(_call=fn, tags=tags, metadata=metadata)
96
+
97
+
98
+ @dataclass(kw_only=True)
99
+ class _BaseTracedCall(Generic[CallT]):
100
+ """Wrapper for traced Call objects."""
101
+
102
+ _call: CallT
103
+ """The original unwrapped Call object."""
104
+
105
+ tags: tuple[str, ...]
106
+ """Tags to be associated with traced calls."""
107
+
108
+ metadata: dict[str, str] = field(default_factory=dict)
109
+ """Arbitrary key-value pairs for additional metadata."""
110
+
111
+ __name__: str = field(init=False, repr=False, default="")
112
+ """The name of the underlying function (preserved for decorator stacking)."""
113
+
114
+ def __post_init__(self) -> None:
115
+ """Preserve standard function attributes for decorator stacking."""
116
+ original_fn = get_original_fn(self._call.prompt.fn)
117
+ copy_function_metadata(self, original_fn)
118
+
119
+
120
+ @dataclass(kw_only=True)
121
+ class TracedCall(_BaseTracedCall[Call[P, FormattableT]]):
122
+ """Traced wrapper for traced synchronous Call objects.
123
+
124
+ When @ops.trace decorates an @llm.call, it returns a TracedCall that wraps
125
+ the call and stream methods with tracing capabilities.
126
+
127
+ Example:
128
+ ```python
129
+ @ops.trace
130
+ @llm.call("gpt-4o-mini")
131
+ def recommend_book(genre: str):
132
+ return f"Recommend a {genre} book"
133
+
134
+ # Returns Response directly (but execution is traced)
135
+ response = recommend_book("fantasy")
136
+ print(response.content)
137
+
138
+ # Same as __call__
139
+ response = recommend_book.call("fantasy")
140
+
141
+ # Streaming returns StreamResponse (traced)
142
+ stream = recommend_book.stream("fantasy")
143
+ for chunk in stream:
144
+ print(chunk)
145
+
146
+ # Use wrapped to get Trace[Response] with span info
147
+ trace = recommend_book.wrapped("fantasy")
148
+ print(trace.result.content)
149
+ print(trace.span_id)
150
+
151
+ # Use wrapped_stream to get Trace[StreamResponse]
152
+ trace = recommend_book.wrapped_stream("fantasy")
153
+ ```
154
+ """
155
+
156
+ call: TracedFunction[P, Response | Response[FormattableT]] = field(init=False)
157
+ """TracedFunction wrapping the call method."""
158
+
159
+ stream: TracedFunction[P, StreamResponse | StreamResponse[FormattableT]] = field(
160
+ init=False
161
+ )
162
+ """TracedFunction wrapping the stream method."""
163
+
164
+ def __post_init__(self) -> None:
165
+ """Initialize TracedFunction wrappers for call and stream methods."""
166
+ super().__post_init__()
167
+ self.call = TracedFunction(
168
+ fn=self._call.call, tags=self.tags, metadata=self.metadata
169
+ )
170
+ self.stream = TracedFunction(
171
+ fn=self._call.stream, tags=self.tags, metadata=self.metadata
172
+ )
173
+
174
+ def __call__(
175
+ self, *args: P.args, **kwargs: P.kwargs
176
+ ) -> Response | Response[FormattableT]:
177
+ """Call the traced function and return Response directly."""
178
+ return self.call(*args, **kwargs)
179
+
180
+ def wrapped(
181
+ self, *args: P.args, **kwargs: P.kwargs
182
+ ) -> Trace[Response | Response[FormattableT]]:
183
+ """Call the traced function and return a wrapped Response."""
184
+ return self.call.wrapped(*args, **kwargs)
185
+
186
+ def wrapped_stream(
187
+ self, *args: P.args, **kwargs: P.kwargs
188
+ ) -> Trace[StreamResponse | StreamResponse[FormattableT]]:
189
+ """Stream the traced function and return a wrapped StreamResponse."""
190
+ return self.stream.wrapped(*args, **kwargs)
191
+
192
+
193
+ @dataclass(kw_only=True)
194
+ class TracedAsyncCall(_BaseTracedCall[AsyncCall[P, FormattableT]]):
195
+ """Traced wrapper for traced asynchronous AsyncCall objects.
196
+
197
+ Example:
198
+ ```python
199
+ @ops.trace
200
+ @llm.call("gpt-4o-mini")
201
+ async def recommend_book(genre: str):
202
+ return f"Recommend a {genre} book"
203
+
204
+ # Returns AsyncResponse directly (but execution is traced)
205
+ response = await recommend_book("fantasy")
206
+ print(response.content)
207
+
208
+ # Use wrapped to get AsyncTrace[AsyncResponse] with span info
209
+ trace = await recommend_book.wrapped("fantasy")
210
+ print(trace.result.content)
211
+ print(trace.span_id)
212
+ ```
213
+ """
214
+
215
+ call: AsyncTracedFunction[P, AsyncResponse | AsyncResponse[FormattableT]] = field(
216
+ init=False
217
+ )
218
+ """AsyncTracedFunction wrapping the call method."""
219
+
220
+ stream: AsyncTracedFunction[
221
+ P, AsyncStreamResponse | AsyncStreamResponse[FormattableT]
222
+ ] = field(init=False)
223
+ """AsyncTracedFunction wrapping the stream method."""
224
+
225
+ def __post_init__(self) -> None:
226
+ """Initialize AsyncTracedFunction wrappers for call and stream methods."""
227
+ super().__post_init__()
228
+ self.call = AsyncTracedFunction(
229
+ fn=self._call.call, tags=self.tags, metadata=self.metadata
230
+ )
231
+ self.stream = AsyncTracedFunction(
232
+ fn=self._call.stream, tags=self.tags, metadata=self.metadata
233
+ )
234
+
235
+ async def __call__(
236
+ self, *args: P.args, **kwargs: P.kwargs
237
+ ) -> AsyncResponse | AsyncResponse[FormattableT]:
238
+ """Call the traced function and return AsyncResponse directly."""
239
+ return await self.call(*args, **kwargs)
240
+
241
+ async def wrapped(
242
+ self, *args: P.args, **kwargs: P.kwargs
243
+ ) -> AsyncTrace[AsyncResponse | AsyncResponse[FormattableT]]:
244
+ """Call the traced function and return a wrapped Response."""
245
+ return await self.call.wrapped(*args, **kwargs)
246
+
247
+ async def wrapped_stream(
248
+ self, *args: P.args, **kwargs: P.kwargs
249
+ ) -> AsyncTrace[AsyncStreamResponse | AsyncStreamResponse[FormattableT]]:
250
+ """Stream the traced function and return a wrapped StreamResponse."""
251
+ return await self.stream.wrapped(*args, **kwargs)
252
+
253
+
254
+ @dataclass(kw_only=True)
255
+ class TracedContextCall(_BaseTracedCall[ContextCall[P, DepsT, FormattableT]]):
256
+ """Traced wrapper for traced synchronous ContextCall objects.
257
+
258
+ Example:
259
+ ```python
260
+ @ops.trace
261
+ @llm.call("gpt-4o-mini")
262
+ def recommend_book(ctx: llm.Context[str], genre: str):
263
+ return f"{ctx.deps} Recommend a {genre} book"
264
+
265
+ ctx = llm.Context(deps="As a librarian,")
266
+
267
+ # Returns ContextResponse directly (but execution is traced)
268
+ response = recommend_book(ctx, "fantasy")
269
+ print(response.content)
270
+
271
+ # Use wrapped to get Trace[ContextResponse] with span info
272
+ trace = recommend_book.wrapped(ctx, "fantasy")
273
+ print(trace.result.content)
274
+ ```
275
+ """
276
+
277
+ call: TracedContextFunction[
278
+ P, DepsT, ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]
279
+ ] = field(init=False)
280
+ """TracedContextFunction wrapping the call method."""
281
+
282
+ stream: TracedContextFunction[
283
+ P,
284
+ DepsT,
285
+ ContextStreamResponse[DepsT, None] | ContextStreamResponse[DepsT, FormattableT],
286
+ ] = field(init=False)
287
+ """TracedContextFunction wrapping the stream method."""
288
+
289
+ def __post_init__(self) -> None:
290
+ """Initialize TracedContextFunction wrappers for call and stream methods."""
291
+ super().__post_init__()
292
+ self.call = TracedContextFunction(
293
+ fn=self._call.call, tags=self.tags, metadata=self.metadata
294
+ )
295
+ self.stream = TracedContextFunction(
296
+ fn=self._call.stream, tags=self.tags, metadata=self.metadata
297
+ )
298
+
299
+ def __call__(
300
+ self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
301
+ ) -> ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]:
302
+ """Call the traced function and return ContextResponse directly."""
303
+ return self.call(ctx, *args, **kwargs)
304
+
305
+ def wrapped(
306
+ self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
307
+ ) -> Trace[ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]]:
308
+ """Call the traced function and return a wrapped Response."""
309
+ return self.call.wrapped(ctx, *args, **kwargs)
310
+
311
+ def wrapped_stream(
312
+ self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
313
+ ) -> Trace[
314
+ ContextStreamResponse[DepsT, None] | ContextStreamResponse[DepsT, FormattableT]
315
+ ]:
316
+ """Stream the traced function and return a wrapped StreamResponse."""
317
+ return self.stream.wrapped(ctx, *args, **kwargs)
318
+
319
+
320
+ @dataclass(kw_only=True)
321
+ class TracedAsyncContextCall(_BaseTracedCall[AsyncContextCall[P, DepsT, FormattableT]]):
322
+ """Traced wrapper for traced asynchronous AsyncContextCall objects.
323
+
324
+ Example:
325
+ ```python
326
+ @ops.trace
327
+ @llm.call("gpt-4o-mini")
328
+ async def recommend_book(ctx: llm.Context[str], genre: str):
329
+ return f"{ctx.deps} Recommend a {genre} book"
330
+
331
+ ctx = llm.Context(deps="As a librarian,")
332
+
333
+ # Returns AsyncContextResponse directly (but execution is traced)
334
+ response = await recommend_book(ctx, "fantasy")
335
+ print(response.content)
336
+
337
+ # Use wrapped to get AsyncTrace[AsyncContextResponse] with span info
338
+ trace = await recommend_book.wrapped(ctx, "fantasy")
339
+ print(trace.result.content)
340
+ ```
341
+ """
342
+
343
+ call: AsyncTracedContextFunction[
344
+ P,
345
+ DepsT,
346
+ AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT],
347
+ ] = field(init=False)
348
+ """AsyncTracedContextFunction wrapping the call method."""
349
+
350
+ stream: AsyncTracedContextFunction[
351
+ P,
352
+ DepsT,
353
+ AsyncContextStreamResponse[DepsT, None]
354
+ | AsyncContextStreamResponse[DepsT, FormattableT],
355
+ ] = field(init=False)
356
+ """AsyncTracedContextFunction wrapping the stream method."""
357
+
358
+ def __post_init__(self) -> None:
359
+ """Initialize AsyncTracedContextFunction wrappers for call and stream methods."""
360
+ super().__post_init__()
361
+ self.call = AsyncTracedContextFunction(
362
+ fn=self._call.call, tags=self.tags, metadata=self.metadata
363
+ )
364
+ self.stream = AsyncTracedContextFunction(
365
+ fn=self._call.stream, tags=self.tags, metadata=self.metadata
366
+ )
367
+
368
+ async def __call__(
369
+ self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
370
+ ) -> AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT]:
371
+ """Call the traced function and return AsyncContextResponse directly."""
372
+ return await self.call(ctx, *args, **kwargs)
373
+
374
+ async def wrapped(
375
+ self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
376
+ ) -> AsyncTrace[
377
+ AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT]
378
+ ]:
379
+ """Call the traced function and return a wrapped Response."""
380
+ return await self.call.wrapped(ctx, *args, **kwargs)
381
+
382
+ async def wrapped_stream(
383
+ self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
384
+ ) -> AsyncTrace[
385
+ AsyncContextStreamResponse[DepsT, None]
386
+ | AsyncContextStreamResponse[DepsT, FormattableT]
387
+ ]:
388
+ """Stream the traced function and return a wrapped StreamResponse."""
389
+ return await self.stream.wrapped(ctx, *args, **kwargs)