mirascope 2.0.0a6__py3-none-any.whl → 2.0.1__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/__init__.py +186 -5
- mirascope/api/_generated/annotations/client.py +38 -6
- mirascope/api/_generated/annotations/raw_client.py +366 -47
- mirascope/api/_generated/annotations/types/annotations_create_response.py +19 -6
- mirascope/api/_generated/annotations/types/annotations_get_response.py +19 -6
- mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item.py +22 -7
- mirascope/api/_generated/annotations/types/annotations_update_response.py +19 -6
- mirascope/api/_generated/api_keys/__init__.py +12 -2
- mirascope/api/_generated/api_keys/client.py +107 -6
- mirascope/api/_generated/api_keys/raw_client.py +486 -38
- mirascope/api/_generated/api_keys/types/__init__.py +7 -1
- mirascope/api/_generated/api_keys/types/api_keys_list_all_for_org_response_item.py +40 -0
- mirascope/api/_generated/client.py +36 -0
- mirascope/api/_generated/docs/raw_client.py +71 -9
- mirascope/api/_generated/environment.py +3 -3
- mirascope/api/_generated/environments/__init__.py +6 -0
- mirascope/api/_generated/environments/client.py +158 -9
- mirascope/api/_generated/environments/raw_client.py +620 -52
- mirascope/api/_generated/environments/types/__init__.py +10 -0
- mirascope/api/_generated/environments/types/environments_get_analytics_response.py +60 -0
- mirascope/api/_generated/environments/types/environments_get_analytics_response_top_functions_item.py +24 -0
- mirascope/api/_generated/{organizations/types/organizations_credits_response.py → environments/types/environments_get_analytics_response_top_models_item.py} +6 -3
- mirascope/api/_generated/errors/__init__.py +6 -0
- mirascope/api/_generated/errors/bad_request_error.py +5 -2
- mirascope/api/_generated/errors/conflict_error.py +5 -2
- mirascope/api/_generated/errors/payment_required_error.py +15 -0
- mirascope/api/_generated/errors/service_unavailable_error.py +14 -0
- mirascope/api/_generated/errors/too_many_requests_error.py +15 -0
- mirascope/api/_generated/functions/__init__.py +10 -0
- mirascope/api/_generated/functions/client.py +222 -8
- mirascope/api/_generated/functions/raw_client.py +975 -134
- mirascope/api/_generated/functions/types/__init__.py +28 -4
- mirascope/api/_generated/functions/types/functions_get_by_env_response.py +53 -0
- mirascope/api/_generated/functions/types/functions_get_by_env_response_dependencies_value.py +22 -0
- mirascope/api/_generated/functions/types/functions_list_by_env_response.py +25 -0
- mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item.py +56 -0
- mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item_dependencies_value.py +22 -0
- mirascope/api/_generated/health/raw_client.py +74 -10
- mirascope/api/_generated/organization_invitations/__init__.py +33 -0
- mirascope/api/_generated/organization_invitations/client.py +546 -0
- mirascope/api/_generated/organization_invitations/raw_client.py +1519 -0
- mirascope/api/_generated/organization_invitations/types/__init__.py +53 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response.py +34 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response_role.py +7 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_request_role.py +7 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response.py +48 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_role.py +7 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_status.py +7 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response.py +48 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_role.py +7 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_status.py +7 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item.py +48 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_role.py +7 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_status.py +7 -0
- mirascope/api/_generated/organization_memberships/__init__.py +19 -0
- mirascope/api/_generated/organization_memberships/client.py +302 -0
- mirascope/api/_generated/organization_memberships/raw_client.py +736 -0
- mirascope/api/_generated/organization_memberships/types/__init__.py +27 -0
- mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item.py +33 -0
- mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item_role.py +7 -0
- mirascope/api/_generated/organization_memberships/types/organization_memberships_update_request_role.py +7 -0
- mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response.py +31 -0
- mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response_role.py +7 -0
- mirascope/api/_generated/organizations/__init__.py +26 -2
- mirascope/api/_generated/organizations/client.py +442 -20
- mirascope/api/_generated/organizations/raw_client.py +1763 -164
- mirascope/api/_generated/organizations/types/__init__.py +48 -2
- mirascope/api/_generated/organizations/types/organizations_create_payment_intent_response.py +24 -0
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_request_target_plan.py +7 -0
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response.py +47 -0
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item.py +33 -0
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item_resource.py +7 -0
- mirascope/api/_generated/organizations/types/organizations_router_balance_response.py +24 -0
- mirascope/api/_generated/organizations/types/organizations_subscription_response.py +53 -0
- mirascope/api/_generated/organizations/types/organizations_subscription_response_current_plan.py +7 -0
- mirascope/api/_generated/organizations/types/organizations_subscription_response_payment_method.py +26 -0
- mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change.py +34 -0
- mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change_target_plan.py +7 -0
- mirascope/api/_generated/organizations/types/organizations_update_subscription_request_target_plan.py +7 -0
- mirascope/api/_generated/organizations/types/organizations_update_subscription_response.py +35 -0
- mirascope/api/_generated/project_memberships/__init__.py +25 -0
- mirascope/api/_generated/project_memberships/client.py +437 -0
- mirascope/api/_generated/project_memberships/raw_client.py +1039 -0
- mirascope/api/_generated/project_memberships/types/__init__.py +29 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_create_request_role.py +7 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_create_response.py +35 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_create_response_role.py +7 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item.py +33 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item_role.py +7 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_update_request_role.py +7 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_update_response.py +35 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_update_response_role.py +7 -0
- mirascope/api/_generated/projects/raw_client.py +415 -58
- mirascope/api/_generated/reference.md +2767 -397
- mirascope/api/_generated/tags/__init__.py +19 -0
- mirascope/api/_generated/tags/client.py +504 -0
- mirascope/api/_generated/tags/raw_client.py +1288 -0
- mirascope/api/_generated/tags/types/__init__.py +17 -0
- mirascope/api/_generated/tags/types/tags_create_response.py +41 -0
- mirascope/api/_generated/tags/types/tags_get_response.py +41 -0
- mirascope/api/_generated/tags/types/tags_list_response.py +23 -0
- mirascope/api/_generated/tags/types/tags_list_response_tags_item.py +41 -0
- mirascope/api/_generated/tags/types/tags_update_response.py +41 -0
- mirascope/api/_generated/token_cost/__init__.py +7 -0
- mirascope/api/_generated/token_cost/client.py +160 -0
- mirascope/api/_generated/token_cost/raw_client.py +264 -0
- mirascope/api/_generated/token_cost/types/__init__.py +8 -0
- mirascope/api/_generated/token_cost/types/token_cost_calculate_request_usage.py +54 -0
- mirascope/api/_generated/token_cost/types/token_cost_calculate_response.py +52 -0
- mirascope/api/_generated/traces/__init__.py +20 -0
- mirascope/api/_generated/traces/client.py +543 -0
- mirascope/api/_generated/traces/raw_client.py +1366 -96
- mirascope/api/_generated/traces/types/__init__.py +28 -0
- mirascope/api/_generated/traces/types/traces_get_analytics_summary_response.py +6 -0
- mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response.py +33 -0
- mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response_spans_item.py +88 -0
- mirascope/api/_generated/traces/types/traces_get_trace_detail_response_spans_item.py +0 -2
- mirascope/api/_generated/traces/types/traces_list_by_function_hash_response.py +25 -0
- mirascope/api/_generated/traces/types/traces_list_by_function_hash_response_traces_item.py +44 -0
- mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item.py +26 -0
- mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item_operator.py +7 -0
- mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_by.py +7 -0
- mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_order.py +7 -0
- mirascope/api/_generated/traces/types/traces_search_by_env_response.py +26 -0
- mirascope/api/_generated/traces/types/traces_search_by_env_response_spans_item.py +50 -0
- mirascope/api/_generated/traces/types/traces_search_response_spans_item.py +10 -1
- mirascope/api/_generated/types/__init__.py +32 -2
- mirascope/api/_generated/types/bad_request_error_body.py +50 -0
- mirascope/api/_generated/types/date.py +3 -0
- mirascope/api/_generated/types/immutable_resource_error.py +22 -0
- mirascope/api/_generated/types/internal_server_error_body.py +3 -3
- mirascope/api/_generated/types/plan_limit_exceeded_error.py +32 -0
- mirascope/api/_generated/types/plan_limit_exceeded_error_tag.py +7 -0
- mirascope/api/_generated/types/pricing_unavailable_error.py +23 -0
- mirascope/api/_generated/types/rate_limit_error.py +31 -0
- mirascope/api/_generated/types/rate_limit_error_tag.py +5 -0
- mirascope/api/_generated/types/service_unavailable_error_body.py +24 -0
- mirascope/api/_generated/types/service_unavailable_error_tag.py +7 -0
- mirascope/api/_generated/types/subscription_past_due_error.py +31 -0
- mirascope/api/_generated/types/subscription_past_due_error_tag.py +7 -0
- mirascope/api/settings.py +19 -1
- mirascope/llm/__init__.py +53 -10
- mirascope/llm/calls/__init__.py +2 -1
- mirascope/llm/calls/calls.py +3 -1
- mirascope/llm/calls/decorator.py +21 -7
- mirascope/llm/content/tool_output.py +22 -5
- mirascope/llm/exceptions.py +284 -71
- mirascope/llm/formatting/__init__.py +17 -0
- mirascope/llm/formatting/format.py +112 -35
- mirascope/llm/formatting/output_parser.py +178 -0
- mirascope/llm/formatting/partial.py +80 -7
- mirascope/llm/formatting/primitives.py +192 -0
- mirascope/llm/formatting/types.py +20 -8
- mirascope/llm/messages/__init__.py +3 -0
- mirascope/llm/messages/_utils.py +34 -0
- mirascope/llm/models/__init__.py +5 -0
- mirascope/llm/models/models.py +137 -69
- mirascope/llm/{providers/base → models}/params.py +7 -57
- mirascope/llm/models/thinking_config.py +61 -0
- mirascope/llm/prompts/_utils.py +0 -32
- mirascope/llm/prompts/decorator.py +16 -5
- mirascope/llm/prompts/prompts.py +131 -68
- mirascope/llm/providers/__init__.py +1 -4
- mirascope/llm/providers/anthropic/_utils/__init__.py +2 -0
- mirascope/llm/providers/anthropic/_utils/beta_decode.py +18 -9
- mirascope/llm/providers/anthropic/_utils/beta_encode.py +62 -13
- mirascope/llm/providers/anthropic/_utils/decode.py +18 -9
- mirascope/llm/providers/anthropic/_utils/encode.py +26 -7
- mirascope/llm/providers/anthropic/_utils/errors.py +2 -2
- mirascope/llm/providers/anthropic/beta_provider.py +64 -18
- mirascope/llm/providers/anthropic/provider.py +91 -33
- mirascope/llm/providers/base/__init__.py +0 -4
- mirascope/llm/providers/base/_utils.py +55 -6
- mirascope/llm/providers/base/base_provider.py +116 -37
- mirascope/llm/providers/google/_utils/__init__.py +2 -0
- mirascope/llm/providers/google/_utils/decode.py +20 -7
- mirascope/llm/providers/google/_utils/encode.py +26 -7
- mirascope/llm/providers/google/_utils/errors.py +3 -2
- mirascope/llm/providers/google/provider.py +64 -18
- mirascope/llm/providers/mirascope/_utils.py +13 -17
- mirascope/llm/providers/mirascope/provider.py +49 -18
- mirascope/llm/providers/mlx/_utils.py +7 -2
- mirascope/llm/providers/mlx/encoding/base.py +5 -2
- mirascope/llm/providers/mlx/encoding/transformers.py +5 -2
- mirascope/llm/providers/mlx/mlx.py +23 -6
- mirascope/llm/providers/mlx/provider.py +42 -13
- mirascope/llm/providers/openai/_utils/errors.py +2 -2
- mirascope/llm/providers/openai/completions/_utils/encode.py +20 -16
- mirascope/llm/providers/openai/completions/base_provider.py +40 -11
- mirascope/llm/providers/openai/provider.py +40 -10
- mirascope/llm/providers/openai/responses/_utils/__init__.py +2 -0
- mirascope/llm/providers/openai/responses/_utils/decode.py +19 -6
- mirascope/llm/providers/openai/responses/_utils/encode.py +22 -10
- mirascope/llm/providers/openai/responses/provider.py +56 -18
- mirascope/llm/providers/provider_registry.py +93 -19
- mirascope/llm/responses/__init__.py +6 -1
- mirascope/llm/responses/_utils.py +102 -12
- mirascope/llm/responses/base_response.py +5 -2
- mirascope/llm/responses/base_stream_response.py +115 -25
- mirascope/llm/responses/response.py +2 -1
- mirascope/llm/responses/root_response.py +89 -17
- mirascope/llm/responses/stream_response.py +6 -9
- mirascope/llm/tools/decorator.py +9 -4
- mirascope/llm/tools/tool_schema.py +12 -6
- mirascope/llm/tools/toolkit.py +35 -27
- mirascope/llm/tools/tools.py +45 -20
- mirascope/ops/__init__.py +4 -0
- mirascope/ops/_internal/configuration.py +82 -31
- mirascope/ops/_internal/exporters/exporters.py +64 -11
- mirascope/ops/_internal/instrumentation/llm/common.py +530 -0
- mirascope/ops/_internal/instrumentation/llm/cost.py +190 -0
- mirascope/ops/_internal/instrumentation/llm/encode.py +1 -1
- mirascope/ops/_internal/instrumentation/llm/llm.py +116 -1242
- mirascope/ops/_internal/instrumentation/llm/model.py +1798 -0
- mirascope/ops/_internal/instrumentation/llm/response.py +521 -0
- mirascope/ops/_internal/instrumentation/llm/serialize.py +300 -0
- mirascope/ops/_internal/protocols.py +83 -1
- mirascope/ops/_internal/traced_calls.py +4 -0
- mirascope/ops/_internal/traced_functions.py +118 -8
- mirascope/ops/_internal/tracing.py +78 -1
- mirascope/ops/_internal/utils.py +52 -4
- {mirascope-2.0.0a6.dist-info → mirascope-2.0.1.dist-info}/METADATA +12 -11
- mirascope-2.0.1.dist-info/RECORD +423 -0
- {mirascope-2.0.0a6.dist-info → mirascope-2.0.1.dist-info}/licenses/LICENSE +1 -1
- mirascope-2.0.0a6.dist-info/RECORD +0 -316
- {mirascope-2.0.0a6.dist-info → mirascope-2.0.1.dist-info}/WHEEL +0 -0
|
@@ -9,8 +9,8 @@ from typing import TYPE_CHECKING, Any, ClassVar, Generic, TypeAlias, cast, overl
|
|
|
9
9
|
from typing_extensions import TypeVar, Unpack
|
|
10
10
|
|
|
11
11
|
from ...context import Context, DepsT
|
|
12
|
-
from ...exceptions import APIError,
|
|
13
|
-
from ...formatting import Format, FormattableT
|
|
12
|
+
from ...exceptions import APIError, ProviderError
|
|
13
|
+
from ...formatting import Format, FormattableT, OutputParser
|
|
14
14
|
from ...messages import Message, UserContent, user
|
|
15
15
|
from ...responses import (
|
|
16
16
|
AsyncChunkIterator,
|
|
@@ -34,10 +34,9 @@ from ...tools import (
|
|
|
34
34
|
Tool,
|
|
35
35
|
Toolkit,
|
|
36
36
|
)
|
|
37
|
-
from .params import Params
|
|
38
37
|
|
|
39
38
|
if TYPE_CHECKING:
|
|
40
|
-
from ...
|
|
39
|
+
from ...models import Params
|
|
41
40
|
from ..provider_id import ProviderId
|
|
42
41
|
|
|
43
42
|
ProviderClientT = TypeVar("ProviderClientT")
|
|
@@ -47,7 +46,7 @@ Provider: TypeAlias = "BaseProvider[Any]"
|
|
|
47
46
|
|
|
48
47
|
ProviderErrorMap: TypeAlias = Mapping[
|
|
49
48
|
type[Exception],
|
|
50
|
-
"type[
|
|
49
|
+
"type[ProviderError] | Callable[[Exception], type[ProviderError]]",
|
|
51
50
|
]
|
|
52
51
|
"""Mapping from provider SDK exceptions to Mirascope error types.
|
|
53
52
|
|
|
@@ -85,7 +84,7 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
85
84
|
(e.g., lambda e: NotFoundError if e.code == "model_not_found" else BadRequestError)
|
|
86
85
|
|
|
87
86
|
The mapping is walked via the exception's MRO, allowing both specific error handling
|
|
88
|
-
and fallback to base SDK error types (e.g., AnthropicError ->
|
|
87
|
+
and fallback to base SDK error types (e.g., AnthropicError -> ProviderError).
|
|
89
88
|
"""
|
|
90
89
|
|
|
91
90
|
client: ProviderClientT
|
|
@@ -96,7 +95,7 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
96
95
|
|
|
97
96
|
Walks the exception's MRO to find the first matching error type in the
|
|
98
97
|
provider's error_map, allowing both specific error handling and fallback
|
|
99
|
-
to base SDK error types (e.g., AnthropicError ->
|
|
98
|
+
to base SDK error types (e.g., AnthropicError -> ProviderError).
|
|
100
99
|
"""
|
|
101
100
|
try:
|
|
102
101
|
yield
|
|
@@ -107,16 +106,24 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
107
106
|
error_type_or_fn = self.error_map[error_class]
|
|
108
107
|
|
|
109
108
|
if isinstance(error_type_or_fn, type):
|
|
110
|
-
error_type = cast(type[
|
|
109
|
+
error_type = cast(type[ProviderError], error_type_or_fn)
|
|
111
110
|
else:
|
|
112
111
|
error_type = error_type_or_fn(e)
|
|
113
112
|
|
|
114
113
|
# Construct Mirascope error with metadata
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
114
|
+
if issubclass(error_type, APIError):
|
|
115
|
+
error: ProviderError = error_type(
|
|
116
|
+
str(e),
|
|
117
|
+
provider=self.id,
|
|
118
|
+
status_code=self.get_error_status(e),
|
|
119
|
+
original_exception=e,
|
|
120
|
+
)
|
|
121
|
+
else:
|
|
122
|
+
error = error_type(
|
|
123
|
+
str(e),
|
|
124
|
+
provider=self.id,
|
|
125
|
+
original_exception=e,
|
|
126
|
+
)
|
|
120
127
|
raise error from e
|
|
121
128
|
|
|
122
129
|
# Not in error_map - not a provider error, re-raise as-is
|
|
@@ -170,7 +177,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
170
177
|
model_id: str,
|
|
171
178
|
messages: Sequence[Message],
|
|
172
179
|
tools: Sequence[Tool] | Toolkit | None = None,
|
|
173
|
-
format: type[FormattableT]
|
|
180
|
+
format: type[FormattableT]
|
|
181
|
+
| Format[FormattableT]
|
|
182
|
+
| OutputParser[FormattableT]
|
|
183
|
+
| None,
|
|
174
184
|
**params: Unpack[Params],
|
|
175
185
|
) -> Response | Response[FormattableT]:
|
|
176
186
|
"""Generate an `llm.Response` with an optional response format."""
|
|
@@ -182,7 +192,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
182
192
|
model_id: str,
|
|
183
193
|
messages: Sequence[Message],
|
|
184
194
|
tools: Sequence[Tool] | Toolkit | None = None,
|
|
185
|
-
format: type[FormattableT]
|
|
195
|
+
format: type[FormattableT]
|
|
196
|
+
| Format[FormattableT]
|
|
197
|
+
| OutputParser[FormattableT]
|
|
198
|
+
| None = None,
|
|
186
199
|
**params: Unpack[Params],
|
|
187
200
|
) -> Response | Response[FormattableT]:
|
|
188
201
|
"""Generate an `llm.Response` by synchronously calling this client's LLM provider.
|
|
@@ -213,7 +226,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
213
226
|
model_id: str,
|
|
214
227
|
messages: Sequence[Message],
|
|
215
228
|
tools: Sequence[Tool] | Toolkit | None = None,
|
|
216
|
-
format: type[FormattableT]
|
|
229
|
+
format: type[FormattableT]
|
|
230
|
+
| Format[FormattableT]
|
|
231
|
+
| OutputParser[FormattableT]
|
|
232
|
+
| None = None,
|
|
217
233
|
**params: Unpack[Params],
|
|
218
234
|
) -> Response | Response[FormattableT]:
|
|
219
235
|
"""Implementation for call(). Subclasses override this method."""
|
|
@@ -261,7 +277,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
261
277
|
tools: Sequence[Tool | ContextTool[DepsT]]
|
|
262
278
|
| ContextToolkit[DepsT]
|
|
263
279
|
| None = None,
|
|
264
|
-
format: type[FormattableT]
|
|
280
|
+
format: type[FormattableT]
|
|
281
|
+
| Format[FormattableT]
|
|
282
|
+
| OutputParser[FormattableT]
|
|
283
|
+
| None,
|
|
265
284
|
**params: Unpack[Params],
|
|
266
285
|
) -> ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]:
|
|
267
286
|
"""Generate an `llm.ContextResponse` with an optional response format."""
|
|
@@ -276,7 +295,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
276
295
|
tools: Sequence[Tool | ContextTool[DepsT]]
|
|
277
296
|
| ContextToolkit[DepsT]
|
|
278
297
|
| None = None,
|
|
279
|
-
format: type[FormattableT]
|
|
298
|
+
format: type[FormattableT]
|
|
299
|
+
| Format[FormattableT]
|
|
300
|
+
| OutputParser[FormattableT]
|
|
301
|
+
| None = None,
|
|
280
302
|
**params: Unpack[Params],
|
|
281
303
|
) -> ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]:
|
|
282
304
|
"""Generate an `llm.ContextResponse` by synchronously calling this client's LLM provider.
|
|
@@ -312,7 +334,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
312
334
|
tools: Sequence[Tool | ContextTool[DepsT]]
|
|
313
335
|
| ContextToolkit[DepsT]
|
|
314
336
|
| None = None,
|
|
315
|
-
format: type[FormattableT]
|
|
337
|
+
format: type[FormattableT]
|
|
338
|
+
| Format[FormattableT]
|
|
339
|
+
| OutputParser[FormattableT]
|
|
340
|
+
| None = None,
|
|
316
341
|
**params: Unpack[Params],
|
|
317
342
|
) -> ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]:
|
|
318
343
|
"""Implementation for context_call(). Subclasses override this method."""
|
|
@@ -351,7 +376,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
351
376
|
model_id: str,
|
|
352
377
|
messages: Sequence[Message],
|
|
353
378
|
tools: Sequence[AsyncTool] | AsyncToolkit | None = None,
|
|
354
|
-
format: type[FormattableT]
|
|
379
|
+
format: type[FormattableT]
|
|
380
|
+
| Format[FormattableT]
|
|
381
|
+
| OutputParser[FormattableT]
|
|
382
|
+
| None,
|
|
355
383
|
**params: Unpack[Params],
|
|
356
384
|
) -> AsyncResponse | AsyncResponse[FormattableT]:
|
|
357
385
|
"""Generate an `llm.AsyncResponse` with an optional response format."""
|
|
@@ -363,7 +391,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
363
391
|
model_id: str,
|
|
364
392
|
messages: Sequence[Message],
|
|
365
393
|
tools: Sequence[AsyncTool] | AsyncToolkit | None = None,
|
|
366
|
-
format: type[FormattableT]
|
|
394
|
+
format: type[FormattableT]
|
|
395
|
+
| Format[FormattableT]
|
|
396
|
+
| OutputParser[FormattableT]
|
|
397
|
+
| None = None,
|
|
367
398
|
**params: Unpack[Params],
|
|
368
399
|
) -> AsyncResponse | AsyncResponse[FormattableT]:
|
|
369
400
|
"""Generate an `llm.AsyncResponse` by asynchronously calling this client's LLM provider.
|
|
@@ -394,7 +425,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
394
425
|
model_id: str,
|
|
395
426
|
messages: Sequence[Message],
|
|
396
427
|
tools: Sequence[AsyncTool] | AsyncToolkit | None = None,
|
|
397
|
-
format: type[FormattableT]
|
|
428
|
+
format: type[FormattableT]
|
|
429
|
+
| Format[FormattableT]
|
|
430
|
+
| OutputParser[FormattableT]
|
|
431
|
+
| None = None,
|
|
398
432
|
**params: Unpack[Params],
|
|
399
433
|
) -> AsyncResponse | AsyncResponse[FormattableT]:
|
|
400
434
|
"""Implementation for call_async(). Subclasses override this method."""
|
|
@@ -442,7 +476,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
442
476
|
tools: Sequence[AsyncTool | AsyncContextTool[DepsT]]
|
|
443
477
|
| AsyncContextToolkit[DepsT]
|
|
444
478
|
| None = None,
|
|
445
|
-
format: type[FormattableT]
|
|
479
|
+
format: type[FormattableT]
|
|
480
|
+
| Format[FormattableT]
|
|
481
|
+
| OutputParser[FormattableT]
|
|
482
|
+
| None,
|
|
446
483
|
**params: Unpack[Params],
|
|
447
484
|
) -> AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT]:
|
|
448
485
|
"""Generate an `llm.AsyncContextResponse` with an optional response format."""
|
|
@@ -457,7 +494,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
457
494
|
tools: Sequence[AsyncTool | AsyncContextTool[DepsT]]
|
|
458
495
|
| AsyncContextToolkit[DepsT]
|
|
459
496
|
| None = None,
|
|
460
|
-
format: type[FormattableT]
|
|
497
|
+
format: type[FormattableT]
|
|
498
|
+
| Format[FormattableT]
|
|
499
|
+
| OutputParser[FormattableT]
|
|
500
|
+
| None = None,
|
|
461
501
|
**params: Unpack[Params],
|
|
462
502
|
) -> AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT]:
|
|
463
503
|
"""Generate an `llm.AsyncContextResponse` by asynchronously calling this client's LLM provider.
|
|
@@ -493,7 +533,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
493
533
|
tools: Sequence[AsyncTool | AsyncContextTool[DepsT]]
|
|
494
534
|
| AsyncContextToolkit[DepsT]
|
|
495
535
|
| None = None,
|
|
496
|
-
format: type[FormattableT]
|
|
536
|
+
format: type[FormattableT]
|
|
537
|
+
| Format[FormattableT]
|
|
538
|
+
| OutputParser[FormattableT]
|
|
539
|
+
| None = None,
|
|
497
540
|
**params: Unpack[Params],
|
|
498
541
|
) -> AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT]:
|
|
499
542
|
"""Implementation for context_call_async(). Subclasses override this method."""
|
|
@@ -532,7 +575,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
532
575
|
model_id: str,
|
|
533
576
|
messages: Sequence[Message],
|
|
534
577
|
tools: Sequence[Tool] | Toolkit | None = None,
|
|
535
|
-
format: type[FormattableT]
|
|
578
|
+
format: type[FormattableT]
|
|
579
|
+
| Format[FormattableT]
|
|
580
|
+
| OutputParser[FormattableT]
|
|
581
|
+
| None,
|
|
536
582
|
**params: Unpack[Params],
|
|
537
583
|
) -> StreamResponse | StreamResponse[FormattableT]:
|
|
538
584
|
"""Stream an `llm.StreamResponse` with an optional response format."""
|
|
@@ -544,7 +590,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
544
590
|
model_id: str,
|
|
545
591
|
messages: Sequence[Message],
|
|
546
592
|
tools: Sequence[Tool] | Toolkit | None = None,
|
|
547
|
-
format: type[FormattableT]
|
|
593
|
+
format: type[FormattableT]
|
|
594
|
+
| Format[FormattableT]
|
|
595
|
+
| OutputParser[FormattableT]
|
|
596
|
+
| None = None,
|
|
548
597
|
**params: Unpack[Params],
|
|
549
598
|
) -> StreamResponse | StreamResponse[FormattableT]:
|
|
550
599
|
"""Generate an `llm.StreamResponse` by synchronously streaming from this client's LLM provider.
|
|
@@ -579,7 +628,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
579
628
|
model_id: str,
|
|
580
629
|
messages: Sequence[Message],
|
|
581
630
|
tools: Sequence[Tool] | Toolkit | None = None,
|
|
582
|
-
format: type[FormattableT]
|
|
631
|
+
format: type[FormattableT]
|
|
632
|
+
| Format[FormattableT]
|
|
633
|
+
| OutputParser[FormattableT]
|
|
634
|
+
| None = None,
|
|
583
635
|
**params: Unpack[Params],
|
|
584
636
|
) -> StreamResponse | StreamResponse[FormattableT]:
|
|
585
637
|
"""Implementation for stream(). Subclasses override this method."""
|
|
@@ -627,7 +679,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
627
679
|
tools: Sequence[Tool | ContextTool[DepsT]]
|
|
628
680
|
| ContextToolkit[DepsT]
|
|
629
681
|
| None = None,
|
|
630
|
-
format: type[FormattableT]
|
|
682
|
+
format: type[FormattableT]
|
|
683
|
+
| Format[FormattableT]
|
|
684
|
+
| OutputParser[FormattableT]
|
|
685
|
+
| None,
|
|
631
686
|
**params: Unpack[Params],
|
|
632
687
|
) -> (
|
|
633
688
|
ContextStreamResponse[DepsT, None] | ContextStreamResponse[DepsT, FormattableT]
|
|
@@ -644,7 +699,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
644
699
|
tools: Sequence[Tool | ContextTool[DepsT]]
|
|
645
700
|
| ContextToolkit[DepsT]
|
|
646
701
|
| None = None,
|
|
647
|
-
format: type[FormattableT]
|
|
702
|
+
format: type[FormattableT]
|
|
703
|
+
| Format[FormattableT]
|
|
704
|
+
| OutputParser[FormattableT]
|
|
705
|
+
| None = None,
|
|
648
706
|
**params: Unpack[Params],
|
|
649
707
|
) -> (
|
|
650
708
|
ContextStreamResponse[DepsT, None] | ContextStreamResponse[DepsT, FormattableT]
|
|
@@ -686,7 +744,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
686
744
|
tools: Sequence[Tool | ContextTool[DepsT]]
|
|
687
745
|
| ContextToolkit[DepsT]
|
|
688
746
|
| None = None,
|
|
689
|
-
format: type[FormattableT]
|
|
747
|
+
format: type[FormattableT]
|
|
748
|
+
| Format[FormattableT]
|
|
749
|
+
| OutputParser[FormattableT]
|
|
750
|
+
| None = None,
|
|
690
751
|
**params: Unpack[Params],
|
|
691
752
|
) -> (
|
|
692
753
|
ContextStreamResponse[DepsT, None] | ContextStreamResponse[DepsT, FormattableT]
|
|
@@ -727,7 +788,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
727
788
|
model_id: str,
|
|
728
789
|
messages: Sequence[Message],
|
|
729
790
|
tools: Sequence[AsyncTool] | AsyncToolkit | None = None,
|
|
730
|
-
format: type[FormattableT]
|
|
791
|
+
format: type[FormattableT]
|
|
792
|
+
| Format[FormattableT]
|
|
793
|
+
| OutputParser[FormattableT]
|
|
794
|
+
| None,
|
|
731
795
|
**params: Unpack[Params],
|
|
732
796
|
) -> AsyncStreamResponse | AsyncStreamResponse[FormattableT]:
|
|
733
797
|
"""Stream an `llm.AsyncStreamResponse` with an optional response format."""
|
|
@@ -739,7 +803,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
739
803
|
model_id: str,
|
|
740
804
|
messages: Sequence[Message],
|
|
741
805
|
tools: Sequence[AsyncTool] | AsyncToolkit | None = None,
|
|
742
|
-
format: type[FormattableT]
|
|
806
|
+
format: type[FormattableT]
|
|
807
|
+
| Format[FormattableT]
|
|
808
|
+
| OutputParser[FormattableT]
|
|
809
|
+
| None = None,
|
|
743
810
|
**params: Unpack[Params],
|
|
744
811
|
) -> AsyncStreamResponse | AsyncStreamResponse[FormattableT]:
|
|
745
812
|
"""Generate an `llm.AsyncStreamResponse` by asynchronously streaming from this client's LLM provider.
|
|
@@ -774,7 +841,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
774
841
|
model_id: str,
|
|
775
842
|
messages: Sequence[Message],
|
|
776
843
|
tools: Sequence[AsyncTool] | AsyncToolkit | None = None,
|
|
777
|
-
format: type[FormattableT]
|
|
844
|
+
format: type[FormattableT]
|
|
845
|
+
| Format[FormattableT]
|
|
846
|
+
| OutputParser[FormattableT]
|
|
847
|
+
| None = None,
|
|
778
848
|
**params: Unpack[Params],
|
|
779
849
|
) -> AsyncStreamResponse | AsyncStreamResponse[FormattableT]:
|
|
780
850
|
"""Implementation for stream_async(). Subclasses override this method."""
|
|
@@ -822,7 +892,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
822
892
|
tools: Sequence[AsyncTool | AsyncContextTool[DepsT]]
|
|
823
893
|
| AsyncContextToolkit[DepsT]
|
|
824
894
|
| None = None,
|
|
825
|
-
format: type[FormattableT]
|
|
895
|
+
format: type[FormattableT]
|
|
896
|
+
| Format[FormattableT]
|
|
897
|
+
| OutputParser[FormattableT]
|
|
898
|
+
| None,
|
|
826
899
|
**params: Unpack[Params],
|
|
827
900
|
) -> (
|
|
828
901
|
AsyncContextStreamResponse[DepsT, None]
|
|
@@ -840,7 +913,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
840
913
|
tools: Sequence[AsyncTool | AsyncContextTool[DepsT]]
|
|
841
914
|
| AsyncContextToolkit[DepsT]
|
|
842
915
|
| None = None,
|
|
843
|
-
format: type[FormattableT]
|
|
916
|
+
format: type[FormattableT]
|
|
917
|
+
| Format[FormattableT]
|
|
918
|
+
| OutputParser[FormattableT]
|
|
919
|
+
| None = None,
|
|
844
920
|
**params: Unpack[Params],
|
|
845
921
|
) -> (
|
|
846
922
|
AsyncContextStreamResponse[DepsT, None]
|
|
@@ -883,7 +959,10 @@ class BaseProvider(Generic[ProviderClientT], ABC):
|
|
|
883
959
|
tools: Sequence[AsyncTool | AsyncContextTool[DepsT]]
|
|
884
960
|
| AsyncContextToolkit[DepsT]
|
|
885
961
|
| None = None,
|
|
886
|
-
format: type[FormattableT]
|
|
962
|
+
format: type[FormattableT]
|
|
963
|
+
| Format[FormattableT]
|
|
964
|
+
| OutputParser[FormattableT]
|
|
965
|
+
| None = None,
|
|
887
966
|
**params: Unpack[Params],
|
|
888
967
|
) -> (
|
|
889
968
|
AsyncContextStreamResponse[DepsT, None]
|
|
@@ -126,6 +126,8 @@ def _decode_candidate_content(
|
|
|
126
126
|
def decode_response(
|
|
127
127
|
response: genai_types.GenerateContentResponse,
|
|
128
128
|
model_id: GoogleModelId,
|
|
129
|
+
*,
|
|
130
|
+
include_thoughts: bool,
|
|
129
131
|
) -> tuple[AssistantMessage, FinishReason | None, Usage | None]:
|
|
130
132
|
"""Returns an `AssistantMessage`, `FinishReason`, and `Usage` extracted from a `GenerateContentResponse`"""
|
|
131
133
|
content: Sequence[AssistantContentPart] = []
|
|
@@ -134,6 +136,8 @@ def decode_response(
|
|
|
134
136
|
|
|
135
137
|
if response.candidates and (candidate := response.candidates[0]):
|
|
136
138
|
content = _decode_candidate_content(candidate)
|
|
139
|
+
if not include_thoughts:
|
|
140
|
+
content = [part for part in content if part.type != "thought"]
|
|
137
141
|
candidate_content = candidate.content
|
|
138
142
|
if candidate.finish_reason:
|
|
139
143
|
finish_reason = GOOGLE_FINISH_REASON_MAP.get(candidate.finish_reason)
|
|
@@ -155,12 +159,13 @@ def decode_response(
|
|
|
155
159
|
class _GoogleChunkProcessor:
|
|
156
160
|
"""Processes Google stream chunks and maintains state across chunks."""
|
|
157
161
|
|
|
158
|
-
def __init__(self) -> None:
|
|
162
|
+
def __init__(self, *, include_thoughts: bool) -> None:
|
|
159
163
|
self.current_content_type: Literal["text", "tool_call", "thought"] | None = None
|
|
160
164
|
self.accumulated_parts: list[genai_types.Part] = []
|
|
161
165
|
self.reconstructed_content = genai_types.Content(parts=[])
|
|
162
166
|
# Track previous cumulative usage to compute deltas
|
|
163
167
|
self.prev_usage = Usage()
|
|
168
|
+
self.include_thoughts = include_thoughts
|
|
164
169
|
|
|
165
170
|
def process_chunk(
|
|
166
171
|
self, chunk: genai_types.GenerateContentResponse
|
|
@@ -175,7 +180,8 @@ class _GoogleChunkProcessor:
|
|
|
175
180
|
for part in candidate.content.parts:
|
|
176
181
|
self.accumulated_parts.append(part)
|
|
177
182
|
if self.current_content_type == "thought" and not part.thought:
|
|
178
|
-
|
|
183
|
+
if self.include_thoughts:
|
|
184
|
+
yield ThoughtEndChunk()
|
|
179
185
|
self.current_content_type = None
|
|
180
186
|
elif (
|
|
181
187
|
self.current_content_type == "text" and not part.text
|
|
@@ -193,13 +199,15 @@ class _GoogleChunkProcessor:
|
|
|
193
199
|
|
|
194
200
|
if part.thought:
|
|
195
201
|
if self.current_content_type is None:
|
|
196
|
-
|
|
202
|
+
if self.include_thoughts:
|
|
203
|
+
yield ThoughtStartChunk()
|
|
197
204
|
self.current_content_type = "thought"
|
|
198
205
|
if not part.text:
|
|
199
206
|
raise ValueError(
|
|
200
207
|
"Inside thought part with no text content"
|
|
201
208
|
) # pragma: no cover
|
|
202
|
-
|
|
209
|
+
if self.include_thoughts:
|
|
210
|
+
yield ThoughtChunk(delta=part.text)
|
|
203
211
|
|
|
204
212
|
elif part.text:
|
|
205
213
|
if self.current_content_type is None:
|
|
@@ -235,7 +243,8 @@ class _GoogleChunkProcessor:
|
|
|
235
243
|
if self.current_content_type == "text":
|
|
236
244
|
yield TextEndChunk()
|
|
237
245
|
elif self.current_content_type == "thought":
|
|
238
|
-
|
|
246
|
+
if self.include_thoughts: # pragma: no cover
|
|
247
|
+
yield ThoughtEndChunk()
|
|
239
248
|
elif self.current_content_type is not None:
|
|
240
249
|
raise NotImplementedError
|
|
241
250
|
|
|
@@ -275,9 +284,11 @@ class _GoogleChunkProcessor:
|
|
|
275
284
|
|
|
276
285
|
def decode_stream(
|
|
277
286
|
google_stream: Iterator[genai_types.GenerateContentResponse],
|
|
287
|
+
*,
|
|
288
|
+
include_thoughts: bool,
|
|
278
289
|
) -> ChunkIterator:
|
|
279
290
|
"""Returns a ChunkIterator converted from a Google stream."""
|
|
280
|
-
processor = _GoogleChunkProcessor()
|
|
291
|
+
processor = _GoogleChunkProcessor(include_thoughts=include_thoughts)
|
|
281
292
|
for chunk in google_stream:
|
|
282
293
|
yield from processor.process_chunk(chunk)
|
|
283
294
|
yield processor.raw_message_chunk()
|
|
@@ -285,9 +296,11 @@ def decode_stream(
|
|
|
285
296
|
|
|
286
297
|
async def decode_async_stream(
|
|
287
298
|
google_stream: AsyncIterator[genai_types.GenerateContentResponse],
|
|
299
|
+
*,
|
|
300
|
+
include_thoughts: bool,
|
|
288
301
|
) -> AsyncChunkIterator:
|
|
289
302
|
"""Returns an AsyncChunkIterator converted from a Google async stream."""
|
|
290
|
-
processor = _GoogleChunkProcessor()
|
|
303
|
+
processor = _GoogleChunkProcessor(include_thoughts=include_thoughts)
|
|
291
304
|
async for chunk in google_stream:
|
|
292
305
|
for item in processor.process_chunk(chunk):
|
|
293
306
|
yield item
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"""Google message encoding and request preparation."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import base64
|
|
4
6
|
import json
|
|
5
7
|
from collections.abc import Sequence
|
|
6
8
|
from functools import lru_cache
|
|
7
|
-
from typing import Any, TypedDict, cast
|
|
9
|
+
from typing import TYPE_CHECKING, Any, TypedDict, cast
|
|
8
10
|
from typing_extensions import Required
|
|
9
11
|
|
|
10
12
|
from google.genai import types as genai_types
|
|
@@ -14,14 +16,18 @@ from ....exceptions import FeatureNotSupportedError
|
|
|
14
16
|
from ....formatting import (
|
|
15
17
|
Format,
|
|
16
18
|
FormattableT,
|
|
19
|
+
OutputParser,
|
|
17
20
|
resolve_format,
|
|
18
21
|
)
|
|
19
22
|
from ....messages import AssistantMessage, Message, UserMessage
|
|
20
23
|
from ....tools import FORMAT_TOOL_NAME, AnyToolSchema, BaseToolkit
|
|
21
|
-
from ...base import
|
|
24
|
+
from ...base import _utils as _base_utils
|
|
22
25
|
from ..model_id import GoogleModelId, model_name
|
|
23
26
|
from ..model_info import MODELS_WITHOUT_STRUCTURED_OUTPUT_AND_TOOLS_SUPPORT
|
|
24
27
|
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
from ....models import Params, ThinkingConfig, ThinkingLevel
|
|
30
|
+
|
|
25
31
|
UNKNOWN_TOOL_ID = "google_unknown_tool_id"
|
|
26
32
|
|
|
27
33
|
# Thinking level to a float multiplier % of max tokens (for 2.5 models using budget)
|
|
@@ -82,7 +88,7 @@ def google_thinking_config(
|
|
|
82
88
|
See: https://ai.google.dev/gemini-api/docs/gemini-3#thinking_level
|
|
83
89
|
"""
|
|
84
90
|
level: ThinkingLevel = thinking_config.get("level", "default")
|
|
85
|
-
|
|
91
|
+
include_thoughts = thinking_config.get("include_thoughts")
|
|
86
92
|
|
|
87
93
|
result = genai_types.ThinkingConfigDict()
|
|
88
94
|
|
|
@@ -108,8 +114,8 @@ def google_thinking_config(
|
|
|
108
114
|
budget = int(multiplier * max_tokens)
|
|
109
115
|
|
|
110
116
|
result["thinking_budget"] = budget
|
|
111
|
-
if
|
|
112
|
-
result["include_thoughts"] =
|
|
117
|
+
if include_thoughts is not None:
|
|
118
|
+
result["include_thoughts"] = include_thoughts
|
|
113
119
|
|
|
114
120
|
return result
|
|
115
121
|
|
|
@@ -193,7 +199,7 @@ def _encode_content(
|
|
|
193
199
|
function_response=genai_types.FunctionResponseDict(
|
|
194
200
|
id=part.id if part.id != UNKNOWN_TOOL_ID else None,
|
|
195
201
|
name=part.name,
|
|
196
|
-
response={"output": str(part.
|
|
202
|
+
response={"output": str(part.result)},
|
|
197
203
|
)
|
|
198
204
|
)
|
|
199
205
|
)
|
|
@@ -265,7 +271,10 @@ def encode_request(
|
|
|
265
271
|
model_id: GoogleModelId,
|
|
266
272
|
messages: Sequence[Message],
|
|
267
273
|
tools: Sequence[AnyToolSchema] | BaseToolkit[AnyToolSchema] | None,
|
|
268
|
-
format: type[FormattableT]
|
|
274
|
+
format: type[FormattableT]
|
|
275
|
+
| Format[FormattableT]
|
|
276
|
+
| OutputParser[FormattableT]
|
|
277
|
+
| None,
|
|
269
278
|
params: Params,
|
|
270
279
|
) -> tuple[Sequence[Message], Format[FormattableT] | None, GoogleKwargs]:
|
|
271
280
|
"""Prepares a request for the genai `Client.models.generate_content` method."""
|
|
@@ -306,6 +315,16 @@ def encode_request(
|
|
|
306
315
|
encode_thoughts_as_text = True
|
|
307
316
|
|
|
308
317
|
tools = tools.tools if isinstance(tools, BaseToolkit) else tools or []
|
|
318
|
+
|
|
319
|
+
if _base_utils.has_strict_tools(tools):
|
|
320
|
+
raise FeatureNotSupportedError(
|
|
321
|
+
feature="strict tools",
|
|
322
|
+
provider_id="google",
|
|
323
|
+
model_id=model_id,
|
|
324
|
+
message="Google does not support strict mode for tools. "
|
|
325
|
+
"Set strict=False on your tools or omit the strict parameter.",
|
|
326
|
+
)
|
|
327
|
+
|
|
309
328
|
google_tools: list[genai_types.ToolDict] = []
|
|
310
329
|
|
|
311
330
|
allows_strict_mode_with_tools = (
|
|
@@ -11,20 +11,21 @@ from ....exceptions import (
|
|
|
11
11
|
BadRequestError,
|
|
12
12
|
NotFoundError,
|
|
13
13
|
PermissionError,
|
|
14
|
+
ProviderError,
|
|
14
15
|
RateLimitError,
|
|
15
16
|
ServerError,
|
|
16
17
|
)
|
|
17
18
|
from ...base import ProviderErrorMap
|
|
18
19
|
|
|
19
20
|
|
|
20
|
-
def map_google_error(e: Exception) -> type[
|
|
21
|
+
def map_google_error(e: Exception) -> type[ProviderError]:
|
|
21
22
|
"""Map Google error to appropriate Mirascope error type.
|
|
22
23
|
|
|
23
24
|
Google only provides ClientError (4xx) and ServerError (5xx) with status codes,
|
|
24
25
|
so we map based on status code and message patterns.
|
|
25
26
|
"""
|
|
26
27
|
if not isinstance(e, GoogleClientError | GoogleServerError):
|
|
27
|
-
return
|
|
28
|
+
return ProviderError
|
|
28
29
|
|
|
29
30
|
# Authentication errors (401) or 400 with "API key not valid"
|
|
30
31
|
if e.code == 401 or (e.code == 400 and "API key not valid" in str(e)):
|