mirascope 2.0.0a6__py3-none-any.whl → 2.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. mirascope/_utils.py +34 -0
  2. mirascope/api/_generated/__init__.py +186 -5
  3. mirascope/api/_generated/annotations/client.py +38 -6
  4. mirascope/api/_generated/annotations/raw_client.py +366 -47
  5. mirascope/api/_generated/annotations/types/annotations_create_response.py +19 -6
  6. mirascope/api/_generated/annotations/types/annotations_get_response.py +19 -6
  7. mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item.py +22 -7
  8. mirascope/api/_generated/annotations/types/annotations_update_response.py +19 -6
  9. mirascope/api/_generated/api_keys/__init__.py +12 -2
  10. mirascope/api/_generated/api_keys/client.py +107 -6
  11. mirascope/api/_generated/api_keys/raw_client.py +486 -38
  12. mirascope/api/_generated/api_keys/types/__init__.py +7 -1
  13. mirascope/api/_generated/api_keys/types/api_keys_list_all_for_org_response_item.py +40 -0
  14. mirascope/api/_generated/client.py +36 -0
  15. mirascope/api/_generated/docs/raw_client.py +71 -9
  16. mirascope/api/_generated/environment.py +3 -3
  17. mirascope/api/_generated/environments/__init__.py +6 -0
  18. mirascope/api/_generated/environments/client.py +158 -9
  19. mirascope/api/_generated/environments/raw_client.py +620 -52
  20. mirascope/api/_generated/environments/types/__init__.py +10 -0
  21. mirascope/api/_generated/environments/types/environments_get_analytics_response.py +60 -0
  22. mirascope/api/_generated/environments/types/environments_get_analytics_response_top_functions_item.py +24 -0
  23. mirascope/api/_generated/{organizations/types/organizations_credits_response.py → environments/types/environments_get_analytics_response_top_models_item.py} +6 -3
  24. mirascope/api/_generated/errors/__init__.py +6 -0
  25. mirascope/api/_generated/errors/bad_request_error.py +5 -2
  26. mirascope/api/_generated/errors/conflict_error.py +5 -2
  27. mirascope/api/_generated/errors/payment_required_error.py +15 -0
  28. mirascope/api/_generated/errors/service_unavailable_error.py +14 -0
  29. mirascope/api/_generated/errors/too_many_requests_error.py +15 -0
  30. mirascope/api/_generated/functions/__init__.py +10 -0
  31. mirascope/api/_generated/functions/client.py +222 -8
  32. mirascope/api/_generated/functions/raw_client.py +975 -134
  33. mirascope/api/_generated/functions/types/__init__.py +28 -4
  34. mirascope/api/_generated/functions/types/functions_get_by_env_response.py +53 -0
  35. mirascope/api/_generated/functions/types/functions_get_by_env_response_dependencies_value.py +22 -0
  36. mirascope/api/_generated/functions/types/functions_list_by_env_response.py +25 -0
  37. mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item.py +56 -0
  38. mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item_dependencies_value.py +22 -0
  39. mirascope/api/_generated/health/raw_client.py +74 -10
  40. mirascope/api/_generated/organization_invitations/__init__.py +33 -0
  41. mirascope/api/_generated/organization_invitations/client.py +546 -0
  42. mirascope/api/_generated/organization_invitations/raw_client.py +1519 -0
  43. mirascope/api/_generated/organization_invitations/types/__init__.py +53 -0
  44. mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response.py +34 -0
  45. mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response_role.py +7 -0
  46. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_request_role.py +7 -0
  47. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response.py +48 -0
  48. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_role.py +7 -0
  49. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_status.py +7 -0
  50. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response.py +48 -0
  51. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_role.py +7 -0
  52. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_status.py +7 -0
  53. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item.py +48 -0
  54. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_role.py +7 -0
  55. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_status.py +7 -0
  56. mirascope/api/_generated/organization_memberships/__init__.py +19 -0
  57. mirascope/api/_generated/organization_memberships/client.py +302 -0
  58. mirascope/api/_generated/organization_memberships/raw_client.py +736 -0
  59. mirascope/api/_generated/organization_memberships/types/__init__.py +27 -0
  60. mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item.py +33 -0
  61. mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item_role.py +7 -0
  62. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_request_role.py +7 -0
  63. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response.py +31 -0
  64. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response_role.py +7 -0
  65. mirascope/api/_generated/organizations/__init__.py +26 -2
  66. mirascope/api/_generated/organizations/client.py +442 -20
  67. mirascope/api/_generated/organizations/raw_client.py +1763 -164
  68. mirascope/api/_generated/organizations/types/__init__.py +48 -2
  69. mirascope/api/_generated/organizations/types/organizations_create_payment_intent_response.py +24 -0
  70. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_request_target_plan.py +7 -0
  71. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response.py +47 -0
  72. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item.py +33 -0
  73. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item_resource.py +7 -0
  74. mirascope/api/_generated/organizations/types/organizations_router_balance_response.py +24 -0
  75. mirascope/api/_generated/organizations/types/organizations_subscription_response.py +53 -0
  76. mirascope/api/_generated/organizations/types/organizations_subscription_response_current_plan.py +7 -0
  77. mirascope/api/_generated/organizations/types/organizations_subscription_response_payment_method.py +26 -0
  78. mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change.py +34 -0
  79. mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change_target_plan.py +7 -0
  80. mirascope/api/_generated/organizations/types/organizations_update_subscription_request_target_plan.py +7 -0
  81. mirascope/api/_generated/organizations/types/organizations_update_subscription_response.py +35 -0
  82. mirascope/api/_generated/project_memberships/__init__.py +25 -0
  83. mirascope/api/_generated/project_memberships/client.py +437 -0
  84. mirascope/api/_generated/project_memberships/raw_client.py +1039 -0
  85. mirascope/api/_generated/project_memberships/types/__init__.py +29 -0
  86. mirascope/api/_generated/project_memberships/types/project_memberships_create_request_role.py +7 -0
  87. mirascope/api/_generated/project_memberships/types/project_memberships_create_response.py +35 -0
  88. mirascope/api/_generated/project_memberships/types/project_memberships_create_response_role.py +7 -0
  89. mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item.py +33 -0
  90. mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item_role.py +7 -0
  91. mirascope/api/_generated/project_memberships/types/project_memberships_update_request_role.py +7 -0
  92. mirascope/api/_generated/project_memberships/types/project_memberships_update_response.py +35 -0
  93. mirascope/api/_generated/project_memberships/types/project_memberships_update_response_role.py +7 -0
  94. mirascope/api/_generated/projects/raw_client.py +415 -58
  95. mirascope/api/_generated/reference.md +2767 -397
  96. mirascope/api/_generated/tags/__init__.py +19 -0
  97. mirascope/api/_generated/tags/client.py +504 -0
  98. mirascope/api/_generated/tags/raw_client.py +1288 -0
  99. mirascope/api/_generated/tags/types/__init__.py +17 -0
  100. mirascope/api/_generated/tags/types/tags_create_response.py +41 -0
  101. mirascope/api/_generated/tags/types/tags_get_response.py +41 -0
  102. mirascope/api/_generated/tags/types/tags_list_response.py +23 -0
  103. mirascope/api/_generated/tags/types/tags_list_response_tags_item.py +41 -0
  104. mirascope/api/_generated/tags/types/tags_update_response.py +41 -0
  105. mirascope/api/_generated/token_cost/__init__.py +7 -0
  106. mirascope/api/_generated/token_cost/client.py +160 -0
  107. mirascope/api/_generated/token_cost/raw_client.py +264 -0
  108. mirascope/api/_generated/token_cost/types/__init__.py +8 -0
  109. mirascope/api/_generated/token_cost/types/token_cost_calculate_request_usage.py +54 -0
  110. mirascope/api/_generated/token_cost/types/token_cost_calculate_response.py +52 -0
  111. mirascope/api/_generated/traces/__init__.py +20 -0
  112. mirascope/api/_generated/traces/client.py +543 -0
  113. mirascope/api/_generated/traces/raw_client.py +1366 -96
  114. mirascope/api/_generated/traces/types/__init__.py +28 -0
  115. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response.py +6 -0
  116. mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response.py +33 -0
  117. mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response_spans_item.py +88 -0
  118. mirascope/api/_generated/traces/types/traces_get_trace_detail_response_spans_item.py +0 -2
  119. mirascope/api/_generated/traces/types/traces_list_by_function_hash_response.py +25 -0
  120. mirascope/api/_generated/traces/types/traces_list_by_function_hash_response_traces_item.py +44 -0
  121. mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item.py +26 -0
  122. mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item_operator.py +7 -0
  123. mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_by.py +7 -0
  124. mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_order.py +7 -0
  125. mirascope/api/_generated/traces/types/traces_search_by_env_response.py +26 -0
  126. mirascope/api/_generated/traces/types/traces_search_by_env_response_spans_item.py +50 -0
  127. mirascope/api/_generated/traces/types/traces_search_response_spans_item.py +10 -1
  128. mirascope/api/_generated/types/__init__.py +32 -2
  129. mirascope/api/_generated/types/bad_request_error_body.py +50 -0
  130. mirascope/api/_generated/types/date.py +3 -0
  131. mirascope/api/_generated/types/immutable_resource_error.py +22 -0
  132. mirascope/api/_generated/types/internal_server_error_body.py +3 -3
  133. mirascope/api/_generated/types/plan_limit_exceeded_error.py +32 -0
  134. mirascope/api/_generated/types/plan_limit_exceeded_error_tag.py +7 -0
  135. mirascope/api/_generated/types/pricing_unavailable_error.py +23 -0
  136. mirascope/api/_generated/types/rate_limit_error.py +31 -0
  137. mirascope/api/_generated/types/rate_limit_error_tag.py +5 -0
  138. mirascope/api/_generated/types/service_unavailable_error_body.py +24 -0
  139. mirascope/api/_generated/types/service_unavailable_error_tag.py +7 -0
  140. mirascope/api/_generated/types/subscription_past_due_error.py +31 -0
  141. mirascope/api/_generated/types/subscription_past_due_error_tag.py +7 -0
  142. mirascope/api/settings.py +19 -1
  143. mirascope/llm/__init__.py +53 -10
  144. mirascope/llm/calls/__init__.py +2 -1
  145. mirascope/llm/calls/calls.py +29 -20
  146. mirascope/llm/calls/decorator.py +21 -7
  147. mirascope/llm/content/tool_output.py +22 -5
  148. mirascope/llm/exceptions.py +284 -71
  149. mirascope/llm/formatting/__init__.py +17 -0
  150. mirascope/llm/formatting/format.py +112 -35
  151. mirascope/llm/formatting/output_parser.py +178 -0
  152. mirascope/llm/formatting/partial.py +80 -7
  153. mirascope/llm/formatting/primitives.py +192 -0
  154. mirascope/llm/formatting/types.py +20 -8
  155. mirascope/llm/messages/__init__.py +3 -0
  156. mirascope/llm/messages/_utils.py +34 -0
  157. mirascope/llm/models/__init__.py +5 -0
  158. mirascope/llm/models/models.py +137 -69
  159. mirascope/llm/{providers/base → models}/params.py +7 -57
  160. mirascope/llm/models/thinking_config.py +61 -0
  161. mirascope/llm/prompts/_utils.py +0 -32
  162. mirascope/llm/prompts/decorator.py +16 -5
  163. mirascope/llm/prompts/prompts.py +160 -92
  164. mirascope/llm/providers/__init__.py +1 -4
  165. mirascope/llm/providers/anthropic/_utils/__init__.py +2 -0
  166. mirascope/llm/providers/anthropic/_utils/beta_decode.py +18 -9
  167. mirascope/llm/providers/anthropic/_utils/beta_encode.py +62 -13
  168. mirascope/llm/providers/anthropic/_utils/decode.py +18 -9
  169. mirascope/llm/providers/anthropic/_utils/encode.py +26 -7
  170. mirascope/llm/providers/anthropic/_utils/errors.py +2 -2
  171. mirascope/llm/providers/anthropic/beta_provider.py +64 -18
  172. mirascope/llm/providers/anthropic/provider.py +91 -33
  173. mirascope/llm/providers/base/__init__.py +0 -4
  174. mirascope/llm/providers/base/_utils.py +55 -6
  175. mirascope/llm/providers/base/base_provider.py +116 -37
  176. mirascope/llm/providers/google/_utils/__init__.py +2 -0
  177. mirascope/llm/providers/google/_utils/decode.py +20 -7
  178. mirascope/llm/providers/google/_utils/encode.py +26 -7
  179. mirascope/llm/providers/google/_utils/errors.py +3 -2
  180. mirascope/llm/providers/google/provider.py +64 -18
  181. mirascope/llm/providers/mirascope/_utils.py +13 -17
  182. mirascope/llm/providers/mirascope/provider.py +49 -18
  183. mirascope/llm/providers/mlx/_utils.py +7 -2
  184. mirascope/llm/providers/mlx/encoding/base.py +5 -2
  185. mirascope/llm/providers/mlx/encoding/transformers.py +5 -2
  186. mirascope/llm/providers/mlx/mlx.py +23 -6
  187. mirascope/llm/providers/mlx/provider.py +42 -13
  188. mirascope/llm/providers/openai/_utils/errors.py +2 -2
  189. mirascope/llm/providers/openai/completions/_utils/encode.py +20 -16
  190. mirascope/llm/providers/openai/completions/base_provider.py +40 -11
  191. mirascope/llm/providers/openai/provider.py +40 -10
  192. mirascope/llm/providers/openai/responses/_utils/__init__.py +2 -0
  193. mirascope/llm/providers/openai/responses/_utils/decode.py +19 -6
  194. mirascope/llm/providers/openai/responses/_utils/encode.py +22 -10
  195. mirascope/llm/providers/openai/responses/provider.py +56 -18
  196. mirascope/llm/providers/provider_registry.py +93 -19
  197. mirascope/llm/responses/__init__.py +6 -1
  198. mirascope/llm/responses/_utils.py +102 -12
  199. mirascope/llm/responses/base_response.py +5 -2
  200. mirascope/llm/responses/base_stream_response.py +115 -25
  201. mirascope/llm/responses/response.py +2 -1
  202. mirascope/llm/responses/root_response.py +89 -17
  203. mirascope/llm/responses/stream_response.py +6 -9
  204. mirascope/llm/tools/decorator.py +9 -4
  205. mirascope/llm/tools/tool_schema.py +17 -6
  206. mirascope/llm/tools/toolkit.py +35 -27
  207. mirascope/llm/tools/tools.py +45 -20
  208. mirascope/ops/__init__.py +4 -0
  209. mirascope/ops/_internal/closure.py +4 -1
  210. mirascope/ops/_internal/configuration.py +82 -31
  211. mirascope/ops/_internal/exporters/exporters.py +55 -35
  212. mirascope/ops/_internal/exporters/utils.py +37 -0
  213. mirascope/ops/_internal/instrumentation/llm/common.py +530 -0
  214. mirascope/ops/_internal/instrumentation/llm/cost.py +190 -0
  215. mirascope/ops/_internal/instrumentation/llm/encode.py +1 -1
  216. mirascope/ops/_internal/instrumentation/llm/llm.py +116 -1242
  217. mirascope/ops/_internal/instrumentation/llm/model.py +1798 -0
  218. mirascope/ops/_internal/instrumentation/llm/response.py +521 -0
  219. mirascope/ops/_internal/instrumentation/llm/serialize.py +300 -0
  220. mirascope/ops/_internal/protocols.py +83 -1
  221. mirascope/ops/_internal/traced_calls.py +18 -0
  222. mirascope/ops/_internal/traced_functions.py +125 -10
  223. mirascope/ops/_internal/tracing.py +78 -1
  224. mirascope/ops/_internal/utils.py +60 -4
  225. mirascope/ops/_internal/versioned_functions.py +1 -1
  226. {mirascope-2.0.0a6.dist-info → mirascope-2.0.2.dist-info}/METADATA +12 -11
  227. mirascope-2.0.2.dist-info/RECORD +424 -0
  228. {mirascope-2.0.0a6.dist-info → mirascope-2.0.2.dist-info}/licenses/LICENSE +1 -1
  229. mirascope-2.0.0a6.dist-info/RECORD +0 -316
  230. {mirascope-2.0.0a6.dist-info → mirascope-2.0.2.dist-info}/WHEEL +0 -0
@@ -0,0 +1,23 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class PricingUnavailableError(UniversalBaseModel):
10
+ message: str
11
+ provider: typing.Optional[str] = None
12
+ model: typing.Optional[str] = None
13
+
14
+ if IS_PYDANTIC_V2:
15
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(
16
+ extra="allow", frozen=True
17
+ ) # type: ignore # Pydantic v2
18
+ else:
19
+
20
+ class Config:
21
+ frozen = True
22
+ smart_union = True
23
+ extra = pydantic.Extra.allow
@@ -0,0 +1,31 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ import typing_extensions
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+ from ..core.serialization import FieldMetadata
9
+ from .rate_limit_error_tag import RateLimitErrorTag
10
+
11
+
12
+ class RateLimitError(UniversalBaseModel):
13
+ message: str
14
+ organization_id: typing_extensions.Annotated[
15
+ str, FieldMetadata(alias="organizationId")
16
+ ]
17
+ limit: float
18
+ retry_after: typing_extensions.Annotated[float, FieldMetadata(alias="retryAfter")]
19
+ plan_tier: typing_extensions.Annotated[str, FieldMetadata(alias="planTier")]
20
+ tag: RateLimitErrorTag
21
+
22
+ if IS_PYDANTIC_V2:
23
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(
24
+ extra="allow", frozen=True
25
+ ) # type: ignore # Pydantic v2
26
+ else:
27
+
28
+ class Config:
29
+ frozen = True
30
+ smart_union = True
31
+ extra = pydantic.Extra.allow
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ RateLimitErrorTag = typing.Union[typing.Literal["RateLimitError"], typing.Any]
@@ -0,0 +1,24 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+ from .service_unavailable_error_tag import ServiceUnavailableErrorTag
8
+
9
+
10
+ class ServiceUnavailableErrorBody(UniversalBaseModel):
11
+ message: str
12
+ service: typing.Optional[str] = None
13
+ tag: ServiceUnavailableErrorTag
14
+
15
+ if IS_PYDANTIC_V2:
16
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(
17
+ extra="allow", frozen=True
18
+ ) # type: ignore # Pydantic v2
19
+ else:
20
+
21
+ class Config:
22
+ frozen = True
23
+ smart_union = True
24
+ extra = pydantic.Extra.allow
@@ -0,0 +1,7 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ ServiceUnavailableErrorTag = typing.Union[
6
+ typing.Literal["ServiceUnavailableError"], typing.Any
7
+ ]
@@ -0,0 +1,31 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ import typing_extensions
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+ from ..core.serialization import FieldMetadata
9
+ from .subscription_past_due_error_tag import SubscriptionPastDueErrorTag
10
+
11
+
12
+ class SubscriptionPastDueError(UniversalBaseModel):
13
+ message: str
14
+ stripe_customer_id: typing_extensions.Annotated[
15
+ str, FieldMetadata(alias="stripeCustomerId")
16
+ ]
17
+ past_due_subscription_ids: typing_extensions.Annotated[
18
+ typing.List[str], FieldMetadata(alias="pastDueSubscriptionIds")
19
+ ]
20
+ tag: SubscriptionPastDueErrorTag
21
+
22
+ if IS_PYDANTIC_V2:
23
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(
24
+ extra="allow", frozen=True
25
+ ) # type: ignore # Pydantic v2
26
+ else:
27
+
28
+ class Config:
29
+ frozen = True
30
+ smart_union = True
31
+ extra = pydantic.Extra.allow
@@ -0,0 +1,7 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ SubscriptionPastDueErrorTag = typing.Union[
6
+ typing.Literal["SubscriptionPastDueError"], typing.Any
7
+ ]
mirascope/api/settings.py CHANGED
@@ -15,7 +15,7 @@ from pydantic_settings import BaseSettings, SettingsConfigDict
15
15
  class Settings(BaseSettings):
16
16
  """Global settings for Mirascope SDK."""
17
17
 
18
- base_url: str = Field(default="https://v2.mirascope.com")
18
+ base_url: str = Field(default="https://mirascope.com/api/v2")
19
19
  api_key: str | None = None
20
20
 
21
21
  def update(self, **kwargs: Any) -> None: # noqa: ANN401
@@ -46,6 +46,24 @@ def get_settings() -> Settings:
46
46
  return settings
47
47
 
48
48
 
49
+ def update_settings(
50
+ *,
51
+ api_key: str | None = None,
52
+ base_url: str | None = None,
53
+ ) -> None:
54
+ """Update the current settings with provided values.
55
+
56
+ This allows programmatic configuration of settings (e.g., from ops.configure)
57
+ that will be used by get_sync_client() and get_async_client().
58
+
59
+ Args:
60
+ api_key: API key to set (if provided)
61
+ base_url: Base URL to set (if provided)
62
+ """
63
+ current = get_settings()
64
+ current.update(api_key=api_key, base_url=base_url)
65
+
66
+
49
67
  @contextmanager
50
68
  def settings(
51
69
  base_url: str | None = None,
mirascope/llm/__init__.py CHANGED
@@ -51,24 +51,37 @@ from .content import (
51
51
  URLImageSource,
52
52
  UserContentPart,
53
53
  )
54
- from .context import Context
54
+ from .context import Context, DepsT
55
55
  from .exceptions import (
56
56
  APIError,
57
57
  AuthenticationError,
58
58
  BadRequestError,
59
59
  ConnectionError,
60
+ Error,
60
61
  FeatureNotSupportedError,
61
- FormattingModeNotSupportedError,
62
- MirascopeLLMError,
62
+ MissingAPIKeyError,
63
63
  NoRegisteredProviderError,
64
64
  NotFoundError,
65
+ ParseError,
65
66
  PermissionError,
67
+ ProviderError,
66
68
  RateLimitError,
69
+ ResponseValidationError,
67
70
  ServerError,
68
71
  TimeoutError,
72
+ ToolError,
73
+ ToolExecutionError,
69
74
  ToolNotFoundError,
70
75
  )
71
- from .formatting import Format, FormattingMode, Partial, format
76
+ from .formatting import (
77
+ Format,
78
+ FormattableT,
79
+ FormattingMode,
80
+ OutputParser,
81
+ Partial,
82
+ format,
83
+ output_parser,
84
+ )
72
85
  from .messages import (
73
86
  AssistantContent,
74
87
  AssistantMessage,
@@ -78,7 +91,15 @@ from .messages import (
78
91
  UserContent,
79
92
  UserMessage,
80
93
  )
81
- from .models import Model, model, model_from_context, use_model
94
+ from .models import (
95
+ Model,
96
+ Params,
97
+ ThinkingConfig,
98
+ ThinkingLevel,
99
+ model,
100
+ model_from_context,
101
+ use_model,
102
+ )
82
103
  from .prompts import (
83
104
  AsyncContextPrompt,
84
105
  AsyncPrompt,
@@ -89,15 +110,13 @@ from .prompts import (
89
110
  )
90
111
  from .providers import (
91
112
  ModelId,
92
- Params,
93
113
  Provider,
94
114
  ProviderId,
95
- ThinkingConfig,
96
- ThinkingLevel,
97
115
  register_provider,
98
116
  reset_provider_registry,
99
117
  )
100
118
  from .responses import (
119
+ AnyResponse,
101
120
  AsyncChunkIterator,
102
121
  AsyncContextResponse,
103
122
  AsyncContextStreamResponse,
@@ -113,6 +132,7 @@ from .responses import (
113
132
  FinishReason,
114
133
  RawMessageChunk,
115
134
  Response,
135
+ RootResponse,
116
136
  Stream,
117
137
  StreamResponse,
118
138
  StreamResponseChunk,
@@ -123,19 +143,28 @@ from .responses import (
123
143
  UsageDeltaChunk,
124
144
  )
125
145
  from .tools import (
146
+ AnyToolFn,
147
+ AnyToolSchema,
126
148
  AsyncContextTool,
127
149
  AsyncContextToolkit,
128
150
  AsyncTool,
129
151
  AsyncToolkit,
152
+ BaseToolkit,
130
153
  ContextTool,
131
154
  ContextToolkit,
132
155
  Tool,
133
156
  Toolkit,
157
+ ToolkitT,
158
+ ToolSchema,
134
159
  tool,
135
160
  )
161
+ from .types import Jsonable
136
162
 
137
163
  __all__ = [
138
164
  "APIError",
165
+ "AnyResponse",
166
+ "AnyToolFn",
167
+ "AnyToolSchema",
139
168
  "AssistantContent",
140
169
  "AssistantContentChunk",
141
170
  "AssistantContentPart",
@@ -162,6 +191,7 @@ __all__ = [
162
191
  "BadRequestError",
163
192
  "Base64AudioSource",
164
193
  "Base64ImageSource",
194
+ "BaseToolkit",
165
195
  "Call",
166
196
  "CallDecorator",
167
197
  "ChunkIterator",
@@ -173,29 +203,37 @@ __all__ = [
173
203
  "ContextStreamResponse",
174
204
  "ContextTool",
175
205
  "ContextToolkit",
206
+ "DepsT",
176
207
  "Document",
208
+ "Error",
177
209
  "FeatureNotSupportedError",
178
210
  "FinishReason",
179
211
  "Format",
212
+ "FormattableT",
180
213
  "FormattingMode",
181
- "FormattingModeNotSupportedError",
182
214
  "Image",
215
+ "Jsonable",
183
216
  "Message",
184
- "MirascopeLLMError",
217
+ "MissingAPIKeyError",
185
218
  "Model",
186
219
  "ModelId",
187
220
  "NoRegisteredProviderError",
188
221
  "NotFoundError",
222
+ "OutputParser",
189
223
  "Params",
224
+ "ParseError",
190
225
  "Partial",
191
226
  "PermissionError",
192
227
  "Prompt",
193
228
  "PromptDecorator",
194
229
  "Provider",
230
+ "ProviderError",
195
231
  "ProviderId",
196
232
  "RateLimitError",
197
233
  "RawMessageChunk",
198
234
  "Response",
235
+ "ResponseValidationError",
236
+ "RootResponse",
199
237
  "ServerError",
200
238
  "Stream",
201
239
  "StreamResponse",
@@ -221,9 +259,13 @@ __all__ = [
221
259
  "ToolCallEndChunk",
222
260
  "ToolCallStartChunk",
223
261
  "ToolCallStream",
262
+ "ToolError",
263
+ "ToolExecutionError",
224
264
  "ToolNotFoundError",
225
265
  "ToolOutput",
266
+ "ToolSchema",
226
267
  "Toolkit",
268
+ "ToolkitT",
227
269
  "URLImageSource",
228
270
  "Usage",
229
271
  "UsageDeltaChunk",
@@ -241,6 +283,7 @@ __all__ = [
241
283
  "model",
242
284
  "model_from_context",
243
285
  "models",
286
+ "output_parser",
244
287
  "prompt",
245
288
  "prompts",
246
289
  "providers",
@@ -1,6 +1,6 @@
1
1
  """The `llm.calls` module."""
2
2
 
3
- from .calls import AsyncCall, AsyncContextCall, Call, ContextCall
3
+ from .calls import AsyncCall, AsyncContextCall, Call, CallT, ContextCall
4
4
  from .decorator import (
5
5
  CallDecorator,
6
6
  call,
@@ -11,6 +11,7 @@ __all__ = [
11
11
  "AsyncContextCall",
12
12
  "Call",
13
13
  "CallDecorator",
14
+ "CallT",
14
15
  "ContextCall",
15
16
  "call",
16
17
  ]
@@ -1,8 +1,10 @@
1
1
  """The Call module for generating responses using LLMs."""
2
2
 
3
- from dataclasses import dataclass
4
- from typing import Generic, overload
3
+ from collections.abc import Callable
4
+ from dataclasses import dataclass, field
5
+ from typing import Any, Generic, TypeVar, overload
5
6
 
7
+ from ..._utils import copy_function_metadata
6
8
  from ..context import Context, DepsT
7
9
  from ..formatting import FormattableT
8
10
  from ..models import Model, use_model
@@ -12,6 +14,7 @@ from ..prompts import (
12
14
  ContextPrompt,
13
15
  Prompt,
14
16
  )
17
+ from ..prompts.prompts import BasePrompt
15
18
  from ..responses import (
16
19
  AsyncContextResponse,
17
20
  AsyncContextStreamResponse,
@@ -24,22 +27,35 @@ from ..responses import (
24
27
  )
25
28
  from ..types import P
26
29
 
30
+ PromptT = TypeVar("PromptT", bound=BasePrompt[Callable[..., Any]])
31
+ CallT = TypeVar("CallT", bound="BaseCall[Any]")
27
32
 
28
- @dataclass
29
- class BaseCall:
33
+
34
+ @dataclass(kw_only=True)
35
+ class BaseCall(Generic[PromptT]):
30
36
  """Base class for all Call types with shared model functionality."""
31
37
 
32
38
  default_model: Model
33
39
  """The default model that will be used if no model is set in context."""
34
40
 
41
+ prompt: PromptT
42
+ """The underlying Prompt instance that generates messages with tools and format."""
43
+
44
+ __name__: str = field(init=False, repr=False, default="")
45
+ """The name of the underlying function (preserved for decorator stacking)."""
46
+
35
47
  @property
36
48
  def model(self) -> Model:
37
49
  """The model used for generating responses. May be overwritten via `with llm.model(...)`."""
38
50
  return use_model(self.default_model)
39
51
 
52
+ def __post_init__(self) -> None:
53
+ """Preserve standard function attributes for decorator stacking."""
54
+ copy_function_metadata(self, self.prompt.fn)
55
+
40
56
 
41
57
  @dataclass
42
- class Call(BaseCall, Generic[P, FormattableT]):
58
+ class Call(BaseCall[Prompt[P, FormattableT]], Generic[P, FormattableT]):
43
59
  """A call that directly generates LLM responses without requiring a model argument.
44
60
 
45
61
  Created by decorating a `MessageTemplate` with `llm.call`. The decorated function
@@ -51,9 +67,6 @@ class Call(BaseCall, Generic[P, FormattableT]):
51
67
  The model can be overridden at runtime using `with llm.model(...)` context manager.
52
68
  """
53
69
 
54
- prompt: Prompt[P, FormattableT]
55
- """The underlying Prompt instance that generates messages with tools and format."""
56
-
57
70
  @overload
58
71
  def __call__(
59
72
  self: "Call[P, None]", *args: P.args, **kwargs: P.kwargs
@@ -102,7 +115,7 @@ class Call(BaseCall, Generic[P, FormattableT]):
102
115
 
103
116
 
104
117
  @dataclass
105
- class AsyncCall(BaseCall, Generic[P, FormattableT]):
118
+ class AsyncCall(BaseCall[AsyncPrompt[P, FormattableT]], Generic[P, FormattableT]):
106
119
  """An async call that directly generates LLM responses without requiring a model argument.
107
120
 
108
121
  Created by decorating an async `MessageTemplate` with `llm.call`. The decorated async
@@ -114,9 +127,6 @@ class AsyncCall(BaseCall, Generic[P, FormattableT]):
114
127
  The model can be overridden at runtime using `with llm.model(...)` context manager.
115
128
  """
116
129
 
117
- prompt: AsyncPrompt[P, FormattableT]
118
- """The underlying AsyncPrompt instance that generates messages with tools and format."""
119
-
120
130
  @overload
121
131
  async def __call__(
122
132
  self: "AsyncCall[P, None]", *args: P.args, **kwargs: P.kwargs
@@ -167,7 +177,9 @@ class AsyncCall(BaseCall, Generic[P, FormattableT]):
167
177
 
168
178
 
169
179
  @dataclass
170
- class ContextCall(BaseCall, Generic[P, DepsT, FormattableT]):
180
+ class ContextCall(
181
+ BaseCall[ContextPrompt[P, DepsT, FormattableT]], Generic[P, DepsT, FormattableT]
182
+ ):
171
183
  """A context-aware call that directly generates LLM responses without requiring a model argument.
172
184
 
173
185
  Created by decorating a `ContextMessageTemplate` with `llm.call`. The decorated function
@@ -180,9 +192,6 @@ class ContextCall(BaseCall, Generic[P, DepsT, FormattableT]):
180
192
  The model can be overridden at runtime using `with llm.model(...)` context manager.
181
193
  """
182
194
 
183
- prompt: ContextPrompt[P, DepsT, FormattableT]
184
- """The underlying ContextPrompt instance that generates messages with tools and format."""
185
-
186
195
  @overload
187
196
  def __call__(
188
197
  self: "ContextCall[P, DepsT, None]",
@@ -253,7 +262,10 @@ class ContextCall(BaseCall, Generic[P, DepsT, FormattableT]):
253
262
 
254
263
 
255
264
  @dataclass
256
- class AsyncContextCall(BaseCall, Generic[P, DepsT, FormattableT]):
265
+ class AsyncContextCall(
266
+ BaseCall[AsyncContextPrompt[P, DepsT, FormattableT]],
267
+ Generic[P, DepsT, FormattableT],
268
+ ):
257
269
  """An async context-aware call that directly generates LLM responses without requiring a model argument.
258
270
 
259
271
  Created by decorating an async `ContextMessageTemplate` with `llm.call`. The decorated async
@@ -266,9 +278,6 @@ class AsyncContextCall(BaseCall, Generic[P, DepsT, FormattableT]):
266
278
  The model can be overridden at runtime using `with llm.model(...)` context manager.
267
279
  """
268
280
 
269
- prompt: AsyncContextPrompt[P, DepsT, FormattableT]
270
- """The underlying AsyncContextPrompt instance that generates messages with tools and format."""
271
-
272
281
  @overload
273
282
  async def __call__(
274
283
  self: "AsyncContextCall[P, DepsT, None]",
@@ -4,11 +4,11 @@ from __future__ import annotations
4
4
 
5
5
  from collections.abc import Sequence
6
6
  from dataclasses import dataclass
7
- from typing import Generic, cast, overload
7
+ from typing import TYPE_CHECKING, Generic, cast, overload
8
8
  from typing_extensions import Unpack
9
9
 
10
10
  from ..context import DepsT
11
- from ..formatting import Format, FormattableT
11
+ from ..formatting import Format, FormattableT, OutputParser
12
12
  from ..models import Model
13
13
  from ..prompts import (
14
14
  AsyncContextMessageTemplate,
@@ -21,7 +21,7 @@ from ..prompts import (
21
21
  Prompt,
22
22
  _utils,
23
23
  )
24
- from ..providers import ModelId, Params
24
+ from ..providers import ModelId
25
25
  from ..tools import (
26
26
  AsyncContextTool,
27
27
  AsyncContextToolkit,
@@ -36,6 +36,9 @@ from ..tools import (
36
36
  from ..types import P
37
37
  from .calls import AsyncCall, AsyncContextCall, Call, ContextCall
38
38
 
39
+ if TYPE_CHECKING:
40
+ from ..models import Params
41
+
39
42
 
40
43
  @dataclass(kw_only=True)
41
44
  class CallDecorator(Generic[ToolT, FormattableT]):
@@ -58,7 +61,9 @@ class CallDecorator(Generic[ToolT, FormattableT]):
58
61
  tools: Sequence[ToolT] | None
59
62
  """The tools that are included in the prompt, if any."""
60
63
 
61
- format: type[FormattableT] | Format[FormattableT] | None
64
+ format: (
65
+ type[FormattableT] | Format[FormattableT] | OutputParser[FormattableT] | None
66
+ )
62
67
  """The structured output format off the prompt, if any."""
63
68
 
64
69
  @overload
@@ -154,7 +159,10 @@ def call(
154
159
  model: ModelId,
155
160
  *,
156
161
  tools: Sequence[ToolT] | None = None,
157
- format: type[FormattableT] | Format[FormattableT] | None = None,
162
+ format: type[FormattableT]
163
+ | Format[FormattableT]
164
+ | OutputParser[FormattableT]
165
+ | None = None,
158
166
  **params: Unpack[Params],
159
167
  ) -> CallDecorator[ToolT, FormattableT]:
160
168
  """Decorator for converting prompt functions into LLM calls.
@@ -169,7 +177,10 @@ def call(
169
177
  model: Model,
170
178
  *,
171
179
  tools: Sequence[ToolT] | None = None,
172
- format: type[FormattableT] | Format[FormattableT] | None = None,
180
+ format: type[FormattableT]
181
+ | Format[FormattableT]
182
+ | OutputParser[FormattableT]
183
+ | None = None,
173
184
  ) -> CallDecorator[ToolT, FormattableT]:
174
185
  """Decorator for converting prompt functions into LLM calls.
175
186
 
@@ -182,7 +193,10 @@ def call(
182
193
  model: ModelId | Model,
183
194
  *,
184
195
  tools: Sequence[ToolT] | None = None,
185
- format: type[FormattableT] | Format[FormattableT] | None = None,
196
+ format: type[FormattableT]
197
+ | Format[FormattableT]
198
+ | OutputParser[FormattableT]
199
+ | None = None,
186
200
  **params: Unpack[Params],
187
201
  ) -> CallDecorator[ToolT, FormattableT]:
188
202
  """Decorates a `MessageTemplate` to create a `Call` that can be invoked directly.
@@ -1,13 +1,14 @@
1
1
  """The `ToolOutput` content class."""
2
2
 
3
3
  from dataclasses import dataclass
4
- from typing import Generic, Literal
4
+ from typing import Generic, Literal, cast
5
5
 
6
- from ..types import JsonableT
6
+ from ..exceptions import ToolError
7
+ from ..types import JsonableCovariantT
7
8
 
8
9
 
9
10
  @dataclass(kw_only=True)
10
- class ToolOutput(Generic[JsonableT]):
11
+ class ToolOutput(Generic[JsonableCovariantT]):
11
12
  """Tool output content for a message.
12
13
 
13
14
  Represents the output from a tool call. This is part of a user message's
@@ -22,5 +23,21 @@ class ToolOutput(Generic[JsonableT]):
22
23
  name: str
23
24
  """The name of the tool that created this output."""
24
25
 
25
- value: JsonableT
26
- """The output value from the tool call."""
26
+ result: JsonableCovariantT | str
27
+ """The result of calling the tool.
28
+
29
+ If the tool executed successfully, this will be the tool output.
30
+ If the tool errored, this will be the error message, as a string.
31
+
32
+ In either case, the result should be passed back to the LLM (so it can
33
+ either process the output, or re-try with awareness of the error.)
34
+ """
35
+
36
+ error: ToolError | None = None
37
+ """The error from calling the tool, if any."""
38
+
39
+ @property
40
+ def output(self) -> JsonableCovariantT:
41
+ if self.error is not None:
42
+ raise self.error
43
+ return cast(JsonableCovariantT, self.result)