mirascope 1.25.7__py3-none-any.whl → 2.0.0a0__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 (474) hide show
  1. mirascope/__init__.py +3 -59
  2. mirascope/graphs/__init__.py +22 -0
  3. mirascope/{experimental/graphs → graphs}/finite_state_machine.py +70 -159
  4. mirascope/llm/__init__.py +206 -16
  5. mirascope/llm/agents/__init__.py +15 -0
  6. mirascope/llm/agents/agent.py +97 -0
  7. mirascope/llm/agents/agent_template.py +45 -0
  8. mirascope/llm/agents/decorator.py +176 -0
  9. mirascope/llm/calls/__init__.py +16 -0
  10. mirascope/llm/calls/base_call.py +33 -0
  11. mirascope/llm/calls/calls.py +315 -0
  12. mirascope/llm/calls/decorator.py +255 -0
  13. mirascope/llm/clients/__init__.py +34 -0
  14. mirascope/llm/clients/anthropic/__init__.py +11 -0
  15. mirascope/llm/clients/anthropic/_utils/__init__.py +13 -0
  16. mirascope/llm/clients/anthropic/_utils/decode.py +244 -0
  17. mirascope/llm/clients/anthropic/_utils/encode.py +243 -0
  18. mirascope/llm/clients/anthropic/clients.py +819 -0
  19. mirascope/llm/clients/anthropic/model_ids.py +8 -0
  20. mirascope/llm/clients/base/__init__.py +15 -0
  21. mirascope/llm/clients/base/_utils.py +192 -0
  22. mirascope/llm/clients/base/client.py +1256 -0
  23. mirascope/llm/clients/base/kwargs.py +12 -0
  24. mirascope/llm/clients/base/params.py +93 -0
  25. mirascope/llm/clients/google/__init__.py +6 -0
  26. mirascope/llm/clients/google/_utils/__init__.py +13 -0
  27. mirascope/llm/clients/google/_utils/decode.py +231 -0
  28. mirascope/llm/clients/google/_utils/encode.py +279 -0
  29. mirascope/llm/clients/google/clients.py +853 -0
  30. mirascope/llm/clients/google/message.py +7 -0
  31. mirascope/llm/clients/google/model_ids.py +15 -0
  32. mirascope/llm/clients/openai/__init__.py +25 -0
  33. mirascope/llm/clients/openai/completions/__init__.py +9 -0
  34. mirascope/llm/clients/openai/completions/_utils/__init__.py +13 -0
  35. mirascope/llm/clients/openai/completions/_utils/decode.py +187 -0
  36. mirascope/llm/clients/openai/completions/_utils/encode.py +358 -0
  37. mirascope/llm/clients/openai/completions/_utils/model_features.py +81 -0
  38. mirascope/llm/clients/openai/completions/clients.py +833 -0
  39. mirascope/llm/clients/openai/completions/model_ids.py +8 -0
  40. mirascope/llm/clients/openai/responses/__init__.py +9 -0
  41. mirascope/llm/clients/openai/responses/_utils/__init__.py +13 -0
  42. mirascope/llm/clients/openai/responses/_utils/decode.py +194 -0
  43. mirascope/llm/clients/openai/responses/_utils/encode.py +333 -0
  44. mirascope/llm/clients/openai/responses/_utils/model_features.py +87 -0
  45. mirascope/llm/clients/openai/responses/clients.py +832 -0
  46. mirascope/llm/clients/openai/responses/model_ids.py +8 -0
  47. mirascope/llm/clients/openai/shared/__init__.py +7 -0
  48. mirascope/llm/clients/openai/shared/_utils.py +55 -0
  49. mirascope/llm/clients/providers.py +175 -0
  50. mirascope/llm/content/__init__.py +70 -0
  51. mirascope/llm/content/audio.py +173 -0
  52. mirascope/llm/content/document.py +94 -0
  53. mirascope/llm/content/image.py +206 -0
  54. mirascope/llm/content/text.py +47 -0
  55. mirascope/llm/content/thought.py +58 -0
  56. mirascope/llm/content/tool_call.py +63 -0
  57. mirascope/llm/content/tool_output.py +26 -0
  58. mirascope/llm/context/__init__.py +6 -0
  59. mirascope/llm/context/_utils.py +28 -0
  60. mirascope/llm/context/context.py +24 -0
  61. mirascope/llm/exceptions.py +105 -0
  62. mirascope/llm/formatting/__init__.py +22 -0
  63. mirascope/llm/formatting/_utils.py +74 -0
  64. mirascope/llm/formatting/format.py +104 -0
  65. mirascope/llm/formatting/from_call_args.py +30 -0
  66. mirascope/llm/formatting/partial.py +58 -0
  67. mirascope/llm/formatting/types.py +109 -0
  68. mirascope/llm/mcp/__init__.py +5 -0
  69. mirascope/llm/mcp/client.py +118 -0
  70. mirascope/llm/messages/__init__.py +32 -0
  71. mirascope/llm/messages/message.py +182 -0
  72. mirascope/llm/models/__init__.py +16 -0
  73. mirascope/llm/models/models.py +1243 -0
  74. mirascope/llm/prompts/__init__.py +33 -0
  75. mirascope/llm/prompts/_utils.py +60 -0
  76. mirascope/llm/prompts/decorator.py +286 -0
  77. mirascope/llm/prompts/protocols.py +99 -0
  78. mirascope/llm/responses/__init__.py +57 -0
  79. mirascope/llm/responses/_utils.py +56 -0
  80. mirascope/llm/responses/base_response.py +91 -0
  81. mirascope/llm/responses/base_stream_response.py +697 -0
  82. mirascope/llm/responses/finish_reason.py +27 -0
  83. mirascope/llm/responses/response.py +345 -0
  84. mirascope/llm/responses/root_response.py +177 -0
  85. mirascope/llm/responses/stream_response.py +572 -0
  86. mirascope/llm/responses/streams.py +363 -0
  87. mirascope/llm/tools/__init__.py +40 -0
  88. mirascope/llm/tools/_utils.py +25 -0
  89. mirascope/llm/tools/decorator.py +175 -0
  90. mirascope/llm/tools/protocols.py +96 -0
  91. mirascope/llm/tools/tool_schema.py +246 -0
  92. mirascope/llm/tools/toolkit.py +152 -0
  93. mirascope/llm/tools/tools.py +169 -0
  94. mirascope/llm/types/__init__.py +22 -0
  95. mirascope/llm/types/dataclass.py +9 -0
  96. mirascope/llm/types/jsonable.py +44 -0
  97. mirascope/llm/types/type_vars.py +19 -0
  98. mirascope-2.0.0a0.dist-info/METADATA +117 -0
  99. mirascope-2.0.0a0.dist-info/RECORD +101 -0
  100. mirascope/beta/__init__.py +0 -3
  101. mirascope/beta/openai/__init__.py +0 -17
  102. mirascope/beta/openai/realtime/__init__.py +0 -13
  103. mirascope/beta/openai/realtime/_utils/__init__.py +0 -3
  104. mirascope/beta/openai/realtime/_utils/_audio.py +0 -74
  105. mirascope/beta/openai/realtime/_utils/_protocols.py +0 -50
  106. mirascope/beta/openai/realtime/realtime.py +0 -500
  107. mirascope/beta/openai/realtime/recording.py +0 -98
  108. mirascope/beta/openai/realtime/tool.py +0 -113
  109. mirascope/beta/rag/__init__.py +0 -24
  110. mirascope/beta/rag/base/__init__.py +0 -22
  111. mirascope/beta/rag/base/chunkers/__init__.py +0 -2
  112. mirascope/beta/rag/base/chunkers/base_chunker.py +0 -37
  113. mirascope/beta/rag/base/chunkers/text_chunker.py +0 -33
  114. mirascope/beta/rag/base/config.py +0 -8
  115. mirascope/beta/rag/base/document.py +0 -11
  116. mirascope/beta/rag/base/embedders.py +0 -35
  117. mirascope/beta/rag/base/embedding_params.py +0 -18
  118. mirascope/beta/rag/base/embedding_response.py +0 -30
  119. mirascope/beta/rag/base/query_results.py +0 -7
  120. mirascope/beta/rag/base/vectorstore_params.py +0 -18
  121. mirascope/beta/rag/base/vectorstores.py +0 -37
  122. mirascope/beta/rag/chroma/__init__.py +0 -11
  123. mirascope/beta/rag/chroma/types.py +0 -62
  124. mirascope/beta/rag/chroma/vectorstores.py +0 -121
  125. mirascope/beta/rag/cohere/__init__.py +0 -11
  126. mirascope/beta/rag/cohere/embedders.py +0 -87
  127. mirascope/beta/rag/cohere/embedding_params.py +0 -29
  128. mirascope/beta/rag/cohere/embedding_response.py +0 -29
  129. mirascope/beta/rag/cohere/py.typed +0 -0
  130. mirascope/beta/rag/openai/__init__.py +0 -11
  131. mirascope/beta/rag/openai/embedders.py +0 -144
  132. mirascope/beta/rag/openai/embedding_params.py +0 -18
  133. mirascope/beta/rag/openai/embedding_response.py +0 -14
  134. mirascope/beta/rag/openai/py.typed +0 -0
  135. mirascope/beta/rag/pinecone/__init__.py +0 -19
  136. mirascope/beta/rag/pinecone/types.py +0 -143
  137. mirascope/beta/rag/pinecone/vectorstores.py +0 -148
  138. mirascope/beta/rag/weaviate/__init__.py +0 -6
  139. mirascope/beta/rag/weaviate/types.py +0 -92
  140. mirascope/beta/rag/weaviate/vectorstores.py +0 -103
  141. mirascope/core/__init__.py +0 -109
  142. mirascope/core/anthropic/__init__.py +0 -31
  143. mirascope/core/anthropic/_call.py +0 -67
  144. mirascope/core/anthropic/_call_kwargs.py +0 -13
  145. mirascope/core/anthropic/_thinking.py +0 -70
  146. mirascope/core/anthropic/_utils/__init__.py +0 -16
  147. mirascope/core/anthropic/_utils/_convert_common_call_params.py +0 -25
  148. mirascope/core/anthropic/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -21
  149. mirascope/core/anthropic/_utils/_convert_message_params.py +0 -102
  150. mirascope/core/anthropic/_utils/_get_json_output.py +0 -31
  151. mirascope/core/anthropic/_utils/_handle_stream.py +0 -113
  152. mirascope/core/anthropic/_utils/_message_param_converter.py +0 -154
  153. mirascope/core/anthropic/_utils/_setup_call.py +0 -146
  154. mirascope/core/anthropic/call_params.py +0 -44
  155. mirascope/core/anthropic/call_response.py +0 -226
  156. mirascope/core/anthropic/call_response_chunk.py +0 -152
  157. mirascope/core/anthropic/dynamic_config.py +0 -40
  158. mirascope/core/anthropic/py.typed +0 -0
  159. mirascope/core/anthropic/stream.py +0 -204
  160. mirascope/core/anthropic/tool.py +0 -101
  161. mirascope/core/azure/__init__.py +0 -31
  162. mirascope/core/azure/_call.py +0 -67
  163. mirascope/core/azure/_call_kwargs.py +0 -13
  164. mirascope/core/azure/_utils/__init__.py +0 -14
  165. mirascope/core/azure/_utils/_convert_common_call_params.py +0 -26
  166. mirascope/core/azure/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -21
  167. mirascope/core/azure/_utils/_convert_message_params.py +0 -121
  168. mirascope/core/azure/_utils/_get_credential.py +0 -33
  169. mirascope/core/azure/_utils/_get_json_output.py +0 -27
  170. mirascope/core/azure/_utils/_handle_stream.py +0 -130
  171. mirascope/core/azure/_utils/_message_param_converter.py +0 -117
  172. mirascope/core/azure/_utils/_setup_call.py +0 -183
  173. mirascope/core/azure/call_params.py +0 -59
  174. mirascope/core/azure/call_response.py +0 -215
  175. mirascope/core/azure/call_response_chunk.py +0 -105
  176. mirascope/core/azure/dynamic_config.py +0 -30
  177. mirascope/core/azure/py.typed +0 -0
  178. mirascope/core/azure/stream.py +0 -147
  179. mirascope/core/azure/tool.py +0 -93
  180. mirascope/core/base/__init__.py +0 -86
  181. mirascope/core/base/_call_factory.py +0 -256
  182. mirascope/core/base/_create.py +0 -253
  183. mirascope/core/base/_extract.py +0 -175
  184. mirascope/core/base/_extract_with_tools.py +0 -189
  185. mirascope/core/base/_partial.py +0 -95
  186. mirascope/core/base/_utils/__init__.py +0 -92
  187. mirascope/core/base/_utils/_base_message_param_converter.py +0 -22
  188. mirascope/core/base/_utils/_base_type.py +0 -26
  189. mirascope/core/base/_utils/_convert_base_model_to_base_tool.py +0 -48
  190. mirascope/core/base/_utils/_convert_base_type_to_base_tool.py +0 -24
  191. mirascope/core/base/_utils/_convert_function_to_base_tool.py +0 -139
  192. mirascope/core/base/_utils/_convert_messages_to_message_params.py +0 -178
  193. mirascope/core/base/_utils/_convert_provider_finish_reason_to_finish_reason.py +0 -20
  194. mirascope/core/base/_utils/_default_tool_docstring.py +0 -6
  195. mirascope/core/base/_utils/_extract_tool_return.py +0 -42
  196. mirascope/core/base/_utils/_fn_is_async.py +0 -24
  197. mirascope/core/base/_utils/_format_template.py +0 -32
  198. mirascope/core/base/_utils/_get_audio_type.py +0 -18
  199. mirascope/core/base/_utils/_get_common_usage.py +0 -20
  200. mirascope/core/base/_utils/_get_create_fn_or_async_create_fn.py +0 -137
  201. mirascope/core/base/_utils/_get_document_type.py +0 -7
  202. mirascope/core/base/_utils/_get_dynamic_configuration.py +0 -69
  203. mirascope/core/base/_utils/_get_fields_from_call_args.py +0 -34
  204. mirascope/core/base/_utils/_get_fn_args.py +0 -23
  205. mirascope/core/base/_utils/_get_image_dimensions.py +0 -39
  206. mirascope/core/base/_utils/_get_image_type.py +0 -26
  207. mirascope/core/base/_utils/_get_metadata.py +0 -17
  208. mirascope/core/base/_utils/_get_possible_user_message_param.py +0 -21
  209. mirascope/core/base/_utils/_get_prompt_template.py +0 -28
  210. mirascope/core/base/_utils/_get_template_values.py +0 -51
  211. mirascope/core/base/_utils/_get_template_variables.py +0 -38
  212. mirascope/core/base/_utils/_get_unsupported_tool_config_keys.py +0 -10
  213. mirascope/core/base/_utils/_is_prompt_template.py +0 -24
  214. mirascope/core/base/_utils/_json_mode_content.py +0 -17
  215. mirascope/core/base/_utils/_messages_decorator.py +0 -121
  216. mirascope/core/base/_utils/_parse_content_template.py +0 -323
  217. mirascope/core/base/_utils/_parse_prompt_messages.py +0 -63
  218. mirascope/core/base/_utils/_pil_image_to_bytes.py +0 -13
  219. mirascope/core/base/_utils/_protocols.py +0 -901
  220. mirascope/core/base/_utils/_setup_call.py +0 -79
  221. mirascope/core/base/_utils/_setup_extract_tool.py +0 -30
  222. mirascope/core/base/call_kwargs.py +0 -13
  223. mirascope/core/base/call_params.py +0 -36
  224. mirascope/core/base/call_response.py +0 -338
  225. mirascope/core/base/call_response_chunk.py +0 -130
  226. mirascope/core/base/dynamic_config.py +0 -82
  227. mirascope/core/base/from_call_args.py +0 -30
  228. mirascope/core/base/merge_decorators.py +0 -59
  229. mirascope/core/base/message_param.py +0 -175
  230. mirascope/core/base/messages.py +0 -116
  231. mirascope/core/base/metadata.py +0 -13
  232. mirascope/core/base/prompt.py +0 -497
  233. mirascope/core/base/response_model_config_dict.py +0 -9
  234. mirascope/core/base/stream.py +0 -479
  235. mirascope/core/base/stream_config.py +0 -11
  236. mirascope/core/base/structured_stream.py +0 -296
  237. mirascope/core/base/tool.py +0 -214
  238. mirascope/core/base/toolkit.py +0 -176
  239. mirascope/core/base/types.py +0 -344
  240. mirascope/core/bedrock/__init__.py +0 -34
  241. mirascope/core/bedrock/_call.py +0 -68
  242. mirascope/core/bedrock/_call_kwargs.py +0 -12
  243. mirascope/core/bedrock/_types.py +0 -104
  244. mirascope/core/bedrock/_utils/__init__.py +0 -14
  245. mirascope/core/bedrock/_utils/_convert_common_call_params.py +0 -39
  246. mirascope/core/bedrock/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
  247. mirascope/core/bedrock/_utils/_convert_message_params.py +0 -111
  248. mirascope/core/bedrock/_utils/_get_json_output.py +0 -30
  249. mirascope/core/bedrock/_utils/_handle_stream.py +0 -104
  250. mirascope/core/bedrock/_utils/_message_param_converter.py +0 -172
  251. mirascope/core/bedrock/_utils/_setup_call.py +0 -258
  252. mirascope/core/bedrock/call_params.py +0 -38
  253. mirascope/core/bedrock/call_response.py +0 -248
  254. mirascope/core/bedrock/call_response_chunk.py +0 -111
  255. mirascope/core/bedrock/dynamic_config.py +0 -37
  256. mirascope/core/bedrock/py.typed +0 -0
  257. mirascope/core/bedrock/stream.py +0 -154
  258. mirascope/core/bedrock/tool.py +0 -100
  259. mirascope/core/cohere/__init__.py +0 -30
  260. mirascope/core/cohere/_call.py +0 -67
  261. mirascope/core/cohere/_call_kwargs.py +0 -11
  262. mirascope/core/cohere/_types.py +0 -20
  263. mirascope/core/cohere/_utils/__init__.py +0 -14
  264. mirascope/core/cohere/_utils/_convert_common_call_params.py +0 -26
  265. mirascope/core/cohere/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -24
  266. mirascope/core/cohere/_utils/_convert_message_params.py +0 -32
  267. mirascope/core/cohere/_utils/_get_json_output.py +0 -30
  268. mirascope/core/cohere/_utils/_handle_stream.py +0 -35
  269. mirascope/core/cohere/_utils/_message_param_converter.py +0 -54
  270. mirascope/core/cohere/_utils/_setup_call.py +0 -150
  271. mirascope/core/cohere/call_params.py +0 -62
  272. mirascope/core/cohere/call_response.py +0 -205
  273. mirascope/core/cohere/call_response_chunk.py +0 -125
  274. mirascope/core/cohere/dynamic_config.py +0 -32
  275. mirascope/core/cohere/py.typed +0 -0
  276. mirascope/core/cohere/stream.py +0 -113
  277. mirascope/core/cohere/tool.py +0 -93
  278. mirascope/core/costs/__init__.py +0 -5
  279. mirascope/core/costs/_anthropic_calculate_cost.py +0 -219
  280. mirascope/core/costs/_azure_calculate_cost.py +0 -11
  281. mirascope/core/costs/_bedrock_calculate_cost.py +0 -15
  282. mirascope/core/costs/_cohere_calculate_cost.py +0 -44
  283. mirascope/core/costs/_gemini_calculate_cost.py +0 -67
  284. mirascope/core/costs/_google_calculate_cost.py +0 -427
  285. mirascope/core/costs/_groq_calculate_cost.py +0 -156
  286. mirascope/core/costs/_litellm_calculate_cost.py +0 -11
  287. mirascope/core/costs/_mistral_calculate_cost.py +0 -64
  288. mirascope/core/costs/_openai_calculate_cost.py +0 -416
  289. mirascope/core/costs/_vertex_calculate_cost.py +0 -67
  290. mirascope/core/costs/_xai_calculate_cost.py +0 -104
  291. mirascope/core/costs/calculate_cost.py +0 -86
  292. mirascope/core/gemini/__init__.py +0 -40
  293. mirascope/core/gemini/_call.py +0 -67
  294. mirascope/core/gemini/_call_kwargs.py +0 -12
  295. mirascope/core/gemini/_utils/__init__.py +0 -14
  296. mirascope/core/gemini/_utils/_convert_common_call_params.py +0 -39
  297. mirascope/core/gemini/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
  298. mirascope/core/gemini/_utils/_convert_message_params.py +0 -156
  299. mirascope/core/gemini/_utils/_get_json_output.py +0 -35
  300. mirascope/core/gemini/_utils/_handle_stream.py +0 -33
  301. mirascope/core/gemini/_utils/_message_param_converter.py +0 -209
  302. mirascope/core/gemini/_utils/_setup_call.py +0 -149
  303. mirascope/core/gemini/call_params.py +0 -52
  304. mirascope/core/gemini/call_response.py +0 -216
  305. mirascope/core/gemini/call_response_chunk.py +0 -100
  306. mirascope/core/gemini/dynamic_config.py +0 -26
  307. mirascope/core/gemini/stream.py +0 -120
  308. mirascope/core/gemini/tool.py +0 -104
  309. mirascope/core/google/__init__.py +0 -29
  310. mirascope/core/google/_call.py +0 -67
  311. mirascope/core/google/_call_kwargs.py +0 -13
  312. mirascope/core/google/_utils/__init__.py +0 -14
  313. mirascope/core/google/_utils/_convert_common_call_params.py +0 -38
  314. mirascope/core/google/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -27
  315. mirascope/core/google/_utils/_convert_message_params.py +0 -297
  316. mirascope/core/google/_utils/_get_json_output.py +0 -37
  317. mirascope/core/google/_utils/_handle_stream.py +0 -58
  318. mirascope/core/google/_utils/_message_param_converter.py +0 -200
  319. mirascope/core/google/_utils/_setup_call.py +0 -201
  320. mirascope/core/google/_utils/_validate_media_type.py +0 -58
  321. mirascope/core/google/call_params.py +0 -22
  322. mirascope/core/google/call_response.py +0 -255
  323. mirascope/core/google/call_response_chunk.py +0 -135
  324. mirascope/core/google/dynamic_config.py +0 -26
  325. mirascope/core/google/stream.py +0 -199
  326. mirascope/core/google/tool.py +0 -146
  327. mirascope/core/groq/__init__.py +0 -30
  328. mirascope/core/groq/_call.py +0 -67
  329. mirascope/core/groq/_call_kwargs.py +0 -13
  330. mirascope/core/groq/_utils/__init__.py +0 -14
  331. mirascope/core/groq/_utils/_convert_common_call_params.py +0 -26
  332. mirascope/core/groq/_utils/_convert_message_params.py +0 -112
  333. mirascope/core/groq/_utils/_get_json_output.py +0 -27
  334. mirascope/core/groq/_utils/_handle_stream.py +0 -123
  335. mirascope/core/groq/_utils/_message_param_converter.py +0 -89
  336. mirascope/core/groq/_utils/_setup_call.py +0 -132
  337. mirascope/core/groq/call_params.py +0 -52
  338. mirascope/core/groq/call_response.py +0 -213
  339. mirascope/core/groq/call_response_chunk.py +0 -104
  340. mirascope/core/groq/dynamic_config.py +0 -29
  341. mirascope/core/groq/py.typed +0 -0
  342. mirascope/core/groq/stream.py +0 -135
  343. mirascope/core/groq/tool.py +0 -80
  344. mirascope/core/litellm/__init__.py +0 -28
  345. mirascope/core/litellm/_call.py +0 -67
  346. mirascope/core/litellm/_utils/__init__.py +0 -5
  347. mirascope/core/litellm/_utils/_setup_call.py +0 -109
  348. mirascope/core/litellm/call_params.py +0 -10
  349. mirascope/core/litellm/call_response.py +0 -24
  350. mirascope/core/litellm/call_response_chunk.py +0 -14
  351. mirascope/core/litellm/dynamic_config.py +0 -8
  352. mirascope/core/litellm/py.typed +0 -0
  353. mirascope/core/litellm/stream.py +0 -86
  354. mirascope/core/litellm/tool.py +0 -13
  355. mirascope/core/mistral/__init__.py +0 -36
  356. mirascope/core/mistral/_call.py +0 -65
  357. mirascope/core/mistral/_call_kwargs.py +0 -19
  358. mirascope/core/mistral/_utils/__init__.py +0 -14
  359. mirascope/core/mistral/_utils/_convert_common_call_params.py +0 -24
  360. mirascope/core/mistral/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -22
  361. mirascope/core/mistral/_utils/_convert_message_params.py +0 -122
  362. mirascope/core/mistral/_utils/_get_json_output.py +0 -34
  363. mirascope/core/mistral/_utils/_handle_stream.py +0 -139
  364. mirascope/core/mistral/_utils/_message_param_converter.py +0 -176
  365. mirascope/core/mistral/_utils/_setup_call.py +0 -164
  366. mirascope/core/mistral/call_params.py +0 -36
  367. mirascope/core/mistral/call_response.py +0 -205
  368. mirascope/core/mistral/call_response_chunk.py +0 -105
  369. mirascope/core/mistral/dynamic_config.py +0 -33
  370. mirascope/core/mistral/py.typed +0 -0
  371. mirascope/core/mistral/stream.py +0 -120
  372. mirascope/core/mistral/tool.py +0 -81
  373. mirascope/core/openai/__init__.py +0 -31
  374. mirascope/core/openai/_call.py +0 -67
  375. mirascope/core/openai/_call_kwargs.py +0 -13
  376. mirascope/core/openai/_utils/__init__.py +0 -14
  377. mirascope/core/openai/_utils/_convert_common_call_params.py +0 -26
  378. mirascope/core/openai/_utils/_convert_message_params.py +0 -148
  379. mirascope/core/openai/_utils/_get_json_output.py +0 -31
  380. mirascope/core/openai/_utils/_handle_stream.py +0 -138
  381. mirascope/core/openai/_utils/_message_param_converter.py +0 -105
  382. mirascope/core/openai/_utils/_setup_call.py +0 -155
  383. mirascope/core/openai/call_params.py +0 -92
  384. mirascope/core/openai/call_response.py +0 -273
  385. mirascope/core/openai/call_response_chunk.py +0 -139
  386. mirascope/core/openai/dynamic_config.py +0 -34
  387. mirascope/core/openai/py.typed +0 -0
  388. mirascope/core/openai/stream.py +0 -185
  389. mirascope/core/openai/tool.py +0 -101
  390. mirascope/core/py.typed +0 -0
  391. mirascope/core/vertex/__init__.py +0 -45
  392. mirascope/core/vertex/_call.py +0 -62
  393. mirascope/core/vertex/_call_kwargs.py +0 -12
  394. mirascope/core/vertex/_utils/__init__.py +0 -14
  395. mirascope/core/vertex/_utils/_convert_common_call_params.py +0 -37
  396. mirascope/core/vertex/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
  397. mirascope/core/vertex/_utils/_convert_message_params.py +0 -171
  398. mirascope/core/vertex/_utils/_get_json_output.py +0 -36
  399. mirascope/core/vertex/_utils/_handle_stream.py +0 -33
  400. mirascope/core/vertex/_utils/_message_param_converter.py +0 -133
  401. mirascope/core/vertex/_utils/_setup_call.py +0 -160
  402. mirascope/core/vertex/call_params.py +0 -24
  403. mirascope/core/vertex/call_response.py +0 -206
  404. mirascope/core/vertex/call_response_chunk.py +0 -99
  405. mirascope/core/vertex/dynamic_config.py +0 -28
  406. mirascope/core/vertex/stream.py +0 -119
  407. mirascope/core/vertex/tool.py +0 -101
  408. mirascope/core/xai/__init__.py +0 -28
  409. mirascope/core/xai/_call.py +0 -67
  410. mirascope/core/xai/_utils/__init__.py +0 -5
  411. mirascope/core/xai/_utils/_setup_call.py +0 -113
  412. mirascope/core/xai/call_params.py +0 -10
  413. mirascope/core/xai/call_response.py +0 -16
  414. mirascope/core/xai/call_response_chunk.py +0 -14
  415. mirascope/core/xai/dynamic_config.py +0 -8
  416. mirascope/core/xai/py.typed +0 -0
  417. mirascope/core/xai/stream.py +0 -57
  418. mirascope/core/xai/tool.py +0 -13
  419. mirascope/experimental/graphs/__init__.py +0 -5
  420. mirascope/integrations/__init__.py +0 -16
  421. mirascope/integrations/_middleware_factory.py +0 -403
  422. mirascope/integrations/langfuse/__init__.py +0 -3
  423. mirascope/integrations/langfuse/_utils.py +0 -114
  424. mirascope/integrations/langfuse/_with_langfuse.py +0 -70
  425. mirascope/integrations/logfire/__init__.py +0 -3
  426. mirascope/integrations/logfire/_utils.py +0 -225
  427. mirascope/integrations/logfire/_with_logfire.py +0 -63
  428. mirascope/integrations/otel/__init__.py +0 -10
  429. mirascope/integrations/otel/_utils.py +0 -270
  430. mirascope/integrations/otel/_with_hyperdx.py +0 -60
  431. mirascope/integrations/otel/_with_otel.py +0 -59
  432. mirascope/integrations/tenacity.py +0 -14
  433. mirascope/llm/_call.py +0 -401
  434. mirascope/llm/_context.py +0 -384
  435. mirascope/llm/_override.py +0 -3639
  436. mirascope/llm/_protocols.py +0 -500
  437. mirascope/llm/_response_metaclass.py +0 -31
  438. mirascope/llm/call_response.py +0 -158
  439. mirascope/llm/call_response_chunk.py +0 -66
  440. mirascope/llm/stream.py +0 -162
  441. mirascope/llm/tool.py +0 -64
  442. mirascope/mcp/__init__.py +0 -7
  443. mirascope/mcp/_utils.py +0 -288
  444. mirascope/mcp/client.py +0 -167
  445. mirascope/mcp/server.py +0 -356
  446. mirascope/mcp/tools.py +0 -110
  447. mirascope/py.typed +0 -0
  448. mirascope/retries/__init__.py +0 -11
  449. mirascope/retries/fallback.py +0 -131
  450. mirascope/retries/tenacity.py +0 -50
  451. mirascope/tools/__init__.py +0 -37
  452. mirascope/tools/base.py +0 -98
  453. mirascope/tools/system/__init__.py +0 -0
  454. mirascope/tools/system/_docker_operation.py +0 -166
  455. mirascope/tools/system/_file_system.py +0 -267
  456. mirascope/tools/web/__init__.py +0 -0
  457. mirascope/tools/web/_duckduckgo.py +0 -111
  458. mirascope/tools/web/_httpx.py +0 -125
  459. mirascope/tools/web/_parse_url_content.py +0 -94
  460. mirascope/tools/web/_requests.py +0 -54
  461. mirascope/v0/__init__.py +0 -43
  462. mirascope/v0/anthropic.py +0 -54
  463. mirascope/v0/base/__init__.py +0 -12
  464. mirascope/v0/base/calls.py +0 -118
  465. mirascope/v0/base/extractors.py +0 -122
  466. mirascope/v0/base/ops_utils.py +0 -207
  467. mirascope/v0/base/prompts.py +0 -48
  468. mirascope/v0/base/types.py +0 -14
  469. mirascope/v0/base/utils.py +0 -21
  470. mirascope/v0/openai.py +0 -54
  471. mirascope-1.25.7.dist-info/METADATA +0 -169
  472. mirascope-1.25.7.dist-info/RECORD +0 -378
  473. {mirascope-1.25.7.dist-info → mirascope-2.0.0a0.dist-info}/WHEEL +0 -0
  474. {mirascope-1.25.7.dist-info → mirascope-2.0.0a0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,363 @@
1
+ """Stream classes for streaming assistant content parts."""
2
+
3
+ from abc import ABC, abstractmethod
4
+ from collections.abc import AsyncIterator, Iterator
5
+ from typing import Generic, Literal, TypeAlias, TypeVar
6
+
7
+ from ..content import (
8
+ AssistantContentPart,
9
+ Text,
10
+ TextChunk,
11
+ Thought,
12
+ ThoughtChunk,
13
+ ToolCall,
14
+ ToolCallChunk,
15
+ )
16
+
17
+ ContentT = TypeVar("ContentT", bound=AssistantContentPart)
18
+ """Type variable for content types (Text, Thought, ToolCall)."""
19
+
20
+ DeltaT = TypeVar("DeltaT")
21
+ """Type variable for the deltas that the stream provides on iteration."""
22
+
23
+
24
+ class BaseStream(ABC, Generic[ContentT, DeltaT]):
25
+ """Base class for synchronous streaming content."""
26
+
27
+ @abstractmethod
28
+ def __iter__(self) -> Iterator[DeltaT]:
29
+ """Iterate over content deltas as they arrive."""
30
+ ...
31
+
32
+ @abstractmethod
33
+ def collect(self) -> ContentT:
34
+ """Collect all chunks and return the final content."""
35
+ ...
36
+
37
+
38
+ class BaseAsyncStream(ABC, Generic[ContentT, DeltaT]):
39
+ """Base class for asynchronous streaming content."""
40
+
41
+ @abstractmethod
42
+ def __aiter__(self) -> AsyncIterator[DeltaT]:
43
+ """Asynchronously iterate over content deltas as they arrive."""
44
+ ...
45
+
46
+ @abstractmethod
47
+ async def collect(self) -> ContentT:
48
+ """Asynchronously collect all chunks and return the final content."""
49
+ ...
50
+
51
+
52
+ class TextStream(BaseStream[Text, str]):
53
+ """Synchronous text stream implementation."""
54
+
55
+ type: Literal["text_stream"] = "text_stream"
56
+
57
+ content_type: Literal["text"] = "text"
58
+ """The type of content stored in this stream."""
59
+
60
+ partial_text: str
61
+ """The accumulated text content as chunks are received."""
62
+
63
+ def __init__(
64
+ self,
65
+ chunk_iterator: Iterator[TextChunk],
66
+ ) -> None:
67
+ """Initialize TextStream with a start chunk and chunk iterator.
68
+
69
+ Args:
70
+ chunk_iterator: Iterator providing subsequent chunks.
71
+ """
72
+ self.partial_text = ""
73
+ self._chunk_iterator = chunk_iterator
74
+
75
+ def __iter__(self) -> Iterator[str]:
76
+ """Iterate over text deltas as they are received.
77
+
78
+ Yields:
79
+ str: Each delta string containing text.
80
+ """
81
+ for chunk in self._chunk_iterator:
82
+ delta = chunk.delta
83
+ self.partial_text += delta
84
+ yield delta
85
+
86
+ def collect(self) -> Text:
87
+ """Collect all chunks and return the final Text content.
88
+
89
+ Returns:
90
+ Text: The complete text content after consuming all chunks.
91
+ """
92
+ for _ in self:
93
+ pass
94
+ return Text(text=self.partial_text)
95
+
96
+
97
+ class AsyncTextStream(BaseAsyncStream[Text, str]):
98
+ """Asynchronous text stream implementation."""
99
+
100
+ type: Literal["async_text_stream"] = "async_text_stream"
101
+
102
+ content_type: Literal["text"] = "text"
103
+ """The type of content stored in this stream."""
104
+
105
+ partial_text: str
106
+ """The accumulated text content as chunks are received."""
107
+
108
+ def __init__(
109
+ self,
110
+ chunk_iterator: AsyncIterator[TextChunk],
111
+ ) -> None:
112
+ """Initialize AsyncTextStream with a chunk iterator.
113
+
114
+ Args:
115
+ chunk_iterator: AsyncIterator providing subsequent chunks.
116
+ """
117
+ self.partial_text = ""
118
+ self._chunk_iterator = chunk_iterator
119
+
120
+ async def __aiter__(self) -> AsyncIterator[str]:
121
+ """Asynchronously iterate over text deltas as they are received.
122
+
123
+ Yields:
124
+ str: Each delta string containing text.
125
+ """
126
+ async for chunk in self._chunk_iterator:
127
+ delta = chunk.delta
128
+ self.partial_text += delta
129
+ yield delta
130
+
131
+ async def collect(self) -> Text:
132
+ """Asynchronously collect all chunks and return the final Text content.
133
+
134
+ Returns:
135
+ Text: The complete text content after consuming all chunks.
136
+ """
137
+ async for _ in self:
138
+ pass
139
+ return Text(text=self.partial_text)
140
+
141
+
142
+ class ThoughtStream(BaseStream[Thought, str]):
143
+ """Synchronous thought stream implementation."""
144
+
145
+ type: Literal["thought_stream"] = "thought_stream"
146
+
147
+ content_type: Literal["thought"] = "thought"
148
+ """The type of content stored in this stream."""
149
+
150
+ partial_thought: str
151
+ """The accumulated thought content as chunks are received."""
152
+
153
+ def __init__(
154
+ self,
155
+ chunk_iterator: Iterator[ThoughtChunk],
156
+ ) -> None:
157
+ """Initialize ThoughtStream with a chunk iterator.
158
+
159
+ Args:
160
+ chunk_iterator: Iterator providing subsequent chunks.
161
+ """
162
+ self.partial_thought = ""
163
+ self._chunk_iterator = chunk_iterator
164
+
165
+ def __iter__(self) -> Iterator[str]:
166
+ """Iterate over thought deltas as they are received.
167
+
168
+ Yields:
169
+ str: Each delta string containing thought text.
170
+ """
171
+ for chunk in self._chunk_iterator:
172
+ delta = chunk.delta
173
+ self.partial_thought += delta
174
+ yield delta
175
+
176
+ def collect(self) -> Thought:
177
+ """Collect all chunks and return the final Thought content.
178
+
179
+ Returns:
180
+ Thought: The complete thought content after consuming all chunks.
181
+ """
182
+ for _ in self:
183
+ pass
184
+ return Thought(thought=self.partial_thought)
185
+
186
+
187
+ class AsyncThoughtStream(BaseAsyncStream[Thought, str]):
188
+ """Asynchronous thought stream implementation."""
189
+
190
+ type: Literal["async_thought_stream"] = "async_thought_stream"
191
+
192
+ content_type: Literal["thought"] = "thought"
193
+ """The type of content stored in this stream."""
194
+
195
+ partial_thought: str
196
+ """The accumulated thought content as chunks are received."""
197
+
198
+ def __init__(
199
+ self,
200
+ chunk_iterator: AsyncIterator[ThoughtChunk],
201
+ ) -> None:
202
+ """Initialize AsyncThoughtStream with a chunk iterator.
203
+
204
+ Args:
205
+ chunk_iterator: AsyncIterator providing subsequent chunks.
206
+ """
207
+ self.partial_thought = ""
208
+ self._chunk_iterator = chunk_iterator
209
+
210
+ async def __aiter__(self) -> AsyncIterator[str]:
211
+ """Asynchronously iterate over thought deltas as they are received.
212
+
213
+ Yields:
214
+ str: Each delta string containing thought text.
215
+ """
216
+ async for chunk in self._chunk_iterator:
217
+ delta = chunk.delta
218
+ self.partial_thought += delta
219
+ yield delta
220
+
221
+ async def collect(self) -> Thought:
222
+ """Asynchronously collect all chunks and return the final Thought content.
223
+
224
+ Returns:
225
+ Thought: The complete thought content after consuming all chunks.
226
+ """
227
+ async for _ in self:
228
+ pass
229
+ return Thought(thought=self.partial_thought)
230
+
231
+
232
+ class ToolCallStream(BaseStream[ToolCall, str]):
233
+ """Synchronous tool call stream implementation."""
234
+
235
+ type: Literal["tool_call_stream"] = "tool_call_stream"
236
+
237
+ content_type: Literal["tool_call"] = "tool_call"
238
+ """The type of content stored in this stream."""
239
+
240
+ tool_id: str
241
+ """A unique identifier for this tool call."""
242
+
243
+ tool_name: str
244
+ """The name of the tool being called."""
245
+
246
+ partial_args: str
247
+ """The accumulated tool arguments as chunks are received."""
248
+
249
+ def __init__(
250
+ self,
251
+ tool_id: str,
252
+ tool_name: str,
253
+ chunk_iterator: Iterator[ToolCallChunk],
254
+ ) -> None:
255
+ """Initialize ToolCallStream with tool metadata and chunk iterator.
256
+
257
+ Args:
258
+ tool_id: A unique identifier for this tool call.
259
+ tool_name: The name of the tool being called.
260
+ chunk_iterator: Iterator providing subsequent chunks.
261
+ """
262
+ self.tool_id = tool_id
263
+ self.tool_name = tool_name
264
+ self.partial_args = ""
265
+ self._chunk_iterator = chunk_iterator
266
+
267
+ def __iter__(self) -> Iterator[str]:
268
+ """Iterate over tool call argument deltas as they are received.
269
+
270
+ Yields:
271
+ str: Each delta string containing JSON argument fragments.
272
+ """
273
+ for chunk in self._chunk_iterator:
274
+ delta = chunk.delta
275
+ self.partial_args += delta
276
+ yield delta
277
+
278
+ def collect(self) -> ToolCall:
279
+ """Collect all chunks and return the final ToolCall content.
280
+
281
+ Returns:
282
+ ToolCall: The complete tool call after consuming all chunks.
283
+ """
284
+ for _ in self:
285
+ pass
286
+ return ToolCall(id=self.tool_id, name=self.tool_name, args=self.partial_args)
287
+
288
+
289
+ class AsyncToolCallStream(BaseAsyncStream[ToolCall, str]):
290
+ """Asynchronous tool call stream implementation."""
291
+
292
+ type: Literal["async_tool_call_stream"] = "async_tool_call_stream"
293
+
294
+ content_type: Literal["tool_call"] = "tool_call"
295
+ """The type of content stored in this stream."""
296
+
297
+ tool_id: str
298
+ """A unique identifier for this tool call."""
299
+
300
+ tool_name: str
301
+ """The name of the tool being called."""
302
+
303
+ partial_args: str
304
+ """The accumulated tool arguments as chunks are received."""
305
+
306
+ def __init__(
307
+ self,
308
+ tool_id: str,
309
+ tool_name: str,
310
+ chunk_iterator: AsyncIterator[ToolCallChunk],
311
+ ) -> None:
312
+ """Initialize AsyncToolCallStream with tool metadata and chunk iterator.
313
+
314
+ Args:
315
+ tool_id: A unique identifier for this tool call.
316
+ tool_name: The name of the tool being called.
317
+ chunk_iterator: AsyncIterator providing subsequent chunks.
318
+ """
319
+ self.tool_id = tool_id
320
+ self.tool_name = tool_name
321
+ self.partial_args = ""
322
+ self._chunk_iterator = chunk_iterator
323
+
324
+ async def __aiter__(self) -> AsyncIterator[str]:
325
+ """Asynchronously iterate over tool call argument deltas as they are received.
326
+
327
+ Yields:
328
+ str: Each delta string containing JSON argument fragments.
329
+ """
330
+ async for chunk in self._chunk_iterator:
331
+ delta = chunk.delta
332
+ self.partial_args += delta
333
+ yield delta
334
+
335
+ async def collect(self) -> ToolCall:
336
+ """Asynchronously collect all chunks and return the final ToolCall content.
337
+
338
+ Returns:
339
+ ToolCall: The complete tool call after consuming all chunks.
340
+ """
341
+ async for _ in self:
342
+ pass
343
+ return ToolCall(id=self.tool_id, name=self.tool_name, args=self.partial_args)
344
+
345
+
346
+ Stream: TypeAlias = TextStream | ToolCallStream | ThoughtStream
347
+ """A synchronous assistant content stream."""
348
+
349
+ AsyncStream: TypeAlias = AsyncTextStream | AsyncToolCallStream | AsyncThoughtStream
350
+ """An asynchronous assistant content stream."""
351
+
352
+ __all__ = [
353
+ "AsyncStream",
354
+ "AsyncTextStream",
355
+ "AsyncThoughtStream",
356
+ "AsyncToolCallStream",
357
+ "BaseAsyncStream",
358
+ "BaseStream",
359
+ "Stream",
360
+ "TextStream",
361
+ "ThoughtStream",
362
+ "ToolCallStream",
363
+ ]
@@ -0,0 +1,40 @@
1
+ """The Tools module for LLMs."""
2
+
3
+ from . import protocols
4
+ from .decorator import ToolDecorator, tool
5
+ from .tool_schema import (
6
+ FORMAT_TOOL_NAME,
7
+ ToolParameterSchema,
8
+ ToolSchema,
9
+ ToolSchemaT,
10
+ )
11
+ from .toolkit import (
12
+ AsyncContextToolkit,
13
+ AsyncToolkit,
14
+ BaseToolkit,
15
+ ContextToolkit,
16
+ Toolkit,
17
+ ToolkitT,
18
+ )
19
+ from .tools import AsyncContextTool, AsyncTool, ContextTool, Tool, ToolT
20
+
21
+ __all__ = [
22
+ "FORMAT_TOOL_NAME",
23
+ "AsyncContextTool",
24
+ "AsyncContextToolkit",
25
+ "AsyncTool",
26
+ "AsyncToolkit",
27
+ "BaseToolkit",
28
+ "ContextTool",
29
+ "ContextToolkit",
30
+ "Tool",
31
+ "ToolDecorator",
32
+ "ToolParameterSchema",
33
+ "ToolSchema",
34
+ "ToolSchemaT",
35
+ "ToolT",
36
+ "Toolkit",
37
+ "ToolkitT",
38
+ "protocols",
39
+ "tool",
40
+ ]
@@ -0,0 +1,25 @@
1
+ """Utilities for tool type checking and validation."""
2
+
3
+ import inspect
4
+ from typing_extensions import TypeIs
5
+
6
+ from ..context import DepsT, _utils as _context_utils
7
+ from ..types import JsonableCovariantT, P
8
+ from .protocols import AsyncContextToolFn, AsyncToolFn, ContextToolFn, ToolFn
9
+
10
+
11
+ def is_context_tool_fn(
12
+ fn: ToolFn | AsyncToolFn | ContextToolFn | AsyncContextToolFn,
13
+ ) -> TypeIs[
14
+ ContextToolFn[DepsT, P, JsonableCovariantT]
15
+ | AsyncContextToolFn[DepsT, P, JsonableCovariantT]
16
+ ]:
17
+ """Type guard to check if a function is a context tool function."""
18
+ return _context_utils.first_param_is_context(fn)
19
+
20
+
21
+ def is_async_tool_fn(
22
+ fn: ToolFn | AsyncToolFn | ContextToolFn | AsyncContextToolFn,
23
+ ) -> TypeIs[AsyncToolFn | AsyncContextToolFn]:
24
+ """Type guard to check if a function is an async tool function."""
25
+ return inspect.iscoroutinefunction(fn)
@@ -0,0 +1,175 @@
1
+ """The `llm.tool` decorator for turning functions into tools."""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import overload
5
+
6
+ from ..context import DepsT
7
+ from ..types import JsonableCovariantT, P
8
+ from . import _utils as _tool_utils
9
+ from .protocols import AsyncContextToolFn, AsyncToolFn, ContextToolFn, ToolFn
10
+ from .tools import AsyncContextTool, AsyncTool, ContextTool, Tool
11
+
12
+
13
+ @dataclass(kw_only=True)
14
+ class ToolDecorator:
15
+ """Protocol for the tool decorator."""
16
+
17
+ strict: bool
18
+ """Whether to use strict tool calling, if supported by the provider."""
19
+
20
+ @overload
21
+ def __call__( # pyright:ignore[reportOverlappingOverload]
22
+ self, fn: ContextToolFn[DepsT, P, JsonableCovariantT]
23
+ ) -> ContextTool[DepsT, P, JsonableCovariantT]:
24
+ """Call the decorator with a context function."""
25
+ ...
26
+
27
+ @overload
28
+ def __call__( # pyright:ignore[reportOverlappingOverload]
29
+ self, fn: AsyncContextToolFn[DepsT, P, JsonableCovariantT]
30
+ ) -> AsyncContextTool[DepsT, P, JsonableCovariantT]:
31
+ """Call the decorator with an async context function."""
32
+ ...
33
+
34
+ @overload
35
+ def __call__(
36
+ self, fn: ToolFn[P, JsonableCovariantT]
37
+ ) -> Tool[P, JsonableCovariantT]:
38
+ """Call the decorator with a sync function."""
39
+ ...
40
+
41
+ @overload
42
+ def __call__(
43
+ self, fn: AsyncToolFn[P, JsonableCovariantT]
44
+ ) -> AsyncTool[P, JsonableCovariantT]:
45
+ """Call the decorator with an async function."""
46
+ ...
47
+
48
+ def __call__(
49
+ self,
50
+ fn: ContextToolFn[DepsT, P, JsonableCovariantT]
51
+ | AsyncContextToolFn[DepsT, P, JsonableCovariantT]
52
+ | ToolFn[P, JsonableCovariantT]
53
+ | AsyncToolFn[P, JsonableCovariantT],
54
+ ) -> (
55
+ ContextTool[DepsT, P, JsonableCovariantT]
56
+ | AsyncContextTool[DepsT, P, JsonableCovariantT]
57
+ | Tool[P, JsonableCovariantT]
58
+ | AsyncTool[P, JsonableCovariantT]
59
+ ):
60
+ """Call the decorator with a function."""
61
+ is_context = _tool_utils.is_context_tool_fn(fn)
62
+ is_async = _tool_utils.is_async_tool_fn(fn)
63
+
64
+ if is_context and is_async:
65
+ return AsyncContextTool[DepsT, P, JsonableCovariantT](
66
+ fn, strict=self.strict
67
+ )
68
+ elif is_context:
69
+ return ContextTool[DepsT, P, JsonableCovariantT](fn, strict=self.strict)
70
+ elif is_async:
71
+ return AsyncTool[P, JsonableCovariantT](fn, strict=self.strict)
72
+ else:
73
+ return Tool[P, JsonableCovariantT](fn, strict=self.strict)
74
+
75
+
76
+ @overload
77
+ def tool( # pyright:ignore[reportOverlappingOverload]
78
+ __fn: AsyncContextToolFn[DepsT, P, JsonableCovariantT],
79
+ ) -> AsyncContextTool[DepsT, P, JsonableCovariantT]:
80
+ """Overload for async context tool functions."""
81
+ ...
82
+
83
+
84
+ @overload
85
+ def tool( # pyright:ignore[reportOverlappingOverload]
86
+ __fn: ContextToolFn[DepsT, P, JsonableCovariantT],
87
+ ) -> ContextTool[DepsT, P, JsonableCovariantT]:
88
+ """Overload for context tool functions."""
89
+ ...
90
+
91
+
92
+ @overload
93
+ def tool(__fn: AsyncToolFn[P, JsonableCovariantT]) -> AsyncTool[P, JsonableCovariantT]:
94
+ """Overload for regular async tool functions."""
95
+ ...
96
+
97
+
98
+ @overload
99
+ def tool(__fn: ToolFn[P, JsonableCovariantT]) -> Tool[P, JsonableCovariantT]:
100
+ """Overload for regular sync tool functions."""
101
+ ...
102
+
103
+
104
+ @overload
105
+ def tool(*, strict: bool = False) -> ToolDecorator:
106
+ """Overload for setting non-default arguments."""
107
+ ...
108
+
109
+
110
+ def tool(
111
+ __fn: ContextToolFn[DepsT, P, JsonableCovariantT]
112
+ | AsyncContextToolFn[DepsT, P, JsonableCovariantT]
113
+ | ToolFn[P, JsonableCovariantT]
114
+ | AsyncToolFn[P, JsonableCovariantT]
115
+ | None = None,
116
+ *,
117
+ strict: bool = False,
118
+ ) -> (
119
+ ContextTool[DepsT, P, JsonableCovariantT]
120
+ | AsyncContextTool[DepsT, P, JsonableCovariantT]
121
+ | Tool[P, JsonableCovariantT]
122
+ | AsyncTool[P, JsonableCovariantT]
123
+ | ToolDecorator
124
+ ):
125
+ '''Decorator that turns a function into a tool definition.
126
+
127
+ This decorator creates a `Tool` or `ContextTool` that can be used with `llm.call`.
128
+ The function's name, docstring, and type hints are used to generate the
129
+ tool's metadata.
130
+
131
+ If the first parameter is named 'ctx' or typed as `llm.Context[T]`, it creates
132
+ a ContextTool. Otherwise, it creates a regular Tool.
133
+
134
+ Args:
135
+ strict: Whether the tool should use strict mode when supported by the model.
136
+
137
+ Returns:
138
+ A decorator function that converts the function into a Tool or ContextTool.
139
+
140
+ Examples:
141
+
142
+ Regular tool:
143
+ ```python
144
+ from mirascope import llm
145
+
146
+ @llm.tool
147
+ def available_books() -> list[str]:
148
+ """Returns the list of available books."""
149
+ return ["The Name of the Wind"]
150
+ ```
151
+
152
+ Context tool:
153
+ ```python
154
+ from dataclasses import dataclass
155
+
156
+ from mirascope import llm
157
+
158
+
159
+ @dataclass
160
+ class Library:
161
+ books: list[str]
162
+
163
+
164
+ library = Library(books=["Mistborn", "Gödel, Escher, Bach", "Dune"])
165
+
166
+ @llm.tool
167
+ def available_books(ctx: llm.Context[Library]) -> list[str]:
168
+ """Returns the list of available books."""
169
+ return ctx.deps.books
170
+ ```
171
+ '''
172
+ decorator = ToolDecorator(strict=strict)
173
+ if __fn is None:
174
+ return decorator
175
+ return decorator(__fn)
@@ -0,0 +1,96 @@
1
+ from typing import Any, Protocol
2
+
3
+ from ..context import Context, DepsT
4
+ from ..types import JsonableCovariantT, P
5
+
6
+
7
+ class ToolFn(Protocol[P, JsonableCovariantT]):
8
+ """Protocol for the tool function."""
9
+
10
+ __name__: str
11
+ """The name of the tool."""
12
+
13
+ def __call__(self, *args: P.args, **kwargs: P.kwargs) -> JsonableCovariantT:
14
+ """Call the function with the given arguments."""
15
+ raise NotImplementedError()
16
+
17
+
18
+ class AsyncToolFn(Protocol[P, JsonableCovariantT]):
19
+ """Protocol for the async tool function."""
20
+
21
+ __name__: str
22
+ """The name of the tool."""
23
+
24
+ async def __call__(self, *args: P.args, **kwargs: P.kwargs) -> JsonableCovariantT:
25
+ """Call the function with the given arguments."""
26
+ raise NotImplementedError()
27
+
28
+
29
+ class ContextToolFn(Protocol[DepsT, P, JsonableCovariantT]):
30
+ """Protocol for the context tool function."""
31
+
32
+ __name__: str
33
+ """The name of the tool."""
34
+
35
+ def __call__(
36
+ self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
37
+ ) -> JsonableCovariantT:
38
+ """Call the function with the given arguments."""
39
+ raise NotImplementedError()
40
+
41
+
42
+ class AsyncContextToolFn(Protocol[DepsT, P, JsonableCovariantT]):
43
+ """Protocol for the async context tool function."""
44
+
45
+ __name__: str
46
+ """The name of the tool."""
47
+
48
+ async def __call__(
49
+ self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
50
+ ) -> JsonableCovariantT:
51
+ """Call the function with the given arguments."""
52
+ raise NotImplementedError()
53
+
54
+
55
+ class _KwargsCallable(Protocol[JsonableCovariantT]):
56
+ """Protocol for functions that can be called with `Any`-typed kwargs.
57
+
58
+ Used internally to type-cast tool functions for compatibility with
59
+ json.loads() output when executing tool calls.
60
+ """
61
+
62
+ def __call__(self, **kwargs: dict[str, Any]) -> JsonableCovariantT: ...
63
+
64
+
65
+ class _AsyncKwargsCallable(Protocol[JsonableCovariantT]):
66
+ """Protocol for async functions that can be called with `Any`-typed kwargs.
67
+
68
+ Used internally to type-cast async tool functions for compatibility with
69
+ json.loads() output when executing tool calls.
70
+ """
71
+
72
+ async def __call__(self, **kwargs: dict[str, Any]) -> JsonableCovariantT: ...
73
+
74
+
75
+ class _ContextKwargsCallable(Protocol[DepsT, JsonableCovariantT]):
76
+ """Protocol for context functions that can be called with `Any`-typed kwargs.
77
+
78
+ Used internally to type-cast context tool functions for compatibility with
79
+ json.loads() output when executing tool calls.
80
+ """
81
+
82
+ def __call__(
83
+ self, ctx: Context[DepsT], **kwargs: dict[str, Any]
84
+ ) -> JsonableCovariantT: ...
85
+
86
+
87
+ class _AsyncJsonKwargsCallable(Protocol[DepsT, JsonableCovariantT]):
88
+ """Protocol for async context functions that can be called with `Any`-typed kwargs.
89
+
90
+ Used internally to type-cast async context tool functions for compatibility with
91
+ json.loads() output when executing tool calls.
92
+ """
93
+
94
+ async def __call__(
95
+ self, ctx: Context[DepsT], **kwargs: dict[str, Any]
96
+ ) -> JsonableCovariantT: ...