mirascope 2.1.0__py3-none-any.whl → 2.2.0__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/api/_generated/functions/client.py +10 -0
- mirascope/api/_generated/functions/raw_client.py +8 -0
- mirascope/api/_generated/functions/types/functions_create_response.py +25 -8
- mirascope/api/_generated/functions/types/functions_find_by_hash_response.py +25 -10
- mirascope/api/_generated/functions/types/functions_get_by_env_response.py +1 -0
- mirascope/api/_generated/functions/types/functions_get_response.py +25 -8
- mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item.py +1 -0
- mirascope/api/_generated/functions/types/functions_list_response_functions_item.py +22 -7
- mirascope/api/_generated/reference.md +9 -0
- mirascope/llm/__init__.py +42 -0
- mirascope/llm/calls/calls.py +38 -11
- mirascope/llm/exceptions.py +69 -0
- mirascope/llm/prompts/prompts.py +47 -9
- mirascope/llm/providers/__init__.py +3 -0
- mirascope/llm/providers/openai/completions/_utils/__init__.py +3 -0
- mirascope/llm/providers/openai/completions/_utils/encode.py +27 -32
- mirascope/llm/providers/openai/completions/_utils/feature_info.py +50 -0
- mirascope/llm/providers/openai/completions/base_provider.py +21 -0
- mirascope/llm/providers/openai/completions/provider.py +8 -2
- mirascope/llm/providers/openrouter/__init__.py +5 -0
- mirascope/llm/providers/openrouter/provider.py +67 -0
- mirascope/llm/providers/provider_id.py +2 -0
- mirascope/llm/providers/provider_registry.py +6 -0
- mirascope/llm/responses/response.py +217 -0
- mirascope/llm/responses/stream_response.py +234 -0
- mirascope/llm/retries/__init__.py +51 -0
- mirascope/llm/retries/retry_calls.py +159 -0
- mirascope/llm/retries/retry_config.py +168 -0
- mirascope/llm/retries/retry_decorator.py +258 -0
- mirascope/llm/retries/retry_models.py +1313 -0
- mirascope/llm/retries/retry_prompts.py +227 -0
- mirascope/llm/retries/retry_responses.py +340 -0
- mirascope/llm/retries/retry_stream_responses.py +571 -0
- mirascope/llm/retries/utils.py +159 -0
- mirascope/ops/_internal/versioned_calls.py +249 -9
- mirascope/ops/_internal/versioned_functions.py +2 -0
- {mirascope-2.1.0.dist-info → mirascope-2.2.0.dist-info}/METADATA +1 -1
- {mirascope-2.1.0.dist-info → mirascope-2.2.0.dist-info}/RECORD +40 -28
- {mirascope-2.1.0.dist-info → mirascope-2.2.0.dist-info}/WHEEL +0 -0
- {mirascope-2.1.0.dist-info → mirascope-2.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"""Utility functions for retry logic."""
|
|
2
|
+
|
|
3
|
+
import random
|
|
4
|
+
from collections.abc import Awaitable, Callable
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import TYPE_CHECKING, TypeVar
|
|
7
|
+
|
|
8
|
+
from ..exceptions import RetriesExhausted
|
|
9
|
+
from .retry_config import RetryConfig
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from ..models import Model
|
|
13
|
+
from .retry_models import RetryModel
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_retry_model_from_context(stored_retry_model: "RetryModel") -> "RetryModel":
|
|
17
|
+
"""Get the RetryModel to use, checking context for overrides.
|
|
18
|
+
|
|
19
|
+
If a model is set in context (via `llm.model()` or `llm.retry_model()`),
|
|
20
|
+
that model is used instead, wrapped with this response's retry config.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
stored_retry_model: The RetryModel stored on the response.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
Either the context model (wrapped in RetryModel if needed) or the stored model.
|
|
27
|
+
"""
|
|
28
|
+
from ..models import model_from_context
|
|
29
|
+
from .retry_models import RetryModel
|
|
30
|
+
|
|
31
|
+
context_model = model_from_context()
|
|
32
|
+
if context_model is not None:
|
|
33
|
+
if isinstance(context_model, RetryModel):
|
|
34
|
+
return context_model
|
|
35
|
+
return RetryModel(context_model, stored_retry_model.retry_config)
|
|
36
|
+
return stored_retry_model
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
_ResultT = TypeVar("_ResultT")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass
|
|
43
|
+
class RetryFailure:
|
|
44
|
+
"""A failed attempt to call a model.
|
|
45
|
+
|
|
46
|
+
Attributes:
|
|
47
|
+
model: The model that was tried.
|
|
48
|
+
exception: The exception that was raised.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
model: "Model"
|
|
52
|
+
exception: BaseException
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def calculate_delay(config: RetryConfig, attempt_for_model: int) -> float:
|
|
56
|
+
"""Calculate the delay before the next retry attempt.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
config: The retry configuration with backoff settings.
|
|
60
|
+
attempt_for_model: The retry attempt number for this model (1-indexed).
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
The delay in seconds, with exponential backoff, capped at max_delay,
|
|
64
|
+
and optionally with jitter applied.
|
|
65
|
+
"""
|
|
66
|
+
# Calculate base delay with exponential backoff
|
|
67
|
+
delay = config.initial_delay * (
|
|
68
|
+
config.backoff_multiplier ** (attempt_for_model - 1)
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# Cap at max_delay
|
|
72
|
+
delay = min(delay, config.max_delay)
|
|
73
|
+
|
|
74
|
+
# Apply jitter if configured
|
|
75
|
+
if config.jitter > 0:
|
|
76
|
+
jitter_range = delay * config.jitter
|
|
77
|
+
delay = delay + random.uniform(-jitter_range, jitter_range)
|
|
78
|
+
# Ensure delay doesn't go negative
|
|
79
|
+
delay = max(0, delay)
|
|
80
|
+
|
|
81
|
+
return delay
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def with_retry(
|
|
85
|
+
fn: Callable[["Model"], _ResultT],
|
|
86
|
+
retry_model: "RetryModel",
|
|
87
|
+
) -> tuple[_ResultT, list[RetryFailure], "RetryModel"]:
|
|
88
|
+
"""Execute a function with retry logic across the RetryModel's models.
|
|
89
|
+
|
|
90
|
+
Tries the active model first, then fallbacks. Each model gets its own
|
|
91
|
+
full retry budget. Returns an updated RetryModel with the successful
|
|
92
|
+
model set as active.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
fn: Function that takes a Model and returns a result.
|
|
96
|
+
retry_model: The RetryModel containing models and retry config.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
A tuple of (result, failures, updated_retry_model).
|
|
100
|
+
failures contains all failed attempts before success.
|
|
101
|
+
The updated_retry_model has the successful model as active.
|
|
102
|
+
|
|
103
|
+
Raises:
|
|
104
|
+
Exception: The last exception encountered if all models exhaust retries.
|
|
105
|
+
"""
|
|
106
|
+
config = retry_model.retry_config
|
|
107
|
+
failures: list[RetryFailure] = []
|
|
108
|
+
|
|
109
|
+
for variant in retry_model.variants():
|
|
110
|
+
model = variant.get_active_model()
|
|
111
|
+
try:
|
|
112
|
+
result = fn(model)
|
|
113
|
+
return result, failures, variant
|
|
114
|
+
except config.retry_on as e:
|
|
115
|
+
failures.append(RetryFailure(model=model, exception=e))
|
|
116
|
+
|
|
117
|
+
# All models exhausted
|
|
118
|
+
if failures:
|
|
119
|
+
raise RetriesExhausted(failures)
|
|
120
|
+
raise AssertionError("Unreachable: no models provided") # pragma: no cover
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
async def with_retry_async(
|
|
124
|
+
fn: Callable[["Model"], Awaitable[_ResultT]],
|
|
125
|
+
retry_model: "RetryModel",
|
|
126
|
+
) -> tuple[_ResultT, list[RetryFailure], "RetryModel"]:
|
|
127
|
+
"""Execute an async function with retry logic across the RetryModel's models.
|
|
128
|
+
|
|
129
|
+
Tries the active model first, then fallbacks. Each model gets its own
|
|
130
|
+
full retry budget. Returns an updated RetryModel with the successful
|
|
131
|
+
model set as active.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
fn: Async function that takes a Model and returns a result.
|
|
135
|
+
retry_model: The RetryModel containing models and retry config.
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
A tuple of (result, failures, updated_retry_model).
|
|
139
|
+
failures contains all failed attempts before success.
|
|
140
|
+
The updated_retry_model has the successful model as active.
|
|
141
|
+
|
|
142
|
+
Raises:
|
|
143
|
+
Exception: The last exception encountered if all models exhaust retries.
|
|
144
|
+
"""
|
|
145
|
+
config = retry_model.retry_config
|
|
146
|
+
failures: list[RetryFailure] = []
|
|
147
|
+
|
|
148
|
+
async for variant in retry_model.variants_async():
|
|
149
|
+
model = variant.get_active_model()
|
|
150
|
+
try:
|
|
151
|
+
result = await fn(model)
|
|
152
|
+
return result, failures, variant
|
|
153
|
+
except config.retry_on as e:
|
|
154
|
+
failures.append(RetryFailure(model=model, exception=e))
|
|
155
|
+
|
|
156
|
+
# All models exhausted
|
|
157
|
+
if failures:
|
|
158
|
+
raise RetriesExhausted(failures)
|
|
159
|
+
raise AssertionError("Unreachable: no models provided") # pragma: no cover
|
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import logging
|
|
6
6
|
from dataclasses import dataclass, field
|
|
7
|
-
from typing import Concatenate, Generic
|
|
7
|
+
from typing import Concatenate, Generic, cast, overload
|
|
8
8
|
from typing_extensions import TypeIs
|
|
9
9
|
|
|
10
10
|
from ...llm.calls import AsyncCall, AsyncContextCall, Call, ContextCall
|
|
@@ -238,23 +238,61 @@ class VersionedCall(_BaseVersionedCall, Generic[P, FormattableT]):
|
|
|
238
238
|
)
|
|
239
239
|
self._compute_closure(self._call, self.call, self.stream)
|
|
240
240
|
|
|
241
|
+
@overload
|
|
242
|
+
def __call__(
|
|
243
|
+
self: VersionedCall[P, None], *args: P.args, **kwargs: P.kwargs
|
|
244
|
+
) -> Response: ...
|
|
245
|
+
|
|
246
|
+
@overload
|
|
247
|
+
def __call__(
|
|
248
|
+
self: VersionedCall[P, FormattableT], *args: P.args, **kwargs: P.kwargs
|
|
249
|
+
) -> Response[FormattableT]: ...
|
|
250
|
+
|
|
241
251
|
def __call__(
|
|
242
252
|
self, *args: P.args, **kwargs: P.kwargs
|
|
243
253
|
) -> Response | Response[FormattableT]:
|
|
244
254
|
"""Call the versioned function and return Response directly."""
|
|
245
255
|
return self.call(*args, **kwargs)
|
|
246
256
|
|
|
257
|
+
@overload
|
|
258
|
+
def wrapped(
|
|
259
|
+
self: VersionedCall[P, None], *args: P.args, **kwargs: P.kwargs
|
|
260
|
+
) -> VersionedResult[Response]: ...
|
|
261
|
+
|
|
262
|
+
@overload
|
|
263
|
+
def wrapped(
|
|
264
|
+
self: VersionedCall[P, FormattableT], *args: P.args, **kwargs: P.kwargs
|
|
265
|
+
) -> VersionedResult[Response[FormattableT]]: ...
|
|
266
|
+
|
|
247
267
|
def wrapped(
|
|
248
268
|
self, *args: P.args, **kwargs: P.kwargs
|
|
249
|
-
) -> VersionedResult[Response | Response[FormattableT]]:
|
|
269
|
+
) -> VersionedResult[Response] | VersionedResult[Response[FormattableT]]:
|
|
250
270
|
"""Call the versioned function and return a wrapped Response."""
|
|
251
|
-
return
|
|
271
|
+
return cast(
|
|
272
|
+
"VersionedResult[Response] | VersionedResult[Response[FormattableT]]",
|
|
273
|
+
self.call.wrapped(*args, **kwargs),
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
@overload
|
|
277
|
+
def wrapped_stream(
|
|
278
|
+
self: VersionedCall[P, None], *args: P.args, **kwargs: P.kwargs
|
|
279
|
+
) -> VersionedResult[StreamResponse]: ...
|
|
280
|
+
|
|
281
|
+
@overload
|
|
282
|
+
def wrapped_stream(
|
|
283
|
+
self: VersionedCall[P, FormattableT], *args: P.args, **kwargs: P.kwargs
|
|
284
|
+
) -> VersionedResult[StreamResponse[FormattableT]]: ...
|
|
252
285
|
|
|
253
286
|
def wrapped_stream(
|
|
254
287
|
self, *args: P.args, **kwargs: P.kwargs
|
|
255
|
-
) ->
|
|
288
|
+
) -> (
|
|
289
|
+
VersionedResult[StreamResponse] | VersionedResult[StreamResponse[FormattableT]]
|
|
290
|
+
):
|
|
256
291
|
"""Stream the versioned function and return a wrapped StreamResponse."""
|
|
257
|
-
return
|
|
292
|
+
return cast(
|
|
293
|
+
"VersionedResult[StreamResponse] | VersionedResult[StreamResponse[FormattableT]]",
|
|
294
|
+
self.stream.wrapped(*args, **kwargs),
|
|
295
|
+
)
|
|
258
296
|
|
|
259
297
|
|
|
260
298
|
@dataclass(kw_only=True)
|
|
@@ -308,23 +346,65 @@ class VersionedAsyncCall(_BaseVersionedCall, Generic[P, FormattableT]):
|
|
|
308
346
|
)
|
|
309
347
|
self._compute_closure(self._call, self.call, self.stream)
|
|
310
348
|
|
|
349
|
+
@overload
|
|
350
|
+
async def __call__(
|
|
351
|
+
self: VersionedAsyncCall[P, None], *args: P.args, **kwargs: P.kwargs
|
|
352
|
+
) -> AsyncResponse: ...
|
|
353
|
+
|
|
354
|
+
@overload
|
|
355
|
+
async def __call__(
|
|
356
|
+
self: VersionedAsyncCall[P, FormattableT], *args: P.args, **kwargs: P.kwargs
|
|
357
|
+
) -> AsyncResponse[FormattableT]: ...
|
|
358
|
+
|
|
311
359
|
async def __call__(
|
|
312
360
|
self, *args: P.args, **kwargs: P.kwargs
|
|
313
361
|
) -> AsyncResponse | AsyncResponse[FormattableT]:
|
|
314
362
|
"""Call the versioned function and return AsyncResponse directly."""
|
|
315
363
|
return await self.call(*args, **kwargs)
|
|
316
364
|
|
|
365
|
+
@overload
|
|
366
|
+
async def wrapped(
|
|
367
|
+
self: VersionedAsyncCall[P, None], *args: P.args, **kwargs: P.kwargs
|
|
368
|
+
) -> AsyncVersionedResult[AsyncResponse]: ...
|
|
369
|
+
|
|
370
|
+
@overload
|
|
371
|
+
async def wrapped(
|
|
372
|
+
self: VersionedAsyncCall[P, FormattableT], *args: P.args, **kwargs: P.kwargs
|
|
373
|
+
) -> AsyncVersionedResult[AsyncResponse[FormattableT]]: ...
|
|
374
|
+
|
|
317
375
|
async def wrapped(
|
|
318
376
|
self, *args: P.args, **kwargs: P.kwargs
|
|
319
|
-
) ->
|
|
377
|
+
) -> (
|
|
378
|
+
AsyncVersionedResult[AsyncResponse]
|
|
379
|
+
| AsyncVersionedResult[AsyncResponse[FormattableT]]
|
|
380
|
+
):
|
|
320
381
|
"""Call the versioned function and return a wrapped Response."""
|
|
321
|
-
return
|
|
382
|
+
return cast(
|
|
383
|
+
"AsyncVersionedResult[AsyncResponse] | AsyncVersionedResult[AsyncResponse[FormattableT]]",
|
|
384
|
+
await self.call.wrapped(*args, **kwargs),
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
@overload
|
|
388
|
+
async def wrapped_stream(
|
|
389
|
+
self: VersionedAsyncCall[P, None], *args: P.args, **kwargs: P.kwargs
|
|
390
|
+
) -> AsyncVersionedResult[AsyncStreamResponse]: ...
|
|
391
|
+
|
|
392
|
+
@overload
|
|
393
|
+
async def wrapped_stream(
|
|
394
|
+
self: VersionedAsyncCall[P, FormattableT], *args: P.args, **kwargs: P.kwargs
|
|
395
|
+
) -> AsyncVersionedResult[AsyncStreamResponse[FormattableT]]: ...
|
|
322
396
|
|
|
323
397
|
async def wrapped_stream(
|
|
324
398
|
self, *args: P.args, **kwargs: P.kwargs
|
|
325
|
-
) ->
|
|
399
|
+
) -> (
|
|
400
|
+
AsyncVersionedResult[AsyncStreamResponse]
|
|
401
|
+
| AsyncVersionedResult[AsyncStreamResponse[FormattableT]]
|
|
402
|
+
):
|
|
326
403
|
"""Stream the versioned function and return a wrapped StreamResponse."""
|
|
327
|
-
return
|
|
404
|
+
return cast(
|
|
405
|
+
"AsyncVersionedResult[AsyncStreamResponse] | AsyncVersionedResult[AsyncStreamResponse[FormattableT]]",
|
|
406
|
+
await self.stream.wrapped(*args, **kwargs),
|
|
407
|
+
)
|
|
328
408
|
|
|
329
409
|
|
|
330
410
|
@dataclass(kw_only=True)
|
|
@@ -381,18 +461,66 @@ class VersionedContextCall(_BaseVersionedCall, Generic[P, DepsT, FormattableT]):
|
|
|
381
461
|
)
|
|
382
462
|
self._compute_closure(self._call, self._call_versioned, self._stream_versioned)
|
|
383
463
|
|
|
464
|
+
@overload
|
|
465
|
+
def call(
|
|
466
|
+
self: VersionedContextCall[P, DepsT, None],
|
|
467
|
+
ctx: Context[DepsT],
|
|
468
|
+
*args: P.args,
|
|
469
|
+
**kwargs: P.kwargs,
|
|
470
|
+
) -> ContextResponse[DepsT, None]: ...
|
|
471
|
+
|
|
472
|
+
@overload
|
|
473
|
+
def call(
|
|
474
|
+
self: VersionedContextCall[P, DepsT, FormattableT],
|
|
475
|
+
ctx: Context[DepsT],
|
|
476
|
+
*args: P.args,
|
|
477
|
+
**kwargs: P.kwargs,
|
|
478
|
+
) -> ContextResponse[DepsT, FormattableT]: ...
|
|
479
|
+
|
|
384
480
|
def call(
|
|
385
481
|
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
386
482
|
) -> ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]:
|
|
387
483
|
"""Call the versioned function and return ContextResponse directly."""
|
|
388
484
|
return self._call_versioned(ctx, *args, **kwargs)
|
|
389
485
|
|
|
486
|
+
@overload
|
|
487
|
+
def __call__(
|
|
488
|
+
self: VersionedContextCall[P, DepsT, None],
|
|
489
|
+
ctx: Context[DepsT],
|
|
490
|
+
*args: P.args,
|
|
491
|
+
**kwargs: P.kwargs,
|
|
492
|
+
) -> ContextResponse[DepsT, None]: ...
|
|
493
|
+
|
|
494
|
+
@overload
|
|
495
|
+
def __call__(
|
|
496
|
+
self: VersionedContextCall[P, DepsT, FormattableT],
|
|
497
|
+
ctx: Context[DepsT],
|
|
498
|
+
*args: P.args,
|
|
499
|
+
**kwargs: P.kwargs,
|
|
500
|
+
) -> ContextResponse[DepsT, FormattableT]: ...
|
|
501
|
+
|
|
390
502
|
def __call__(
|
|
391
503
|
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
392
504
|
) -> ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]:
|
|
393
505
|
"""Call the versioned function and return ContextResponse directly."""
|
|
394
506
|
return self.call(ctx, *args, **kwargs)
|
|
395
507
|
|
|
508
|
+
@overload
|
|
509
|
+
def stream(
|
|
510
|
+
self: VersionedContextCall[P, DepsT, None],
|
|
511
|
+
ctx: Context[DepsT],
|
|
512
|
+
*args: P.args,
|
|
513
|
+
**kwargs: P.kwargs,
|
|
514
|
+
) -> ContextStreamResponse[DepsT, None]: ...
|
|
515
|
+
|
|
516
|
+
@overload
|
|
517
|
+
def stream(
|
|
518
|
+
self: VersionedContextCall[P, DepsT, FormattableT],
|
|
519
|
+
ctx: Context[DepsT],
|
|
520
|
+
*args: P.args,
|
|
521
|
+
**kwargs: P.kwargs,
|
|
522
|
+
) -> ContextStreamResponse[DepsT, FormattableT]: ...
|
|
523
|
+
|
|
396
524
|
def stream(
|
|
397
525
|
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
398
526
|
) -> (
|
|
@@ -401,6 +529,22 @@ class VersionedContextCall(_BaseVersionedCall, Generic[P, DepsT, FormattableT]):
|
|
|
401
529
|
"""Stream the versioned function and return a ContextStreamResponse."""
|
|
402
530
|
return self._stream_versioned(ctx, *args, **kwargs)
|
|
403
531
|
|
|
532
|
+
@overload
|
|
533
|
+
def wrapped(
|
|
534
|
+
self: VersionedContextCall[P, DepsT, None],
|
|
535
|
+
ctx: Context[DepsT],
|
|
536
|
+
*args: P.args,
|
|
537
|
+
**kwargs: P.kwargs,
|
|
538
|
+
) -> VersionedResult[ContextResponse[DepsT, None]]: ...
|
|
539
|
+
|
|
540
|
+
@overload
|
|
541
|
+
def wrapped(
|
|
542
|
+
self: VersionedContextCall[P, DepsT, FormattableT],
|
|
543
|
+
ctx: Context[DepsT],
|
|
544
|
+
*args: P.args,
|
|
545
|
+
**kwargs: P.kwargs,
|
|
546
|
+
) -> VersionedResult[ContextResponse[DepsT, FormattableT]]: ...
|
|
547
|
+
|
|
404
548
|
def wrapped(
|
|
405
549
|
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
406
550
|
) -> VersionedResult[
|
|
@@ -409,6 +553,22 @@ class VersionedContextCall(_BaseVersionedCall, Generic[P, DepsT, FormattableT]):
|
|
|
409
553
|
"""Call the versioned function and return a wrapped Response."""
|
|
410
554
|
return self._call_versioned.wrapped(ctx, *args, **kwargs)
|
|
411
555
|
|
|
556
|
+
@overload
|
|
557
|
+
def wrapped_stream(
|
|
558
|
+
self: VersionedContextCall[P, DepsT, None],
|
|
559
|
+
ctx: Context[DepsT],
|
|
560
|
+
*args: P.args,
|
|
561
|
+
**kwargs: P.kwargs,
|
|
562
|
+
) -> VersionedResult[ContextStreamResponse[DepsT, None]]: ...
|
|
563
|
+
|
|
564
|
+
@overload
|
|
565
|
+
def wrapped_stream(
|
|
566
|
+
self: VersionedContextCall[P, DepsT, FormattableT],
|
|
567
|
+
ctx: Context[DepsT],
|
|
568
|
+
*args: P.args,
|
|
569
|
+
**kwargs: P.kwargs,
|
|
570
|
+
) -> VersionedResult[ContextStreamResponse[DepsT, FormattableT]]: ...
|
|
571
|
+
|
|
412
572
|
def wrapped_stream(
|
|
413
573
|
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
414
574
|
) -> VersionedResult[
|
|
@@ -473,18 +633,66 @@ class VersionedAsyncContextCall(_BaseVersionedCall, Generic[P, DepsT, Formattabl
|
|
|
473
633
|
)
|
|
474
634
|
self._compute_closure(self._call, self._call_versioned, self._stream_versioned)
|
|
475
635
|
|
|
636
|
+
@overload
|
|
637
|
+
async def call(
|
|
638
|
+
self: VersionedAsyncContextCall[P, DepsT, None],
|
|
639
|
+
ctx: Context[DepsT],
|
|
640
|
+
*args: P.args,
|
|
641
|
+
**kwargs: P.kwargs,
|
|
642
|
+
) -> AsyncContextResponse[DepsT, None]: ...
|
|
643
|
+
|
|
644
|
+
@overload
|
|
645
|
+
async def call(
|
|
646
|
+
self: VersionedAsyncContextCall[P, DepsT, FormattableT],
|
|
647
|
+
ctx: Context[DepsT],
|
|
648
|
+
*args: P.args,
|
|
649
|
+
**kwargs: P.kwargs,
|
|
650
|
+
) -> AsyncContextResponse[DepsT, FormattableT]: ...
|
|
651
|
+
|
|
476
652
|
async def call(
|
|
477
653
|
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
478
654
|
) -> AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT]:
|
|
479
655
|
"""Call the versioned function and return AsyncContextResponse directly."""
|
|
480
656
|
return await self._call_versioned(ctx, *args, **kwargs)
|
|
481
657
|
|
|
658
|
+
@overload
|
|
659
|
+
async def __call__(
|
|
660
|
+
self: VersionedAsyncContextCall[P, DepsT, None],
|
|
661
|
+
ctx: Context[DepsT],
|
|
662
|
+
*args: P.args,
|
|
663
|
+
**kwargs: P.kwargs,
|
|
664
|
+
) -> AsyncContextResponse[DepsT, None]: ...
|
|
665
|
+
|
|
666
|
+
@overload
|
|
667
|
+
async def __call__(
|
|
668
|
+
self: VersionedAsyncContextCall[P, DepsT, FormattableT],
|
|
669
|
+
ctx: Context[DepsT],
|
|
670
|
+
*args: P.args,
|
|
671
|
+
**kwargs: P.kwargs,
|
|
672
|
+
) -> AsyncContextResponse[DepsT, FormattableT]: ...
|
|
673
|
+
|
|
482
674
|
async def __call__(
|
|
483
675
|
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
484
676
|
) -> AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT]:
|
|
485
677
|
"""Call the versioned function and return AsyncContextResponse directly."""
|
|
486
678
|
return await self.call(ctx, *args, **kwargs)
|
|
487
679
|
|
|
680
|
+
@overload
|
|
681
|
+
async def stream(
|
|
682
|
+
self: VersionedAsyncContextCall[P, DepsT, None],
|
|
683
|
+
ctx: Context[DepsT],
|
|
684
|
+
*args: P.args,
|
|
685
|
+
**kwargs: P.kwargs,
|
|
686
|
+
) -> AsyncContextStreamResponse[DepsT, None]: ...
|
|
687
|
+
|
|
688
|
+
@overload
|
|
689
|
+
async def stream(
|
|
690
|
+
self: VersionedAsyncContextCall[P, DepsT, FormattableT],
|
|
691
|
+
ctx: Context[DepsT],
|
|
692
|
+
*args: P.args,
|
|
693
|
+
**kwargs: P.kwargs,
|
|
694
|
+
) -> AsyncContextStreamResponse[DepsT, FormattableT]: ...
|
|
695
|
+
|
|
488
696
|
async def stream(
|
|
489
697
|
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
490
698
|
) -> (
|
|
@@ -494,6 +702,22 @@ class VersionedAsyncContextCall(_BaseVersionedCall, Generic[P, DepsT, Formattabl
|
|
|
494
702
|
"""Stream the versioned function and return an AsyncContextStreamResponse."""
|
|
495
703
|
return await self._stream_versioned(ctx, *args, **kwargs)
|
|
496
704
|
|
|
705
|
+
@overload
|
|
706
|
+
async def wrapped(
|
|
707
|
+
self: VersionedAsyncContextCall[P, DepsT, None],
|
|
708
|
+
ctx: Context[DepsT],
|
|
709
|
+
*args: P.args,
|
|
710
|
+
**kwargs: P.kwargs,
|
|
711
|
+
) -> AsyncVersionedResult[AsyncContextResponse[DepsT, None]]: ...
|
|
712
|
+
|
|
713
|
+
@overload
|
|
714
|
+
async def wrapped(
|
|
715
|
+
self: VersionedAsyncContextCall[P, DepsT, FormattableT],
|
|
716
|
+
ctx: Context[DepsT],
|
|
717
|
+
*args: P.args,
|
|
718
|
+
**kwargs: P.kwargs,
|
|
719
|
+
) -> AsyncVersionedResult[AsyncContextResponse[DepsT, FormattableT]]: ...
|
|
720
|
+
|
|
497
721
|
async def wrapped(
|
|
498
722
|
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
499
723
|
) -> AsyncVersionedResult[
|
|
@@ -502,6 +726,22 @@ class VersionedAsyncContextCall(_BaseVersionedCall, Generic[P, DepsT, Formattabl
|
|
|
502
726
|
"""Call the versioned function and return a wrapped Response."""
|
|
503
727
|
return await self._call_versioned.wrapped(ctx, *args, **kwargs)
|
|
504
728
|
|
|
729
|
+
@overload
|
|
730
|
+
async def wrapped_stream(
|
|
731
|
+
self: VersionedAsyncContextCall[P, DepsT, None],
|
|
732
|
+
ctx: Context[DepsT],
|
|
733
|
+
*args: P.args,
|
|
734
|
+
**kwargs: P.kwargs,
|
|
735
|
+
) -> AsyncVersionedResult[AsyncContextStreamResponse[DepsT, None]]: ...
|
|
736
|
+
|
|
737
|
+
@overload
|
|
738
|
+
async def wrapped_stream(
|
|
739
|
+
self: VersionedAsyncContextCall[P, DepsT, FormattableT],
|
|
740
|
+
ctx: Context[DepsT],
|
|
741
|
+
*args: P.args,
|
|
742
|
+
**kwargs: P.kwargs,
|
|
743
|
+
) -> AsyncVersionedResult[AsyncContextStreamResponse[DepsT, FormattableT]]: ...
|
|
744
|
+
|
|
505
745
|
async def wrapped_stream(
|
|
506
746
|
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
507
747
|
) -> AsyncVersionedResult[
|
|
@@ -270,6 +270,7 @@ class VersionedFunction(_BaseVersionedFunction[P, R], BaseSyncTracedFunction[P,
|
|
|
270
270
|
signature=self.closure.signature,
|
|
271
271
|
signature_hash=self.closure.signature_hash,
|
|
272
272
|
name=self.name or self.closure.name,
|
|
273
|
+
language="python",
|
|
273
274
|
description=self.closure.docstring,
|
|
274
275
|
tags=list(self.tags) if self.tags else None,
|
|
275
276
|
metadata=cast(dict[str, str | None], self.metadata)
|
|
@@ -344,6 +345,7 @@ class AsyncVersionedFunction(
|
|
|
344
345
|
signature=self.closure.signature,
|
|
345
346
|
signature_hash=self.closure.signature_hash,
|
|
346
347
|
name=self.name or self.closure.name,
|
|
348
|
+
language="python",
|
|
347
349
|
description=self.closure.docstring,
|
|
348
350
|
tags=list(self.tags) if self.tags else None,
|
|
349
351
|
metadata=cast(dict[str, str | None], self.metadata)
|