mirascope 2.0.0a2__py3-none-any.whl → 2.0.0a4__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 (252) hide show
  1. mirascope/__init__.py +2 -2
  2. mirascope/api/__init__.py +6 -0
  3. mirascope/api/_generated/README.md +207 -0
  4. mirascope/api/_generated/__init__.py +141 -0
  5. mirascope/api/_generated/client.py +163 -0
  6. mirascope/api/_generated/core/__init__.py +52 -0
  7. mirascope/api/_generated/core/api_error.py +23 -0
  8. mirascope/api/_generated/core/client_wrapper.py +58 -0
  9. mirascope/api/_generated/core/datetime_utils.py +30 -0
  10. mirascope/api/_generated/core/file.py +70 -0
  11. mirascope/api/_generated/core/force_multipart.py +16 -0
  12. mirascope/api/_generated/core/http_client.py +619 -0
  13. mirascope/api/_generated/core/http_response.py +55 -0
  14. mirascope/api/_generated/core/jsonable_encoder.py +102 -0
  15. mirascope/api/_generated/core/pydantic_utilities.py +310 -0
  16. mirascope/api/_generated/core/query_encoder.py +60 -0
  17. mirascope/api/_generated/core/remove_none_from_dict.py +11 -0
  18. mirascope/api/_generated/core/request_options.py +35 -0
  19. mirascope/api/_generated/core/serialization.py +282 -0
  20. mirascope/api/_generated/docs/__init__.py +4 -0
  21. mirascope/api/_generated/docs/client.py +95 -0
  22. mirascope/api/_generated/docs/raw_client.py +132 -0
  23. mirascope/api/_generated/environment.py +9 -0
  24. mirascope/api/_generated/errors/__init__.py +17 -0
  25. mirascope/api/_generated/errors/bad_request_error.py +15 -0
  26. mirascope/api/_generated/errors/conflict_error.py +15 -0
  27. mirascope/api/_generated/errors/forbidden_error.py +15 -0
  28. mirascope/api/_generated/errors/internal_server_error.py +15 -0
  29. mirascope/api/_generated/errors/not_found_error.py +15 -0
  30. mirascope/api/_generated/health/__init__.py +7 -0
  31. mirascope/api/_generated/health/client.py +96 -0
  32. mirascope/api/_generated/health/raw_client.py +129 -0
  33. mirascope/api/_generated/health/types/__init__.py +8 -0
  34. mirascope/api/_generated/health/types/health_check_response.py +24 -0
  35. mirascope/api/_generated/health/types/health_check_response_status.py +5 -0
  36. mirascope/api/_generated/organizations/__init__.py +25 -0
  37. mirascope/api/_generated/organizations/client.py +380 -0
  38. mirascope/api/_generated/organizations/raw_client.py +876 -0
  39. mirascope/api/_generated/organizations/types/__init__.py +23 -0
  40. mirascope/api/_generated/organizations/types/organizations_create_response.py +24 -0
  41. mirascope/api/_generated/organizations/types/organizations_create_response_role.py +7 -0
  42. mirascope/api/_generated/organizations/types/organizations_get_response.py +24 -0
  43. mirascope/api/_generated/organizations/types/organizations_get_response_role.py +7 -0
  44. mirascope/api/_generated/organizations/types/organizations_list_response_item.py +24 -0
  45. mirascope/api/_generated/organizations/types/organizations_list_response_item_role.py +7 -0
  46. mirascope/api/_generated/organizations/types/organizations_update_response.py +24 -0
  47. mirascope/api/_generated/organizations/types/organizations_update_response_role.py +7 -0
  48. mirascope/api/_generated/projects/__init__.py +17 -0
  49. mirascope/api/_generated/projects/client.py +458 -0
  50. mirascope/api/_generated/projects/raw_client.py +1016 -0
  51. mirascope/api/_generated/projects/types/__init__.py +15 -0
  52. mirascope/api/_generated/projects/types/projects_create_response.py +30 -0
  53. mirascope/api/_generated/projects/types/projects_get_response.py +30 -0
  54. mirascope/api/_generated/projects/types/projects_list_response_item.py +30 -0
  55. mirascope/api/_generated/projects/types/projects_update_response.py +30 -0
  56. mirascope/api/_generated/reference.md +753 -0
  57. mirascope/api/_generated/traces/__init__.py +55 -0
  58. mirascope/api/_generated/traces/client.py +162 -0
  59. mirascope/api/_generated/traces/raw_client.py +168 -0
  60. mirascope/api/_generated/traces/types/__init__.py +95 -0
  61. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item.py +36 -0
  62. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource.py +31 -0
  63. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item.py +25 -0
  64. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value.py +54 -0
  65. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_array_value.py +23 -0
  66. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value.py +28 -0
  67. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value_values_item.py +24 -0
  68. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item.py +35 -0
  69. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope.py +35 -0
  70. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item.py +27 -0
  71. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value.py +54 -0
  72. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_array_value.py +23 -0
  73. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value.py +28 -0
  74. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value_values_item.py +24 -0
  75. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item.py +60 -0
  76. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item.py +29 -0
  77. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value.py +54 -0
  78. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_array_value.py +23 -0
  79. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value.py +28 -0
  80. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value_values_item.py +24 -0
  81. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_status.py +24 -0
  82. mirascope/api/_generated/traces/types/traces_create_response.py +27 -0
  83. mirascope/api/_generated/traces/types/traces_create_response_partial_success.py +28 -0
  84. mirascope/api/_generated/types/__init__.py +37 -0
  85. mirascope/api/_generated/types/already_exists_error.py +24 -0
  86. mirascope/api/_generated/types/already_exists_error_tag.py +5 -0
  87. mirascope/api/_generated/types/database_error.py +24 -0
  88. mirascope/api/_generated/types/database_error_tag.py +5 -0
  89. mirascope/api/_generated/types/http_api_decode_error.py +29 -0
  90. mirascope/api/_generated/types/http_api_decode_error_tag.py +5 -0
  91. mirascope/api/_generated/types/issue.py +40 -0
  92. mirascope/api/_generated/types/issue_tag.py +17 -0
  93. mirascope/api/_generated/types/not_found_error_body.py +24 -0
  94. mirascope/api/_generated/types/not_found_error_tag.py +5 -0
  95. mirascope/api/_generated/types/permission_denied_error.py +24 -0
  96. mirascope/api/_generated/types/permission_denied_error_tag.py +7 -0
  97. mirascope/api/_generated/types/property_key.py +7 -0
  98. mirascope/api/_generated/types/property_key_key.py +27 -0
  99. mirascope/api/_generated/types/property_key_key_tag.py +5 -0
  100. mirascope/api/client.py +255 -0
  101. mirascope/api/settings.py +81 -0
  102. mirascope/llm/__init__.py +45 -11
  103. mirascope/llm/calls/calls.py +81 -57
  104. mirascope/llm/calls/decorator.py +121 -115
  105. mirascope/llm/content/__init__.py +3 -2
  106. mirascope/llm/context/_utils.py +19 -6
  107. mirascope/llm/exceptions.py +30 -16
  108. mirascope/llm/formatting/_utils.py +9 -5
  109. mirascope/llm/formatting/format.py +2 -2
  110. mirascope/llm/formatting/from_call_args.py +2 -2
  111. mirascope/llm/messages/message.py +13 -5
  112. mirascope/llm/models/__init__.py +2 -2
  113. mirascope/llm/models/models.py +189 -81
  114. mirascope/llm/prompts/__init__.py +13 -12
  115. mirascope/llm/prompts/_utils.py +27 -24
  116. mirascope/llm/prompts/decorator.py +133 -204
  117. mirascope/llm/prompts/prompts.py +424 -0
  118. mirascope/llm/prompts/protocols.py +25 -59
  119. mirascope/llm/providers/__init__.py +44 -0
  120. mirascope/llm/{clients → providers}/_missing_import_stubs.py +8 -6
  121. mirascope/llm/providers/anthropic/__init__.py +29 -0
  122. mirascope/llm/providers/anthropic/_utils/__init__.py +23 -0
  123. mirascope/llm/providers/anthropic/_utils/beta_decode.py +271 -0
  124. mirascope/llm/providers/anthropic/_utils/beta_encode.py +216 -0
  125. mirascope/llm/{clients → providers}/anthropic/_utils/decode.py +44 -11
  126. mirascope/llm/providers/anthropic/_utils/encode.py +356 -0
  127. mirascope/llm/providers/anthropic/beta_provider.py +322 -0
  128. mirascope/llm/providers/anthropic/model_id.py +23 -0
  129. mirascope/llm/providers/anthropic/model_info.py +87 -0
  130. mirascope/llm/providers/anthropic/provider.py +416 -0
  131. mirascope/llm/{clients → providers}/base/__init__.py +3 -3
  132. mirascope/llm/{clients → providers}/base/_utils.py +25 -8
  133. mirascope/llm/{clients/base/client.py → providers/base/base_provider.py} +255 -126
  134. mirascope/llm/providers/google/__init__.py +21 -0
  135. mirascope/llm/{clients → providers}/google/_utils/decode.py +61 -7
  136. mirascope/llm/{clients → providers}/google/_utils/encode.py +44 -30
  137. mirascope/llm/providers/google/model_id.py +22 -0
  138. mirascope/llm/providers/google/model_info.py +62 -0
  139. mirascope/llm/providers/google/provider.py +442 -0
  140. mirascope/llm/providers/load_provider.py +54 -0
  141. mirascope/llm/providers/mlx/__init__.py +24 -0
  142. mirascope/llm/providers/mlx/_utils.py +129 -0
  143. mirascope/llm/providers/mlx/encoding/__init__.py +8 -0
  144. mirascope/llm/providers/mlx/encoding/base.py +69 -0
  145. mirascope/llm/providers/mlx/encoding/transformers.py +147 -0
  146. mirascope/llm/providers/mlx/mlx.py +237 -0
  147. mirascope/llm/providers/mlx/model_id.py +17 -0
  148. mirascope/llm/providers/mlx/provider.py +415 -0
  149. mirascope/llm/providers/model_id.py +16 -0
  150. mirascope/llm/providers/ollama/__init__.py +19 -0
  151. mirascope/llm/providers/ollama/provider.py +71 -0
  152. mirascope/llm/providers/openai/__init__.py +6 -0
  153. mirascope/llm/providers/openai/completions/__init__.py +25 -0
  154. mirascope/llm/{clients → providers}/openai/completions/_utils/__init__.py +2 -0
  155. mirascope/llm/{clients → providers}/openai/completions/_utils/decode.py +60 -6
  156. mirascope/llm/{clients → providers}/openai/completions/_utils/encode.py +37 -26
  157. mirascope/llm/providers/openai/completions/base_provider.py +513 -0
  158. mirascope/llm/providers/openai/completions/provider.py +22 -0
  159. mirascope/llm/providers/openai/model_id.py +31 -0
  160. mirascope/llm/providers/openai/model_info.py +303 -0
  161. mirascope/llm/providers/openai/provider.py +398 -0
  162. mirascope/llm/providers/openai/responses/__init__.py +21 -0
  163. mirascope/llm/{clients → providers}/openai/responses/_utils/decode.py +59 -6
  164. mirascope/llm/{clients → providers}/openai/responses/_utils/encode.py +34 -23
  165. mirascope/llm/providers/openai/responses/provider.py +469 -0
  166. mirascope/llm/providers/provider_id.py +23 -0
  167. mirascope/llm/providers/provider_registry.py +169 -0
  168. mirascope/llm/providers/together/__init__.py +19 -0
  169. mirascope/llm/providers/together/provider.py +40 -0
  170. mirascope/llm/responses/__init__.py +3 -0
  171. mirascope/llm/responses/base_response.py +14 -5
  172. mirascope/llm/responses/base_stream_response.py +35 -6
  173. mirascope/llm/responses/finish_reason.py +1 -0
  174. mirascope/llm/responses/response.py +33 -13
  175. mirascope/llm/responses/root_response.py +12 -13
  176. mirascope/llm/responses/stream_response.py +35 -23
  177. mirascope/llm/responses/usage.py +95 -0
  178. mirascope/llm/tools/__init__.py +9 -2
  179. mirascope/llm/tools/_utils.py +12 -3
  180. mirascope/llm/tools/protocols.py +4 -4
  181. mirascope/llm/tools/tool_schema.py +44 -9
  182. mirascope/llm/tools/tools.py +10 -9
  183. mirascope/ops/__init__.py +156 -0
  184. mirascope/ops/_internal/__init__.py +5 -0
  185. mirascope/ops/_internal/closure.py +1118 -0
  186. mirascope/ops/_internal/configuration.py +126 -0
  187. mirascope/ops/_internal/context.py +76 -0
  188. mirascope/ops/_internal/exporters/__init__.py +26 -0
  189. mirascope/ops/_internal/exporters/exporters.py +342 -0
  190. mirascope/ops/_internal/exporters/processors.py +104 -0
  191. mirascope/ops/_internal/exporters/types.py +165 -0
  192. mirascope/ops/_internal/exporters/utils.py +29 -0
  193. mirascope/ops/_internal/instrumentation/__init__.py +8 -0
  194. mirascope/ops/_internal/instrumentation/llm/__init__.py +8 -0
  195. mirascope/ops/_internal/instrumentation/llm/encode.py +238 -0
  196. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/__init__.py +38 -0
  197. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_input_messages.py +31 -0
  198. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_output_messages.py +38 -0
  199. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_system_instructions.py +18 -0
  200. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/shared.py +100 -0
  201. mirascope/ops/_internal/instrumentation/llm/llm.py +1288 -0
  202. mirascope/ops/_internal/propagation.py +198 -0
  203. mirascope/ops/_internal/protocols.py +51 -0
  204. mirascope/ops/_internal/session.py +139 -0
  205. mirascope/ops/_internal/spans.py +232 -0
  206. mirascope/ops/_internal/traced_calls.py +371 -0
  207. mirascope/ops/_internal/traced_functions.py +394 -0
  208. mirascope/ops/_internal/tracing.py +276 -0
  209. mirascope/ops/_internal/types.py +13 -0
  210. mirascope/ops/_internal/utils.py +75 -0
  211. mirascope/ops/_internal/versioned_calls.py +512 -0
  212. mirascope/ops/_internal/versioned_functions.py +346 -0
  213. mirascope/ops/_internal/versioning.py +303 -0
  214. mirascope/ops/exceptions.py +21 -0
  215. {mirascope-2.0.0a2.dist-info → mirascope-2.0.0a4.dist-info}/METADATA +78 -3
  216. mirascope-2.0.0a4.dist-info/RECORD +247 -0
  217. {mirascope-2.0.0a2.dist-info → mirascope-2.0.0a4.dist-info}/WHEEL +1 -1
  218. mirascope/graphs/__init__.py +0 -22
  219. mirascope/graphs/finite_state_machine.py +0 -625
  220. mirascope/llm/agents/__init__.py +0 -15
  221. mirascope/llm/agents/agent.py +0 -97
  222. mirascope/llm/agents/agent_template.py +0 -45
  223. mirascope/llm/agents/decorator.py +0 -176
  224. mirascope/llm/calls/base_call.py +0 -33
  225. mirascope/llm/clients/__init__.py +0 -34
  226. mirascope/llm/clients/anthropic/__init__.py +0 -25
  227. mirascope/llm/clients/anthropic/_utils/encode.py +0 -243
  228. mirascope/llm/clients/anthropic/clients.py +0 -819
  229. mirascope/llm/clients/anthropic/model_ids.py +0 -8
  230. mirascope/llm/clients/google/__init__.py +0 -20
  231. mirascope/llm/clients/google/clients.py +0 -853
  232. mirascope/llm/clients/google/model_ids.py +0 -15
  233. mirascope/llm/clients/openai/__init__.py +0 -25
  234. mirascope/llm/clients/openai/completions/__init__.py +0 -28
  235. mirascope/llm/clients/openai/completions/_utils/model_features.py +0 -81
  236. mirascope/llm/clients/openai/completions/clients.py +0 -833
  237. mirascope/llm/clients/openai/completions/model_ids.py +0 -8
  238. mirascope/llm/clients/openai/responses/__init__.py +0 -26
  239. mirascope/llm/clients/openai/responses/_utils/__init__.py +0 -13
  240. mirascope/llm/clients/openai/responses/_utils/model_features.py +0 -87
  241. mirascope/llm/clients/openai/responses/clients.py +0 -832
  242. mirascope/llm/clients/openai/responses/model_ids.py +0 -8
  243. mirascope/llm/clients/openai/shared/__init__.py +0 -7
  244. mirascope/llm/clients/openai/shared/_utils.py +0 -55
  245. mirascope/llm/clients/providers.py +0 -175
  246. mirascope-2.0.0a2.dist-info/RECORD +0 -102
  247. /mirascope/llm/{clients → providers}/base/kwargs.py +0 -0
  248. /mirascope/llm/{clients → providers}/base/params.py +0 -0
  249. /mirascope/llm/{clients/anthropic → providers/google}/_utils/__init__.py +0 -0
  250. /mirascope/llm/{clients → providers}/google/message.py +0 -0
  251. /mirascope/llm/{clients/google → providers/openai/responses}/_utils/__init__.py +0 -0
  252. {mirascope-2.0.0a2.dist-info → mirascope-2.0.0a4.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,371 @@
1
+ """Traced call wrappers for @ops.trace decorated @llm.call functions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from typing import Any, Generic, TypeVar
7
+ from typing_extensions import TypeIs
8
+
9
+ from ...llm.calls import AsyncCall, AsyncContextCall, Call, ContextCall
10
+ from ...llm.context import Context, DepsT
11
+ from ...llm.formatting import FormattableT
12
+ from ...llm.responses import (
13
+ AsyncContextResponse,
14
+ AsyncContextStreamResponse,
15
+ AsyncResponse,
16
+ AsyncStreamResponse,
17
+ ContextResponse,
18
+ ContextStreamResponse,
19
+ Response,
20
+ StreamResponse,
21
+ )
22
+ from ...llm.types import P
23
+ from .protocols import (
24
+ AsyncFunction,
25
+ R,
26
+ SyncFunction,
27
+ )
28
+ from .traced_functions import (
29
+ AsyncTrace,
30
+ AsyncTracedContextFunction,
31
+ AsyncTracedFunction,
32
+ Trace,
33
+ TracedContextFunction,
34
+ TracedFunction,
35
+ )
36
+
37
+ CallT = TypeVar(
38
+ "CallT",
39
+ bound=Call[..., Any]
40
+ | AsyncCall[..., Any]
41
+ | ContextCall[..., Any, Any]
42
+ | AsyncContextCall[..., Any, Any],
43
+ )
44
+
45
+
46
+ def is_call_type(
47
+ fn: (
48
+ SyncFunction[P, R]
49
+ | AsyncFunction[P, R]
50
+ | ContextCall[P, DepsT, FormattableT]
51
+ | AsyncContextCall[P, DepsT, FormattableT]
52
+ | Call[P, FormattableT]
53
+ | AsyncCall[P, FormattableT]
54
+ ),
55
+ ) -> TypeIs[
56
+ ContextCall[P, DepsT, FormattableT]
57
+ | AsyncContextCall[P, DepsT, FormattableT]
58
+ | Call[P, FormattableT]
59
+ | AsyncCall[P, FormattableT]
60
+ ]:
61
+ """Check if fn is any of the Call types."""
62
+ return isinstance(fn, Call | AsyncCall | ContextCall | AsyncContextCall)
63
+
64
+
65
+ def wrap_call(
66
+ fn: (
67
+ ContextCall[P, DepsT, FormattableT]
68
+ | AsyncContextCall[P, DepsT, FormattableT]
69
+ | Call[P, FormattableT]
70
+ | AsyncCall[P, FormattableT]
71
+ ),
72
+ tags: tuple[str, ...],
73
+ metadata: dict[str, str] | None = None,
74
+ ) -> (
75
+ TracedContextCall[P, DepsT, FormattableT]
76
+ | TracedAsyncContextCall[P, DepsT, FormattableT]
77
+ | TracedCall[P, FormattableT]
78
+ | TracedAsyncCall[P, FormattableT]
79
+ ):
80
+ """Wrap a Call object with the appropriate TracedCall type."""
81
+ metadata = metadata or {}
82
+ if isinstance(fn, AsyncContextCall):
83
+ return TracedAsyncContextCall(_call=fn, tags=tags, metadata=metadata)
84
+ elif isinstance(fn, ContextCall):
85
+ return TracedContextCall(_call=fn, tags=tags, metadata=metadata)
86
+ elif isinstance(fn, AsyncCall):
87
+ return TracedAsyncCall(_call=fn, tags=tags, metadata=metadata)
88
+ else:
89
+ return TracedCall(_call=fn, tags=tags, metadata=metadata)
90
+
91
+
92
+ @dataclass(kw_only=True)
93
+ class _BaseTracedCall(Generic[CallT]):
94
+ """Wrapper for traced Call objects."""
95
+
96
+ _call: CallT
97
+ """The original unwrapped Call object."""
98
+
99
+ tags: tuple[str, ...]
100
+ """Tags to be associated with traced calls."""
101
+
102
+ metadata: dict[str, str] = field(default_factory=dict)
103
+ """Arbitrary key-value pairs for additional metadata."""
104
+
105
+
106
+ @dataclass(kw_only=True)
107
+ class TracedCall(_BaseTracedCall[Call[P, FormattableT]]):
108
+ """Traced wrapper for traced synchronous Call objects.
109
+
110
+ When @ops.trace decorates an @llm.call, it returns a TracedCall that wraps
111
+ the call and stream methods with tracing capabilities.
112
+
113
+ Example:
114
+ ```python
115
+ @ops.trace
116
+ @llm.call("gpt-4o-mini")
117
+ def recommend_book(genre: str):
118
+ return f"Recommend a {genre} book"
119
+
120
+ # Returns Response directly (but execution is traced)
121
+ response = recommend_book("fantasy")
122
+ print(response.content)
123
+
124
+ # Same as __call__
125
+ response = recommend_book.call("fantasy")
126
+
127
+ # Streaming returns StreamResponse (traced)
128
+ stream = recommend_book.stream("fantasy")
129
+ for chunk in stream:
130
+ print(chunk)
131
+
132
+ # Use wrapped to get Trace[Response] with span info
133
+ trace = recommend_book.wrapped("fantasy")
134
+ print(trace.result.content)
135
+ print(trace.span_id)
136
+
137
+ # Use wrapped_stream to get Trace[StreamResponse]
138
+ trace = recommend_book.wrapped_stream("fantasy")
139
+ ```
140
+ """
141
+
142
+ call: TracedFunction[P, Response | Response[FormattableT]] = field(init=False)
143
+ """TracedFunction wrapping the call method."""
144
+
145
+ stream: TracedFunction[P, StreamResponse | StreamResponse[FormattableT]] = field(
146
+ init=False
147
+ )
148
+ """TracedFunction wrapping the stream method."""
149
+
150
+ def __post_init__(self) -> None:
151
+ """Initialize TracedFunction wrappers for call and stream methods."""
152
+ self.call = TracedFunction(
153
+ fn=self._call.call, tags=self.tags, metadata=self.metadata
154
+ )
155
+ self.stream = TracedFunction(
156
+ fn=self._call.stream, tags=self.tags, metadata=self.metadata
157
+ )
158
+
159
+ def __call__(
160
+ self, *args: P.args, **kwargs: P.kwargs
161
+ ) -> Response | Response[FormattableT]:
162
+ """Call the traced function and return Response directly."""
163
+ return self.call(*args, **kwargs)
164
+
165
+ def wrapped(
166
+ self, *args: P.args, **kwargs: P.kwargs
167
+ ) -> Trace[Response | Response[FormattableT]]:
168
+ """Call the traced function and return a wrapped Response."""
169
+ return self.call.wrapped(*args, **kwargs)
170
+
171
+ def wrapped_stream(
172
+ self, *args: P.args, **kwargs: P.kwargs
173
+ ) -> Trace[StreamResponse | StreamResponse[FormattableT]]:
174
+ """Stream the traced function and return a wrapped StreamResponse."""
175
+ return self.stream.wrapped(*args, **kwargs)
176
+
177
+
178
+ @dataclass(kw_only=True)
179
+ class TracedAsyncCall(_BaseTracedCall[AsyncCall[P, FormattableT]]):
180
+ """Traced wrapper for traced asynchronous AsyncCall objects.
181
+
182
+ Example:
183
+ ```python
184
+ @ops.trace
185
+ @llm.call("gpt-4o-mini")
186
+ async def recommend_book(genre: str):
187
+ return f"Recommend a {genre} book"
188
+
189
+ # Returns AsyncResponse directly (but execution is traced)
190
+ response = await recommend_book("fantasy")
191
+ print(response.content)
192
+
193
+ # Use wrapped to get AsyncTrace[AsyncResponse] with span info
194
+ trace = await recommend_book.wrapped("fantasy")
195
+ print(trace.result.content)
196
+ print(trace.span_id)
197
+ ```
198
+ """
199
+
200
+ call: AsyncTracedFunction[P, AsyncResponse | AsyncResponse[FormattableT]] = field(
201
+ init=False
202
+ )
203
+ """AsyncTracedFunction wrapping the call method."""
204
+
205
+ stream: AsyncTracedFunction[
206
+ P, AsyncStreamResponse | AsyncStreamResponse[FormattableT]
207
+ ] = field(init=False)
208
+ """AsyncTracedFunction wrapping the stream method."""
209
+
210
+ def __post_init__(self) -> None:
211
+ """Initialize AsyncTracedFunction wrappers for call and stream methods."""
212
+ self.call = AsyncTracedFunction(
213
+ fn=self._call.call, tags=self.tags, metadata=self.metadata
214
+ )
215
+ self.stream = AsyncTracedFunction(
216
+ fn=self._call.stream, tags=self.tags, metadata=self.metadata
217
+ )
218
+
219
+ async def __call__(
220
+ self, *args: P.args, **kwargs: P.kwargs
221
+ ) -> AsyncResponse | AsyncResponse[FormattableT]:
222
+ """Call the traced function and return AsyncResponse directly."""
223
+ return await self.call(*args, **kwargs)
224
+
225
+ async def wrapped(
226
+ self, *args: P.args, **kwargs: P.kwargs
227
+ ) -> AsyncTrace[AsyncResponse | AsyncResponse[FormattableT]]:
228
+ """Call the traced function and return a wrapped Response."""
229
+ return await self.call.wrapped(*args, **kwargs)
230
+
231
+ async def wrapped_stream(
232
+ self, *args: P.args, **kwargs: P.kwargs
233
+ ) -> AsyncTrace[AsyncStreamResponse | AsyncStreamResponse[FormattableT]]:
234
+ """Stream the traced function and return a wrapped StreamResponse."""
235
+ return await self.stream.wrapped(*args, **kwargs)
236
+
237
+
238
+ @dataclass(kw_only=True)
239
+ class TracedContextCall(_BaseTracedCall[ContextCall[P, DepsT, FormattableT]]):
240
+ """Traced wrapper for traced synchronous ContextCall objects.
241
+
242
+ Example:
243
+ ```python
244
+ @ops.trace
245
+ @llm.call("gpt-4o-mini")
246
+ def recommend_book(ctx: llm.Context[str], genre: str):
247
+ return f"{ctx.deps} Recommend a {genre} book"
248
+
249
+ ctx = llm.Context(deps="As a librarian,")
250
+
251
+ # Returns ContextResponse directly (but execution is traced)
252
+ response = recommend_book(ctx, "fantasy")
253
+ print(response.content)
254
+
255
+ # Use wrapped to get Trace[ContextResponse] with span info
256
+ trace = recommend_book.wrapped(ctx, "fantasy")
257
+ print(trace.result.content)
258
+ ```
259
+ """
260
+
261
+ call: TracedContextFunction[
262
+ P, DepsT, ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]
263
+ ] = field(init=False)
264
+ """TracedContextFunction wrapping the call method."""
265
+
266
+ stream: TracedContextFunction[
267
+ P,
268
+ DepsT,
269
+ ContextStreamResponse[DepsT, None] | ContextStreamResponse[DepsT, FormattableT],
270
+ ] = field(init=False)
271
+ """TracedContextFunction wrapping the stream method."""
272
+
273
+ def __post_init__(self) -> None:
274
+ """Initialize TracedContextFunction wrappers for call and stream methods."""
275
+ self.call = TracedContextFunction(
276
+ fn=self._call.call, tags=self.tags, metadata=self.metadata
277
+ )
278
+ self.stream = TracedContextFunction(
279
+ fn=self._call.stream, tags=self.tags, metadata=self.metadata
280
+ )
281
+
282
+ def __call__(
283
+ self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
284
+ ) -> ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]:
285
+ """Call the traced function and return ContextResponse directly."""
286
+ return self.call(ctx, *args, **kwargs)
287
+
288
+ def wrapped(
289
+ self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
290
+ ) -> Trace[ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]]:
291
+ """Call the traced function and return a wrapped Response."""
292
+ return self.call.wrapped(ctx, *args, **kwargs)
293
+
294
+ def wrapped_stream(
295
+ self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
296
+ ) -> Trace[
297
+ ContextStreamResponse[DepsT, None] | ContextStreamResponse[DepsT, FormattableT]
298
+ ]:
299
+ """Stream the traced function and return a wrapped StreamResponse."""
300
+ return self.stream.wrapped(ctx, *args, **kwargs)
301
+
302
+
303
+ @dataclass(kw_only=True)
304
+ class TracedAsyncContextCall(_BaseTracedCall[AsyncContextCall[P, DepsT, FormattableT]]):
305
+ """Traced wrapper for traced asynchronous AsyncContextCall objects.
306
+
307
+ Example:
308
+ ```python
309
+ @ops.trace
310
+ @llm.call("gpt-4o-mini")
311
+ async def recommend_book(ctx: llm.Context[str], genre: str):
312
+ return f"{ctx.deps} Recommend a {genre} book"
313
+
314
+ ctx = llm.Context(deps="As a librarian,")
315
+
316
+ # Returns AsyncContextResponse directly (but execution is traced)
317
+ response = await recommend_book(ctx, "fantasy")
318
+ print(response.content)
319
+
320
+ # Use wrapped to get AsyncTrace[AsyncContextResponse] with span info
321
+ trace = await recommend_book.wrapped(ctx, "fantasy")
322
+ print(trace.result.content)
323
+ ```
324
+ """
325
+
326
+ call: AsyncTracedContextFunction[
327
+ P,
328
+ DepsT,
329
+ AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT],
330
+ ] = field(init=False)
331
+ """AsyncTracedContextFunction wrapping the call method."""
332
+
333
+ stream: AsyncTracedContextFunction[
334
+ P,
335
+ DepsT,
336
+ AsyncContextStreamResponse[DepsT, None]
337
+ | AsyncContextStreamResponse[DepsT, FormattableT],
338
+ ] = field(init=False)
339
+ """AsyncTracedContextFunction wrapping the stream method."""
340
+
341
+ def __post_init__(self) -> None:
342
+ """Initialize AsyncTracedContextFunction wrappers for call and stream methods."""
343
+ self.call = AsyncTracedContextFunction(
344
+ fn=self._call.call, tags=self.tags, metadata=self.metadata
345
+ )
346
+ self.stream = AsyncTracedContextFunction(
347
+ fn=self._call.stream, tags=self.tags, metadata=self.metadata
348
+ )
349
+
350
+ async def __call__(
351
+ self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
352
+ ) -> AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT]:
353
+ """Call the traced function and return AsyncContextResponse directly."""
354
+ return await self.call(ctx, *args, **kwargs)
355
+
356
+ async def wrapped(
357
+ self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
358
+ ) -> AsyncTrace[
359
+ AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT]
360
+ ]:
361
+ """Call the traced function and return a wrapped Response."""
362
+ return await self.call.wrapped(ctx, *args, **kwargs)
363
+
364
+ async def wrapped_stream(
365
+ self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
366
+ ) -> AsyncTrace[
367
+ AsyncContextStreamResponse[DepsT, None]
368
+ | AsyncContextStreamResponse[DepsT, FormattableT]
369
+ ]:
370
+ """Stream the traced function and return a wrapped StreamResponse."""
371
+ return await self.stream.wrapped(ctx, *args, **kwargs)