mirascope 2.0.0__py3-none-any.whl → 2.0.0a0__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 (442) hide show
  1. mirascope/__init__.py +2 -11
  2. mirascope/graphs/__init__.py +22 -0
  3. mirascope/graphs/finite_state_machine.py +625 -0
  4. mirascope/llm/__init__.py +16 -101
  5. mirascope/llm/agents/__init__.py +15 -0
  6. mirascope/llm/agents/agent.py +97 -0
  7. mirascope/llm/agents/agent_template.py +45 -0
  8. mirascope/llm/agents/decorator.py +176 -0
  9. mirascope/llm/calls/__init__.py +1 -2
  10. mirascope/llm/calls/base_call.py +33 -0
  11. mirascope/llm/calls/calls.py +58 -84
  12. mirascope/llm/calls/decorator.py +120 -140
  13. mirascope/llm/clients/__init__.py +34 -0
  14. mirascope/llm/clients/anthropic/__init__.py +11 -0
  15. mirascope/llm/{providers/openai/completions → clients/anthropic}/_utils/__init__.py +0 -2
  16. mirascope/llm/{providers → clients}/anthropic/_utils/decode.py +22 -66
  17. mirascope/llm/clients/anthropic/_utils/encode.py +243 -0
  18. mirascope/llm/clients/anthropic/clients.py +819 -0
  19. mirascope/llm/clients/anthropic/model_ids.py +8 -0
  20. mirascope/llm/{providers → clients}/base/__init__.py +5 -4
  21. mirascope/llm/{providers → clients}/base/_utils.py +17 -78
  22. mirascope/llm/{providers/base/base_provider.py → clients/base/client.py} +145 -468
  23. mirascope/llm/{models → clients/base}/params.py +37 -16
  24. mirascope/llm/clients/google/__init__.py +6 -0
  25. mirascope/llm/{providers/openai/responses → clients/google}/_utils/__init__.py +0 -2
  26. mirascope/llm/{providers → clients}/google/_utils/decode.py +22 -98
  27. mirascope/llm/{providers → clients}/google/_utils/encode.py +46 -168
  28. mirascope/llm/clients/google/clients.py +853 -0
  29. mirascope/llm/clients/google/model_ids.py +15 -0
  30. mirascope/llm/clients/openai/__init__.py +25 -0
  31. mirascope/llm/clients/openai/completions/__init__.py +9 -0
  32. mirascope/llm/{providers/google → clients/openai/completions}/_utils/__init__.py +0 -4
  33. mirascope/llm/{providers → clients}/openai/completions/_utils/decode.py +9 -74
  34. mirascope/llm/{providers → clients}/openai/completions/_utils/encode.py +52 -70
  35. mirascope/llm/clients/openai/completions/_utils/model_features.py +81 -0
  36. mirascope/llm/clients/openai/completions/clients.py +833 -0
  37. mirascope/llm/clients/openai/completions/model_ids.py +8 -0
  38. mirascope/llm/clients/openai/responses/__init__.py +9 -0
  39. mirascope/llm/clients/openai/responses/_utils/__init__.py +13 -0
  40. mirascope/llm/{providers → clients}/openai/responses/_utils/decode.py +14 -80
  41. mirascope/llm/{providers → clients}/openai/responses/_utils/encode.py +41 -92
  42. mirascope/llm/clients/openai/responses/_utils/model_features.py +87 -0
  43. mirascope/llm/clients/openai/responses/clients.py +832 -0
  44. mirascope/llm/clients/openai/responses/model_ids.py +8 -0
  45. mirascope/llm/clients/openai/shared/__init__.py +7 -0
  46. mirascope/llm/clients/openai/shared/_utils.py +55 -0
  47. mirascope/llm/clients/providers.py +175 -0
  48. mirascope/llm/content/__init__.py +2 -3
  49. mirascope/llm/content/tool_call.py +0 -6
  50. mirascope/llm/content/tool_output.py +5 -22
  51. mirascope/llm/context/_utils.py +6 -19
  52. mirascope/llm/exceptions.py +43 -298
  53. mirascope/llm/formatting/__init__.py +2 -19
  54. mirascope/llm/formatting/_utils.py +74 -0
  55. mirascope/llm/formatting/format.py +30 -219
  56. mirascope/llm/formatting/from_call_args.py +2 -2
  57. mirascope/llm/formatting/partial.py +7 -80
  58. mirascope/llm/formatting/types.py +64 -21
  59. mirascope/llm/mcp/__init__.py +2 -2
  60. mirascope/llm/mcp/client.py +118 -0
  61. mirascope/llm/messages/__init__.py +0 -3
  62. mirascope/llm/messages/message.py +5 -13
  63. mirascope/llm/models/__init__.py +2 -7
  64. mirascope/llm/models/models.py +139 -315
  65. mirascope/llm/prompts/__init__.py +12 -13
  66. mirascope/llm/prompts/_utils.py +43 -14
  67. mirascope/llm/prompts/decorator.py +204 -144
  68. mirascope/llm/prompts/protocols.py +59 -25
  69. mirascope/llm/responses/__init__.py +1 -9
  70. mirascope/llm/responses/_utils.py +12 -102
  71. mirascope/llm/responses/base_response.py +6 -18
  72. mirascope/llm/responses/base_stream_response.py +50 -173
  73. mirascope/llm/responses/finish_reason.py +0 -1
  74. mirascope/llm/responses/response.py +13 -34
  75. mirascope/llm/responses/root_response.py +29 -100
  76. mirascope/llm/responses/stream_response.py +31 -40
  77. mirascope/llm/tools/__init__.py +2 -9
  78. mirascope/llm/tools/_utils.py +3 -12
  79. mirascope/llm/tools/decorator.py +16 -25
  80. mirascope/llm/tools/protocols.py +4 -4
  81. mirascope/llm/tools/tool_schema.py +19 -87
  82. mirascope/llm/tools/toolkit.py +27 -35
  83. mirascope/llm/tools/tools.py +41 -135
  84. {mirascope-2.0.0.dist-info → mirascope-2.0.0a0.dist-info}/METADATA +9 -95
  85. mirascope-2.0.0a0.dist-info/RECORD +101 -0
  86. {mirascope-2.0.0.dist-info → mirascope-2.0.0a0.dist-info}/WHEEL +1 -1
  87. {mirascope-2.0.0.dist-info → mirascope-2.0.0a0.dist-info}/licenses/LICENSE +1 -1
  88. mirascope/_stubs.py +0 -363
  89. mirascope/api/__init__.py +0 -14
  90. mirascope/api/_generated/README.md +0 -207
  91. mirascope/api/_generated/__init__.py +0 -440
  92. mirascope/api/_generated/annotations/__init__.py +0 -33
  93. mirascope/api/_generated/annotations/client.py +0 -506
  94. mirascope/api/_generated/annotations/raw_client.py +0 -1414
  95. mirascope/api/_generated/annotations/types/__init__.py +0 -31
  96. mirascope/api/_generated/annotations/types/annotations_create_request_label.py +0 -5
  97. mirascope/api/_generated/annotations/types/annotations_create_response.py +0 -48
  98. mirascope/api/_generated/annotations/types/annotations_create_response_label.py +0 -5
  99. mirascope/api/_generated/annotations/types/annotations_get_response.py +0 -48
  100. mirascope/api/_generated/annotations/types/annotations_get_response_label.py +0 -5
  101. mirascope/api/_generated/annotations/types/annotations_list_request_label.py +0 -5
  102. mirascope/api/_generated/annotations/types/annotations_list_response.py +0 -21
  103. mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item.py +0 -50
  104. mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item_label.py +0 -5
  105. mirascope/api/_generated/annotations/types/annotations_update_request_label.py +0 -5
  106. mirascope/api/_generated/annotations/types/annotations_update_response.py +0 -48
  107. mirascope/api/_generated/annotations/types/annotations_update_response_label.py +0 -5
  108. mirascope/api/_generated/api_keys/__init__.py +0 -17
  109. mirascope/api/_generated/api_keys/client.py +0 -530
  110. mirascope/api/_generated/api_keys/raw_client.py +0 -1236
  111. mirascope/api/_generated/api_keys/types/__init__.py +0 -15
  112. mirascope/api/_generated/api_keys/types/api_keys_create_response.py +0 -28
  113. mirascope/api/_generated/api_keys/types/api_keys_get_response.py +0 -27
  114. mirascope/api/_generated/api_keys/types/api_keys_list_all_for_org_response_item.py +0 -40
  115. mirascope/api/_generated/api_keys/types/api_keys_list_response_item.py +0 -27
  116. mirascope/api/_generated/client.py +0 -211
  117. mirascope/api/_generated/core/__init__.py +0 -52
  118. mirascope/api/_generated/core/api_error.py +0 -23
  119. mirascope/api/_generated/core/client_wrapper.py +0 -46
  120. mirascope/api/_generated/core/datetime_utils.py +0 -28
  121. mirascope/api/_generated/core/file.py +0 -67
  122. mirascope/api/_generated/core/force_multipart.py +0 -16
  123. mirascope/api/_generated/core/http_client.py +0 -543
  124. mirascope/api/_generated/core/http_response.py +0 -55
  125. mirascope/api/_generated/core/jsonable_encoder.py +0 -100
  126. mirascope/api/_generated/core/pydantic_utilities.py +0 -255
  127. mirascope/api/_generated/core/query_encoder.py +0 -58
  128. mirascope/api/_generated/core/remove_none_from_dict.py +0 -11
  129. mirascope/api/_generated/core/request_options.py +0 -35
  130. mirascope/api/_generated/core/serialization.py +0 -276
  131. mirascope/api/_generated/docs/__init__.py +0 -4
  132. mirascope/api/_generated/docs/client.py +0 -91
  133. mirascope/api/_generated/docs/raw_client.py +0 -178
  134. mirascope/api/_generated/environment.py +0 -9
  135. mirascope/api/_generated/environments/__init__.py +0 -23
  136. mirascope/api/_generated/environments/client.py +0 -649
  137. mirascope/api/_generated/environments/raw_client.py +0 -1567
  138. mirascope/api/_generated/environments/types/__init__.py +0 -25
  139. mirascope/api/_generated/environments/types/environments_create_response.py +0 -24
  140. mirascope/api/_generated/environments/types/environments_get_analytics_response.py +0 -60
  141. mirascope/api/_generated/environments/types/environments_get_analytics_response_top_functions_item.py +0 -24
  142. mirascope/api/_generated/environments/types/environments_get_analytics_response_top_models_item.py +0 -22
  143. mirascope/api/_generated/environments/types/environments_get_response.py +0 -24
  144. mirascope/api/_generated/environments/types/environments_list_response_item.py +0 -24
  145. mirascope/api/_generated/environments/types/environments_update_response.py +0 -24
  146. mirascope/api/_generated/errors/__init__.py +0 -25
  147. mirascope/api/_generated/errors/bad_request_error.py +0 -14
  148. mirascope/api/_generated/errors/conflict_error.py +0 -14
  149. mirascope/api/_generated/errors/forbidden_error.py +0 -11
  150. mirascope/api/_generated/errors/internal_server_error.py +0 -10
  151. mirascope/api/_generated/errors/not_found_error.py +0 -11
  152. mirascope/api/_generated/errors/payment_required_error.py +0 -15
  153. mirascope/api/_generated/errors/service_unavailable_error.py +0 -14
  154. mirascope/api/_generated/errors/too_many_requests_error.py +0 -15
  155. mirascope/api/_generated/errors/unauthorized_error.py +0 -11
  156. mirascope/api/_generated/functions/__init__.py +0 -39
  157. mirascope/api/_generated/functions/client.py +0 -647
  158. mirascope/api/_generated/functions/raw_client.py +0 -1890
  159. mirascope/api/_generated/functions/types/__init__.py +0 -53
  160. mirascope/api/_generated/functions/types/functions_create_request_dependencies_value.py +0 -20
  161. mirascope/api/_generated/functions/types/functions_create_response.py +0 -37
  162. mirascope/api/_generated/functions/types/functions_create_response_dependencies_value.py +0 -20
  163. mirascope/api/_generated/functions/types/functions_find_by_hash_response.py +0 -39
  164. mirascope/api/_generated/functions/types/functions_find_by_hash_response_dependencies_value.py +0 -20
  165. mirascope/api/_generated/functions/types/functions_get_by_env_response.py +0 -53
  166. mirascope/api/_generated/functions/types/functions_get_by_env_response_dependencies_value.py +0 -22
  167. mirascope/api/_generated/functions/types/functions_get_response.py +0 -37
  168. mirascope/api/_generated/functions/types/functions_get_response_dependencies_value.py +0 -20
  169. mirascope/api/_generated/functions/types/functions_list_by_env_response.py +0 -25
  170. mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item.py +0 -56
  171. mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item_dependencies_value.py +0 -22
  172. mirascope/api/_generated/functions/types/functions_list_response.py +0 -21
  173. mirascope/api/_generated/functions/types/functions_list_response_functions_item.py +0 -41
  174. mirascope/api/_generated/functions/types/functions_list_response_functions_item_dependencies_value.py +0 -20
  175. mirascope/api/_generated/health/__init__.py +0 -7
  176. mirascope/api/_generated/health/client.py +0 -92
  177. mirascope/api/_generated/health/raw_client.py +0 -175
  178. mirascope/api/_generated/health/types/__init__.py +0 -8
  179. mirascope/api/_generated/health/types/health_check_response.py +0 -22
  180. mirascope/api/_generated/health/types/health_check_response_status.py +0 -5
  181. mirascope/api/_generated/organization_invitations/__init__.py +0 -33
  182. mirascope/api/_generated/organization_invitations/client.py +0 -546
  183. mirascope/api/_generated/organization_invitations/raw_client.py +0 -1519
  184. mirascope/api/_generated/organization_invitations/types/__init__.py +0 -53
  185. mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response.py +0 -34
  186. mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response_role.py +0 -7
  187. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_request_role.py +0 -7
  188. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response.py +0 -48
  189. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_role.py +0 -7
  190. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_status.py +0 -7
  191. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response.py +0 -48
  192. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_role.py +0 -7
  193. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_status.py +0 -7
  194. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item.py +0 -48
  195. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_role.py +0 -7
  196. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_status.py +0 -7
  197. mirascope/api/_generated/organization_memberships/__init__.py +0 -19
  198. mirascope/api/_generated/organization_memberships/client.py +0 -302
  199. mirascope/api/_generated/organization_memberships/raw_client.py +0 -736
  200. mirascope/api/_generated/organization_memberships/types/__init__.py +0 -27
  201. mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item.py +0 -33
  202. mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item_role.py +0 -7
  203. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_request_role.py +0 -7
  204. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response.py +0 -31
  205. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response_role.py +0 -7
  206. mirascope/api/_generated/organizations/__init__.py +0 -51
  207. mirascope/api/_generated/organizations/client.py +0 -869
  208. mirascope/api/_generated/organizations/raw_client.py +0 -2593
  209. mirascope/api/_generated/organizations/types/__init__.py +0 -71
  210. mirascope/api/_generated/organizations/types/organizations_create_payment_intent_response.py +0 -24
  211. mirascope/api/_generated/organizations/types/organizations_create_response.py +0 -26
  212. mirascope/api/_generated/organizations/types/organizations_create_response_role.py +0 -5
  213. mirascope/api/_generated/organizations/types/organizations_get_response.py +0 -26
  214. mirascope/api/_generated/organizations/types/organizations_get_response_role.py +0 -5
  215. mirascope/api/_generated/organizations/types/organizations_list_response_item.py +0 -26
  216. mirascope/api/_generated/organizations/types/organizations_list_response_item_role.py +0 -5
  217. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_request_target_plan.py +0 -7
  218. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response.py +0 -47
  219. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item.py +0 -33
  220. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item_resource.py +0 -7
  221. mirascope/api/_generated/organizations/types/organizations_router_balance_response.py +0 -24
  222. mirascope/api/_generated/organizations/types/organizations_subscription_response.py +0 -53
  223. mirascope/api/_generated/organizations/types/organizations_subscription_response_current_plan.py +0 -7
  224. mirascope/api/_generated/organizations/types/organizations_subscription_response_payment_method.py +0 -26
  225. mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change.py +0 -34
  226. mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change_target_plan.py +0 -7
  227. mirascope/api/_generated/organizations/types/organizations_update_response.py +0 -26
  228. mirascope/api/_generated/organizations/types/organizations_update_response_role.py +0 -5
  229. mirascope/api/_generated/organizations/types/organizations_update_subscription_request_target_plan.py +0 -7
  230. mirascope/api/_generated/organizations/types/organizations_update_subscription_response.py +0 -35
  231. mirascope/api/_generated/project_memberships/__init__.py +0 -25
  232. mirascope/api/_generated/project_memberships/client.py +0 -437
  233. mirascope/api/_generated/project_memberships/raw_client.py +0 -1039
  234. mirascope/api/_generated/project_memberships/types/__init__.py +0 -29
  235. mirascope/api/_generated/project_memberships/types/project_memberships_create_request_role.py +0 -7
  236. mirascope/api/_generated/project_memberships/types/project_memberships_create_response.py +0 -35
  237. mirascope/api/_generated/project_memberships/types/project_memberships_create_response_role.py +0 -7
  238. mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item.py +0 -33
  239. mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item_role.py +0 -7
  240. mirascope/api/_generated/project_memberships/types/project_memberships_update_request_role.py +0 -7
  241. mirascope/api/_generated/project_memberships/types/project_memberships_update_response.py +0 -35
  242. mirascope/api/_generated/project_memberships/types/project_memberships_update_response_role.py +0 -7
  243. mirascope/api/_generated/projects/__init__.py +0 -7
  244. mirascope/api/_generated/projects/client.py +0 -428
  245. mirascope/api/_generated/projects/raw_client.py +0 -1302
  246. mirascope/api/_generated/projects/types/__init__.py +0 -10
  247. mirascope/api/_generated/projects/types/projects_create_response.py +0 -25
  248. mirascope/api/_generated/projects/types/projects_get_response.py +0 -25
  249. mirascope/api/_generated/projects/types/projects_list_response_item.py +0 -25
  250. mirascope/api/_generated/projects/types/projects_update_response.py +0 -25
  251. mirascope/api/_generated/reference.md +0 -4915
  252. mirascope/api/_generated/tags/__init__.py +0 -19
  253. mirascope/api/_generated/tags/client.py +0 -504
  254. mirascope/api/_generated/tags/raw_client.py +0 -1288
  255. mirascope/api/_generated/tags/types/__init__.py +0 -17
  256. mirascope/api/_generated/tags/types/tags_create_response.py +0 -41
  257. mirascope/api/_generated/tags/types/tags_get_response.py +0 -41
  258. mirascope/api/_generated/tags/types/tags_list_response.py +0 -23
  259. mirascope/api/_generated/tags/types/tags_list_response_tags_item.py +0 -41
  260. mirascope/api/_generated/tags/types/tags_update_response.py +0 -41
  261. mirascope/api/_generated/token_cost/__init__.py +0 -7
  262. mirascope/api/_generated/token_cost/client.py +0 -160
  263. mirascope/api/_generated/token_cost/raw_client.py +0 -264
  264. mirascope/api/_generated/token_cost/types/__init__.py +0 -8
  265. mirascope/api/_generated/token_cost/types/token_cost_calculate_request_usage.py +0 -54
  266. mirascope/api/_generated/token_cost/types/token_cost_calculate_response.py +0 -52
  267. mirascope/api/_generated/traces/__init__.py +0 -97
  268. mirascope/api/_generated/traces/client.py +0 -1103
  269. mirascope/api/_generated/traces/raw_client.py +0 -2322
  270. mirascope/api/_generated/traces/types/__init__.py +0 -155
  271. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item.py +0 -29
  272. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource.py +0 -27
  273. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item.py +0 -23
  274. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value.py +0 -38
  275. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_array_value.py +0 -19
  276. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value.py +0 -22
  277. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value_values_item.py +0 -20
  278. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item.py +0 -29
  279. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope.py +0 -31
  280. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item.py +0 -23
  281. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value.py +0 -38
  282. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_array_value.py +0 -19
  283. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value.py +0 -22
  284. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value_values_item.py +0 -22
  285. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item.py +0 -48
  286. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item.py +0 -23
  287. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value.py +0 -38
  288. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_array_value.py +0 -19
  289. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value.py +0 -24
  290. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value_values_item.py +0 -22
  291. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_status.py +0 -20
  292. mirascope/api/_generated/traces/types/traces_create_response.py +0 -24
  293. mirascope/api/_generated/traces/types/traces_create_response_partial_success.py +0 -22
  294. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response.py +0 -60
  295. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_functions_item.py +0 -24
  296. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_models_item.py +0 -22
  297. mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response.py +0 -33
  298. mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response_spans_item.py +0 -88
  299. mirascope/api/_generated/traces/types/traces_get_trace_detail_response.py +0 -33
  300. mirascope/api/_generated/traces/types/traces_get_trace_detail_response_spans_item.py +0 -88
  301. mirascope/api/_generated/traces/types/traces_list_by_function_hash_response.py +0 -25
  302. mirascope/api/_generated/traces/types/traces_list_by_function_hash_response_traces_item.py +0 -44
  303. mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item.py +0 -26
  304. mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item_operator.py +0 -7
  305. mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_by.py +0 -7
  306. mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_order.py +0 -7
  307. mirascope/api/_generated/traces/types/traces_search_by_env_response.py +0 -26
  308. mirascope/api/_generated/traces/types/traces_search_by_env_response_spans_item.py +0 -50
  309. mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item.py +0 -26
  310. mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item_operator.py +0 -7
  311. mirascope/api/_generated/traces/types/traces_search_request_sort_by.py +0 -7
  312. mirascope/api/_generated/traces/types/traces_search_request_sort_order.py +0 -5
  313. mirascope/api/_generated/traces/types/traces_search_response.py +0 -26
  314. mirascope/api/_generated/traces/types/traces_search_response_spans_item.py +0 -50
  315. mirascope/api/_generated/types/__init__.py +0 -85
  316. mirascope/api/_generated/types/already_exists_error.py +0 -22
  317. mirascope/api/_generated/types/already_exists_error_tag.py +0 -5
  318. mirascope/api/_generated/types/bad_request_error_body.py +0 -50
  319. mirascope/api/_generated/types/click_house_error.py +0 -22
  320. mirascope/api/_generated/types/database_error.py +0 -22
  321. mirascope/api/_generated/types/database_error_tag.py +0 -5
  322. mirascope/api/_generated/types/date.py +0 -3
  323. mirascope/api/_generated/types/http_api_decode_error.py +0 -27
  324. mirascope/api/_generated/types/http_api_decode_error_tag.py +0 -5
  325. mirascope/api/_generated/types/immutable_resource_error.py +0 -22
  326. mirascope/api/_generated/types/internal_server_error_body.py +0 -49
  327. mirascope/api/_generated/types/issue.py +0 -38
  328. mirascope/api/_generated/types/issue_tag.py +0 -10
  329. mirascope/api/_generated/types/not_found_error_body.py +0 -22
  330. mirascope/api/_generated/types/not_found_error_tag.py +0 -5
  331. mirascope/api/_generated/types/number_from_string.py +0 -3
  332. mirascope/api/_generated/types/permission_denied_error.py +0 -22
  333. mirascope/api/_generated/types/permission_denied_error_tag.py +0 -5
  334. mirascope/api/_generated/types/plan_limit_exceeded_error.py +0 -32
  335. mirascope/api/_generated/types/plan_limit_exceeded_error_tag.py +0 -7
  336. mirascope/api/_generated/types/pricing_unavailable_error.py +0 -23
  337. mirascope/api/_generated/types/property_key.py +0 -7
  338. mirascope/api/_generated/types/property_key_key.py +0 -25
  339. mirascope/api/_generated/types/property_key_key_tag.py +0 -5
  340. mirascope/api/_generated/types/rate_limit_error.py +0 -31
  341. mirascope/api/_generated/types/rate_limit_error_tag.py +0 -5
  342. mirascope/api/_generated/types/service_unavailable_error_body.py +0 -24
  343. mirascope/api/_generated/types/service_unavailable_error_tag.py +0 -7
  344. mirascope/api/_generated/types/stripe_error.py +0 -20
  345. mirascope/api/_generated/types/subscription_past_due_error.py +0 -31
  346. mirascope/api/_generated/types/subscription_past_due_error_tag.py +0 -7
  347. mirascope/api/_generated/types/unauthorized_error_body.py +0 -21
  348. mirascope/api/_generated/types/unauthorized_error_tag.py +0 -5
  349. mirascope/api/client.py +0 -255
  350. mirascope/api/settings.py +0 -99
  351. mirascope/llm/formatting/output_parser.py +0 -178
  352. mirascope/llm/formatting/primitives.py +0 -192
  353. mirascope/llm/mcp/mcp_client.py +0 -130
  354. mirascope/llm/messages/_utils.py +0 -34
  355. mirascope/llm/models/thinking_config.py +0 -61
  356. mirascope/llm/prompts/prompts.py +0 -487
  357. mirascope/llm/providers/__init__.py +0 -62
  358. mirascope/llm/providers/anthropic/__init__.py +0 -11
  359. mirascope/llm/providers/anthropic/_utils/__init__.py +0 -27
  360. mirascope/llm/providers/anthropic/_utils/beta_decode.py +0 -282
  361. mirascope/llm/providers/anthropic/_utils/beta_encode.py +0 -266
  362. mirascope/llm/providers/anthropic/_utils/encode.py +0 -418
  363. mirascope/llm/providers/anthropic/_utils/errors.py +0 -46
  364. mirascope/llm/providers/anthropic/beta_provider.py +0 -374
  365. mirascope/llm/providers/anthropic/model_id.py +0 -23
  366. mirascope/llm/providers/anthropic/model_info.py +0 -87
  367. mirascope/llm/providers/anthropic/provider.py +0 -479
  368. mirascope/llm/providers/google/__init__.py +0 -6
  369. mirascope/llm/providers/google/_utils/errors.py +0 -50
  370. mirascope/llm/providers/google/model_id.py +0 -22
  371. mirascope/llm/providers/google/model_info.py +0 -63
  372. mirascope/llm/providers/google/provider.py +0 -492
  373. mirascope/llm/providers/mirascope/__init__.py +0 -5
  374. mirascope/llm/providers/mirascope/_utils.py +0 -73
  375. mirascope/llm/providers/mirascope/provider.py +0 -349
  376. mirascope/llm/providers/mlx/__init__.py +0 -9
  377. mirascope/llm/providers/mlx/_utils.py +0 -141
  378. mirascope/llm/providers/mlx/encoding/__init__.py +0 -8
  379. mirascope/llm/providers/mlx/encoding/base.py +0 -72
  380. mirascope/llm/providers/mlx/encoding/transformers.py +0 -150
  381. mirascope/llm/providers/mlx/mlx.py +0 -254
  382. mirascope/llm/providers/mlx/model_id.py +0 -17
  383. mirascope/llm/providers/mlx/provider.py +0 -452
  384. mirascope/llm/providers/model_id.py +0 -16
  385. mirascope/llm/providers/ollama/__init__.py +0 -7
  386. mirascope/llm/providers/ollama/provider.py +0 -71
  387. mirascope/llm/providers/openai/__init__.py +0 -15
  388. mirascope/llm/providers/openai/_utils/__init__.py +0 -5
  389. mirascope/llm/providers/openai/_utils/errors.py +0 -46
  390. mirascope/llm/providers/openai/completions/__init__.py +0 -7
  391. mirascope/llm/providers/openai/completions/base_provider.py +0 -542
  392. mirascope/llm/providers/openai/completions/provider.py +0 -22
  393. mirascope/llm/providers/openai/model_id.py +0 -31
  394. mirascope/llm/providers/openai/model_info.py +0 -303
  395. mirascope/llm/providers/openai/provider.py +0 -441
  396. mirascope/llm/providers/openai/responses/__init__.py +0 -5
  397. mirascope/llm/providers/openai/responses/provider.py +0 -513
  398. mirascope/llm/providers/provider_id.py +0 -24
  399. mirascope/llm/providers/provider_registry.py +0 -299
  400. mirascope/llm/providers/together/__init__.py +0 -7
  401. mirascope/llm/providers/together/provider.py +0 -40
  402. mirascope/llm/responses/usage.py +0 -95
  403. mirascope/ops/__init__.py +0 -111
  404. mirascope/ops/_internal/__init__.py +0 -5
  405. mirascope/ops/_internal/closure.py +0 -1169
  406. mirascope/ops/_internal/configuration.py +0 -177
  407. mirascope/ops/_internal/context.py +0 -76
  408. mirascope/ops/_internal/exporters/__init__.py +0 -26
  409. mirascope/ops/_internal/exporters/exporters.py +0 -395
  410. mirascope/ops/_internal/exporters/processors.py +0 -104
  411. mirascope/ops/_internal/exporters/types.py +0 -165
  412. mirascope/ops/_internal/exporters/utils.py +0 -29
  413. mirascope/ops/_internal/instrumentation/__init__.py +0 -8
  414. mirascope/ops/_internal/instrumentation/llm/__init__.py +0 -8
  415. mirascope/ops/_internal/instrumentation/llm/common.py +0 -530
  416. mirascope/ops/_internal/instrumentation/llm/cost.py +0 -190
  417. mirascope/ops/_internal/instrumentation/llm/encode.py +0 -238
  418. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/__init__.py +0 -38
  419. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_input_messages.py +0 -31
  420. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_output_messages.py +0 -38
  421. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_system_instructions.py +0 -18
  422. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/shared.py +0 -100
  423. mirascope/ops/_internal/instrumentation/llm/llm.py +0 -161
  424. mirascope/ops/_internal/instrumentation/llm/model.py +0 -1798
  425. mirascope/ops/_internal/instrumentation/llm/response.py +0 -521
  426. mirascope/ops/_internal/instrumentation/llm/serialize.py +0 -300
  427. mirascope/ops/_internal/propagation.py +0 -198
  428. mirascope/ops/_internal/protocols.py +0 -133
  429. mirascope/ops/_internal/session.py +0 -139
  430. mirascope/ops/_internal/spans.py +0 -232
  431. mirascope/ops/_internal/traced_calls.py +0 -375
  432. mirascope/ops/_internal/traced_functions.py +0 -523
  433. mirascope/ops/_internal/tracing.py +0 -353
  434. mirascope/ops/_internal/types.py +0 -13
  435. mirascope/ops/_internal/utils.py +0 -123
  436. mirascope/ops/_internal/versioned_calls.py +0 -512
  437. mirascope/ops/_internal/versioned_functions.py +0 -357
  438. mirascope/ops/_internal/versioning.py +0 -303
  439. mirascope/ops/exceptions.py +0 -21
  440. mirascope-2.0.0.dist-info/RECORD +0 -423
  441. /mirascope/llm/{providers → clients}/base/kwargs.py +0 -0
  442. /mirascope/llm/{providers → clients}/google/message.py +0 -0
@@ -1,177 +0,0 @@
1
- """Configuration utilities for Mirascope ops module initialization and setup."""
2
-
3
- from __future__ import annotations
4
-
5
- import logging
6
- from collections.abc import Iterator
7
- from contextlib import contextmanager
8
- from typing import TYPE_CHECKING
9
-
10
- from opentelemetry import trace as otel_trace
11
- from opentelemetry.sdk.trace import TracerProvider
12
- from opentelemetry.sdk.trace.export import BatchSpanProcessor
13
-
14
- from ...api.client import Mirascope
15
- from ...api.settings import update_settings
16
- from .exporters import MirascopeOTLPExporter
17
-
18
- if TYPE_CHECKING:
19
- from opentelemetry.trace import Tracer
20
-
21
- DEFAULT_TRACER_NAME = "mirascope.llm"
22
-
23
- logger = logging.getLogger(__name__)
24
-
25
- _tracer_provider: TracerProvider | None = None
26
- _tracer_name: str = DEFAULT_TRACER_NAME
27
- _tracer_version: str | None = None
28
- _tracer: Tracer | None = None
29
-
30
-
31
- def _create_mirascope_cloud_provider(
32
- api_key: str | None = None, base_url: str | None = None
33
- ) -> TracerProvider:
34
- """Create a TracerProvider configured for Mirascope Cloud.
35
-
36
- Args:
37
- api_key: Optional API key. If not provided, uses MIRASCOPE_API_KEY env var.
38
-
39
- Returns:
40
- Configured TracerProvider with MirascopeOTLPExporter.
41
-
42
- Raises:
43
- RuntimeError: If API key is not available.
44
- """
45
- try:
46
- client = Mirascope(api_key=api_key, base_url=base_url)
47
- except (ValueError, RuntimeError) as e:
48
- raise RuntimeError(
49
- "Failed to create Mirascope Cloud client. "
50
- "Set MIRASCOPE_API_KEY environment variable or pass api_key parameter."
51
- ) from e
52
-
53
- exporter = MirascopeOTLPExporter(client=client)
54
- provider = TracerProvider()
55
- provider.add_span_processor(BatchSpanProcessor(exporter))
56
-
57
- return provider
58
-
59
-
60
- def configure(
61
- *,
62
- api_key: str | None = None,
63
- base_url: str | None = None,
64
- tracer_provider: TracerProvider | None = None,
65
- tracer_name: str = DEFAULT_TRACER_NAME,
66
- tracer_version: str | None = None,
67
- ) -> None:
68
- """Configure the ops module for tracing.
69
-
70
- When called without arguments, automatically configures Mirascope Cloud
71
- using the MIRASCOPE_API_KEY environment variable.
72
-
73
- Args:
74
- tracer_provider: Optional custom TracerProvider. If provided, this takes
75
- precedence over automatic Mirascope Cloud configuration.
76
- api_key: Optional Mirascope Cloud API key. If not provided, uses
77
- MIRASCOPE_API_KEY environment variable.
78
- tracer_name: Tracer name to use when creating a tracer.
79
- Defaults to "mirascope.llm".
80
- tracer_version: Optional tracer version.
81
-
82
- Raises:
83
- RuntimeError: If no tracer_provider is given and Mirascope Cloud
84
- cannot be configured (missing API key).
85
-
86
- Example:
87
- Simple Mirascope Cloud configuration (recommended):
88
- ```python
89
- import os
90
- os.environ["MIRASCOPE_API_KEY"] = "your-api-key"
91
-
92
- from mirascope import ops
93
-
94
- ops.configure() # Automatically uses Mirascope Cloud
95
- ```
96
-
97
- With explicit API key:
98
- ```python
99
- from mirascope import ops
100
-
101
- ops.configure(api_key="your-api-key")
102
- ```
103
-
104
- With custom tracer provider:
105
- ```python
106
- from mirascope import ops
107
- from opentelemetry.sdk.trace import TracerProvider
108
-
109
- provider = TracerProvider()
110
- ops.configure(tracer_provider=provider)
111
- ```
112
- """
113
- global _tracer_provider, _tracer_name, _tracer_version, _tracer
114
-
115
- # Update settings so get_sync_client/get_async_client can use these values
116
- if api_key is not None or base_url is not None:
117
- update_settings(api_key=api_key, base_url=base_url)
118
-
119
- # If no tracer_provider given, auto-configure Mirascope Cloud
120
- if tracer_provider is None:
121
- tracer_provider = _create_mirascope_cloud_provider(
122
- api_key=api_key, base_url=base_url
123
- )
124
-
125
- _tracer_provider = tracer_provider
126
- otel_trace.set_tracer_provider(tracer_provider)
127
-
128
- _tracer_name = tracer_name
129
- _tracer_version = tracer_version
130
-
131
- _tracer = tracer_provider.get_tracer(_tracer_name, _tracer_version)
132
-
133
-
134
- def set_tracer(tracer: Tracer | None) -> None:
135
- """Set the configured tracer instance."""
136
- global _tracer
137
- _tracer = tracer
138
-
139
-
140
- def get_tracer() -> Tracer | None:
141
- """Return the configured tracer instance."""
142
- return _tracer
143
-
144
-
145
- @contextmanager
146
- def tracer_context(tracer: Tracer | None) -> Iterator[Tracer | None]:
147
- """Context manager for temporarily setting a tracer.
148
-
149
- Temporarily sets the tracer for the duration of the context and restores
150
- the previous tracer when the context exits.
151
-
152
- Args:
153
- tracer: The tracer to use within the context.
154
-
155
- Yields:
156
- The tracer that was set.
157
-
158
- Example:
159
- ```python
160
- from mirascope import ops
161
- from opentelemetry.sdk.trace import TracerProvider
162
-
163
- provider = TracerProvider()
164
- tracer = provider.get_tracer("my-tracer")
165
-
166
- with ops.tracer_context(tracer):
167
- # Use the tracer within this context
168
- ...
169
- # Previous tracer is restored here
170
- ```
171
- """
172
- previous_tracer = get_tracer()
173
- set_tracer(tracer)
174
- try:
175
- yield tracer
176
- finally:
177
- set_tracer(previous_tracer)
@@ -1,76 +0,0 @@
1
- """Context management utilities for distributed tracing."""
2
-
3
- from __future__ import annotations
4
-
5
- from collections.abc import Iterator, Mapping
6
- from contextlib import ExitStack, contextmanager
7
- from typing import Any
8
-
9
- from opentelemetry import context as otel_context
10
- from opentelemetry.context import Context
11
-
12
- from .propagation import extract_context
13
- from .session import extract_session_id, session
14
-
15
-
16
- @contextmanager
17
- def propagated_context(
18
- *,
19
- parent: Context | None = None,
20
- extract_from: Mapping[str, Any] | None = None,
21
- ) -> Iterator[None]:
22
- """Attach a parent context or extract context from carrier headers.
23
-
24
- This context manager is used to establish trace context continuity,
25
- typically on the server side when receiving requests. It either extracts
26
- context from incoming headers or attaches a pre-existing context.
27
-
28
- Args:
29
- parent: Pre-existing OTEL context to attach. Mutually exclusive with extract_from.
30
- extract_from: Dictionary of headers to extract context from (e.g., request.headers).
31
- Mutually exclusive with parent.
32
-
33
- Raises:
34
- ValueError: If both parent and extract_from are provided, or if neither is provided.
35
-
36
- Example:
37
- Server-side context extraction from FastAPI request:
38
-
39
- ```python
40
- @app.post("/endpoint")
41
- async def endpoint(request: Request):
42
- with propagated_context(extract_from=dict(request.headers)):
43
- result = process_request()
44
- return result
45
- ```
46
-
47
- Using a pre-existing context:
48
-
49
- ```python
50
- with propagated_context(parent=existing_context):
51
- do_work()
52
- ```
53
- """
54
- if parent is not None and extract_from is not None:
55
- raise ValueError("Cannot specify both 'parent' and 'extract_from' parameters")
56
-
57
- if parent is None and extract_from is None:
58
- raise ValueError("Must specify either 'parent' or 'extract_from' parameter")
59
-
60
- if extract_from is not None:
61
- with ExitStack() as stack:
62
- session_id = extract_session_id(extract_from)
63
- if session_id:
64
- stack.enter_context(session(id=session_id))
65
-
66
- extracted_context = extract_context(extract_from)
67
- token = otel_context.attach(extracted_context)
68
- stack.callback(otel_context.detach, token)
69
-
70
- yield
71
- elif parent is not None:
72
- token = otel_context.attach(parent)
73
- try:
74
- yield
75
- finally:
76
- otel_context.detach(token)
@@ -1,26 +0,0 @@
1
- """Mirascope OpenTelemetry exporters for two-phase telemetry.
2
-
3
- This package provides a two-phase export system for OpenTelemetry tracing:
4
- 1. Immediate start event transmission for real-time visibility
5
- 2. Batched end event transmission for efficiency
6
- """
7
-
8
- from .exporters import MirascopeOTLPExporter
9
- from .processors import MirascopeSpanProcessor
10
- from .types import (
11
- Link,
12
- SpanContextDict,
13
- SpanEvent,
14
- SpanEventType,
15
- Status,
16
- )
17
-
18
- __all__ = [
19
- "Link",
20
- "MirascopeOTLPExporter",
21
- "MirascopeSpanProcessor",
22
- "SpanContextDict",
23
- "SpanEvent",
24
- "SpanEventType",
25
- "Status",
26
- ]
@@ -1,395 +0,0 @@
1
- """Exporter implementation for OpenTelemetry exporters.
2
-
3
- This module provides the export layer for sending OpenTelemetry span
4
- events to the Mirascope ingestion endpoint. It wraps the Fern-generated
5
- Mirascope client to provide the interface needed by OpenTelemetry exporters.
6
- """
7
-
8
- from __future__ import annotations
9
-
10
- import logging
11
- import time
12
- from collections.abc import Sequence
13
-
14
- from opentelemetry.sdk.trace import ReadableSpan
15
- from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
16
- from opentelemetry.util.types import AttributeValue
17
-
18
- from ....api._generated.traces.types import (
19
- TracesCreateRequestResourceSpansItem,
20
- TracesCreateRequestResourceSpansItemResource,
21
- TracesCreateRequestResourceSpansItemResourceAttributesItem,
22
- TracesCreateRequestResourceSpansItemResourceAttributesItemValue,
23
- TracesCreateRequestResourceSpansItemScopeSpansItem,
24
- TracesCreateRequestResourceSpansItemScopeSpansItemScope,
25
- TracesCreateRequestResourceSpansItemScopeSpansItemSpansItem,
26
- TracesCreateRequestResourceSpansItemScopeSpansItemSpansItemAttributesItem,
27
- TracesCreateRequestResourceSpansItemScopeSpansItemSpansItemAttributesItemValue,
28
- TracesCreateRequestResourceSpansItemScopeSpansItemSpansItemStatus,
29
- )
30
- from ....api.client import Mirascope
31
-
32
- logger = logging.getLogger(__name__)
33
-
34
-
35
- class MirascopeOTLPExporter(SpanExporter):
36
- """OTLP/HTTP exporter for completed spans.
37
-
38
- This exporter implements the OpenTelemetry SpanExporter interface
39
- for exporting completed spans in OTLP format over HTTP. It's
40
- designed to work with BatchSpanProcessor for efficient batching.
41
-
42
- This uses the Fern auto-generated client for sending converted spans.
43
-
44
- Attributes:
45
- exporter: Export client for sending events.
46
- timeout: Request timeout in seconds.
47
- """
48
-
49
- def __init__(
50
- self,
51
- client: Mirascope,
52
- timeout: float = 30.0,
53
- max_retry_attempts: int = 3,
54
- ) -> None:
55
- """Initialize the telemetry exporter.
56
-
57
- Args:
58
- client: The Fern-generated Mirascope client instance.
59
- In the future, this will accept the enhanced client from
60
- mirascope.api.client that provides error handling and caching
61
- capabilities.
62
- timeout: Request timeout in seconds for telemetry operations.
63
- max_retry_attempts: Maximum number of retry attempts for failed exports.
64
- """
65
- self.client = client
66
- self.timeout = timeout
67
- self.max_retry_attempts = max_retry_attempts
68
- self._shutdown = False
69
-
70
- def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult:
71
- """Export a batch of spans to the telemetry endpoint.
72
-
73
- This is the standard OpenTelemetry export interface.
74
-
75
- Args:
76
- spans: Sequence of ReadableSpan objects to export.
77
-
78
- Returns:
79
- SpanExportResult indicating success or failure.
80
- """
81
- if self._shutdown:
82
- return SpanExportResult.FAILURE
83
-
84
- if not spans:
85
- return SpanExportResult.SUCCESS
86
-
87
- exceptions: list[Exception] = []
88
- delay = 0.1
89
-
90
- for i in range(self.max_retry_attempts):
91
- if i > 0:
92
- time.sleep(delay)
93
- delay = min(delay * 2, 5.0)
94
-
95
- try:
96
- otlp_data = self._convert_spans_to_otlp(spans)
97
- response = self.client.traces.create(resource_spans=otlp_data)
98
-
99
- if (
100
- response
101
- and hasattr(response, "partial_success")
102
- and response.partial_success
103
- ):
104
- partial_success = response.partial_success
105
- if hasattr(partial_success, "rejected_spans"):
106
- rejected = partial_success.rejected_spans
107
- if rejected is not None and rejected > 0:
108
- return SpanExportResult.FAILURE
109
-
110
- return SpanExportResult.SUCCESS
111
-
112
- except Exception as e:
113
- exceptions.append(e)
114
- logger.warning(
115
- f"Export attempt {i + 1} failed, retrying in {delay}s: {e}"
116
- )
117
-
118
- logger.error(
119
- f"Failed to export spans after {self.max_retry_attempts} attempts: {exceptions}"
120
- )
121
-
122
- return SpanExportResult.FAILURE
123
-
124
- def _convert_spans_to_otlp(
125
- self, spans: Sequence[ReadableSpan]
126
- ) -> list[TracesCreateRequestResourceSpansItem]:
127
- """Convert OpenTelemetry spans to OTLP format.
128
-
129
- Args:
130
- spans: Sequence of ReadableSpan objects.
131
-
132
- Returns:
133
- List of ResourceSpans in OTLP format.
134
- """
135
- resource_spans_map = {}
136
-
137
- for span in spans:
138
- try:
139
- otlp_span = self._convert_span(span)
140
- except ValueError as e:
141
- logger.warning(f"Skipping span due to error: {e}")
142
- continue
143
-
144
- resource_key = id(span.resource) if span.resource else "default"
145
-
146
- if resource_key not in resource_spans_map:
147
- resource = None
148
- if span.resource:
149
- resource_attrs = []
150
- for key, value in span.resource.attributes.items():
151
- attr_value = self._convert_resource_attribute_value(value)
152
- resource_attrs.append(
153
- TracesCreateRequestResourceSpansItemResourceAttributesItem(
154
- key=key,
155
- value=attr_value,
156
- )
157
- )
158
- resource = TracesCreateRequestResourceSpansItemResource(
159
- attributes=resource_attrs
160
- )
161
-
162
- resource_spans_map[resource_key] = {
163
- "resource": resource,
164
- "scope_spans": {},
165
- }
166
-
167
- scope_key = (
168
- span.instrumentation_scope.name
169
- if span.instrumentation_scope
170
- else "unknown"
171
- )
172
-
173
- if scope_key not in resource_spans_map[resource_key]["scope_spans"]:
174
- scope = None
175
- if span.instrumentation_scope:
176
- scope = TracesCreateRequestResourceSpansItemScopeSpansItemScope(
177
- name=span.instrumentation_scope.name,
178
- version=span.instrumentation_scope.version,
179
- )
180
-
181
- resource_spans_map[resource_key]["scope_spans"][scope_key] = {
182
- "scope": scope,
183
- "spans": [],
184
- }
185
-
186
- resource_spans_map[resource_key]["scope_spans"][scope_key]["spans"].append(
187
- otlp_span
188
- )
189
-
190
- result = []
191
- for resource_data in resource_spans_map.values():
192
- scope_spans = []
193
- for scope_data in resource_data["scope_spans"].values():
194
- scope_spans.append(
195
- TracesCreateRequestResourceSpansItemScopeSpansItem(
196
- scope=scope_data["scope"],
197
- spans=scope_data["spans"],
198
- )
199
- )
200
-
201
- result.append(
202
- TracesCreateRequestResourceSpansItem(
203
- resource=resource_data["resource"],
204
- scope_spans=scope_spans,
205
- )
206
- )
207
-
208
- return result
209
-
210
- def _convert_span(
211
- self, span: ReadableSpan
212
- ) -> TracesCreateRequestResourceSpansItemScopeSpansItemSpansItem:
213
- """Convert a single ReadableSpan to OTLP format."""
214
- context = span.get_span_context()
215
- if not context or not context.is_valid:
216
- raise ValueError(f"Cannot export span without valid context: {span.name}")
217
-
218
- attributes = []
219
- if span.attributes:
220
- for key, value in span.attributes.items():
221
- attr_value = self._convert_attribute_value(value)
222
- attributes.append(
223
- TracesCreateRequestResourceSpansItemScopeSpansItemSpansItemAttributesItem(
224
- key=key,
225
- value=attr_value,
226
- )
227
- )
228
-
229
- status = None
230
- if span.status:
231
- status = TracesCreateRequestResourceSpansItemScopeSpansItemSpansItemStatus(
232
- code=span.status.status_code.value,
233
- message=span.status.description or "",
234
- )
235
-
236
- # Convert events
237
- events = None
238
- if span.events:
239
- events = []
240
- for event in span.events:
241
- event_attrs: list[dict[str, object]] = []
242
- if event.attributes:
243
- for key, value in event.attributes.items():
244
- # Convert to OTLP attribute format with typed values
245
- attr_value = self._convert_event_attribute_value(value)
246
- event_attrs.append({"key": key, "value": attr_value})
247
- events.append(
248
- {
249
- "name": event.name,
250
- "timeUnixNano": str(event.timestamp)
251
- if event.timestamp
252
- else None,
253
- "attributes": event_attrs if event_attrs else None,
254
- }
255
- )
256
-
257
- trace_id = format(context.trace_id, "032x")
258
- span_id = format(context.span_id, "016x")
259
-
260
- # Build kwargs, only including events if present (to avoid sending null)
261
- kwargs: dict[str, object] = {
262
- "trace_id": trace_id,
263
- "span_id": span_id,
264
- "parent_span_id": (
265
- format(span.parent.span_id, "016x")
266
- if span.parent and span.parent.span_id
267
- else None
268
- ),
269
- "name": span.name,
270
- "kind": span.kind.value if span.kind else 0,
271
- "start_time_unix_nano": str(span.start_time) if span.start_time else "0",
272
- "end_time_unix_nano": str(span.end_time) if span.end_time else "0",
273
- "attributes": attributes or None,
274
- "status": status,
275
- }
276
- # Only include events if present (omit entirely to avoid sending null)
277
- if events:
278
- kwargs["events"] = events
279
-
280
- return TracesCreateRequestResourceSpansItemScopeSpansItemSpansItem(**kwargs) # type: ignore[arg-type]
281
-
282
- def _convert_attribute_value(
283
- self, value: AttributeValue
284
- ) -> TracesCreateRequestResourceSpansItemScopeSpansItemSpansItemAttributesItemValue:
285
- """Convert OpenTelemetry AttributeValue to Mirascope API's KeyValueValue.
286
-
287
- This conversion is necessary because the Fern-generated API client
288
- expects KeyValueValue objects, not OpenTelemetry's AttributeValue types.
289
-
290
- Args:
291
- value: An OpenTelemetry AttributeValue (bool, int, float, str, or Sequence)
292
-
293
- Returns:
294
- A KeyValueValue object for the Mirascope API
295
- """
296
- match value:
297
- case str():
298
- return TracesCreateRequestResourceSpansItemScopeSpansItemSpansItemAttributesItemValue(
299
- string_value=value
300
- )
301
- case bool():
302
- return TracesCreateRequestResourceSpansItemScopeSpansItemSpansItemAttributesItemValue(
303
- bool_value=value
304
- )
305
- case int():
306
- return TracesCreateRequestResourceSpansItemScopeSpansItemSpansItemAttributesItemValue(
307
- int_value=str(value)
308
- )
309
- case float():
310
- return TracesCreateRequestResourceSpansItemScopeSpansItemSpansItemAttributesItemValue(
311
- double_value=value
312
- )
313
- case _:
314
- return TracesCreateRequestResourceSpansItemScopeSpansItemSpansItemAttributesItemValue(
315
- string_value=str(list(value))
316
- )
317
-
318
- def _convert_event_attribute_value(
319
- self, value: AttributeValue
320
- ) -> dict[str, object]:
321
- """Convert OpenTelemetry AttributeValue to OTLP event attribute value format.
322
-
323
- This uses the OTLP JSON format with typed value wrappers (e.g., stringValue, intValue).
324
-
325
- Args:
326
- value: An OpenTelemetry AttributeValue (bool, int, float, str, or Sequence)
327
-
328
- Returns:
329
- A dict with the typed value (e.g., {"stringValue": "..."})
330
- """
331
- match value:
332
- case str():
333
- return {"stringValue": value}
334
- case bool():
335
- return {"boolValue": value}
336
- case int():
337
- return {"intValue": str(value)}
338
- case float():
339
- return {"doubleValue": value}
340
- case _:
341
- # Sequences - convert to string representation
342
- return {"stringValue": str(list(value))}
343
-
344
- def _convert_resource_attribute_value(
345
- self, value: AttributeValue
346
- ) -> TracesCreateRequestResourceSpansItemResourceAttributesItemValue:
347
- """Convert OpenTelemetry AttributeValue to Mirascope API's resource KeyValueValue.
348
-
349
- This conversion is necessary because the Fern-generated API client
350
- expects KeyValueValue objects, not OpenTelemetry's AttributeValue types.
351
-
352
- Args:
353
- value: An OpenTelemetry AttributeValue (bool, int, float, str, or Sequence)
354
-
355
- Returns:
356
- A KeyValueValue object for the Mirascope API resource attributes
357
- """
358
- match value:
359
- case str():
360
- return TracesCreateRequestResourceSpansItemResourceAttributesItemValue(
361
- string_value=value
362
- )
363
- case bool():
364
- return TracesCreateRequestResourceSpansItemResourceAttributesItemValue(
365
- bool_value=value
366
- )
367
- case int():
368
- return TracesCreateRequestResourceSpansItemResourceAttributesItemValue(
369
- int_value=str(value)
370
- )
371
- case float():
372
- return TracesCreateRequestResourceSpansItemResourceAttributesItemValue(
373
- double_value=value
374
- )
375
- case _:
376
- return TracesCreateRequestResourceSpansItemResourceAttributesItemValue(
377
- string_value=str(list(value))
378
- )
379
-
380
- def shutdown(self) -> None:
381
- """Shutdown the exporter. Subsequent exports will return FAILURE."""
382
- self._shutdown = True
383
-
384
- def force_flush(self, timeout_millis: int = 30000) -> bool:
385
- """Force flush any pending data.
386
-
387
- No-op since this exporter does not buffer data internally.
388
-
389
- Args:
390
- timeout_millis: Maximum time to wait in milliseconds (unused).
391
-
392
- Returns:
393
- Always True since there is no internal buffer to flush.
394
- """
395
- return True