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,95 @@
1
+ """Provider-agnostic usage statistics for LLM API calls."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from typing import Any, Literal
7
+
8
+
9
+ @dataclass(kw_only=True)
10
+ class UsageDeltaChunk:
11
+ """A chunk containing incremental token usage information from a streaming response.
12
+
13
+ This represents a delta/increment in usage statistics as they arrive during streaming.
14
+ Multiple UsageDeltaChunks are accumulated to produce the final Usage object.
15
+ """
16
+
17
+ type: Literal["usage_delta_chunk"] = "usage_delta_chunk"
18
+
19
+ input_tokens: int = 0
20
+ """Delta in input tokens."""
21
+
22
+ output_tokens: int = 0
23
+ """Delta in output tokens."""
24
+
25
+ cache_read_tokens: int = 0
26
+ """Delta in cache read tokens."""
27
+
28
+ cache_write_tokens: int = 0
29
+ """Delta in cache write tokens."""
30
+
31
+ reasoning_tokens: int = 0
32
+ """Delta in reasoning/thinking tokens."""
33
+
34
+
35
+ @dataclass(kw_only=True)
36
+ class Usage:
37
+ """Token usage statistics from an LLM API call.
38
+
39
+ This abstraction captures common usage metrics across providers while preserving
40
+ access to the raw provider-specific usage data.
41
+ """
42
+
43
+ input_tokens: int = 0
44
+ """The number of input tokens used.
45
+
46
+ This includes ALL input tokens, including cache read and write tokens.
47
+
48
+ Will be 0 if not reported by the provider.
49
+ """
50
+
51
+ output_tokens: int = 0
52
+ """The number of output tokens used.
53
+
54
+ This includes ALL output tokens, including `reasoning_tokens` that may not be
55
+ in the user's visible output, or other "hidden" tokens.
56
+
57
+ Will be 0 if not reported by the provider.
58
+ """
59
+
60
+ cache_read_tokens: int = 0
61
+ """The number of tokens read from cache (prompt caching).
62
+
63
+ These are input tokens that were read from cache. Cache read tokens are generally
64
+ much less expensive than regular input tokens.
65
+
66
+ Will be 0 if not reported by the provider or if caching was not used.
67
+ """
68
+
69
+ cache_write_tokens: int = 0
70
+ """The number of tokens written to cache (cache creation).
71
+
72
+ These are input tokens that were written to cache, for future reuse and retrieval.
73
+ Cache write tokens are generally more expensive than uncached input tokens,
74
+ but may lead to cost savings down the line when they are re-read as cache_read_tokens.
75
+
76
+ Will be 0 if not reported by the provider or if caching was not used.
77
+ """
78
+
79
+ reasoning_tokens: int = 0
80
+ """The number of tokens used for reasoning/thinking.
81
+
82
+ Reasoning tokens are a subset of output_tokens that were generated as part of the model's
83
+ interior reasoning process. They are billed as output tokens, though they are generally
84
+ not shown to the user.
85
+
86
+ Will be 0 if not reported by the provider or if the model does not support reasoning.
87
+ """
88
+
89
+ raw: Any = None
90
+ """The raw usage object from the provider."""
91
+
92
+ @property
93
+ def total_tokens(self) -> int:
94
+ """The total number of tokens used (input + output)."""
95
+ return self.input_tokens + self.output_tokens
@@ -1,9 +1,11 @@
1
1
  """The Tools module for LLMs."""
2
2
 
3
- from . import protocols
4
3
  from .decorator import ToolDecorator, tool
4
+ from .protocols import AsyncContextToolFn, AsyncToolFn, ContextToolFn, ToolFn
5
5
  from .tool_schema import (
6
6
  FORMAT_TOOL_NAME,
7
+ AnyToolFn,
8
+ AnyToolSchema,
7
9
  ToolParameterSchema,
8
10
  ToolSchema,
9
11
  ToolSchemaT,
@@ -20,21 +22,26 @@ from .tools import AsyncContextTool, AsyncTool, ContextTool, Tool, ToolT
20
22
 
21
23
  __all__ = [
22
24
  "FORMAT_TOOL_NAME",
25
+ "AnyToolFn",
26
+ "AnyToolSchema",
23
27
  "AsyncContextTool",
28
+ "AsyncContextToolFn",
24
29
  "AsyncContextToolkit",
25
30
  "AsyncTool",
31
+ "AsyncToolFn",
26
32
  "AsyncToolkit",
27
33
  "BaseToolkit",
28
34
  "ContextTool",
35
+ "ContextToolFn",
29
36
  "ContextToolkit",
30
37
  "Tool",
31
38
  "ToolDecorator",
39
+ "ToolFn",
32
40
  "ToolParameterSchema",
33
41
  "ToolSchema",
34
42
  "ToolSchemaT",
35
43
  "ToolT",
36
44
  "Toolkit",
37
45
  "ToolkitT",
38
- "protocols",
39
46
  "tool",
40
47
  ]
@@ -9,7 +9,10 @@ from .protocols import AsyncContextToolFn, AsyncToolFn, ContextToolFn, ToolFn
9
9
 
10
10
 
11
11
  def is_context_tool_fn(
12
- fn: ToolFn | AsyncToolFn | ContextToolFn | AsyncContextToolFn,
12
+ fn: ContextToolFn[DepsT, P, JsonableCovariantT]
13
+ | AsyncContextToolFn[DepsT, P, JsonableCovariantT]
14
+ | ToolFn[P, JsonableCovariantT]
15
+ | AsyncToolFn[P, JsonableCovariantT],
13
16
  ) -> TypeIs[
14
17
  ContextToolFn[DepsT, P, JsonableCovariantT]
15
18
  | AsyncContextToolFn[DepsT, P, JsonableCovariantT]
@@ -19,7 +22,13 @@ def is_context_tool_fn(
19
22
 
20
23
 
21
24
  def is_async_tool_fn(
22
- fn: ToolFn | AsyncToolFn | ContextToolFn | AsyncContextToolFn,
23
- ) -> TypeIs[AsyncToolFn | AsyncContextToolFn]:
25
+ fn: ContextToolFn[DepsT, P, JsonableCovariantT]
26
+ | AsyncContextToolFn[DepsT, P, JsonableCovariantT]
27
+ | ToolFn[P, JsonableCovariantT]
28
+ | AsyncToolFn[P, JsonableCovariantT],
29
+ ) -> TypeIs[
30
+ AsyncContextToolFn[DepsT, P, JsonableCovariantT]
31
+ | AsyncToolFn[P, JsonableCovariantT]
32
+ ]:
24
33
  """Type guard to check if a function is an async tool function."""
25
34
  return inspect.iscoroutinefunction(fn)
@@ -52,7 +52,7 @@ class AsyncContextToolFn(Protocol[DepsT, P, JsonableCovariantT]):
52
52
  raise NotImplementedError()
53
53
 
54
54
 
55
- class _KwargsCallable(Protocol[JsonableCovariantT]):
55
+ class KwargsCallable(Protocol[JsonableCovariantT]):
56
56
  """Protocol for functions that can be called with `Any`-typed kwargs.
57
57
 
58
58
  Used internally to type-cast tool functions for compatibility with
@@ -62,7 +62,7 @@ class _KwargsCallable(Protocol[JsonableCovariantT]):
62
62
  def __call__(self, **kwargs: dict[str, Any]) -> JsonableCovariantT: ...
63
63
 
64
64
 
65
- class _AsyncKwargsCallable(Protocol[JsonableCovariantT]):
65
+ class AsyncKwargsCallable(Protocol[JsonableCovariantT]):
66
66
  """Protocol for async functions that can be called with `Any`-typed kwargs.
67
67
 
68
68
  Used internally to type-cast async tool functions for compatibility with
@@ -72,7 +72,7 @@ class _AsyncKwargsCallable(Protocol[JsonableCovariantT]):
72
72
  async def __call__(self, **kwargs: dict[str, Any]) -> JsonableCovariantT: ...
73
73
 
74
74
 
75
- class _ContextKwargsCallable(Protocol[DepsT, JsonableCovariantT]):
75
+ class ContextKwargsCallable(Protocol[DepsT, JsonableCovariantT]):
76
76
  """Protocol for context functions that can be called with `Any`-typed kwargs.
77
77
 
78
78
  Used internally to type-cast context tool functions for compatibility with
@@ -84,7 +84,7 @@ class _ContextKwargsCallable(Protocol[DepsT, JsonableCovariantT]):
84
84
  ) -> JsonableCovariantT: ...
85
85
 
86
86
 
87
- class _AsyncJsonKwargsCallable(Protocol[DepsT, JsonableCovariantT]):
87
+ class AsyncJsonKwargsCallable(Protocol[DepsT, JsonableCovariantT]):
88
88
  """Protocol for async context functions that can be called with `Any`-typed kwargs.
89
89
 
90
90
  Used internally to type-cast async context tool functions for compatibility with
@@ -3,13 +3,16 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import inspect
6
- from collections import namedtuple
7
6
  from dataclasses import dataclass
8
7
  from typing import (
9
8
  Annotated,
10
9
  Any,
11
10
  Generic,
11
+ NamedTuple,
12
+ TypeAlias,
13
+ TypedDict,
12
14
  TypeVar,
15
+ cast,
13
16
  get_args,
14
17
  get_origin,
15
18
  get_type_hints,
@@ -20,16 +23,48 @@ from pydantic import BaseModel, Field, create_model
20
23
  from pydantic.fields import FieldInfo
21
24
 
22
25
  from ..content import ToolCall
26
+ from ..types import Jsonable
23
27
  from .protocols import AsyncContextToolFn, AsyncToolFn, ContextToolFn, ToolFn
24
28
 
29
+ AnyToolFn: TypeAlias = (
30
+ ToolFn[..., Jsonable]
31
+ | AsyncToolFn[..., Jsonable]
32
+ | ContextToolFn[Any, ..., Jsonable]
33
+ | AsyncContextToolFn[Any, ..., Jsonable]
34
+ )
35
+
25
36
  ToolFnT = TypeVar(
26
37
  "ToolFnT",
27
- bound=ToolFn | AsyncToolFn | ContextToolFn | AsyncContextToolFn,
38
+ bound=AnyToolFn,
28
39
  covariant=True,
29
40
  )
30
- ToolSchemaT = TypeVar("ToolSchemaT", bound="ToolSchema")
31
41
 
32
- DocstringArg = namedtuple("DocstringArg", ["name", "description"])
42
+ AnyToolSchema: TypeAlias = "ToolSchema[AnyToolFn]"
43
+ ToolSchemaT = TypeVar("ToolSchemaT", bound=AnyToolSchema, covariant=True)
44
+
45
+
46
+ ModelJsonSchema = TypedDict(
47
+ "ModelJsonSchema",
48
+ {
49
+ "properties": dict[str, dict[str, Any]],
50
+ "required": list[str],
51
+ "$defs": dict[str, dict[str, Any]],
52
+ },
53
+ total=False,
54
+ )
55
+ """Type for Pydantic's model_json_schema() output.
56
+
57
+ This TypedDict defines the structure of JSON schemas returned by Pydantic models,
58
+ allowing us to avoid type casts when extracting schema components.
59
+ """
60
+
61
+
62
+ class DocstringArg(NamedTuple):
63
+ """A parameter from a docstring."""
64
+
65
+ name: str
66
+ description: str
67
+
33
68
 
34
69
  FORMAT_TOOL_NAME = "__mirascope_formatted_output_tool__"
35
70
  """Reserved name of the formatted output tool.
@@ -63,7 +98,7 @@ def _parse_docstring_params(docstring: str | None) -> ParsedDocstring:
63
98
  return ParsedDocstring(args=[])
64
99
 
65
100
  parsed = parse(docstring)
66
- args = []
101
+ args: list[DocstringArg] = []
67
102
 
68
103
  for param in parsed.params:
69
104
  if param.description:
@@ -170,7 +205,7 @@ class ToolSchema(Generic[ToolFnT]):
170
205
 
171
206
  param_descriptions = _parse_docstring_params(fn.__doc__)
172
207
 
173
- field_definitions = {}
208
+ field_definitions: dict[str, tuple[Any, Any]] = {}
174
209
  hints = get_type_hints(fn, include_extras=True)
175
210
 
176
211
  context_param_skipped = False
@@ -203,7 +238,7 @@ class ToolSchema(Generic[ToolFnT]):
203
238
  description=field_info.description,
204
239
  )
205
240
  else:
206
- docstring_description = None
241
+ docstring_description: str | None = None
207
242
  for arg in param_descriptions.args:
208
243
  if arg.name == param.name:
209
244
  docstring_description = arg.description
@@ -217,9 +252,9 @@ class ToolSchema(Generic[ToolFnT]):
217
252
 
218
253
  field_definitions[param.name] = (param_type, field_value)
219
254
 
220
- TempModel = create_model("TempModel", **field_definitions)
255
+ TempModel = create_model("TempModel", **cast(dict[str, Any], field_definitions))
221
256
 
222
- schema = TempModel.model_json_schema()
257
+ schema = cast(ModelJsonSchema, TempModel.model_json_schema())
223
258
 
224
259
  parameters = ToolParameterSchema(
225
260
  properties=schema.get("properties", {}),
@@ -4,20 +4,21 @@ from __future__ import annotations
4
4
 
5
5
  import json
6
6
  from collections.abc import Awaitable
7
- from typing import Any, Generic, TypeVar, cast
7
+ from typing import Any, Generic, cast
8
+ from typing_extensions import TypeVar
8
9
 
9
10
  from ..content import ToolCall, ToolOutput
10
11
  from ..context import Context, DepsT
11
12
  from ..types import AnyP, JsonableCovariantT
12
13
  from .protocols import (
13
14
  AsyncContextToolFn,
15
+ AsyncJsonKwargsCallable,
16
+ AsyncKwargsCallable,
14
17
  AsyncToolFn,
18
+ ContextKwargsCallable,
15
19
  ContextToolFn,
20
+ KwargsCallable,
16
21
  ToolFn,
17
- _AsyncJsonKwargsCallable,
18
- _AsyncKwargsCallable,
19
- _ContextKwargsCallable,
20
- _KwargsCallable,
21
22
  )
22
23
  from .tool_schema import ToolSchema
23
24
 
@@ -51,7 +52,7 @@ class Tool(
51
52
  def execute(self, tool_call: ToolCall) -> ToolOutput[JsonableCovariantT]:
52
53
  """Execute the tool using an LLM-provided `ToolCall`."""
53
54
  kwargs_from_json = json.loads(tool_call.args)
54
- kwargs_callable = cast(_KwargsCallable[JsonableCovariantT], self.fn)
55
+ kwargs_callable = cast(KwargsCallable[JsonableCovariantT], self.fn)
55
56
  result = kwargs_callable(**kwargs_from_json)
56
57
  return ToolOutput(id=tool_call.id, value=result, name=self.name)
57
58
 
@@ -82,7 +83,7 @@ class AsyncTool(
82
83
  async def execute(self, tool_call: ToolCall) -> ToolOutput[JsonableCovariantT]:
83
84
  """Execute the async tool using an LLM-provided `ToolCall`."""
84
85
  kwargs_from_json = json.loads(tool_call.args)
85
- kwargs_callable = cast(_AsyncKwargsCallable[JsonableCovariantT], self.fn)
86
+ kwargs_callable = cast(AsyncKwargsCallable[JsonableCovariantT], self.fn)
86
87
  result = await kwargs_callable(**kwargs_from_json)
87
88
  return ToolOutput(id=tool_call.id, value=result, name=self.name)
88
89
 
@@ -122,7 +123,7 @@ class ContextTool(
122
123
  """Execute the context tool using an LLM-provided `ToolCall`."""
123
124
  kwargs_from_json = json.loads(tool_call.args)
124
125
  kwargs_callable = cast(
125
- _ContextKwargsCallable[DepsT, JsonableCovariantT], self.fn
126
+ ContextKwargsCallable[DepsT, JsonableCovariantT], self.fn
126
127
  )
127
128
  result = kwargs_callable(ctx, **kwargs_from_json)
128
129
  return ToolOutput(id=tool_call.id, value=result, name=self.name)
@@ -163,7 +164,7 @@ class AsyncContextTool(
163
164
  """Execute the async context tool using an LLM-provided `ToolCall`."""
164
165
  kwargs_from_json = json.loads(tool_call.args)
165
166
  kwargs_callable = cast(
166
- _AsyncJsonKwargsCallable[DepsT, JsonableCovariantT], self.fn
167
+ AsyncJsonKwargsCallable[DepsT, JsonableCovariantT], self.fn
167
168
  )
168
169
  result = await kwargs_callable(ctx, **kwargs_from_json)
169
170
  return ToolOutput(id=tool_call.id, value=result, name=self.name)
@@ -0,0 +1,156 @@
1
+ """Operational helpers (tracing, sessions, future ops.* utilities)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ try:
6
+ from ._internal.configuration import configure, tracer_context
7
+ from ._internal.context import propagated_context
8
+ from ._internal.instrumentation.llm import (
9
+ instrument_llm,
10
+ uninstrument_llm,
11
+ )
12
+ from ._internal.propagation import (
13
+ ContextPropagator,
14
+ PropagatorFormat,
15
+ extract_context,
16
+ get_propagator,
17
+ inject_context,
18
+ reset_propagator,
19
+ )
20
+ from ._internal.session import (
21
+ SESSION_HEADER_NAME,
22
+ SessionContext,
23
+ current_session,
24
+ extract_session_id,
25
+ session,
26
+ )
27
+ from ._internal.spans import Span, span
28
+ from ._internal.traced_calls import (
29
+ TracedAsyncCall,
30
+ TracedAsyncContextCall,
31
+ TracedCall,
32
+ TracedContextCall,
33
+ )
34
+ from ._internal.traced_functions import (
35
+ AsyncTrace,
36
+ AsyncTracedFunction,
37
+ Trace,
38
+ TracedFunction,
39
+ )
40
+ from ._internal.tracing import (
41
+ TraceDecorator,
42
+ trace,
43
+ )
44
+ from ._internal.versioned_calls import (
45
+ VersionedAsyncCall,
46
+ VersionedAsyncContextCall,
47
+ VersionedCall,
48
+ VersionedContextCall,
49
+ )
50
+ from ._internal.versioned_functions import (
51
+ AsyncVersionedFunction,
52
+ VersionedFunction,
53
+ VersionInfo,
54
+ )
55
+ from ._internal.versioning import (
56
+ VersionDecorator,
57
+ version,
58
+ )
59
+ from .exceptions import ClosureComputationError
60
+
61
+ except ImportError: # pragma: no cover
62
+ # TODO: refactor alongside other import error handling improvements
63
+ from collections.abc import Callable
64
+
65
+ def _create_otel_import_error_stub(name: str) -> Callable[..., None]:
66
+ """Create a stub that raises ImportError with helpful message."""
67
+
68
+ def _raise_not_installed() -> None:
69
+ raise ImportError(
70
+ f"The 'opentelemetry' packages are required to use {name}. "
71
+ "Install them with: `uv add 'mirascope[otel]'`."
72
+ )
73
+
74
+ return _raise_not_installed
75
+
76
+ propagated_context = _create_otel_import_error_stub("propagated_context")
77
+ instrument_llm = _create_otel_import_error_stub("instrument_llm")
78
+ uninstrument_llm = _create_otel_import_error_stub("uninstrument_llm")
79
+ ContextPropagator = _create_otel_import_error_stub("ContextPropagator")
80
+ PropagatorFormat = str
81
+ extract_context = _create_otel_import_error_stub("extract_context")
82
+ get_propagator = _create_otel_import_error_stub("get_propagator")
83
+ inject_context = _create_otel_import_error_stub("inject_context")
84
+ reset_propagator = _create_otel_import_error_stub("reset_propagator")
85
+ SESSION_HEADER_NAME = "X-Mirascope-Session-ID"
86
+ SessionContext = _create_otel_import_error_stub("SessionContext")
87
+ current_session = _create_otel_import_error_stub("current_session")
88
+ extract_session_id = _create_otel_import_error_stub("extract_session_id")
89
+ session = _create_otel_import_error_stub("session")
90
+ Span = _create_otel_import_error_stub("Span")
91
+ span = _create_otel_import_error_stub("span")
92
+ AsyncTrace = _create_otel_import_error_stub("AsyncTrace")
93
+ AsyncTracedFunction = _create_otel_import_error_stub("AsyncTracedFunction")
94
+ Trace = _create_otel_import_error_stub("Trace")
95
+ TraceDecorator = _create_otel_import_error_stub("TraceDecorator")
96
+ TracedAsyncCall = _create_otel_import_error_stub("TracedAsyncCall")
97
+ TracedAsyncContextCall = _create_otel_import_error_stub("TracedAsyncContextCall")
98
+ TracedCall = _create_otel_import_error_stub("TracedCall")
99
+ TracedContextCall = _create_otel_import_error_stub("TracedContextCall")
100
+ TracedFunction = _create_otel_import_error_stub("TracedFunction")
101
+ trace = _create_otel_import_error_stub("trace")
102
+ configure = _create_otel_import_error_stub("configure")
103
+ tracer_context = _create_otel_import_error_stub("tracer_context")
104
+ AsyncVersionedFunction = _create_otel_import_error_stub("AsyncVersionedFunction")
105
+ VersionDecorator = _create_otel_import_error_stub("VersionDecorator")
106
+ VersionedAsyncCall = _create_otel_import_error_stub("VersionedAsyncCall")
107
+ VersionedAsyncContextCall = _create_otel_import_error_stub(
108
+ "VersionedAsyncContextCall"
109
+ )
110
+ VersionedCall = _create_otel_import_error_stub("VersionedCall")
111
+ VersionedContextCall = _create_otel_import_error_stub("VersionedContextCall")
112
+ VersionedFunction = _create_otel_import_error_stub("VersionedFunction")
113
+ VersionInfo = _create_otel_import_error_stub("VersionInfo")
114
+ version = _create_otel_import_error_stub("version")
115
+
116
+
117
+ __all__ = [
118
+ "SESSION_HEADER_NAME",
119
+ "AsyncTrace",
120
+ "AsyncTracedFunction",
121
+ "AsyncVersionedFunction",
122
+ "ClosureComputationError",
123
+ "ContextPropagator",
124
+ "PropagatorFormat",
125
+ "SessionContext",
126
+ "Span",
127
+ "Trace",
128
+ "TraceDecorator",
129
+ "TracedAsyncCall",
130
+ "TracedAsyncContextCall",
131
+ "TracedCall",
132
+ "TracedContextCall",
133
+ "TracedFunction",
134
+ "VersionDecorator",
135
+ "VersionInfo",
136
+ "VersionedAsyncCall",
137
+ "VersionedAsyncContextCall",
138
+ "VersionedCall",
139
+ "VersionedContextCall",
140
+ "VersionedFunction",
141
+ "configure",
142
+ "current_session",
143
+ "extract_context",
144
+ "extract_session_id",
145
+ "get_propagator",
146
+ "inject_context",
147
+ "instrument_llm",
148
+ "propagated_context",
149
+ "reset_propagator",
150
+ "session",
151
+ "span",
152
+ "trace",
153
+ "tracer_context",
154
+ "uninstrument_llm",
155
+ "version",
156
+ ]
@@ -0,0 +1,5 @@
1
+ """Private internal module for Mirascope.
2
+
3
+ All modules within this directory are considered private implementation details
4
+ and should not be imported directly by users.
5
+ """