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,300 +0,0 @@
1
- """Mirascope-specific serialization for span attributes."""
2
-
3
- from __future__ import annotations
4
-
5
- import logging
6
- from collections.abc import Sequence
7
- from typing import TYPE_CHECKING, Any, Protocol
8
-
9
- from .....llm.content import (
10
- Audio,
11
- Base64ImageSource,
12
- Document,
13
- Image,
14
- Text,
15
- Thought,
16
- ToolCall,
17
- ToolOutput,
18
- )
19
- from .....llm.content.document import Base64DocumentSource, TextDocumentSource
20
- from .....llm.messages import AssistantMessage, Message, SystemMessage, UserMessage
21
- from .....llm.responses.usage import Usage
22
- from ...utils import json_dumps
23
- from .cost import calculate_cost_async, calculate_cost_sync
24
-
25
- if TYPE_CHECKING:
26
- from opentelemetry.util.types import AttributeValue
27
-
28
- from .....llm.responses.root_response import RootResponse
29
- from .....llm.types import Jsonable
30
-
31
- logger = logging.getLogger(__name__)
32
-
33
-
34
- class SpanProtocol(Protocol):
35
- """Protocol for span objects that support setting attributes."""
36
-
37
- def set(self, **attributes: AttributeValue) -> None:
38
- """Set attributes on the span."""
39
- ...
40
-
41
-
42
- def _serialize_content_part(
43
- part: Text | ToolCall | Thought | Image | Audio | Document | ToolOutput[Jsonable],
44
- ) -> dict[str, Any]:
45
- """Serialize a single content part to a dict matching the Mirascope dataclass structure."""
46
- if isinstance(part, Text):
47
- return {"type": "text", "text": part.text}
48
- elif isinstance(part, ToolCall):
49
- return {
50
- "type": "tool_call",
51
- "id": part.id,
52
- "name": part.name,
53
- "args": part.args,
54
- }
55
- elif isinstance(part, Thought):
56
- return {"type": "thought", "thought": part.thought}
57
- elif isinstance(part, ToolOutput):
58
- return {
59
- "type": "tool_output",
60
- "id": part.id,
61
- "name": part.name,
62
- "result": part.result,
63
- }
64
- elif isinstance(part, Image):
65
- if isinstance(part.source, Base64ImageSource):
66
- return {
67
- "type": "image",
68
- "source": {
69
- "type": "base64_image_source",
70
- "mime_type": part.source.mime_type,
71
- "data": part.source.data,
72
- },
73
- }
74
- else: # URLImageSource
75
- return {
76
- "type": "image",
77
- "source": {"type": "url_image_source", "url": part.source.url},
78
- }
79
- elif isinstance(part, Audio):
80
- return {
81
- "type": "audio",
82
- "source": {
83
- "type": "base64_audio_source",
84
- "mime_type": part.source.mime_type,
85
- "data": part.source.data,
86
- },
87
- }
88
- elif isinstance(part, Document):
89
- # Document has multiple source types - serialize based on actual type
90
- if isinstance(part.source, Base64DocumentSource):
91
- return {
92
- "type": "document",
93
- "source": {
94
- "type": "base64_document_source",
95
- "data": part.source.data,
96
- "media_type": part.source.media_type,
97
- },
98
- }
99
- elif isinstance(part.source, TextDocumentSource):
100
- return {
101
- "type": "document",
102
- "source": {
103
- "type": "text_document_source",
104
- "data": part.source.data,
105
- "media_type": part.source.media_type,
106
- },
107
- }
108
- else: # URLDocumentSource
109
- return {
110
- "type": "document",
111
- "source": {
112
- "type": "url_document_source",
113
- "url": part.source.url,
114
- },
115
- }
116
- return {"type": "unknown"} # pragma: no cover
117
-
118
-
119
- def _serialize_message(message: Message) -> dict[str, Any]:
120
- """Serialize a Message to a dict matching the Mirascope dataclass structure."""
121
- if isinstance(message, SystemMessage):
122
- return {
123
- "role": "system",
124
- "content": _serialize_content_part(message.content),
125
- }
126
- elif isinstance(message, UserMessage):
127
- return {
128
- "role": "user",
129
- "content": [_serialize_content_part(p) for p in message.content],
130
- "name": message.name,
131
- }
132
- elif isinstance(message, AssistantMessage):
133
- return {
134
- "role": "assistant",
135
- "content": [_serialize_content_part(p) for p in message.content],
136
- "name": message.name,
137
- }
138
- return {"role": "unknown"} # pragma: no cover
139
-
140
-
141
- def serialize_mirascope_messages(messages: Sequence[Message]) -> str:
142
- """Serialize input messages to JSON for span attributes."""
143
- return json_dumps([_serialize_message(m) for m in messages])
144
-
145
-
146
- def serialize_mirascope_content(
147
- content: Sequence[Text | ToolCall | Thought],
148
- ) -> str:
149
- """Serialize response content to JSON for span attributes."""
150
- return json_dumps([_serialize_content_part(p) for p in content])
151
-
152
-
153
- def serialize_mirascope_usage(usage: Usage | None) -> AttributeValue | None:
154
- """Serialize response usage to JSON for span attributes. Returns None if usage is None."""
155
- if usage is None:
156
- return None
157
- return json_dumps(
158
- {
159
- "input_tokens": usage.input_tokens,
160
- "output_tokens": usage.output_tokens,
161
- "cache_read_tokens": usage.cache_read_tokens,
162
- "cache_write_tokens": usage.cache_write_tokens,
163
- "reasoning_tokens": usage.reasoning_tokens,
164
- "total_tokens": usage.total_tokens,
165
- }
166
- )
167
-
168
-
169
- def serialize_mirascope_cost(
170
- input_cost: float,
171
- output_cost: float,
172
- total_cost: float,
173
- cache_read_cost: float | None = None,
174
- cache_write_cost: float | None = None,
175
- ) -> str:
176
- """Serialize cost to JSON for span attributes.
177
-
178
- All costs are in centicents (1 centicent = $0.0001).
179
- Consumers can divide by 10,000 to get dollar amounts.
180
- """
181
- return json_dumps(
182
- {
183
- "input_cost": input_cost,
184
- "output_cost": output_cost,
185
- "cache_read_cost": cache_read_cost,
186
- "cache_write_cost": cache_write_cost,
187
- "total_cost": total_cost,
188
- }
189
- )
190
-
191
-
192
- def attach_mirascope_response(
193
- span: SpanProtocol, response: RootResponse[Any, Any]
194
- ) -> None:
195
- """Attach Mirascope-specific response attributes to a span.
196
-
197
- Sets the following attributes:
198
- - mirascope.trace.output: Pretty-printed response
199
- - mirascope.response.messages: Serialized input messages (excluding final assistant message)
200
- - mirascope.response.content: Serialized response content
201
- - mirascope.response.usage: Serialized usage (if available)
202
- - mirascope.response.cost: Serialized cost (if available)
203
- """
204
- span.set(
205
- **{
206
- "mirascope.response.provider_id": response.provider_id,
207
- "mirascope.response.model_id": response.model_id,
208
- "mirascope.trace.output": response.pretty(),
209
- "mirascope.response.messages": serialize_mirascope_messages(
210
- response.messages[:-1]
211
- ),
212
- "mirascope.response.content": serialize_mirascope_content(response.content),
213
- }
214
- )
215
- if (usage_json := serialize_mirascope_usage(response.usage)) is not None:
216
- span.set(**{"mirascope.response.usage": usage_json})
217
- logger.debug("Attached usage to span")
218
- else:
219
- logger.debug("No usage available, skipping cost calculation")
220
-
221
- # Calculate and attach cost if usage is available
222
- if response.usage is not None:
223
- logger.debug("Attempting cost calculation (sync)")
224
- cost = calculate_cost_sync(
225
- response.provider_id, response.model_id, response.usage
226
- )
227
- if cost is not None:
228
- span.set(
229
- **{
230
- "mirascope.response.cost": serialize_mirascope_cost(
231
- input_cost=cost.input_cost_centicents,
232
- output_cost=cost.output_cost_centicents,
233
- total_cost=cost.total_cost_centicents,
234
- cache_read_cost=cost.cache_read_cost_centicents,
235
- cache_write_cost=cost.cache_write_cost_centicents,
236
- )
237
- }
238
- )
239
- logger.debug(
240
- "Attached cost to span: total=%s centicents", cost.total_cost_centicents
241
- )
242
- else:
243
- logger.debug("Cost calculation returned None, not attaching cost to span")
244
-
245
-
246
- async def attach_mirascope_response_async(
247
- span: SpanProtocol, response: RootResponse[Any, Any]
248
- ) -> None:
249
- """Attach Mirascope-specific response attributes to a span (async version).
250
-
251
- Sets the following attributes:
252
- - mirascope.trace.output: Pretty-printed response
253
- - mirascope.response.messages: Serialized input messages (excluding final assistant message)
254
- - mirascope.response.content: Serialized response content
255
- - mirascope.response.usage: Serialized usage (if available)
256
- - mirascope.response.cost: Serialized cost (if available)
257
- """
258
- span.set(
259
- **{
260
- "mirascope.response.provider_id": response.provider_id,
261
- "mirascope.response.model_id": response.model_id,
262
- "mirascope.trace.output": response.pretty(),
263
- "mirascope.response.messages": serialize_mirascope_messages(
264
- response.messages[:-1]
265
- ),
266
- "mirascope.response.content": serialize_mirascope_content(response.content),
267
- }
268
- )
269
- if (usage_json := serialize_mirascope_usage(response.usage)) is not None:
270
- span.set(**{"mirascope.response.usage": usage_json})
271
- logger.debug("Attached usage to span (async)")
272
- else:
273
- logger.debug("No usage available, skipping cost calculation (async)")
274
-
275
- # Calculate and attach cost if usage is available (async)
276
- if response.usage is not None:
277
- logger.debug("Attempting cost calculation (async)")
278
- cost = await calculate_cost_async(
279
- response.provider_id, response.model_id, response.usage
280
- )
281
- if cost is not None:
282
- span.set(
283
- **{
284
- "mirascope.response.cost": serialize_mirascope_cost(
285
- input_cost=cost.input_cost_centicents,
286
- output_cost=cost.output_cost_centicents,
287
- total_cost=cost.total_cost_centicents,
288
- cache_read_cost=cost.cache_read_cost_centicents,
289
- cache_write_cost=cost.cache_write_cost_centicents,
290
- )
291
- }
292
- )
293
- logger.debug(
294
- "Attached cost to span (async): total=%s centicents",
295
- cost.total_cost_centicents,
296
- )
297
- else:
298
- logger.debug(
299
- "Cost calculation returned None, not attaching cost to span (async)"
300
- )
@@ -1,198 +0,0 @@
1
- """Context propagation utilities for distributed tracing."""
2
-
3
- from __future__ import annotations
4
-
5
- import logging
6
- import os
7
- from collections.abc import Mapping, MutableMapping
8
- from typing import Literal, TypeAlias
9
-
10
- from opentelemetry import propagate
11
- from opentelemetry.context import Context
12
- from opentelemetry.propagators.b3 import B3MultiFormat, B3SingleFormat
13
- from opentelemetry.propagators.composite import CompositePropagator
14
- from opentelemetry.propagators.jaeger import JaegerPropagator
15
- from opentelemetry.propagators.textmap import Setter, TextMapPropagator
16
- from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
17
-
18
- from ..exceptions import ConfigurationError
19
- from .session import SESSION_HEADER_NAME, current_session
20
-
21
- logger = logging.getLogger(__name__)
22
-
23
- PropagatorFormat: TypeAlias = Literal[
24
- "tracecontext", "b3", "b3multi", "jaeger", "composite"
25
- ]
26
- CarrierValue: TypeAlias = str | list[str]
27
-
28
- # Environment variable names
29
- ENV_PROPAGATOR_FORMAT = "MIRASCOPE_PROPAGATOR"
30
- ENV_PROPAGATOR_SET_GLOBAL = "_MIRASCOPE_PROPAGATOR_SET_GLOBAL"
31
-
32
- _PROPAGATOR: ContextPropagator | None = None
33
-
34
-
35
- class _StrSetter(Setter[MutableMapping[str, str]]):
36
- """Setter that writes string header values into the carrier."""
37
-
38
- def set(self, carrier: MutableMapping[str, str], key: str, value: str) -> None:
39
- """Set a single header value on the carrier."""
40
- carrier[key] = value
41
-
42
-
43
- _STR_SETTER = _StrSetter()
44
-
45
-
46
- class ContextPropagator:
47
- """Manages OpenTelemetry context propagation across service boundaries."""
48
-
49
- _propagator: TextMapPropagator
50
-
51
- def __init__(self, *, set_global: bool = True) -> None:
52
- """Initialize propagator and optionally set as global.
53
-
54
- Propagator format is determined by MIRASCOPE_PROPAGATOR environment variable.
55
- Defaults to "tracecontext" if not set.
56
-
57
- Args:
58
- set_global: Whether to set this propagator as the global textmap propagator.
59
-
60
- Raises:
61
- ConfigurationError: If the propagator format is invalid.
62
- """
63
- env_format = os.environ.get(ENV_PROPAGATOR_FORMAT, "tracecontext")
64
- propagator_name: PropagatorFormat
65
- if env_format in ("tracecontext", "b3", "b3multi", "jaeger", "composite"):
66
- propagator_name = env_format
67
- else:
68
- error_message = (
69
- f"Invalid propagator format: {env_format}. "
70
- f"Valid options: tracecontext, b3, b3multi, jaeger, composite"
71
- )
72
- logger.error(error_message)
73
- raise ConfigurationError(error_message)
74
- logger.debug(f"Initializing ContextPropagator with format: {propagator_name}")
75
-
76
- match propagator_name:
77
- case "tracecontext":
78
- self._propagator = TraceContextTextMapPropagator()
79
- case "b3":
80
- self._propagator = B3SingleFormat()
81
- case "b3multi":
82
- self._propagator = B3MultiFormat()
83
- case "jaeger":
84
- self._propagator = JaegerPropagator()
85
- case "composite":
86
- propagators: list[TextMapPropagator] = [
87
- TraceContextTextMapPropagator(),
88
- B3SingleFormat(),
89
- B3MultiFormat(),
90
- JaegerPropagator(),
91
- ]
92
- self._propagator = CompositePropagator(propagators)
93
-
94
- if set_global:
95
- should_set_global = os.environ.get(ENV_PROPAGATOR_SET_GLOBAL, "true")
96
- if should_set_global.lower() == "true":
97
- propagate.set_global_textmap(self._propagator)
98
- logger.debug(f"Set {propagator_name} as global textmap propagator")
99
-
100
- def extract_context(self, carrier: Mapping[str, CarrierValue]) -> Context:
101
- """Extract OTEL context from carrier headers.
102
-
103
- Args:
104
- carrier: Dictionary containing HTTP headers or similar carrier data.
105
-
106
- Returns:
107
- Extracted OpenTelemetry context. Returns empty context if extraction fails.
108
- """
109
- try:
110
- context = self._propagator.extract(carrier=carrier)
111
- logger.debug("Successfully extracted context from carrier")
112
- return context
113
- except Exception as exception:
114
- logger.debug(
115
- f"Failed to extract context from carrier: {type(exception).__name__}: {exception}"
116
- )
117
- return Context()
118
-
119
- def inject_context(
120
- self,
121
- carrier: MutableMapping[str, str],
122
- context: Context | None = None,
123
- ) -> None:
124
- """Inject current OTEL context into carrier headers.
125
-
126
- This method also injects session context if one is active, adding the
127
- SESSION_HEADER_NAME header to the carrier.
128
-
129
- Args:
130
- carrier: Mutable mapping (e.g., HTTP headers dict) to inject context into.
131
- context: Optional specific context to inject. If None, uses current context.
132
- """
133
- try:
134
- self._propagator.inject(
135
- carrier=carrier, context=context, setter=_STR_SETTER
136
- )
137
- logger.debug("Successfully injected context into carrier")
138
- except Exception as exception:
139
- logger.debug(
140
- f"Failed to inject context into carrier: {type(exception).__name__}: {exception}"
141
- )
142
-
143
- session_ctx = current_session()
144
- if session_ctx is not None:
145
- carrier[SESSION_HEADER_NAME] = session_ctx.id
146
-
147
-
148
- def get_propagator() -> ContextPropagator:
149
- """Get or create the singleton ContextPropagator instance.
150
-
151
- Reads propagator format from MIRASCOPE_PROPAGATOR environment variable.
152
-
153
- Returns:
154
- The global ContextPropagator instance.
155
- """
156
- global _PROPAGATOR
157
- if _PROPAGATOR is None:
158
- _PROPAGATOR = ContextPropagator()
159
- return _PROPAGATOR
160
-
161
-
162
- def reset_propagator() -> None:
163
- """Reset the singleton ContextPropagator instance.
164
-
165
- This is primarily useful for testing to ensure a clean state between tests.
166
- The next call to get_propagator() will create a new instance.
167
- """
168
- global _PROPAGATOR
169
- _PROPAGATOR = None
170
-
171
-
172
- def extract_context(carrier: Mapping[str, CarrierValue]) -> Context:
173
- """Extract OTEL context from carrier headers using the global propagator.
174
-
175
- Args:
176
- carrier: Dictionary containing HTTP headers or similar carrier data.
177
-
178
- Returns:
179
- Extracted OpenTelemetry context.
180
- """
181
- return get_propagator().extract_context(carrier)
182
-
183
-
184
- def inject_context(
185
- carrier: MutableMapping[str, str],
186
- *,
187
- context: Context | None = None,
188
- ) -> None:
189
- """Inject current OTEL context into carrier headers using the global propagator.
190
-
191
- This function also injects session context if one is active, adding the
192
- SESSION_HEADER_NAME header to the carrier.
193
-
194
- Args:
195
- carrier: Mutable mapping (e.g., HTTP headers dict) to inject context into.
196
- context: Optional specific context to inject. If None, uses current context.
197
- """
198
- get_propagator().inject_context(carrier, context)
@@ -1,133 +0,0 @@
1
- """Call protocol helpers for ops.tracing."""
2
-
3
- from __future__ import annotations
4
-
5
- import inspect
6
- from typing import TYPE_CHECKING, Protocol
7
- from typing_extensions import TypeIs
8
-
9
- from ...llm.context import Context, DepsT
10
- from .types import P, R
11
-
12
- if TYPE_CHECKING:
13
- from .spans import Span
14
-
15
-
16
- class SyncFunction(Protocol[P, R]):
17
- """Protocol for synchronous callable functions."""
18
-
19
- def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R:
20
- """The function required a synchronous call method."""
21
- ... # pragma: no cover
22
-
23
-
24
- class AsyncFunction(Protocol[P, R]):
25
- """Protocol for asynchronous callable functions."""
26
-
27
- async def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R:
28
- """The function's required asynchronous call method."""
29
- ... # pragma: no cover
30
-
31
-
32
- class SyncSpanFunction(Protocol[P, R]):
33
- """Protocol for synchronous functions that receive injected Span.
34
-
35
- Functions matching this protocol have `trace_ctx: Span` as their first
36
- parameter. The trace decorator will inject the span automatically.
37
- """
38
-
39
- def __call__(self, trace_ctx: Span, *args: P.args, **kwargs: P.kwargs) -> R:
40
- """The function receives a Span as first parameter."""
41
- ... # pragma: no cover
42
-
43
-
44
- class AsyncSpanFunction(Protocol[P, R]):
45
- """Protocol for asynchronous functions that receive injected Span.
46
-
47
- Functions matching this protocol have `trace_ctx: Span` as their first
48
- parameter. The trace decorator will inject the span automatically.
49
- """
50
-
51
- async def __call__(self, trace_ctx: Span, *args: P.args, **kwargs: P.kwargs) -> R:
52
- """The function receives a Span as first parameter."""
53
- ... # pragma: no cover
54
-
55
-
56
- class SyncContextFunction(Protocol[P, DepsT, R]):
57
- """Protocol for synchronous callable functions with Context parameter."""
58
-
59
- def __call__(self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs) -> R:
60
- """The function required a synchronous call method with context."""
61
- ... # pragma: no cover
62
-
63
-
64
- class AsyncContextFunction(Protocol[P, DepsT, R]):
65
- """Protocol for asynchronous callable functions with Context parameter."""
66
-
67
- async def __call__(
68
- self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
69
- ) -> R:
70
- """The function's required asynchronous call method with context."""
71
- ... # pragma: no cover
72
-
73
-
74
- def fn_is_async(
75
- fn: SyncFunction[P, R] | AsyncFunction[P, R],
76
- ) -> TypeIs[AsyncFunction[P, R]]:
77
- """Type check to determine if a given function is asynchronous."""
78
- return inspect.iscoroutinefunction(fn) or inspect.isasyncgenfunction(fn)
79
-
80
-
81
- def fn_wants_span(
82
- fn: (
83
- SyncFunction[P, R]
84
- | AsyncFunction[P, R]
85
- | SyncSpanFunction[P, R]
86
- | AsyncSpanFunction[P, R]
87
- ),
88
- ) -> TypeIs[SyncSpanFunction[P, R] | AsyncSpanFunction[P, R]]:
89
- """Check if function wants Span injection as first parameter.
90
-
91
- Returns True if the function has a first parameter named `trace_ctx`
92
- with type annotation `Span`.
93
- """
94
- # Import here to avoid circular imports
95
- from .spans import Span
96
-
97
- try:
98
- sig = inspect.signature(fn)
99
- except (ValueError, TypeError):
100
- return False
101
-
102
- params = list(sig.parameters.values())
103
- if not params:
104
- return False
105
-
106
- first_param = params[0]
107
- if first_param.name != "trace_ctx":
108
- return False
109
-
110
- # Check annotation
111
- annotation = first_param.annotation
112
- if annotation is inspect.Parameter.empty:
113
- return False
114
-
115
- # Handle string annotations (forward references)
116
- # The annotation could be "Span", "ops.Span", "mirascope.ops.Span", etc.
117
- if isinstance(annotation, str):
118
- return annotation == "Span" or annotation.endswith(".Span")
119
-
120
- # Check by identity first
121
- if annotation is Span:
122
- return True
123
-
124
- # Fallback: check by class name and module for robustness
125
- # This handles cases where the same class might have different identities
126
- # due to module reloading or import issues in test environments
127
- if isinstance(annotation, type):
128
- return (
129
- annotation.__name__ == "Span"
130
- and annotation.__module__ == "mirascope.ops._internal.spans"
131
- )
132
-
133
- return False