mirascope 2.0.0a2__py3-none-any.whl → 2.0.0a4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (252) hide show
  1. mirascope/__init__.py +2 -2
  2. mirascope/api/__init__.py +6 -0
  3. mirascope/api/_generated/README.md +207 -0
  4. mirascope/api/_generated/__init__.py +141 -0
  5. mirascope/api/_generated/client.py +163 -0
  6. mirascope/api/_generated/core/__init__.py +52 -0
  7. mirascope/api/_generated/core/api_error.py +23 -0
  8. mirascope/api/_generated/core/client_wrapper.py +58 -0
  9. mirascope/api/_generated/core/datetime_utils.py +30 -0
  10. mirascope/api/_generated/core/file.py +70 -0
  11. mirascope/api/_generated/core/force_multipart.py +16 -0
  12. mirascope/api/_generated/core/http_client.py +619 -0
  13. mirascope/api/_generated/core/http_response.py +55 -0
  14. mirascope/api/_generated/core/jsonable_encoder.py +102 -0
  15. mirascope/api/_generated/core/pydantic_utilities.py +310 -0
  16. mirascope/api/_generated/core/query_encoder.py +60 -0
  17. mirascope/api/_generated/core/remove_none_from_dict.py +11 -0
  18. mirascope/api/_generated/core/request_options.py +35 -0
  19. mirascope/api/_generated/core/serialization.py +282 -0
  20. mirascope/api/_generated/docs/__init__.py +4 -0
  21. mirascope/api/_generated/docs/client.py +95 -0
  22. mirascope/api/_generated/docs/raw_client.py +132 -0
  23. mirascope/api/_generated/environment.py +9 -0
  24. mirascope/api/_generated/errors/__init__.py +17 -0
  25. mirascope/api/_generated/errors/bad_request_error.py +15 -0
  26. mirascope/api/_generated/errors/conflict_error.py +15 -0
  27. mirascope/api/_generated/errors/forbidden_error.py +15 -0
  28. mirascope/api/_generated/errors/internal_server_error.py +15 -0
  29. mirascope/api/_generated/errors/not_found_error.py +15 -0
  30. mirascope/api/_generated/health/__init__.py +7 -0
  31. mirascope/api/_generated/health/client.py +96 -0
  32. mirascope/api/_generated/health/raw_client.py +129 -0
  33. mirascope/api/_generated/health/types/__init__.py +8 -0
  34. mirascope/api/_generated/health/types/health_check_response.py +24 -0
  35. mirascope/api/_generated/health/types/health_check_response_status.py +5 -0
  36. mirascope/api/_generated/organizations/__init__.py +25 -0
  37. mirascope/api/_generated/organizations/client.py +380 -0
  38. mirascope/api/_generated/organizations/raw_client.py +876 -0
  39. mirascope/api/_generated/organizations/types/__init__.py +23 -0
  40. mirascope/api/_generated/organizations/types/organizations_create_response.py +24 -0
  41. mirascope/api/_generated/organizations/types/organizations_create_response_role.py +7 -0
  42. mirascope/api/_generated/organizations/types/organizations_get_response.py +24 -0
  43. mirascope/api/_generated/organizations/types/organizations_get_response_role.py +7 -0
  44. mirascope/api/_generated/organizations/types/organizations_list_response_item.py +24 -0
  45. mirascope/api/_generated/organizations/types/organizations_list_response_item_role.py +7 -0
  46. mirascope/api/_generated/organizations/types/organizations_update_response.py +24 -0
  47. mirascope/api/_generated/organizations/types/organizations_update_response_role.py +7 -0
  48. mirascope/api/_generated/projects/__init__.py +17 -0
  49. mirascope/api/_generated/projects/client.py +458 -0
  50. mirascope/api/_generated/projects/raw_client.py +1016 -0
  51. mirascope/api/_generated/projects/types/__init__.py +15 -0
  52. mirascope/api/_generated/projects/types/projects_create_response.py +30 -0
  53. mirascope/api/_generated/projects/types/projects_get_response.py +30 -0
  54. mirascope/api/_generated/projects/types/projects_list_response_item.py +30 -0
  55. mirascope/api/_generated/projects/types/projects_update_response.py +30 -0
  56. mirascope/api/_generated/reference.md +753 -0
  57. mirascope/api/_generated/traces/__init__.py +55 -0
  58. mirascope/api/_generated/traces/client.py +162 -0
  59. mirascope/api/_generated/traces/raw_client.py +168 -0
  60. mirascope/api/_generated/traces/types/__init__.py +95 -0
  61. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item.py +36 -0
  62. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource.py +31 -0
  63. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item.py +25 -0
  64. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value.py +54 -0
  65. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_array_value.py +23 -0
  66. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value.py +28 -0
  67. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value_values_item.py +24 -0
  68. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item.py +35 -0
  69. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope.py +35 -0
  70. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item.py +27 -0
  71. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value.py +54 -0
  72. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_array_value.py +23 -0
  73. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value.py +28 -0
  74. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value_values_item.py +24 -0
  75. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item.py +60 -0
  76. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item.py +29 -0
  77. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value.py +54 -0
  78. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_array_value.py +23 -0
  79. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value.py +28 -0
  80. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value_values_item.py +24 -0
  81. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_status.py +24 -0
  82. mirascope/api/_generated/traces/types/traces_create_response.py +27 -0
  83. mirascope/api/_generated/traces/types/traces_create_response_partial_success.py +28 -0
  84. mirascope/api/_generated/types/__init__.py +37 -0
  85. mirascope/api/_generated/types/already_exists_error.py +24 -0
  86. mirascope/api/_generated/types/already_exists_error_tag.py +5 -0
  87. mirascope/api/_generated/types/database_error.py +24 -0
  88. mirascope/api/_generated/types/database_error_tag.py +5 -0
  89. mirascope/api/_generated/types/http_api_decode_error.py +29 -0
  90. mirascope/api/_generated/types/http_api_decode_error_tag.py +5 -0
  91. mirascope/api/_generated/types/issue.py +40 -0
  92. mirascope/api/_generated/types/issue_tag.py +17 -0
  93. mirascope/api/_generated/types/not_found_error_body.py +24 -0
  94. mirascope/api/_generated/types/not_found_error_tag.py +5 -0
  95. mirascope/api/_generated/types/permission_denied_error.py +24 -0
  96. mirascope/api/_generated/types/permission_denied_error_tag.py +7 -0
  97. mirascope/api/_generated/types/property_key.py +7 -0
  98. mirascope/api/_generated/types/property_key_key.py +27 -0
  99. mirascope/api/_generated/types/property_key_key_tag.py +5 -0
  100. mirascope/api/client.py +255 -0
  101. mirascope/api/settings.py +81 -0
  102. mirascope/llm/__init__.py +45 -11
  103. mirascope/llm/calls/calls.py +81 -57
  104. mirascope/llm/calls/decorator.py +121 -115
  105. mirascope/llm/content/__init__.py +3 -2
  106. mirascope/llm/context/_utils.py +19 -6
  107. mirascope/llm/exceptions.py +30 -16
  108. mirascope/llm/formatting/_utils.py +9 -5
  109. mirascope/llm/formatting/format.py +2 -2
  110. mirascope/llm/formatting/from_call_args.py +2 -2
  111. mirascope/llm/messages/message.py +13 -5
  112. mirascope/llm/models/__init__.py +2 -2
  113. mirascope/llm/models/models.py +189 -81
  114. mirascope/llm/prompts/__init__.py +13 -12
  115. mirascope/llm/prompts/_utils.py +27 -24
  116. mirascope/llm/prompts/decorator.py +133 -204
  117. mirascope/llm/prompts/prompts.py +424 -0
  118. mirascope/llm/prompts/protocols.py +25 -59
  119. mirascope/llm/providers/__init__.py +44 -0
  120. mirascope/llm/{clients → providers}/_missing_import_stubs.py +8 -6
  121. mirascope/llm/providers/anthropic/__init__.py +29 -0
  122. mirascope/llm/providers/anthropic/_utils/__init__.py +23 -0
  123. mirascope/llm/providers/anthropic/_utils/beta_decode.py +271 -0
  124. mirascope/llm/providers/anthropic/_utils/beta_encode.py +216 -0
  125. mirascope/llm/{clients → providers}/anthropic/_utils/decode.py +44 -11
  126. mirascope/llm/providers/anthropic/_utils/encode.py +356 -0
  127. mirascope/llm/providers/anthropic/beta_provider.py +322 -0
  128. mirascope/llm/providers/anthropic/model_id.py +23 -0
  129. mirascope/llm/providers/anthropic/model_info.py +87 -0
  130. mirascope/llm/providers/anthropic/provider.py +416 -0
  131. mirascope/llm/{clients → providers}/base/__init__.py +3 -3
  132. mirascope/llm/{clients → providers}/base/_utils.py +25 -8
  133. mirascope/llm/{clients/base/client.py → providers/base/base_provider.py} +255 -126
  134. mirascope/llm/providers/google/__init__.py +21 -0
  135. mirascope/llm/{clients → providers}/google/_utils/decode.py +61 -7
  136. mirascope/llm/{clients → providers}/google/_utils/encode.py +44 -30
  137. mirascope/llm/providers/google/model_id.py +22 -0
  138. mirascope/llm/providers/google/model_info.py +62 -0
  139. mirascope/llm/providers/google/provider.py +442 -0
  140. mirascope/llm/providers/load_provider.py +54 -0
  141. mirascope/llm/providers/mlx/__init__.py +24 -0
  142. mirascope/llm/providers/mlx/_utils.py +129 -0
  143. mirascope/llm/providers/mlx/encoding/__init__.py +8 -0
  144. mirascope/llm/providers/mlx/encoding/base.py +69 -0
  145. mirascope/llm/providers/mlx/encoding/transformers.py +147 -0
  146. mirascope/llm/providers/mlx/mlx.py +237 -0
  147. mirascope/llm/providers/mlx/model_id.py +17 -0
  148. mirascope/llm/providers/mlx/provider.py +415 -0
  149. mirascope/llm/providers/model_id.py +16 -0
  150. mirascope/llm/providers/ollama/__init__.py +19 -0
  151. mirascope/llm/providers/ollama/provider.py +71 -0
  152. mirascope/llm/providers/openai/__init__.py +6 -0
  153. mirascope/llm/providers/openai/completions/__init__.py +25 -0
  154. mirascope/llm/{clients → providers}/openai/completions/_utils/__init__.py +2 -0
  155. mirascope/llm/{clients → providers}/openai/completions/_utils/decode.py +60 -6
  156. mirascope/llm/{clients → providers}/openai/completions/_utils/encode.py +37 -26
  157. mirascope/llm/providers/openai/completions/base_provider.py +513 -0
  158. mirascope/llm/providers/openai/completions/provider.py +22 -0
  159. mirascope/llm/providers/openai/model_id.py +31 -0
  160. mirascope/llm/providers/openai/model_info.py +303 -0
  161. mirascope/llm/providers/openai/provider.py +398 -0
  162. mirascope/llm/providers/openai/responses/__init__.py +21 -0
  163. mirascope/llm/{clients → providers}/openai/responses/_utils/decode.py +59 -6
  164. mirascope/llm/{clients → providers}/openai/responses/_utils/encode.py +34 -23
  165. mirascope/llm/providers/openai/responses/provider.py +469 -0
  166. mirascope/llm/providers/provider_id.py +23 -0
  167. mirascope/llm/providers/provider_registry.py +169 -0
  168. mirascope/llm/providers/together/__init__.py +19 -0
  169. mirascope/llm/providers/together/provider.py +40 -0
  170. mirascope/llm/responses/__init__.py +3 -0
  171. mirascope/llm/responses/base_response.py +14 -5
  172. mirascope/llm/responses/base_stream_response.py +35 -6
  173. mirascope/llm/responses/finish_reason.py +1 -0
  174. mirascope/llm/responses/response.py +33 -13
  175. mirascope/llm/responses/root_response.py +12 -13
  176. mirascope/llm/responses/stream_response.py +35 -23
  177. mirascope/llm/responses/usage.py +95 -0
  178. mirascope/llm/tools/__init__.py +9 -2
  179. mirascope/llm/tools/_utils.py +12 -3
  180. mirascope/llm/tools/protocols.py +4 -4
  181. mirascope/llm/tools/tool_schema.py +44 -9
  182. mirascope/llm/tools/tools.py +10 -9
  183. mirascope/ops/__init__.py +156 -0
  184. mirascope/ops/_internal/__init__.py +5 -0
  185. mirascope/ops/_internal/closure.py +1118 -0
  186. mirascope/ops/_internal/configuration.py +126 -0
  187. mirascope/ops/_internal/context.py +76 -0
  188. mirascope/ops/_internal/exporters/__init__.py +26 -0
  189. mirascope/ops/_internal/exporters/exporters.py +342 -0
  190. mirascope/ops/_internal/exporters/processors.py +104 -0
  191. mirascope/ops/_internal/exporters/types.py +165 -0
  192. mirascope/ops/_internal/exporters/utils.py +29 -0
  193. mirascope/ops/_internal/instrumentation/__init__.py +8 -0
  194. mirascope/ops/_internal/instrumentation/llm/__init__.py +8 -0
  195. mirascope/ops/_internal/instrumentation/llm/encode.py +238 -0
  196. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/__init__.py +38 -0
  197. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_input_messages.py +31 -0
  198. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_output_messages.py +38 -0
  199. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_system_instructions.py +18 -0
  200. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/shared.py +100 -0
  201. mirascope/ops/_internal/instrumentation/llm/llm.py +1288 -0
  202. mirascope/ops/_internal/propagation.py +198 -0
  203. mirascope/ops/_internal/protocols.py +51 -0
  204. mirascope/ops/_internal/session.py +139 -0
  205. mirascope/ops/_internal/spans.py +232 -0
  206. mirascope/ops/_internal/traced_calls.py +371 -0
  207. mirascope/ops/_internal/traced_functions.py +394 -0
  208. mirascope/ops/_internal/tracing.py +276 -0
  209. mirascope/ops/_internal/types.py +13 -0
  210. mirascope/ops/_internal/utils.py +75 -0
  211. mirascope/ops/_internal/versioned_calls.py +512 -0
  212. mirascope/ops/_internal/versioned_functions.py +346 -0
  213. mirascope/ops/_internal/versioning.py +303 -0
  214. mirascope/ops/exceptions.py +21 -0
  215. {mirascope-2.0.0a2.dist-info → mirascope-2.0.0a4.dist-info}/METADATA +78 -3
  216. mirascope-2.0.0a4.dist-info/RECORD +247 -0
  217. {mirascope-2.0.0a2.dist-info → mirascope-2.0.0a4.dist-info}/WHEEL +1 -1
  218. mirascope/graphs/__init__.py +0 -22
  219. mirascope/graphs/finite_state_machine.py +0 -625
  220. mirascope/llm/agents/__init__.py +0 -15
  221. mirascope/llm/agents/agent.py +0 -97
  222. mirascope/llm/agents/agent_template.py +0 -45
  223. mirascope/llm/agents/decorator.py +0 -176
  224. mirascope/llm/calls/base_call.py +0 -33
  225. mirascope/llm/clients/__init__.py +0 -34
  226. mirascope/llm/clients/anthropic/__init__.py +0 -25
  227. mirascope/llm/clients/anthropic/_utils/encode.py +0 -243
  228. mirascope/llm/clients/anthropic/clients.py +0 -819
  229. mirascope/llm/clients/anthropic/model_ids.py +0 -8
  230. mirascope/llm/clients/google/__init__.py +0 -20
  231. mirascope/llm/clients/google/clients.py +0 -853
  232. mirascope/llm/clients/google/model_ids.py +0 -15
  233. mirascope/llm/clients/openai/__init__.py +0 -25
  234. mirascope/llm/clients/openai/completions/__init__.py +0 -28
  235. mirascope/llm/clients/openai/completions/_utils/model_features.py +0 -81
  236. mirascope/llm/clients/openai/completions/clients.py +0 -833
  237. mirascope/llm/clients/openai/completions/model_ids.py +0 -8
  238. mirascope/llm/clients/openai/responses/__init__.py +0 -26
  239. mirascope/llm/clients/openai/responses/_utils/__init__.py +0 -13
  240. mirascope/llm/clients/openai/responses/_utils/model_features.py +0 -87
  241. mirascope/llm/clients/openai/responses/clients.py +0 -832
  242. mirascope/llm/clients/openai/responses/model_ids.py +0 -8
  243. mirascope/llm/clients/openai/shared/__init__.py +0 -7
  244. mirascope/llm/clients/openai/shared/_utils.py +0 -55
  245. mirascope/llm/clients/providers.py +0 -175
  246. mirascope-2.0.0a2.dist-info/RECORD +0 -102
  247. /mirascope/llm/{clients → providers}/base/kwargs.py +0 -0
  248. /mirascope/llm/{clients → providers}/base/params.py +0 -0
  249. /mirascope/llm/{clients/anthropic → providers/google}/_utils/__init__.py +0 -0
  250. /mirascope/llm/{clients → providers}/google/message.py +0 -0
  251. /mirascope/llm/{clients/google → providers/openai/responses}/_utils/__init__.py +0 -0
  252. {mirascope-2.0.0a2.dist-info → mirascope-2.0.0a4.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,29 @@
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 .http_api_decode_error_tag import HttpApiDecodeErrorTag
8
+ from .issue import Issue
9
+
10
+
11
+ class HttpApiDecodeError(UniversalBaseModel):
12
+ """
13
+ The request did not match the expected schema
14
+ """
15
+
16
+ issues: typing.List[Issue]
17
+ message: str
18
+ tag: HttpApiDecodeErrorTag
19
+
20
+ if IS_PYDANTIC_V2:
21
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(
22
+ extra="allow", frozen=True
23
+ ) # type: ignore # Pydantic v2
24
+ else:
25
+
26
+ class Config:
27
+ frozen = True
28
+ smart_union = True
29
+ 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
+ HttpApiDecodeErrorTag = typing.Union[typing.Literal["HttpApiDecodeError"], typing.Any]
@@ -0,0 +1,40 @@
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 .issue_tag import IssueTag
8
+ from .property_key import PropertyKey
9
+
10
+
11
+ class Issue(UniversalBaseModel):
12
+ """
13
+ Represents an error encountered while parsing a value to match the schema
14
+ """
15
+
16
+ tag: IssueTag = pydantic.Field()
17
+ """
18
+ The tag identifying the type of parse issue
19
+ """
20
+
21
+ path: typing.List[PropertyKey] = pydantic.Field()
22
+ """
23
+ The path to the property where the issue occurred
24
+ """
25
+
26
+ message: str = pydantic.Field()
27
+ """
28
+ A descriptive message explaining the issue
29
+ """
30
+
31
+ if IS_PYDANTIC_V2:
32
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(
33
+ extra="allow", frozen=True
34
+ ) # type: ignore # Pydantic v2
35
+ else:
36
+
37
+ class Config:
38
+ frozen = True
39
+ smart_union = True
40
+ extra = pydantic.Extra.allow
@@ -0,0 +1,17 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ IssueTag = typing.Union[
6
+ typing.Literal[
7
+ "Pointer",
8
+ "Unexpected",
9
+ "Missing",
10
+ "Composite",
11
+ "Refinement",
12
+ "Transformation",
13
+ "Type",
14
+ "Forbidden",
15
+ ],
16
+ typing.Any,
17
+ ]
@@ -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 .not_found_error_tag import NotFoundErrorTag
8
+
9
+
10
+ class NotFoundErrorBody(UniversalBaseModel):
11
+ message: str
12
+ resource: typing.Optional[str] = None
13
+ tag: NotFoundErrorTag
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,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ NotFoundErrorTag = typing.Union[typing.Literal["NotFoundError"], 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 .permission_denied_error_tag import PermissionDeniedErrorTag
8
+
9
+
10
+ class PermissionDeniedError(UniversalBaseModel):
11
+ message: str
12
+ resource: typing.Optional[str] = None
13
+ tag: PermissionDeniedErrorTag
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
+ PermissionDeniedErrorTag = typing.Union[
6
+ typing.Literal["PermissionDeniedError"], typing.Any
7
+ ]
@@ -0,0 +1,7 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ from .property_key_key import PropertyKeyKey
6
+
7
+ PropertyKey = typing.Union[str, float, PropertyKeyKey]
@@ -0,0 +1,27 @@
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 .property_key_key_tag import PropertyKeyKeyTag
8
+
9
+
10
+ class PropertyKeyKey(UniversalBaseModel):
11
+ """
12
+ an object to be decoded into a globally shared symbol
13
+ """
14
+
15
+ tag: PropertyKeyKeyTag
16
+ key: str
17
+
18
+ if IS_PYDANTIC_V2:
19
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(
20
+ extra="allow", frozen=True
21
+ ) # type: ignore # Pydantic v2
22
+ else:
23
+
24
+ class Config:
25
+ frozen = True
26
+ smart_union = True
27
+ 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
+ PropertyKeyKeyTag = typing.Union[typing.Literal["symbol"], typing.Any]
@@ -0,0 +1,255 @@
1
+ """Client interfaces and factory for Mirascope SDK.
2
+
3
+ This module provides interfaces and factory functions for creating Mirascope clients
4
+ that support both the Fern-generated API client and OpenTelemetry exporters.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import asyncio
10
+ import logging
11
+ import weakref
12
+ from collections.abc import Callable
13
+ from functools import lru_cache
14
+ from typing import ParamSpec, TypeAlias, TypeVar
15
+
16
+ import httpx
17
+
18
+ from ._generated.client import (
19
+ AsyncMirascope as _BaseAsyncMirascope,
20
+ Mirascope as _BaseMirascope,
21
+ )
22
+ from .settings import get_settings
23
+
24
+ ApiKey: TypeAlias = str
25
+ BaseUrl: TypeAlias = str
26
+ Token: TypeAlias = str | Callable[[], str] | None
27
+ _P = ParamSpec("_P")
28
+ _R = TypeVar("_R")
29
+
30
+ logger = logging.getLogger(__name__)
31
+
32
+
33
+ class Mirascope(_BaseMirascope):
34
+ """Enhanced Mirascope client with error handling.
35
+
36
+ This client automatically handles API errors and provides fallback behavior
37
+ for non-critical failures while preserving important exceptions like NotFoundError.
38
+ """
39
+
40
+ def __init__(
41
+ self,
42
+ *,
43
+ base_url: str | None = None,
44
+ api_key: str | None = None,
45
+ token: Token = None,
46
+ timeout: float | None = None,
47
+ follow_redirects: bool | None = True,
48
+ httpx_client: httpx.Client | None = None,
49
+ ) -> None:
50
+ """Initialize the enhanced Mirascope client."""
51
+ try:
52
+ settings = get_settings()
53
+ self.api_key = api_key or settings.api_key
54
+ if not self.api_key:
55
+ raise ValueError("`Mirascope` client requires `api_key`.")
56
+
57
+ self.base_url = base_url or settings.base_url
58
+
59
+ headers = {"Authorization": f"Bearer {self.api_key}"}
60
+ if httpx_client:
61
+ if hasattr(httpx_client, "headers"):
62
+ httpx_client.headers.update(headers)
63
+ else:
64
+ httpx_client = httpx.Client(
65
+ headers=headers,
66
+ timeout=timeout or 30.0,
67
+ follow_redirects=follow_redirects
68
+ if follow_redirects is not None
69
+ else True,
70
+ )
71
+
72
+ super().__init__(
73
+ base_url=self.base_url,
74
+ timeout=timeout,
75
+ follow_redirects=follow_redirects,
76
+ httpx_client=httpx_client,
77
+ )
78
+
79
+ except Exception as e:
80
+ logger.error("Failed to initialize Mirascope client: %s", e)
81
+ raise RuntimeError(f"Client initialization failed: {e}") from e
82
+
83
+ def close(self) -> None:
84
+ """Close the underlying synchronous HTTP client."""
85
+ wrapper_client = getattr(self._client_wrapper, "httpx_client", None)
86
+ underlying_httpx_client = getattr(wrapper_client, "httpx_client", None)
87
+ if underlying_httpx_client is not None:
88
+ underlying_httpx_client.close()
89
+
90
+
91
+ class AsyncMirascope(_BaseAsyncMirascope):
92
+ """Enhanced async Mirascope client with error handling.
93
+
94
+ This client automatically handles API errors and provides fallback behavior
95
+ for non-critical failures while preserving important exceptions like NotFoundError.
96
+ """
97
+
98
+ def __init__(
99
+ self,
100
+ *,
101
+ base_url: str | None = None,
102
+ api_key: str | None = None,
103
+ token: Token = None,
104
+ timeout: float | None = None,
105
+ follow_redirects: bool | None = True,
106
+ httpx_client: httpx.AsyncClient | None = None,
107
+ ) -> None:
108
+ """Initialize the enhanced async Mirascope client."""
109
+ try:
110
+ settings = get_settings()
111
+ self.api_key = api_key or settings.api_key
112
+ if not self.api_key:
113
+ raise ValueError("`AsyncMirascope` client requires `api_key`.")
114
+
115
+ self.base_url = base_url or settings.base_url
116
+
117
+ headers = {"Authorization": f"Bearer {self.api_key}"}
118
+ if httpx_client:
119
+ if hasattr(httpx_client, "headers"):
120
+ httpx_client.headers.update(headers)
121
+ else:
122
+ httpx_client = httpx.AsyncClient(
123
+ headers=headers,
124
+ timeout=timeout or 30.0,
125
+ follow_redirects=follow_redirects
126
+ if follow_redirects is not None
127
+ else True,
128
+ )
129
+
130
+ super().__init__(
131
+ base_url=self.base_url,
132
+ timeout=timeout,
133
+ follow_redirects=follow_redirects,
134
+ httpx_client=httpx_client,
135
+ )
136
+
137
+ except Exception as e:
138
+ logger.error("Failed to initialize AsyncMirascope client: %s", e)
139
+ raise RuntimeError(f"Async client initialization failed: {e}") from e
140
+
141
+ async def aclose(self) -> None:
142
+ """Close the underlying asynchronous HTTP client."""
143
+ wrapper_client = getattr(self._client_wrapper, "httpx_client", None)
144
+ underlying_httpx_client = getattr(wrapper_client, "httpx_client", None)
145
+ if underlying_httpx_client is not None:
146
+ await underlying_httpx_client.aclose()
147
+
148
+
149
+ @lru_cache(maxsize=256)
150
+ def _sync_singleton(api_key: str | None, base_url: str | None) -> Mirascope:
151
+ """Return the process-wide synchronous client, creating one if none yet exists"""
152
+ try:
153
+ logger.debug("Creating sync client with api_key=*****, base_url=%s", base_url)
154
+ return Mirascope(api_key=api_key, base_url=base_url)
155
+ except Exception as e:
156
+ logger.error("Failed to create singleton Mirascope client: %s", e)
157
+ raise RuntimeError(f"Failed to create cached client: {e}") from e
158
+
159
+
160
+ def get_sync_client(
161
+ api_key: str | None = None,
162
+ base_url: str | None = None,
163
+ ) -> Mirascope:
164
+ """Get or create a cached synchronous client.
165
+
166
+ Args:
167
+ api_key: API key for authentication
168
+ base_url: Base URL for the API
169
+
170
+ Returns:
171
+ Cached Mirascope client instance
172
+ """
173
+ settings = get_settings()
174
+
175
+ return _sync_singleton(
176
+ api_key or settings.api_key,
177
+ base_url or settings.base_url,
178
+ )
179
+
180
+
181
+ @lru_cache(maxsize=256)
182
+ def _async_singleton(
183
+ _loop_id_for_cache: int, api_key: str | None, base_url: str | None
184
+ ) -> AsyncMirascope:
185
+ """Return the loop-specific asynchronous client, creating one if none yet exists"""
186
+ try:
187
+ logger.debug("Creating async client with api_key=*****, base_url=%s", base_url)
188
+ loop = asyncio.get_running_loop()
189
+ client = AsyncMirascope(api_key=api_key, base_url=base_url)
190
+ weakref.finalize(loop, _async_singleton.cache_clear)
191
+ return client
192
+ except Exception as e:
193
+ logger.error("Failed to create singleton AsyncMirascope client: %s", e)
194
+ raise RuntimeError(f"Failed to create cached async client: {e}") from e
195
+
196
+
197
+ def get_async_client(
198
+ api_key: str | None = None,
199
+ base_url: str | None = None,
200
+ ) -> AsyncMirascope:
201
+ """Get or create a cached asynchronous client.
202
+
203
+ Args:
204
+ api_key: API key for authentication
205
+ base_url: Base URL for the API
206
+
207
+ Returns:
208
+ Cached AsyncMirascope client instance
209
+ """
210
+ try:
211
+ loop = asyncio.get_running_loop()
212
+ except RuntimeError as exc:
213
+ raise RuntimeError(
214
+ "get_async_client() must be called from within an active event loop."
215
+ ) from exc
216
+
217
+ settings = get_settings()
218
+
219
+ return _async_singleton(
220
+ id(loop),
221
+ api_key or settings.api_key,
222
+ base_url or settings.base_url,
223
+ )
224
+
225
+
226
+ def create_export_client(
227
+ *,
228
+ base_url: str | None = None,
229
+ api_key: str | None = None,
230
+ timeout: float = 30.0,
231
+ httpx_client: httpx.Client | None = None,
232
+ ) -> Mirascope:
233
+ """Create a client suitable for OpenTelemetry export.
234
+
235
+ Args:
236
+ base_url: Base URL for the API
237
+ api_key: API key for authentication
238
+ timeout: Request timeout in seconds
239
+ httpx_client: Optional custom httpx client
240
+
241
+ Returns:
242
+ Mirascope client configured for export use
243
+ """
244
+ return Mirascope(
245
+ base_url=base_url,
246
+ api_key=api_key,
247
+ timeout=timeout,
248
+ httpx_client=httpx_client,
249
+ )
250
+
251
+
252
+ def close_cached_clients() -> None:
253
+ """Close all cached client instances."""
254
+ _sync_singleton.cache_clear()
255
+ _async_singleton.cache_clear()
@@ -0,0 +1,81 @@
1
+ """Settings and configuration for Mirascope SDK."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Iterator
6
+ from contextlib import contextmanager
7
+ from contextvars import ContextVar
8
+ from functools import cache
9
+ from typing import Any
10
+
11
+ from pydantic import Field
12
+ from pydantic_settings import BaseSettings, SettingsConfigDict
13
+
14
+
15
+ class Settings(BaseSettings):
16
+ """Global settings for Mirascope SDK."""
17
+
18
+ base_url: str = Field(default="https://v2.mirascope.com")
19
+ api_key: str | None = None
20
+
21
+ def update(self, **kwargs: Any) -> None: # noqa: ANN401
22
+ """Update non-None fields in place."""
23
+ for k, v in kwargs.items():
24
+ if v is not None and hasattr(self, k):
25
+ setattr(self, k, v)
26
+
27
+ model_config = SettingsConfigDict(env_prefix="MIRASCOPE_")
28
+
29
+
30
+ @cache
31
+ def _default_settings() -> Settings:
32
+ return Settings()
33
+
34
+
35
+ CURRENT_SETTINGS: ContextVar[Settings | None] = ContextVar(
36
+ "CURRENT_SETTINGS", default=None
37
+ )
38
+
39
+
40
+ def get_settings() -> Settings:
41
+ """Return Settings for the current context."""
42
+ settings = CURRENT_SETTINGS.get()
43
+ if settings is None:
44
+ settings = _default_settings()
45
+ CURRENT_SETTINGS.set(settings)
46
+ return settings
47
+
48
+
49
+ @contextmanager
50
+ def settings(
51
+ base_url: str | None = None,
52
+ api_key: str | None = None,
53
+ ) -> Iterator[Settings]:
54
+ """Context manager for temporarily overriding settings.
55
+
56
+ Args:
57
+ base_url: Override the base URL for API calls
58
+ api_key: Override the API key
59
+
60
+ Yields:
61
+ Settings instance with overrides applied
62
+
63
+ Example:
64
+ with settings(base_url="https://api.example.com", api_key="test-key"):
65
+ # Use custom settings within this context
66
+ client = MirascopeClient()
67
+ """
68
+ current = CURRENT_SETTINGS.get()
69
+ if current is None:
70
+ current = _default_settings()
71
+
72
+ new_settings = Settings(
73
+ base_url=base_url or current.base_url,
74
+ api_key=api_key or current.api_key,
75
+ )
76
+
77
+ token = CURRENT_SETTINGS.set(new_settings)
78
+ try:
79
+ yield new_settings
80
+ finally:
81
+ CURRENT_SETTINGS.reset(token)
mirascope/llm/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- """The `llm` module for writing provider-agnostic LLM Generations.
1
+ """LLM abstractions that aren't obstructions.
2
2
 
3
3
  This module provides a unified interface for interacting with different LLM providers,
4
4
  including messages, tools, response formatting, and streaming. It allows you to write
@@ -12,13 +12,13 @@ from contextlib import suppress
12
12
 
13
13
  from . import (
14
14
  calls,
15
- clients,
16
15
  content,
17
16
  exceptions,
18
17
  formatting,
19
18
  messages,
20
19
  models,
21
20
  prompts,
21
+ providers,
22
22
  responses,
23
23
  tools,
24
24
  types,
@@ -26,8 +26,7 @@ from . import (
26
26
 
27
27
  with suppress(ImportError):
28
28
  from . import mcp
29
- from .calls import call
30
- from .clients import ModelId, Params, Provider, client, get_client
29
+ from .calls import AsyncCall, AsyncContextCall, Call, CallDecorator, ContextCall, call
31
30
  from .content import (
32
31
  AssistantContentChunk,
33
32
  AssistantContentPart,
@@ -60,7 +59,8 @@ from .exceptions import (
60
59
  ConnectionError,
61
60
  FeatureNotSupportedError,
62
61
  FormattingModeNotSupportedError,
63
- MirascopeError,
62
+ MirascopeLLMError,
63
+ NoRegisteredProviderError,
64
64
  NotFoundError,
65
65
  PermissionError,
66
66
  RateLimitError,
@@ -78,8 +78,23 @@ from .messages import (
78
78
  UserContent,
79
79
  UserMessage,
80
80
  )
81
- from .models import Model, model, use_model
82
- from .prompts import prompt
81
+ from .models import Model, model, model_from_context, use_model
82
+ from .prompts import (
83
+ AsyncContextPrompt,
84
+ AsyncPrompt,
85
+ ContextPrompt,
86
+ Prompt,
87
+ PromptDecorator,
88
+ prompt,
89
+ )
90
+ from .providers import (
91
+ ModelId,
92
+ Params,
93
+ Provider,
94
+ ProviderId,
95
+ load_provider,
96
+ register_provider,
97
+ )
83
98
  from .responses import (
84
99
  AsyncChunkIterator,
85
100
  AsyncContextResponse,
@@ -102,6 +117,8 @@ from .responses import (
102
117
  TextStream,
103
118
  ThoughtStream,
104
119
  ToolCallStream,
120
+ Usage,
121
+ UsageDeltaChunk,
105
122
  )
106
123
  from .tools import (
107
124
  AsyncContextTool,
@@ -121,11 +138,15 @@ __all__ = [
121
138
  "AssistantContentChunk",
122
139
  "AssistantContentPart",
123
140
  "AssistantMessage",
141
+ "AsyncCall",
124
142
  "AsyncChunkIterator",
143
+ "AsyncContextCall",
144
+ "AsyncContextPrompt",
125
145
  "AsyncContextResponse",
126
146
  "AsyncContextStreamResponse",
127
147
  "AsyncContextTool",
128
148
  "AsyncContextToolkit",
149
+ "AsyncPrompt",
129
150
  "AsyncResponse",
130
151
  "AsyncStream",
131
152
  "AsyncStreamResponse",
@@ -139,9 +160,13 @@ __all__ = [
139
160
  "BadRequestError",
140
161
  "Base64AudioSource",
141
162
  "Base64ImageSource",
163
+ "Call",
164
+ "CallDecorator",
142
165
  "ChunkIterator",
143
166
  "ConnectionError",
144
167
  "Context",
168
+ "ContextCall",
169
+ "ContextPrompt",
145
170
  "ContextResponse",
146
171
  "ContextStreamResponse",
147
172
  "ContextTool",
@@ -154,12 +179,18 @@ __all__ = [
154
179
  "FormattingModeNotSupportedError",
155
180
  "Image",
156
181
  "Message",
157
- "MirascopeError",
182
+ "MirascopeLLMError",
158
183
  "Model",
184
+ "ModelId",
185
+ "NoRegisteredProviderError",
159
186
  "NotFoundError",
160
187
  "Params",
161
188
  "Partial",
162
189
  "PermissionError",
190
+ "Prompt",
191
+ "PromptDecorator",
192
+ "Provider",
193
+ "ProviderId",
163
194
  "RateLimitError",
164
195
  "RawMessageChunk",
165
196
  "Response",
@@ -190,24 +221,27 @@ __all__ = [
190
221
  "ToolOutput",
191
222
  "Toolkit",
192
223
  "URLImageSource",
224
+ "Usage",
225
+ "UsageDeltaChunk",
193
226
  "UserContent",
194
227
  "UserContentPart",
195
228
  "UserMessage",
196
229
  "call",
197
230
  "calls",
198
- "client",
199
- "clients",
200
231
  "content",
201
232
  "exceptions",
202
233
  "format",
203
234
  "formatting",
204
- "get_client",
235
+ "load_provider",
205
236
  "mcp",
206
237
  "messages",
207
238
  "model",
239
+ "model_from_context",
208
240
  "models",
209
241
  "prompt",
210
242
  "prompts",
243
+ "providers",
244
+ "register_provider",
211
245
  "responses",
212
246
  "tool",
213
247
  "tools",