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,104 @@
1
+ """The `llm.format` decorator for defining response formats as classes."""
2
+
3
+ import inspect
4
+
5
+ from ..types import NoneType
6
+ from ._utils import default_formatting_instructions
7
+ from .types import Format, FormattableT, FormattingMode, HasFormattingInstructions
8
+
9
+
10
+ def format(
11
+ formattable: type[FormattableT] | None,
12
+ *,
13
+ mode: FormattingMode,
14
+ ) -> Format[FormattableT] | None:
15
+ """Returns a `Format` that describes structured output for a Formattable type.
16
+
17
+ This function converts a Formattable type (e.g. Pydantic BaseModel) into a `Format`
18
+ object that describes how the object should be formatted. Calling `llm.format`
19
+ is optional, as all the APIs that expect a `Format` can also take the Formattable
20
+ type directly. However, calling `llm.format` is necessary in order to specify the
21
+ formatting mode that will be used.
22
+
23
+ Args:
24
+ mode: The format mode to use, one of the following:
25
+ - "strict": Use model strict structured outputs, or fail if unavailable.
26
+ - "tool": Use forced tool calling with a special tool that represents a
27
+ formatted response.
28
+ - "json": Use provider json mode if available, or modify prompt to request
29
+ json if not.
30
+
31
+ The Formattable type may provide custom formatting instructions via a
32
+ `formatting_instructions(cls)` classmethod. If that method is present, it will be called,
33
+ and the resulting instructions will automatically be appended to the system prompt.
34
+
35
+ If no formatting instructions are present, then Mirascope may auto-generate instructions
36
+ based on the active format mode. To disable this behavior and all prompt modification,
37
+ you can add the `formatting_instructions` classmethod and have it return `None`.
38
+
39
+ Returns:
40
+ A `Format` object describing the Formattable type.
41
+
42
+ Example:
43
+ Using with an LLM call:
44
+
45
+ ```python
46
+ from pydantic import BaseModel
47
+
48
+ from mirascope import llm
49
+
50
+
51
+ class Book(BaseModel):
52
+ title: str
53
+ author: str
54
+
55
+ format = llm.format(Book, mode="strict")
56
+
57
+ @llm.call(
58
+ provider="openai:completions",
59
+ model_id="gpt-4o-mini",
60
+ format=format,
61
+ )
62
+ def recommend_book(genre: str):
63
+ return f"Recommend a {genre} book."
64
+
65
+ response = recommend_book("fantasy")
66
+ book: Book = response.parse()
67
+ print(f"{book.title} by {book.author}")
68
+ ```
69
+ """
70
+ # TODO: Add caching or memoization to this function (e.g. functools.lru_cache)
71
+
72
+ if formattable is None or formattable is NoneType:
73
+ return None
74
+
75
+ description = None
76
+ if formattable.__doc__:
77
+ description = inspect.cleandoc(formattable.__doc__)
78
+
79
+ schema = formattable.model_json_schema()
80
+ formatting_instructions = None
81
+ if isinstance(formattable, HasFormattingInstructions):
82
+ formatting_instructions = formattable.formatting_instructions()
83
+ else:
84
+ formatting_instructions = default_formatting_instructions(schema, mode)
85
+
86
+ return Format[FormattableT](
87
+ name=formattable.__name__,
88
+ description=description,
89
+ schema=schema,
90
+ mode=mode,
91
+ formatting_instructions=formatting_instructions,
92
+ formattable=formattable,
93
+ )
94
+
95
+
96
+ def resolve_format(
97
+ formattable: type[FormattableT] | Format[FormattableT] | None,
98
+ default_mode: FormattingMode,
99
+ ) -> Format[FormattableT] | None:
100
+ """Resolve a `Format` (or None) from a possible `Format` or Formattable."""
101
+ if isinstance(formattable, Format):
102
+ return formattable
103
+ else:
104
+ return format(formattable, mode=default_mode)
@@ -0,0 +1,30 @@
1
+ """The `FromCallArgs` class annotation for marking a field as a call argument."""
2
+
3
+
4
+ class FromCallArgs:
5
+ """A marker class for indicating that a field is a call argument.
6
+
7
+ This ensures that the LLM call does not attempt to generate this field. Instead, it
8
+ will populate this field with the call argument with a matching name.
9
+
10
+ This is useful for colocating e.g. validation of a generated output against and
11
+ input argument (such as the length of an output given a number input).
12
+
13
+ Example:
14
+
15
+ ```
16
+ class Book(BaseModel):
17
+ title: Annotated[str, llm.formatting.FromCallArgs()]
18
+ author: Annotated[str, llm.formatting.FromCallArgs()]
19
+ summary: str
20
+
21
+
22
+ @llm.call(
23
+ provider="openai:completions",
24
+ model_id="gpt-4o-mini",
25
+ format=Book,
26
+ )
27
+ def summarize_book(title: str, author: str):
28
+ return f"Summarize {title} by {author}."
29
+ ```
30
+ """
@@ -0,0 +1,58 @@
1
+ """
2
+ --------------------------------------------------------------------------------
3
+ Source: https://github.com/pydantic/pydantic/issues/6381#issuecomment-1831607091
4
+ By: silviumarcu
5
+
6
+ This code is used in accordance with the repository's license, and this reference
7
+ serves as an acknowledgment of the original author's contribution to this project.
8
+ --------------------------------------------------------------------------------
9
+ """
10
+
11
+ from typing import Generic, NoReturn
12
+
13
+ from .format import FormattableT
14
+
15
+
16
+ class Partial(Generic[FormattableT]):
17
+ """Generate a new class with all attributes optionals.
18
+
19
+ Notes:
20
+ This will wrap a class inheriting form BaseModel and will recursively
21
+ convert all its attributes and its children's attributes to optionals.
22
+
23
+ Example:
24
+ Partial[SomeModel]
25
+ """
26
+
27
+ def __new__(
28
+ cls,
29
+ *args: object, # noqa :ARG003
30
+ **kwargs: object, # noqa :ARG003
31
+ ) -> "Partial[FormattableT]":
32
+ """Cannot instantiate.
33
+
34
+ Raises:
35
+ TypeError: Direct instantiation not allowed.
36
+ """
37
+ raise TypeError("Cannot instantiate abstract Partial class.")
38
+
39
+ def __init_subclass__(
40
+ cls,
41
+ *args: object,
42
+ **kwargs: object,
43
+ ) -> NoReturn:
44
+ """Cannot subclass.
45
+
46
+ Raises:
47
+ TypeError: Subclassing not allowed.
48
+ """
49
+ raise TypeError(f"Cannot subclass {cls.__module__}.Partial")
50
+
51
+ def __class_getitem__(
52
+ cls,
53
+ wrapped_class: type[FormattableT],
54
+ ) -> type[FormattableT]:
55
+ """Convert model to a partial model with all fields being optionals."""
56
+ # TODO: Implement proper partial model generation
57
+ # For now, return the original class to avoid import errors
58
+ return wrapped_class
@@ -0,0 +1,109 @@
1
+ """Type for the formatting module."""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Generic, Literal, Protocol, runtime_checkable
5
+ from typing_extensions import TypeVar
6
+
7
+ from pydantic import BaseModel
8
+
9
+ # TODO: Support primitive types (e.g. `format=list[Book]`)
10
+ FormattableT = TypeVar("FormattableT", bound=BaseModel | None, default=None)
11
+ """Type variable for structured response format types.
12
+
13
+ This TypeVar represents the type of structured output format that LLM responses
14
+ can be parsed into, or None if no format is specified.
15
+ If format is specified, it must extend Pydantic BaseModel.
16
+ """
17
+
18
+
19
+ FormattingMode = Literal[
20
+ "strict",
21
+ "json",
22
+ "tool",
23
+ ]
24
+ """Available modes for response format generation.
25
+
26
+ - "strict": Use strict mode for structured outputs, asking the LLM to strictly adhere
27
+ to a given JSON schema. Not all providers or models support it, and may not be
28
+ compatible with tool calling. When making a call using this mode, an
29
+ `llm.FormattingModeNotSupportedError` error may be raised (if "strict" mode is wholly
30
+ unsupported), or an `llm.FeatureNotSupportedError` may be raised (if trying to use
31
+ strict along with tools and that is unsupported).
32
+
33
+ - "json": Use JSON mode for structured outputs. In contrast to strict mode, we ask the
34
+ LLM to output JSON as text, though without guarantees that the model will output
35
+ the expected format schema. If the provider has explicit JSON mode, it will be used;
36
+ otherwise, Mirascope will modify the system prompt to request JSON output. May
37
+ raise an `llm.FeatureNotSupportedError` if tools are present and the
38
+ model does not support tool calling when using JSON mode.
39
+
40
+ - "tool": Use forced tool calling to structure outputs. Mirascope will construct an
41
+ ad-hoc tool with the required json schema as tool args. When the LLM chooses that
42
+ tool, it will automatically be converted from a `ToolCall` into regular response
43
+ content (abstracting over the tool call). If other tools are present, they will
44
+ be handled as regular tool calls.
45
+
46
+ Note: When `llm.format` is not used, the provider will automatically choose a mode at call time.
47
+ """
48
+
49
+
50
+ @dataclass(kw_only=True)
51
+ class Format(Generic[FormattableT]):
52
+ """Class representing a structured output format for LLM responses.
53
+
54
+ A `Format` contains metadata needed to describe a structured output type
55
+ to the LLM, including the expected schema. This class is not instantiated directly,
56
+ but is created by calling `llm.format`, or is automatically generated by LLM
57
+ providers when a `Formattable` is passed to a call method.
58
+
59
+ Example:
60
+
61
+ ```python
62
+ from mirascope import llm
63
+
64
+ class Book:
65
+ title: str
66
+ author: str
67
+
68
+ print(llm.format(Book, mode="tool"))
69
+ ```
70
+ """
71
+
72
+ name: str
73
+ """The name of the response format."""
74
+
75
+ description: str | None
76
+ """A description of the response format, if available."""
77
+
78
+ schema: dict[str, object]
79
+ """JSON schema representation of the structured output format."""
80
+
81
+ mode: FormattingMode
82
+ """The decorator-provided mode of the response format.
83
+
84
+ Determines how the LLM call may be modified in order to extract the expected format.
85
+ """
86
+
87
+ formatting_instructions: str | None
88
+ """The formatting instructions that will be added to the LLM system prompt.
89
+
90
+ If the format type has a `formatting_instructions` class method, the output of that
91
+ call will be used for instructions. Otherwise, instructions may be auto-generated
92
+ based on the formatting mode.
93
+ """
94
+
95
+ formattable: type[FormattableT]
96
+ """The `Formattable` type that this `Format` describes.
97
+
98
+ While the `FormattbleT` typevar allows for `None`, a `Format` will never be
99
+ constructed when the `FormattableT` is `None`, so you may treat this as
100
+ a `RequiredFormattableT` in practice.
101
+ """
102
+
103
+
104
+ @runtime_checkable
105
+ class HasFormattingInstructions(Protocol):
106
+ """Protocol for classes that have been decorated with `@format()`."""
107
+
108
+ @classmethod
109
+ def formatting_instructions(cls) -> str | None: ...
@@ -0,0 +1,5 @@
1
+ """MCP compatibility module."""
2
+
3
+ from .client import MCPClient, sse_client, stdio_client, streamablehttp_client
4
+
5
+ __all__ = ["MCPClient", "sse_client", "stdio_client", "streamablehttp_client"]
@@ -0,0 +1,118 @@
1
+ import contextlib
2
+ from collections.abc import AsyncIterator, Callable
3
+ from datetime import timedelta
4
+
5
+ import httpx
6
+ from mcp import ClientSession
7
+ from mcp.client.session import ListRootsFnT, SamplingFnT
8
+ from mcp.client.sse import sse_client as mcp_sse_client
9
+ from mcp.client.stdio import StdioServerParameters
10
+ from mcp.client.streamable_http import (
11
+ streamablehttp_client as mcp_streamablehttp_client,
12
+ )
13
+ from mcp.shared._httpx_utils import McpHttpClientFactory
14
+
15
+ from ..tools import AsyncTool
16
+
17
+
18
+ class MCPClient:
19
+ """Mirascope wrapper around a MCP ClientSession.
20
+
21
+ It provides a way to get MCP results that are pre-converted into Mirascope-friendly
22
+ types.
23
+
24
+ The underlying MCP ClientSession may be accessed by .session if needed.
25
+ """
26
+
27
+ def __init__(self, session: ClientSession) -> None:
28
+ self._session = session
29
+
30
+ @property
31
+ def session(self) -> ClientSession:
32
+ """Access the underlying MCP ClientSession if needed."""
33
+ return self._session
34
+
35
+ async def list_tools(self) -> list[AsyncTool]:
36
+ """List all tools available on the MCP server.
37
+
38
+ Returns:
39
+ A list of dynamically created `llm.Tool`s.
40
+ """
41
+ raise NotImplementedError()
42
+
43
+
44
+ @contextlib.asynccontextmanager
45
+ async def streamablehttp_client(
46
+ url: str,
47
+ headers: dict[str, str] | None = None,
48
+ timeout: float | timedelta | None = None,
49
+ sse_read_timeout: float | timedelta | None = None,
50
+ terminate_on_close: bool = True,
51
+ httpx_client_factory: McpHttpClientFactory | None = None,
52
+ auth: httpx.Auth | None = None,
53
+ ) -> AsyncIterator[MCPClient]:
54
+ """Create a Mirascope MCPClient using StreamableHTTP."""
55
+ kwargs = {}
56
+ if headers is not None:
57
+ kwargs["headers"] = headers
58
+ if timeout is not None:
59
+ kwargs["timeout"] = timeout
60
+ if sse_read_timeout is not None:
61
+ kwargs["sse_read_timeout"] = sse_read_timeout
62
+ if httpx_client_factory is not None:
63
+ kwargs["httpx_client_factory"] = httpx_client_factory
64
+ if auth is not None:
65
+ kwargs["auth"] = auth
66
+
67
+ async with (
68
+ mcp_streamablehttp_client(
69
+ url,
70
+ terminate_on_close=terminate_on_close,
71
+ **kwargs,
72
+ ) as (read, write, get_session_id),
73
+ ClientSession(
74
+ read,
75
+ write,
76
+ ) as session,
77
+ ):
78
+ await session.initialize()
79
+ yield MCPClient(session)
80
+
81
+
82
+ @contextlib.asynccontextmanager
83
+ async def stdio_client(
84
+ server_parameters: StdioServerParameters,
85
+ read_stream_exception_handler: Callable[[Exception], None] | None = None,
86
+ ) -> AsyncIterator[MCPClient]:
87
+ """Create a Mirascope MCPClient using stdio."""
88
+
89
+ async with (
90
+ ClientSession(None, None) as session, # pyright: ignore [reportArgumentType]
91
+ ):
92
+ raise NotImplementedError()
93
+ await session.initialize()
94
+ yield MCPClient(session)
95
+
96
+
97
+ @contextlib.asynccontextmanager
98
+ async def sse_client(
99
+ url: str,
100
+ list_roots_callback: ListRootsFnT | None = None,
101
+ read_timeout_seconds: timedelta | None = None,
102
+ sampling_callback: SamplingFnT | None = None,
103
+ session: ClientSession | None = None,
104
+ ) -> AsyncIterator[MCPClient]:
105
+ """Create a Mirascope MCPClient using sse."""
106
+
107
+ async with (
108
+ mcp_sse_client(url) as (read, write),
109
+ ClientSession(
110
+ read,
111
+ write,
112
+ read_timeout_seconds=read_timeout_seconds,
113
+ sampling_callback=sampling_callback,
114
+ list_roots_callback=list_roots_callback,
115
+ ) as session,
116
+ ):
117
+ await session.initialize()
118
+ yield MCPClient(session)
@@ -0,0 +1,32 @@
1
+ """The messages module for LLM interactions.
2
+
3
+ This module defines the message types used in LLM interactions. Messages are represented
4
+ as a unified `Message` class with different roles (system, user, assistant) and flexible
5
+ content arrays that can include text, images, audio, documents, and tool interactions.
6
+ """
7
+
8
+ from .message import (
9
+ AssistantContent,
10
+ AssistantMessage,
11
+ Message,
12
+ SystemContent,
13
+ SystemMessage,
14
+ UserContent,
15
+ UserMessage,
16
+ assistant,
17
+ system,
18
+ user,
19
+ )
20
+
21
+ __all__ = [
22
+ "AssistantContent",
23
+ "AssistantMessage",
24
+ "Message",
25
+ "SystemContent",
26
+ "SystemMessage",
27
+ "UserContent",
28
+ "UserMessage",
29
+ "assistant",
30
+ "system",
31
+ "user",
32
+ ]
@@ -0,0 +1,182 @@
1
+ """The `Message` class and its utility constructors."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Sequence
6
+ from dataclasses import dataclass
7
+ from typing import TYPE_CHECKING, Literal, TypeAlias
8
+
9
+ from ..content import AssistantContentPart, Text, UserContentPart
10
+ from ..types import Jsonable
11
+
12
+ if TYPE_CHECKING:
13
+ from ..clients import ModelId, Provider
14
+
15
+
16
+ @dataclass(kw_only=True)
17
+ class SystemMessage:
18
+ """A system message that sets context and instructions for the conversation."""
19
+
20
+ role: Literal["system"] = "system"
21
+ """The role of this message. Always "system"."""
22
+
23
+ content: Text
24
+ """The content of this `SystemMesssage`."""
25
+
26
+
27
+ @dataclass(kw_only=True)
28
+ class UserMessage:
29
+ """A user message containing input from the user."""
30
+
31
+ role: Literal["user"] = "user"
32
+ """The role of this message. Always "user"."""
33
+
34
+ content: Sequence[UserContentPart]
35
+ """The content of the user message."""
36
+
37
+ name: str | None = None
38
+ """A name identifying the creator of this message."""
39
+
40
+
41
+ @dataclass(kw_only=True)
42
+ class AssistantMessage:
43
+ """An assistant message containing the model's response."""
44
+
45
+ role: Literal["assistant"] = "assistant"
46
+ """The role of this message. Always "assistant"."""
47
+
48
+ content: Sequence[AssistantContentPart]
49
+ """The content of the assistant message."""
50
+
51
+ name: str | None = None
52
+ """A name identifying the creator of this message."""
53
+
54
+ provider: Provider | None
55
+ """The LLM provider that generated this assistant message, if available."""
56
+
57
+ model_id: ModelId | None
58
+ """The model identifier of the LLM that generated this assistant message, if available."""
59
+
60
+ raw_message: Jsonable | None
61
+ """The provider-specific raw representation of this assistant message, if available.
62
+
63
+ If raw_content is truthy, then it may be used for provider-specific behavior when
64
+ resuming an LLM interaction that included this assistant message. For example, we can
65
+ reuse the provider-specific raw encoding rather than re-encoding the message from it's
66
+ Mirascope content representation. This may also take advantage of server-side provider
67
+ context, e.g. identifiers of reasoning context tokens that the provider generated.
68
+
69
+ If present, the content should be encoded as JSON-serializable data, and in a format
70
+ that matches representation the provider expects representing the Mirascope data.
71
+ This may involve e.g. converting Pydantic `BaseModel`s into plain dicts via `model_dump`.
72
+
73
+ Raw content is not required, as the Mirascope content can also be used to generate
74
+ a valid input to the provider (potentially without taking advantage of provider-specific
75
+ reasoning caches, etc). In that case raw content should be left empty.
76
+ """
77
+
78
+
79
+ Message: TypeAlias = SystemMessage | UserMessage | AssistantMessage
80
+ """A message in an LLM interaction.
81
+
82
+ Messages have a role (system, user, or assistant) and content that is a sequence
83
+ of content parts. The content can include text, images, audio, documents, and
84
+ tool interactions.
85
+
86
+ For most use cases, prefer the convenience functions `system()`, `user()`, and
87
+ `assistant()` instead of directly creating `Message` objects.
88
+
89
+ Example:
90
+
91
+ ```python
92
+ from mirascope import llm
93
+
94
+ messages = [
95
+ llm.messages.system("You are a helpful assistant."),
96
+ llm.messages.user("Hello, how are you?"),
97
+ ]
98
+ ```
99
+ """
100
+
101
+ UserContent: TypeAlias = str | UserContentPart | Sequence[str | UserContentPart]
102
+ """Type alias for content that can fit into a `UserMessage`."""
103
+
104
+ AssistantContent: TypeAlias = (
105
+ str | AssistantContentPart | Sequence[str | AssistantContentPart]
106
+ )
107
+ """Type alias for content that can fit into an `AssistantMessage`."""
108
+
109
+ SystemContent: TypeAlias = str | Text
110
+ """Type alias for content that can fit into a `SystemMessage`."""
111
+
112
+
113
+ def system(content: SystemContent) -> SystemMessage:
114
+ """Creates a system message.
115
+
116
+ Args:
117
+ content: The content of the message, which must be a `str` or `Text` content.
118
+
119
+ Returns:
120
+ A `SystemMessage`.
121
+ """
122
+ promoted_content = Text(text=content) if isinstance(content, str) else content
123
+ return SystemMessage(content=promoted_content)
124
+
125
+
126
+ def user(
127
+ content: UserContent,
128
+ *,
129
+ name: str | None = None,
130
+ ) -> UserMessage:
131
+ """Creates a user message.
132
+
133
+ Args:
134
+ content: The content of the message, which can be `str` or any `UserContent`,
135
+ or a sequence of such user content pieces.
136
+ name: Optional name to identify a specific user in multi-party conversations.
137
+
138
+ Returns:
139
+ A `UserMessage`.
140
+ """
141
+ if isinstance(content, str) or not isinstance(content, Sequence):
142
+ content = [content]
143
+ promoted_content = [
144
+ Text(text=part) if isinstance(part, str) else part for part in content
145
+ ]
146
+ return UserMessage(content=promoted_content, name=name)
147
+
148
+
149
+ def assistant(
150
+ content: AssistantContent,
151
+ *,
152
+ provider: Provider | None,
153
+ model_id: ModelId | None,
154
+ raw_message: Jsonable | None = None,
155
+ name: str | None = None,
156
+ ) -> AssistantMessage:
157
+ """Creates an assistant message.
158
+
159
+ Args:
160
+ content: The content of the message, which can be `str` or any `AssistantContent`,
161
+ or a sequence of assistant content pieces.
162
+ provider: Optional identifier of the provider that produced this message.
163
+ model_id: Optional id of the model that produced this message.
164
+ raw_message: Optional Jsonable object that contains the provider-specific
165
+ "raw" data representation of the content for this assistant message.
166
+ name: Optional name to identify a specific assistant in multi-party conversations.
167
+
168
+ Returns:
169
+ An `AssistantMessage`.
170
+ """
171
+ if isinstance(content, str) or not isinstance(content, Sequence):
172
+ content = [content]
173
+ promoted_content = [
174
+ Text(text=part) if isinstance(part, str) else part for part in content
175
+ ]
176
+ return AssistantMessage(
177
+ content=promoted_content,
178
+ provider=provider,
179
+ model_id=model_id,
180
+ raw_message=raw_message,
181
+ name=name,
182
+ )
@@ -0,0 +1,16 @@
1
+ """The `llm.models` module for implementing the `Model` interface and utilities.
2
+
3
+ This module provides a unified interface for interacting with different LLM models
4
+ through the `Model` class. The `llm.model()` context manager allows you to override
5
+ the model at runtime, and `llm.use_model()` retrieves the model from context or
6
+ creates a default one.
7
+ """
8
+
9
+ from .models import Model, get_model_from_context, model, use_model
10
+
11
+ __all__ = [
12
+ "Model",
13
+ "get_model_from_context",
14
+ "model",
15
+ "use_model",
16
+ ]