mirascope 2.0.0a2__py3-none-any.whl → 2.0.0a3__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.
- mirascope/__init__.py +2 -2
- mirascope/api/__init__.py +6 -0
- mirascope/api/_generated/README.md +207 -0
- mirascope/api/_generated/__init__.py +85 -0
- mirascope/api/_generated/client.py +155 -0
- mirascope/api/_generated/core/__init__.py +52 -0
- mirascope/api/_generated/core/api_error.py +23 -0
- mirascope/api/_generated/core/client_wrapper.py +58 -0
- mirascope/api/_generated/core/datetime_utils.py +30 -0
- mirascope/api/_generated/core/file.py +70 -0
- mirascope/api/_generated/core/force_multipart.py +16 -0
- mirascope/api/_generated/core/http_client.py +619 -0
- mirascope/api/_generated/core/http_response.py +55 -0
- mirascope/api/_generated/core/jsonable_encoder.py +102 -0
- mirascope/api/_generated/core/pydantic_utilities.py +310 -0
- mirascope/api/_generated/core/query_encoder.py +60 -0
- mirascope/api/_generated/core/remove_none_from_dict.py +11 -0
- mirascope/api/_generated/core/request_options.py +35 -0
- mirascope/api/_generated/core/serialization.py +282 -0
- mirascope/api/_generated/docs/__init__.py +4 -0
- mirascope/api/_generated/docs/client.py +95 -0
- mirascope/api/_generated/docs/raw_client.py +132 -0
- mirascope/api/_generated/environment.py +9 -0
- mirascope/api/_generated/errors/__init__.py +7 -0
- mirascope/api/_generated/errors/bad_request_error.py +15 -0
- mirascope/api/_generated/health/__init__.py +7 -0
- mirascope/api/_generated/health/client.py +96 -0
- mirascope/api/_generated/health/raw_client.py +129 -0
- mirascope/api/_generated/health/types/__init__.py +8 -0
- mirascope/api/_generated/health/types/health_check_response.py +24 -0
- mirascope/api/_generated/health/types/health_check_response_status.py +5 -0
- mirascope/api/_generated/reference.md +167 -0
- mirascope/api/_generated/traces/__init__.py +55 -0
- mirascope/api/_generated/traces/client.py +162 -0
- mirascope/api/_generated/traces/raw_client.py +168 -0
- mirascope/api/_generated/traces/types/__init__.py +95 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item.py +36 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource.py +31 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item.py +25 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value.py +54 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_array_value.py +23 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value.py +28 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value_values_item.py +24 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item.py +35 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope.py +35 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item.py +27 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value.py +54 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_array_value.py +23 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value.py +28 -0
- 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
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item.py +60 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item.py +29 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value.py +54 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_array_value.py +23 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value.py +28 -0
- 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
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_status.py +24 -0
- mirascope/api/_generated/traces/types/traces_create_response.py +27 -0
- mirascope/api/_generated/traces/types/traces_create_response_partial_success.py +28 -0
- mirascope/api/_generated/types/__init__.py +21 -0
- mirascope/api/_generated/types/http_api_decode_error.py +31 -0
- mirascope/api/_generated/types/http_api_decode_error_tag.py +5 -0
- mirascope/api/_generated/types/issue.py +44 -0
- mirascope/api/_generated/types/issue_tag.py +17 -0
- mirascope/api/_generated/types/property_key.py +7 -0
- mirascope/api/_generated/types/property_key_tag.py +29 -0
- mirascope/api/_generated/types/property_key_tag_tag.py +5 -0
- mirascope/api/client.py +255 -0
- mirascope/api/settings.py +81 -0
- mirascope/llm/__init__.py +41 -11
- mirascope/llm/calls/calls.py +81 -57
- mirascope/llm/calls/decorator.py +121 -115
- mirascope/llm/content/__init__.py +3 -2
- mirascope/llm/context/_utils.py +19 -6
- mirascope/llm/exceptions.py +30 -16
- mirascope/llm/formatting/_utils.py +9 -5
- mirascope/llm/formatting/format.py +2 -2
- mirascope/llm/formatting/from_call_args.py +2 -2
- mirascope/llm/messages/message.py +13 -5
- mirascope/llm/models/__init__.py +2 -2
- mirascope/llm/models/models.py +189 -81
- mirascope/llm/prompts/__init__.py +13 -12
- mirascope/llm/prompts/_utils.py +27 -24
- mirascope/llm/prompts/decorator.py +133 -204
- mirascope/llm/prompts/prompts.py +424 -0
- mirascope/llm/prompts/protocols.py +25 -59
- mirascope/llm/providers/__init__.py +38 -0
- mirascope/llm/{clients → providers}/_missing_import_stubs.py +8 -6
- mirascope/llm/providers/anthropic/__init__.py +24 -0
- mirascope/llm/{clients → providers}/anthropic/_utils/decode.py +5 -4
- mirascope/llm/{clients → providers}/anthropic/_utils/encode.py +31 -10
- mirascope/llm/providers/anthropic/model_id.py +40 -0
- mirascope/llm/{clients/anthropic/clients.py → providers/anthropic/provider.py} +33 -418
- mirascope/llm/{clients → providers}/base/__init__.py +3 -3
- mirascope/llm/{clients → providers}/base/_utils.py +10 -7
- mirascope/llm/{clients/base/client.py → providers/base/base_provider.py} +255 -126
- mirascope/llm/providers/google/__init__.py +21 -0
- mirascope/llm/{clients → providers}/google/_utils/decode.py +6 -4
- mirascope/llm/{clients → providers}/google/_utils/encode.py +30 -24
- mirascope/llm/providers/google/model_id.py +28 -0
- mirascope/llm/providers/google/provider.py +438 -0
- mirascope/llm/providers/load_provider.py +48 -0
- mirascope/llm/providers/mlx/__init__.py +24 -0
- mirascope/llm/providers/mlx/_utils.py +107 -0
- mirascope/llm/providers/mlx/encoding/__init__.py +8 -0
- mirascope/llm/providers/mlx/encoding/base.py +69 -0
- mirascope/llm/providers/mlx/encoding/transformers.py +131 -0
- mirascope/llm/providers/mlx/mlx.py +237 -0
- mirascope/llm/providers/mlx/model_id.py +17 -0
- mirascope/llm/providers/mlx/provider.py +411 -0
- mirascope/llm/providers/model_id.py +16 -0
- mirascope/llm/providers/openai/__init__.py +6 -0
- mirascope/llm/providers/openai/completions/__init__.py +20 -0
- mirascope/llm/{clients/openai/responses → providers/openai/completions}/_utils/__init__.py +2 -0
- mirascope/llm/{clients → providers}/openai/completions/_utils/decode.py +5 -3
- mirascope/llm/{clients → providers}/openai/completions/_utils/encode.py +33 -23
- mirascope/llm/providers/openai/completions/provider.py +456 -0
- mirascope/llm/providers/openai/model_id.py +31 -0
- mirascope/llm/providers/openai/model_info.py +246 -0
- mirascope/llm/providers/openai/provider.py +386 -0
- mirascope/llm/providers/openai/responses/__init__.py +21 -0
- mirascope/llm/{clients → providers}/openai/responses/_utils/decode.py +5 -3
- mirascope/llm/{clients → providers}/openai/responses/_utils/encode.py +28 -17
- mirascope/llm/providers/openai/responses/provider.py +470 -0
- mirascope/llm/{clients → providers}/openai/shared/_utils.py +7 -3
- mirascope/llm/providers/provider_id.py +13 -0
- mirascope/llm/providers/provider_registry.py +167 -0
- mirascope/llm/responses/base_response.py +10 -5
- mirascope/llm/responses/base_stream_response.py +10 -5
- mirascope/llm/responses/response.py +24 -13
- mirascope/llm/responses/root_response.py +7 -12
- mirascope/llm/responses/stream_response.py +35 -23
- mirascope/llm/tools/__init__.py +9 -2
- mirascope/llm/tools/_utils.py +12 -3
- mirascope/llm/tools/protocols.py +4 -4
- mirascope/llm/tools/tool_schema.py +44 -9
- mirascope/llm/tools/tools.py +10 -9
- mirascope/ops/__init__.py +156 -0
- mirascope/ops/_internal/__init__.py +5 -0
- mirascope/ops/_internal/closure.py +1118 -0
- mirascope/ops/_internal/configuration.py +126 -0
- mirascope/ops/_internal/context.py +76 -0
- mirascope/ops/_internal/exporters/__init__.py +26 -0
- mirascope/ops/_internal/exporters/exporters.py +342 -0
- mirascope/ops/_internal/exporters/processors.py +104 -0
- mirascope/ops/_internal/exporters/types.py +165 -0
- mirascope/ops/_internal/exporters/utils.py +29 -0
- mirascope/ops/_internal/instrumentation/__init__.py +8 -0
- mirascope/ops/_internal/instrumentation/llm/__init__.py +8 -0
- mirascope/ops/_internal/instrumentation/llm/encode.py +238 -0
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/__init__.py +38 -0
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_input_messages.py +31 -0
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_output_messages.py +38 -0
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_system_instructions.py +18 -0
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/shared.py +100 -0
- mirascope/ops/_internal/instrumentation/llm/llm.py +1288 -0
- mirascope/ops/_internal/propagation.py +198 -0
- mirascope/ops/_internal/protocols.py +51 -0
- mirascope/ops/_internal/session.py +139 -0
- mirascope/ops/_internal/spans.py +232 -0
- mirascope/ops/_internal/traced_calls.py +371 -0
- mirascope/ops/_internal/traced_functions.py +394 -0
- mirascope/ops/_internal/tracing.py +276 -0
- mirascope/ops/_internal/types.py +13 -0
- mirascope/ops/_internal/utils.py +75 -0
- mirascope/ops/_internal/versioned_calls.py +512 -0
- mirascope/ops/_internal/versioned_functions.py +346 -0
- mirascope/ops/_internal/versioning.py +303 -0
- mirascope/ops/exceptions.py +21 -0
- {mirascope-2.0.0a2.dist-info → mirascope-2.0.0a3.dist-info}/METADATA +76 -1
- mirascope-2.0.0a3.dist-info/RECORD +206 -0
- {mirascope-2.0.0a2.dist-info → mirascope-2.0.0a3.dist-info}/WHEEL +1 -1
- mirascope/graphs/__init__.py +0 -22
- mirascope/graphs/finite_state_machine.py +0 -625
- mirascope/llm/agents/__init__.py +0 -15
- mirascope/llm/agents/agent.py +0 -97
- mirascope/llm/agents/agent_template.py +0 -45
- mirascope/llm/agents/decorator.py +0 -176
- mirascope/llm/calls/base_call.py +0 -33
- mirascope/llm/clients/__init__.py +0 -34
- mirascope/llm/clients/anthropic/__init__.py +0 -25
- mirascope/llm/clients/anthropic/model_ids.py +0 -8
- mirascope/llm/clients/google/__init__.py +0 -20
- mirascope/llm/clients/google/clients.py +0 -853
- mirascope/llm/clients/google/model_ids.py +0 -15
- mirascope/llm/clients/openai/__init__.py +0 -25
- mirascope/llm/clients/openai/completions/__init__.py +0 -28
- mirascope/llm/clients/openai/completions/_utils/model_features.py +0 -81
- mirascope/llm/clients/openai/completions/clients.py +0 -833
- mirascope/llm/clients/openai/completions/model_ids.py +0 -8
- mirascope/llm/clients/openai/responses/__init__.py +0 -26
- mirascope/llm/clients/openai/responses/_utils/model_features.py +0 -87
- mirascope/llm/clients/openai/responses/clients.py +0 -832
- mirascope/llm/clients/openai/responses/model_ids.py +0 -8
- mirascope/llm/clients/providers.py +0 -175
- mirascope-2.0.0a2.dist-info/RECORD +0 -102
- /mirascope/llm/{clients → providers}/anthropic/_utils/__init__.py +0 -0
- /mirascope/llm/{clients → providers}/base/kwargs.py +0 -0
- /mirascope/llm/{clients → providers}/base/params.py +0 -0
- /mirascope/llm/{clients → providers}/google/_utils/__init__.py +0 -0
- /mirascope/llm/{clients → providers}/google/message.py +0 -0
- /mirascope/llm/{clients/openai/completions → providers/openai/responses}/_utils/__init__.py +0 -0
- /mirascope/llm/{clients → providers}/openai/shared/__init__.py +0 -0
- {mirascope-2.0.0a2.dist-info → mirascope-2.0.0a3.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)
|