mirascope 2.0.0a4__py3-none-any.whl → 2.0.0a6__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 (215) hide show
  1. mirascope/__init__.py +10 -1
  2. mirascope/_stubs.py +363 -0
  3. mirascope/api/__init__.py +8 -0
  4. mirascope/api/_generated/__init__.py +119 -1
  5. mirascope/api/_generated/annotations/__init__.py +33 -0
  6. mirascope/api/_generated/annotations/client.py +474 -0
  7. mirascope/api/_generated/annotations/raw_client.py +1095 -0
  8. mirascope/api/_generated/annotations/types/__init__.py +31 -0
  9. mirascope/api/_generated/annotations/types/annotations_create_request_label.py +5 -0
  10. mirascope/api/_generated/annotations/types/annotations_create_response.py +35 -0
  11. mirascope/api/_generated/annotations/types/annotations_create_response_label.py +5 -0
  12. mirascope/api/_generated/annotations/types/annotations_get_response.py +35 -0
  13. mirascope/api/_generated/annotations/types/annotations_get_response_label.py +5 -0
  14. mirascope/api/_generated/annotations/types/annotations_list_request_label.py +5 -0
  15. mirascope/api/_generated/annotations/types/annotations_list_response.py +21 -0
  16. mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item.py +35 -0
  17. mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item_label.py +5 -0
  18. mirascope/api/_generated/annotations/types/annotations_update_request_label.py +5 -0
  19. mirascope/api/_generated/annotations/types/annotations_update_response.py +35 -0
  20. mirascope/api/_generated/annotations/types/annotations_update_response_label.py +5 -0
  21. mirascope/api/_generated/api_keys/__init__.py +7 -0
  22. mirascope/api/_generated/api_keys/client.py +429 -0
  23. mirascope/api/_generated/api_keys/raw_client.py +788 -0
  24. mirascope/api/_generated/api_keys/types/__init__.py +9 -0
  25. mirascope/api/_generated/api_keys/types/api_keys_create_response.py +28 -0
  26. mirascope/api/_generated/api_keys/types/api_keys_get_response.py +27 -0
  27. mirascope/api/_generated/api_keys/types/api_keys_list_response_item.py +27 -0
  28. mirascope/api/_generated/client.py +12 -0
  29. mirascope/api/_generated/core/client_wrapper.py +2 -14
  30. mirascope/api/_generated/core/datetime_utils.py +1 -3
  31. mirascope/api/_generated/core/file.py +2 -5
  32. mirascope/api/_generated/core/http_client.py +36 -112
  33. mirascope/api/_generated/core/jsonable_encoder.py +1 -3
  34. mirascope/api/_generated/core/pydantic_utilities.py +19 -74
  35. mirascope/api/_generated/core/query_encoder.py +1 -3
  36. mirascope/api/_generated/core/serialization.py +4 -10
  37. mirascope/api/_generated/docs/client.py +2 -6
  38. mirascope/api/_generated/docs/raw_client.py +4 -20
  39. mirascope/api/_generated/environments/__init__.py +17 -0
  40. mirascope/api/_generated/environments/client.py +500 -0
  41. mirascope/api/_generated/environments/raw_client.py +999 -0
  42. mirascope/api/_generated/environments/types/__init__.py +15 -0
  43. mirascope/api/_generated/environments/types/environments_create_response.py +24 -0
  44. mirascope/api/_generated/environments/types/environments_get_response.py +24 -0
  45. mirascope/api/_generated/environments/types/environments_list_response_item.py +24 -0
  46. mirascope/api/_generated/environments/types/environments_update_response.py +24 -0
  47. mirascope/api/_generated/errors/__init__.py +2 -0
  48. mirascope/api/_generated/errors/bad_request_error.py +1 -5
  49. mirascope/api/_generated/errors/conflict_error.py +1 -5
  50. mirascope/api/_generated/errors/forbidden_error.py +1 -5
  51. mirascope/api/_generated/errors/internal_server_error.py +1 -6
  52. mirascope/api/_generated/errors/not_found_error.py +1 -5
  53. mirascope/api/_generated/errors/unauthorized_error.py +11 -0
  54. mirascope/api/_generated/functions/__init__.py +29 -0
  55. mirascope/api/_generated/functions/client.py +433 -0
  56. mirascope/api/_generated/functions/raw_client.py +1049 -0
  57. mirascope/api/_generated/functions/types/__init__.py +29 -0
  58. mirascope/api/_generated/functions/types/functions_create_request_dependencies_value.py +20 -0
  59. mirascope/api/_generated/functions/types/functions_create_response.py +37 -0
  60. mirascope/api/_generated/functions/types/functions_create_response_dependencies_value.py +20 -0
  61. mirascope/api/_generated/functions/types/functions_find_by_hash_response.py +39 -0
  62. mirascope/api/_generated/functions/types/functions_find_by_hash_response_dependencies_value.py +20 -0
  63. mirascope/api/_generated/functions/types/functions_get_response.py +37 -0
  64. mirascope/api/_generated/functions/types/functions_get_response_dependencies_value.py +20 -0
  65. mirascope/api/_generated/functions/types/functions_list_response.py +21 -0
  66. mirascope/api/_generated/functions/types/functions_list_response_functions_item.py +41 -0
  67. mirascope/api/_generated/functions/types/functions_list_response_functions_item_dependencies_value.py +20 -0
  68. mirascope/api/_generated/health/client.py +2 -6
  69. mirascope/api/_generated/health/raw_client.py +5 -23
  70. mirascope/api/_generated/health/types/health_check_response.py +1 -3
  71. mirascope/api/_generated/organizations/__init__.py +2 -0
  72. mirascope/api/_generated/organizations/client.py +94 -27
  73. mirascope/api/_generated/organizations/raw_client.py +246 -128
  74. mirascope/api/_generated/organizations/types/__init__.py +2 -0
  75. mirascope/api/_generated/organizations/types/organizations_create_response.py +5 -3
  76. mirascope/api/_generated/organizations/types/organizations_create_response_role.py +1 -3
  77. mirascope/api/_generated/organizations/types/organizations_credits_response.py +19 -0
  78. mirascope/api/_generated/organizations/types/organizations_get_response.py +5 -3
  79. mirascope/api/_generated/organizations/types/organizations_get_response_role.py +1 -3
  80. mirascope/api/_generated/organizations/types/organizations_list_response_item.py +5 -3
  81. mirascope/api/_generated/organizations/types/organizations_list_response_item_role.py +1 -3
  82. mirascope/api/_generated/organizations/types/organizations_update_response.py +5 -3
  83. mirascope/api/_generated/organizations/types/organizations_update_response_role.py +1 -3
  84. mirascope/api/_generated/projects/__init__.py +2 -12
  85. mirascope/api/_generated/projects/client.py +38 -68
  86. mirascope/api/_generated/projects/raw_client.py +92 -163
  87. mirascope/api/_generated/projects/types/__init__.py +1 -6
  88. mirascope/api/_generated/projects/types/projects_create_response.py +4 -9
  89. mirascope/api/_generated/projects/types/projects_get_response.py +4 -9
  90. mirascope/api/_generated/projects/types/projects_list_response_item.py +4 -9
  91. mirascope/api/_generated/projects/types/projects_update_response.py +4 -9
  92. mirascope/api/_generated/reference.md +1862 -70
  93. mirascope/api/_generated/traces/__init__.py +22 -0
  94. mirascope/api/_generated/traces/client.py +398 -0
  95. mirascope/api/_generated/traces/raw_client.py +902 -18
  96. mirascope/api/_generated/traces/types/__init__.py +32 -0
  97. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item.py +4 -11
  98. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource.py +2 -6
  99. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item.py +1 -3
  100. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value.py +8 -24
  101. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_array_value.py +2 -6
  102. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value.py +3 -9
  103. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value_values_item.py +2 -6
  104. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item.py +3 -9
  105. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope.py +4 -8
  106. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item.py +2 -6
  107. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value.py +8 -24
  108. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_array_value.py +2 -6
  109. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value.py +3 -9
  110. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value_values_item.py +1 -3
  111. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item.py +6 -18
  112. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item.py +3 -9
  113. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value.py +8 -24
  114. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_array_value.py +2 -6
  115. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value.py +2 -6
  116. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value_values_item.py +1 -3
  117. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_status.py +2 -6
  118. mirascope/api/_generated/traces/types/traces_create_response.py +2 -5
  119. mirascope/api/_generated/traces/types/traces_create_response_partial_success.py +3 -9
  120. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response.py +54 -0
  121. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_functions_item.py +24 -0
  122. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_models_item.py +22 -0
  123. mirascope/api/_generated/traces/types/traces_get_trace_detail_response.py +33 -0
  124. mirascope/api/_generated/traces/types/traces_get_trace_detail_response_spans_item.py +90 -0
  125. mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item.py +26 -0
  126. mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item_operator.py +7 -0
  127. mirascope/api/_generated/traces/types/traces_search_request_sort_by.py +7 -0
  128. mirascope/api/_generated/traces/types/traces_search_request_sort_order.py +5 -0
  129. mirascope/api/_generated/traces/types/traces_search_response.py +26 -0
  130. mirascope/api/_generated/traces/types/traces_search_response_spans_item.py +41 -0
  131. mirascope/api/_generated/types/__init__.py +18 -0
  132. mirascope/api/_generated/types/already_exists_error.py +1 -3
  133. mirascope/api/_generated/types/click_house_error.py +22 -0
  134. mirascope/api/_generated/types/database_error.py +1 -3
  135. mirascope/api/_generated/types/http_api_decode_error.py +1 -3
  136. mirascope/api/_generated/types/internal_server_error_body.py +49 -0
  137. mirascope/api/_generated/types/issue.py +1 -3
  138. mirascope/api/_generated/types/issue_tag.py +1 -8
  139. mirascope/api/_generated/types/not_found_error_body.py +1 -3
  140. mirascope/api/_generated/types/number_from_string.py +3 -0
  141. mirascope/api/_generated/types/permission_denied_error.py +1 -3
  142. mirascope/api/_generated/types/permission_denied_error_tag.py +1 -3
  143. mirascope/api/_generated/types/property_key_key.py +1 -3
  144. mirascope/api/_generated/types/stripe_error.py +20 -0
  145. mirascope/api/_generated/types/unauthorized_error_body.py +21 -0
  146. mirascope/api/_generated/types/unauthorized_error_tag.py +5 -0
  147. mirascope/llm/__init__.py +6 -2
  148. mirascope/llm/content/tool_call.py +6 -0
  149. mirascope/llm/exceptions.py +28 -0
  150. mirascope/llm/formatting/__init__.py +2 -2
  151. mirascope/llm/formatting/format.py +120 -8
  152. mirascope/llm/formatting/types.py +1 -56
  153. mirascope/llm/mcp/__init__.py +2 -2
  154. mirascope/llm/mcp/mcp_client.py +130 -0
  155. mirascope/llm/providers/__init__.py +26 -5
  156. mirascope/llm/providers/anthropic/__init__.py +3 -21
  157. mirascope/llm/providers/anthropic/_utils/__init__.py +2 -0
  158. mirascope/llm/providers/anthropic/_utils/beta_decode.py +4 -2
  159. mirascope/llm/providers/anthropic/_utils/beta_encode.py +13 -12
  160. mirascope/llm/providers/anthropic/_utils/decode.py +4 -2
  161. mirascope/llm/providers/anthropic/_utils/encode.py +57 -14
  162. mirascope/llm/providers/anthropic/_utils/errors.py +46 -0
  163. mirascope/llm/providers/anthropic/beta_provider.py +6 -0
  164. mirascope/llm/providers/anthropic/provider.py +5 -0
  165. mirascope/llm/providers/base/__init__.py +5 -2
  166. mirascope/llm/providers/base/_utils.py +2 -7
  167. mirascope/llm/providers/base/base_provider.py +173 -58
  168. mirascope/llm/providers/base/params.py +63 -34
  169. mirascope/llm/providers/google/__init__.py +2 -17
  170. mirascope/llm/providers/google/_utils/__init__.py +2 -0
  171. mirascope/llm/providers/google/_utils/decode.py +17 -8
  172. mirascope/llm/providers/google/_utils/encode.py +105 -16
  173. mirascope/llm/providers/google/_utils/errors.py +49 -0
  174. mirascope/llm/providers/google/model_info.py +1 -0
  175. mirascope/llm/providers/google/provider.py +9 -5
  176. mirascope/llm/providers/mirascope/__init__.py +5 -0
  177. mirascope/llm/providers/mirascope/_utils.py +77 -0
  178. mirascope/llm/providers/mirascope/provider.py +318 -0
  179. mirascope/llm/providers/mlx/__init__.py +2 -17
  180. mirascope/llm/providers/mlx/_utils.py +9 -2
  181. mirascope/llm/providers/mlx/provider.py +8 -0
  182. mirascope/llm/providers/ollama/__init__.py +1 -13
  183. mirascope/llm/providers/openai/__init__.py +10 -1
  184. mirascope/llm/providers/openai/_utils/__init__.py +5 -0
  185. mirascope/llm/providers/openai/_utils/errors.py +46 -0
  186. mirascope/llm/providers/openai/completions/__init__.py +2 -20
  187. mirascope/llm/providers/openai/completions/_utils/decode.py +14 -3
  188. mirascope/llm/providers/openai/completions/_utils/encode.py +15 -12
  189. mirascope/llm/providers/openai/completions/base_provider.py +6 -6
  190. mirascope/llm/providers/openai/provider.py +14 -1
  191. mirascope/llm/providers/openai/responses/__init__.py +1 -17
  192. mirascope/llm/providers/openai/responses/_utils/decode.py +2 -2
  193. mirascope/llm/providers/openai/responses/_utils/encode.py +43 -15
  194. mirascope/llm/providers/openai/responses/provider.py +13 -7
  195. mirascope/llm/providers/provider_id.py +1 -0
  196. mirascope/llm/providers/provider_registry.py +59 -3
  197. mirascope/llm/providers/together/__init__.py +1 -13
  198. mirascope/llm/responses/base_stream_response.py +24 -20
  199. mirascope/llm/tools/decorator.py +8 -4
  200. mirascope/llm/tools/tool_schema.py +33 -6
  201. mirascope/llm/tools/tools.py +84 -16
  202. mirascope/ops/__init__.py +60 -109
  203. mirascope/ops/_internal/closure.py +62 -11
  204. mirascope/ops/_internal/instrumentation/llm/llm.py +1 -2
  205. mirascope/ops/_internal/traced_functions.py +23 -4
  206. mirascope/ops/_internal/versioned_functions.py +54 -43
  207. {mirascope-2.0.0a4.dist-info → mirascope-2.0.0a6.dist-info}/METADATA +7 -7
  208. mirascope-2.0.0a6.dist-info/RECORD +316 -0
  209. mirascope/llm/formatting/_utils.py +0 -78
  210. mirascope/llm/mcp/client.py +0 -118
  211. mirascope/llm/providers/_missing_import_stubs.py +0 -49
  212. mirascope/llm/providers/load_provider.py +0 -54
  213. mirascope-2.0.0a4.dist-info/RECORD +0 -247
  214. {mirascope-2.0.0a4.dist-info → mirascope-2.0.0a6.dist-info}/WHEEL +0 -0
  215. {mirascope-2.0.0a4.dist-info → mirascope-2.0.0a6.dist-info}/licenses/LICENSE +0 -0
mirascope/ops/__init__.py CHANGED
@@ -2,117 +2,68 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- try:
6
- from ._internal.configuration import configure, tracer_context
7
- from ._internal.context import propagated_context
8
- from ._internal.instrumentation.llm import (
9
- instrument_llm,
10
- uninstrument_llm,
11
- )
12
- from ._internal.propagation import (
13
- ContextPropagator,
14
- PropagatorFormat,
15
- extract_context,
16
- get_propagator,
17
- inject_context,
18
- reset_propagator,
19
- )
20
- from ._internal.session import (
21
- SESSION_HEADER_NAME,
22
- SessionContext,
23
- current_session,
24
- extract_session_id,
25
- session,
26
- )
27
- from ._internal.spans import Span, span
28
- from ._internal.traced_calls import (
29
- TracedAsyncCall,
30
- TracedAsyncContextCall,
31
- TracedCall,
32
- TracedContextCall,
33
- )
34
- from ._internal.traced_functions import (
35
- AsyncTrace,
36
- AsyncTracedFunction,
37
- Trace,
38
- TracedFunction,
39
- )
40
- from ._internal.tracing import (
41
- TraceDecorator,
42
- trace,
43
- )
44
- from ._internal.versioned_calls import (
45
- VersionedAsyncCall,
46
- VersionedAsyncContextCall,
47
- VersionedCall,
48
- VersionedContextCall,
49
- )
50
- from ._internal.versioned_functions import (
51
- AsyncVersionedFunction,
52
- VersionedFunction,
53
- VersionInfo,
54
- )
55
- from ._internal.versioning import (
56
- VersionDecorator,
57
- version,
58
- )
59
- from .exceptions import ClosureComputationError
5
+ from .._stubs import stub_module_if_missing
60
6
 
61
- except ImportError: # pragma: no cover
62
- # TODO: refactor alongside other import error handling improvements
63
- from collections.abc import Callable
64
-
65
- def _create_otel_import_error_stub(name: str) -> Callable[..., None]:
66
- """Create a stub that raises ImportError with helpful message."""
67
-
68
- def _raise_not_installed() -> None:
69
- raise ImportError(
70
- f"The 'opentelemetry' packages are required to use {name}. "
71
- "Install them with: `uv add 'mirascope[otel]'`."
72
- )
73
-
74
- return _raise_not_installed
75
-
76
- propagated_context = _create_otel_import_error_stub("propagated_context")
77
- instrument_llm = _create_otel_import_error_stub("instrument_llm")
78
- uninstrument_llm = _create_otel_import_error_stub("uninstrument_llm")
79
- ContextPropagator = _create_otel_import_error_stub("ContextPropagator")
80
- PropagatorFormat = str
81
- extract_context = _create_otel_import_error_stub("extract_context")
82
- get_propagator = _create_otel_import_error_stub("get_propagator")
83
- inject_context = _create_otel_import_error_stub("inject_context")
84
- reset_propagator = _create_otel_import_error_stub("reset_propagator")
85
- SESSION_HEADER_NAME = "X-Mirascope-Session-ID"
86
- SessionContext = _create_otel_import_error_stub("SessionContext")
87
- current_session = _create_otel_import_error_stub("current_session")
88
- extract_session_id = _create_otel_import_error_stub("extract_session_id")
89
- session = _create_otel_import_error_stub("session")
90
- Span = _create_otel_import_error_stub("Span")
91
- span = _create_otel_import_error_stub("span")
92
- AsyncTrace = _create_otel_import_error_stub("AsyncTrace")
93
- AsyncTracedFunction = _create_otel_import_error_stub("AsyncTracedFunction")
94
- Trace = _create_otel_import_error_stub("Trace")
95
- TraceDecorator = _create_otel_import_error_stub("TraceDecorator")
96
- TracedAsyncCall = _create_otel_import_error_stub("TracedAsyncCall")
97
- TracedAsyncContextCall = _create_otel_import_error_stub("TracedAsyncContextCall")
98
- TracedCall = _create_otel_import_error_stub("TracedCall")
99
- TracedContextCall = _create_otel_import_error_stub("TracedContextCall")
100
- TracedFunction = _create_otel_import_error_stub("TracedFunction")
101
- trace = _create_otel_import_error_stub("trace")
102
- configure = _create_otel_import_error_stub("configure")
103
- tracer_context = _create_otel_import_error_stub("tracer_context")
104
- AsyncVersionedFunction = _create_otel_import_error_stub("AsyncVersionedFunction")
105
- VersionDecorator = _create_otel_import_error_stub("VersionDecorator")
106
- VersionedAsyncCall = _create_otel_import_error_stub("VersionedAsyncCall")
107
- VersionedAsyncContextCall = _create_otel_import_error_stub(
108
- "VersionedAsyncContextCall"
109
- )
110
- VersionedCall = _create_otel_import_error_stub("VersionedCall")
111
- VersionedContextCall = _create_otel_import_error_stub("VersionedContextCall")
112
- VersionedFunction = _create_otel_import_error_stub("VersionedFunction")
113
- VersionInfo = _create_otel_import_error_stub("VersionInfo")
114
- version = _create_otel_import_error_stub("version")
7
+ # Stub modules for missing optional dependencies BEFORE importing
8
+ # This must happen before any imports from these modules
9
+ stub_module_if_missing("mirascope.ops", "ops")
115
10
 
11
+ # Now imports work regardless of which packages are installed
12
+ # ruff: noqa: E402
13
+ from ._internal.configuration import configure, tracer_context
14
+ from ._internal.context import propagated_context
15
+ from ._internal.instrumentation.llm import (
16
+ instrument_llm,
17
+ uninstrument_llm,
18
+ )
19
+ from ._internal.propagation import (
20
+ ContextPropagator,
21
+ PropagatorFormat,
22
+ extract_context,
23
+ get_propagator,
24
+ inject_context,
25
+ reset_propagator,
26
+ )
27
+ from ._internal.session import (
28
+ SESSION_HEADER_NAME,
29
+ SessionContext,
30
+ current_session,
31
+ extract_session_id,
32
+ session,
33
+ )
34
+ from ._internal.spans import Span, span
35
+ from ._internal.traced_calls import (
36
+ TracedAsyncCall,
37
+ TracedAsyncContextCall,
38
+ TracedCall,
39
+ TracedContextCall,
40
+ )
41
+ from ._internal.traced_functions import (
42
+ AsyncTrace,
43
+ AsyncTracedFunction,
44
+ Trace,
45
+ TracedFunction,
46
+ )
47
+ from ._internal.tracing import (
48
+ TraceDecorator,
49
+ trace,
50
+ )
51
+ from ._internal.versioned_calls import (
52
+ VersionedAsyncCall,
53
+ VersionedAsyncContextCall,
54
+ VersionedCall,
55
+ VersionedContextCall,
56
+ )
57
+ from ._internal.versioned_functions import (
58
+ AsyncVersionedFunction,
59
+ VersionedFunction,
60
+ VersionInfo,
61
+ )
62
+ from ._internal.versioning import (
63
+ VersionDecorator,
64
+ version,
65
+ )
66
+ from .exceptions import ClosureComputationError
116
67
 
117
68
  __all__ = [
118
69
  "SESSION_HEADER_NAME",
@@ -50,6 +50,55 @@ def _is_third_party(module: ModuleType, site_packages: set[str]) -> bool:
50
50
  )
51
51
 
52
52
 
53
+ class _RemoveVersionDecoratorTransformer(cst.CSTTransformer):
54
+ """CST transformer to remove @ops.version and @version decorators."""
55
+
56
+ @classmethod
57
+ def _is_version_decorator(cls, decorator: cst.Decorator) -> bool:
58
+ """Returns True if the decorator is @version or @ops.version."""
59
+ decorator_node = decorator.decorator
60
+
61
+ if isinstance(decorator_node, cst.Name) and decorator_node.value == "version":
62
+ return True
63
+ if (
64
+ isinstance(decorator_node, cst.Call)
65
+ and isinstance(decorator_node.func, cst.Name)
66
+ and decorator_node.func.value == "version"
67
+ ):
68
+ return True
69
+
70
+ if (
71
+ isinstance(decorator_node, cst.Attribute)
72
+ and isinstance(decorator_node.value, cst.Name)
73
+ and decorator_node.value.value == "ops"
74
+ and decorator_node.attr.value == "version"
75
+ ):
76
+ return True
77
+ if isinstance(decorator_node, cst.Call) and isinstance(
78
+ decorator_node.func, cst.Attribute
79
+ ):
80
+ func_attribute = decorator_node.func
81
+ if (
82
+ isinstance(func_attribute.value, cst.Name)
83
+ and func_attribute.value.value == "ops"
84
+ and func_attribute.attr.value == "version"
85
+ ):
86
+ return True
87
+
88
+ return False
89
+
90
+ def leave_FunctionDef(
91
+ self, original_node: cst.FunctionDef, updated_node: cst.FunctionDef
92
+ ) -> cst.FunctionDef:
93
+ """Returns function definition with @version/@ops.version decorators removed."""
94
+ new_decorators = [
95
+ decorator
96
+ for decorator in updated_node.decorators
97
+ if not self._is_version_decorator(decorator)
98
+ ]
99
+ return updated_node.with_changes(decorators=new_decorators)
100
+
101
+
53
102
  class _RemoveDocstringTransformer(cst.CSTTransformer):
54
103
  """CST transformer to remove docstrings from functions and classes."""
55
104
 
@@ -125,14 +174,9 @@ def _clean_source_code(
125
174
  if docstr_flag in ("1", "true", "yes"):
126
175
  return source.rstrip()
127
176
  module = cst.parse_module(source)
128
-
129
- transformer = _RemoveDocstringTransformer(exclude_fn_body=exclude_fn_body)
130
- new_module = module.visit(transformer)
131
-
132
- code = new_module.code
133
- code = code.rstrip()
134
-
135
- return code
177
+ module = module.visit(_RemoveVersionDecoratorTransformer())
178
+ module = module.visit(_RemoveDocstringTransformer(exclude_fn_body=exclude_fn_body))
179
+ return module.code.rstrip()
136
180
 
137
181
 
138
182
  @dataclass(frozen=True)
@@ -596,9 +640,9 @@ def _clean_source_from_string(source: str, exclude_fn_body: bool = False) -> str
596
640
  """Returns cleaned source code string with optional docstring removal."""
597
641
  source = dedent(source)
598
642
  module = cst.parse_module(source)
599
- transformer = _RemoveDocstringTransformer(exclude_fn_body=exclude_fn_body)
600
- new_module = module.visit(transformer)
601
- return new_module.code.rstrip()
643
+ module = module.visit(_RemoveVersionDecoratorTransformer())
644
+ module = module.visit(_RemoveDocstringTransformer(exclude_fn_body=exclude_fn_body))
645
+ return module.code.rstrip()
602
646
 
603
647
 
604
648
  def _get_class_source_from_method(method: Callable[..., Any]) -> str:
@@ -694,6 +738,13 @@ class _DependencyCollector:
694
738
  # For Python 3.13+
695
739
  return definition.func # pyright: ignore[reportFunctionMemberAccess] # pragma: no cover
696
740
 
741
+ if (
742
+ (wrapped_function := getattr(definition, "fn", None)) is not None
743
+ and not hasattr(definition, "__qualname__")
744
+ and callable(wrapped_function)
745
+ ):
746
+ return wrapped_function
747
+
697
748
  return definition
698
749
 
699
750
  def _get_source_code(self, definition: Callable[..., Any] | type) -> str | None:
@@ -21,7 +21,6 @@ from opentelemetry.semconv.attributes import (
21
21
 
22
22
  from .....llm.context import Context, DepsT
23
23
  from .....llm.formatting import Format, FormattableT
24
- from .....llm.formatting._utils import create_tool_schema
25
24
  from .....llm.messages import Message
26
25
  from .....llm.models import Model
27
26
  from .....llm.providers import Params, ProviderId
@@ -230,7 +229,7 @@ def _serialize_tool_definitions(
230
229
  tool_schemas = _collect_tool_schemas(tools)
231
230
 
232
231
  if isinstance(format, Format) and format.mode == "tool":
233
- tool_schemas.append(create_tool_schema(format))
232
+ tool_schemas.append(format.create_tool_schema())
234
233
 
235
234
  if not tool_schemas:
236
235
  return None
@@ -15,6 +15,7 @@ from typing import (
15
15
 
16
16
  from opentelemetry.util.types import AttributeValue
17
17
 
18
+ from ...api.client import get_async_client, get_sync_client
18
19
  from ...llm.context import Context, DepsT
19
20
  from ...llm.responses.root_response import RootResponse
20
21
  from .protocols import (
@@ -91,7 +92,16 @@ class Trace(_BaseTrace[R]):
91
92
  metadata: dict[str, Jsonable] | None = None,
92
93
  ) -> None:
93
94
  """Annotates the current trace span."""
94
- raise NotImplementedError("Trace.annotate not yet implemented")
95
+ if self.span.span_id is None or self.span.trace_id is None:
96
+ return
97
+
98
+ get_sync_client().annotations.create(
99
+ otel_span_id=self.span.span_id,
100
+ otel_trace_id=self.span.trace_id,
101
+ label=label,
102
+ reasoning=reasoning,
103
+ metadata=metadata,
104
+ )
95
105
 
96
106
  def tag(self, *tags: str) -> None:
97
107
  """Adds given tags to the current trace span."""
@@ -113,12 +123,21 @@ class AsyncTrace(_BaseTrace[R]):
113
123
  async def annotate(
114
124
  self,
115
125
  *,
116
- label: str | None = None,
117
- data: dict[str, Jsonable] | None = None,
126
+ label: Literal["pass", "fail"],
118
127
  reasoning: str | None = None,
128
+ metadata: dict[str, Jsonable] | None = None,
119
129
  ) -> None:
120
130
  """Annotates the current trace span."""
121
- raise NotImplementedError("AsyncTrace.annotate not yet implemented")
131
+ if self.span.span_id is None or self.span.trace_id is None:
132
+ return
133
+
134
+ await get_async_client().annotations.create(
135
+ otel_span_id=self.span.span_id,
136
+ otel_trace_id=self.span.trace_id,
137
+ label=label,
138
+ reasoning=reasoning,
139
+ metadata=metadata,
140
+ )
122
141
 
123
142
  async def tag(self, *tags: str) -> None:
124
143
  """Adds given tags to the current trace span."""
@@ -7,8 +7,13 @@ from collections.abc import Generator, Mapping
7
7
  from contextlib import contextmanager
8
8
  from dataclasses import dataclass, field
9
9
  from functools import cached_property, lru_cache
10
- from typing import Any, NewType
10
+ from typing import Any, NewType, cast
11
11
 
12
+ from ...api._generated.errors.not_found_error import NotFoundError
13
+ from ...api._generated.functions.types.functions_create_request_dependencies_value import (
14
+ FunctionsCreateRequestDependenciesValue,
15
+ )
16
+ from ...api.client import get_async_client, get_sync_client
12
17
  from ..exceptions import ClosureComputationError
13
18
  from .closure import Closure
14
19
  from .spans import Span
@@ -239,40 +244,43 @@ class VersionedFunction(_BaseVersionedFunction[P, R], BaseSyncTracedFunction[P,
239
244
  raise NotImplementedError("VersionedFunction.get_version not yet implemented")
240
245
 
241
246
  def _ensure_registration(self) -> str | None:
242
- """Returns function UUID after ensuring registration with API.
243
-
244
- TODO: Implement API client integration to:
245
- 1. Get sync client via `get_sync_client()`
246
- 2. Check if function exists by hash: `client.functions.get_function_by_hash(self.closure.hash)`
247
- 3. If not found, create new version: `client.functions.create_a_new_function_version(...)`
248
- 4. Return the function UUID
249
-
250
- Example implementation (from lilypad):
251
- ```python
247
+ """Returns function UUID after ensuring registration with API."""
252
248
  if self.closure is None:
253
249
  return None
254
250
  try:
255
251
  client = get_sync_client()
256
252
  except Exception as e:
257
- logger.warning(f"Failed to get client for function registration: {e}")
253
+ logger.warning("Failed to get client for function registration: %s", e)
258
254
  return None
259
255
 
260
256
  try:
261
- existing = client.functions.get_function_by_hash(self.closure.hash)
262
- return existing.uuid_
257
+ existing = client.functions.findbyhash(self.closure.hash)
258
+ return existing.id
263
259
  except NotFoundError:
264
- response = client.functions.create_a_new_function_version(
260
+ dependencies: dict[str, FunctionsCreateRequestDependenciesValue | None] = {
261
+ name: FunctionsCreateRequestDependenciesValue(
262
+ version=dep_info["version"],
263
+ extras=dep_info.get("extras"),
264
+ )
265
+ for name, dep_info in self.closure.dependencies.items()
266
+ }
267
+ response = client.functions.create(
265
268
  code=self.closure.code,
266
269
  hash=self.closure.hash,
267
- name=self.closure.name,
268
270
  signature=self.closure.signature,
269
- dependencies=self.closure.dependencies,
271
+ signature_hash=self.closure.signature_hash,
272
+ name=self.name or self.closure.name,
273
+ description=self.closure.docstring,
274
+ tags=list(self.tags) if self.tags else None,
275
+ metadata=cast(dict[str, str | None], self.metadata)
276
+ if self.metadata
277
+ else None,
278
+ dependencies=dependencies if dependencies else None,
270
279
  )
271
- return response.uuid_
272
- ```
273
- """
274
- # TODO: Implement when API client is available
275
- return None
280
+ return response.id
281
+ except Exception as e:
282
+ logger.warning("Failed to register function: %s", e)
283
+ return None
276
284
 
277
285
 
278
286
  @dataclass(kw_only=True)
@@ -310,37 +318,40 @@ class AsyncVersionedFunction(
310
318
  )
311
319
 
312
320
  async def _ensure_registration(self) -> str | None:
313
- """Returns function UUID after ensuring registration with API.
314
-
315
- TODO: Implement API client integration to:
316
- 1. Get async client via `get_async_client()`
317
- 2. Check if function exists by hash: `await client.functions.get_function_by_hash(self.closure.hash)`
318
- 3. If not found, create new version: `await client.functions.create_a_new_function_version(...)`
319
- 4. Return the function UUID
320
-
321
- Example implementation (from lilypad):
322
- ```python
321
+ """Returns function UUID after ensuring registration with API."""
323
322
  if self.closure is None:
324
323
  return None
325
324
  try:
326
325
  client = get_async_client()
327
326
  except Exception as e:
328
- logger.warning(f"Failed to get client for function registration: {e}")
327
+ logger.warning("Failed to get client for function registration: %s", e)
329
328
  return None
330
329
 
331
330
  try:
332
- existing = await client.functions.get_function_by_hash(self.closure.hash)
333
- return existing.uuid_
331
+ existing = await client.functions.findbyhash(self.closure.hash)
332
+ return existing.id
334
333
  except NotFoundError:
335
- response = await client.functions.create_a_new_function_version(
334
+ dependencies: dict[str, FunctionsCreateRequestDependenciesValue | None] = {
335
+ name: FunctionsCreateRequestDependenciesValue(
336
+ version=dep_info["version"],
337
+ extras=dep_info.get("extras"),
338
+ )
339
+ for name, dep_info in self.closure.dependencies.items()
340
+ }
341
+ response = await client.functions.create(
336
342
  code=self.closure.code,
337
343
  hash=self.closure.hash,
338
- name=self.closure.name,
339
344
  signature=self.closure.signature,
340
- dependencies=self.closure.dependencies,
345
+ signature_hash=self.closure.signature_hash,
346
+ name=self.name or self.closure.name,
347
+ description=self.closure.docstring,
348
+ tags=list(self.tags) if self.tags else None,
349
+ metadata=cast(dict[str, str | None], self.metadata)
350
+ if self.metadata
351
+ else None,
352
+ dependencies=dependencies if dependencies else None,
341
353
  )
342
- return response.uuid_
343
- ```
344
- """
345
- # TODO: Implement when API client is available
346
- return None
354
+ return response.id
355
+ except Exception as e:
356
+ logger.warning("Failed to register function: %s", e)
357
+ return None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mirascope
3
- Version: 2.0.0a4
3
+ Version: 2.0.0a6
4
4
  Summary: LLM abstractions that aren't obstructions
5
5
  Project-URL: Homepage, https://mirascope.com
6
6
  Project-URL: Documentation, https://mirascope.com/docs/mirascope/v2
@@ -52,11 +52,11 @@ Requires-Dist: pydantic>=2.0.0
52
52
  Requires-Dist: typing-extensions>=4.10.0
53
53
  Provides-Extra: all
54
54
  Requires-Dist: anthropic<1.0,>=0.75.0; extra == 'all'
55
- Requires-Dist: google-genai<2,>=1.48.0; extra == 'all'
55
+ Requires-Dist: google-genai<2,>=1.57.0; extra == 'all'
56
56
  Requires-Dist: libcst>=1.8.6; extra == 'all'
57
- Requires-Dist: mcp<2,>=1.0.0; extra == 'all'
57
+ Requires-Dist: mcp<2,>=1.25.0; extra == 'all'
58
58
  Requires-Dist: mlx-lm<1,>=0.28.4; extra == 'all'
59
- Requires-Dist: openai<3,>=2.7.1; extra == 'all'
59
+ Requires-Dist: openai<3,>=2.14.0; extra == 'all'
60
60
  Requires-Dist: opentelemetry-api<2,>=1.38.0; extra == 'all'
61
61
  Requires-Dist: opentelemetry-exporter-otlp<2,>=1.38.0; extra == 'all'
62
62
  Requires-Dist: opentelemetry-instrumentation<1,>=0.59b0; extra == 'all'
@@ -74,15 +74,15 @@ Requires-Dist: anthropic<1.0,>=0.75.0; extra == 'anthropic'
74
74
  Provides-Extra: api
75
75
  Requires-Dist: pydantic-settings>=2.12.0; extra == 'api'
76
76
  Provides-Extra: google
77
- Requires-Dist: google-genai<2,>=1.48.0; extra == 'google'
77
+ Requires-Dist: google-genai<2,>=1.57.0; extra == 'google'
78
78
  Requires-Dist: pillow<11,>=10.4.0; extra == 'google'
79
79
  Requires-Dist: proto-plus>=1.24.0; extra == 'google'
80
80
  Provides-Extra: mcp
81
- Requires-Dist: mcp<2,>=1.0.0; extra == 'mcp'
81
+ Requires-Dist: mcp<2,>=1.25.0; extra == 'mcp'
82
82
  Provides-Extra: mlx
83
83
  Requires-Dist: mlx-lm<1,>=0.28.4; extra == 'mlx'
84
84
  Provides-Extra: openai
85
- Requires-Dist: openai<3,>=2.7.1; extra == 'openai'
85
+ Requires-Dist: openai<3,>=2.14.0; extra == 'openai'
86
86
  Provides-Extra: ops
87
87
  Requires-Dist: libcst>=1.8.6; extra == 'ops'
88
88
  Requires-Dist: opentelemetry-api<2,>=1.38.0; extra == 'ops'