mirascope 1.25.7__py3-none-any.whl → 2.0.0__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 (797) hide show
  1. mirascope/__init__.py +5 -52
  2. mirascope/_stubs.py +363 -0
  3. mirascope/api/__init__.py +14 -0
  4. mirascope/api/_generated/README.md +207 -0
  5. mirascope/api/_generated/__init__.py +440 -0
  6. mirascope/api/_generated/annotations/__init__.py +33 -0
  7. mirascope/api/_generated/annotations/client.py +506 -0
  8. mirascope/api/_generated/annotations/raw_client.py +1414 -0
  9. mirascope/api/_generated/annotations/types/__init__.py +31 -0
  10. mirascope/api/_generated/annotations/types/annotations_create_request_label.py +5 -0
  11. mirascope/api/_generated/annotations/types/annotations_create_response.py +48 -0
  12. mirascope/api/_generated/annotations/types/annotations_create_response_label.py +5 -0
  13. mirascope/api/_generated/annotations/types/annotations_get_response.py +48 -0
  14. mirascope/api/_generated/annotations/types/annotations_get_response_label.py +5 -0
  15. mirascope/api/_generated/annotations/types/annotations_list_request_label.py +5 -0
  16. mirascope/api/_generated/annotations/types/annotations_list_response.py +21 -0
  17. mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item.py +50 -0
  18. mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item_label.py +5 -0
  19. mirascope/api/_generated/annotations/types/annotations_update_request_label.py +5 -0
  20. mirascope/api/_generated/annotations/types/annotations_update_response.py +48 -0
  21. mirascope/api/_generated/annotations/types/annotations_update_response_label.py +5 -0
  22. mirascope/api/_generated/api_keys/__init__.py +17 -0
  23. mirascope/api/_generated/api_keys/client.py +530 -0
  24. mirascope/api/_generated/api_keys/raw_client.py +1236 -0
  25. mirascope/api/_generated/api_keys/types/__init__.py +15 -0
  26. mirascope/api/_generated/api_keys/types/api_keys_create_response.py +28 -0
  27. mirascope/api/_generated/api_keys/types/api_keys_get_response.py +27 -0
  28. mirascope/api/_generated/api_keys/types/api_keys_list_all_for_org_response_item.py +40 -0
  29. mirascope/api/_generated/api_keys/types/api_keys_list_response_item.py +27 -0
  30. mirascope/api/_generated/client.py +211 -0
  31. mirascope/api/_generated/core/__init__.py +52 -0
  32. mirascope/api/_generated/core/api_error.py +23 -0
  33. mirascope/api/_generated/core/client_wrapper.py +46 -0
  34. mirascope/api/_generated/core/datetime_utils.py +28 -0
  35. mirascope/api/_generated/core/file.py +67 -0
  36. mirascope/api/_generated/core/force_multipart.py +16 -0
  37. mirascope/api/_generated/core/http_client.py +543 -0
  38. mirascope/api/_generated/core/http_response.py +55 -0
  39. mirascope/api/_generated/core/jsonable_encoder.py +100 -0
  40. mirascope/api/_generated/core/pydantic_utilities.py +255 -0
  41. mirascope/api/_generated/core/query_encoder.py +58 -0
  42. mirascope/api/_generated/core/remove_none_from_dict.py +11 -0
  43. mirascope/api/_generated/core/request_options.py +35 -0
  44. mirascope/api/_generated/core/serialization.py +276 -0
  45. mirascope/api/_generated/docs/__init__.py +4 -0
  46. mirascope/api/_generated/docs/client.py +91 -0
  47. mirascope/api/_generated/docs/raw_client.py +178 -0
  48. mirascope/api/_generated/environment.py +9 -0
  49. mirascope/api/_generated/environments/__init__.py +23 -0
  50. mirascope/api/_generated/environments/client.py +649 -0
  51. mirascope/api/_generated/environments/raw_client.py +1567 -0
  52. mirascope/api/_generated/environments/types/__init__.py +25 -0
  53. mirascope/api/_generated/environments/types/environments_create_response.py +24 -0
  54. mirascope/api/_generated/environments/types/environments_get_analytics_response.py +60 -0
  55. mirascope/api/_generated/environments/types/environments_get_analytics_response_top_functions_item.py +24 -0
  56. mirascope/api/_generated/environments/types/environments_get_analytics_response_top_models_item.py +22 -0
  57. mirascope/api/_generated/environments/types/environments_get_response.py +24 -0
  58. mirascope/api/_generated/environments/types/environments_list_response_item.py +24 -0
  59. mirascope/api/_generated/environments/types/environments_update_response.py +24 -0
  60. mirascope/api/_generated/errors/__init__.py +25 -0
  61. mirascope/api/_generated/errors/bad_request_error.py +14 -0
  62. mirascope/api/_generated/errors/conflict_error.py +14 -0
  63. mirascope/api/_generated/errors/forbidden_error.py +11 -0
  64. mirascope/api/_generated/errors/internal_server_error.py +10 -0
  65. mirascope/api/_generated/errors/not_found_error.py +11 -0
  66. mirascope/api/_generated/errors/payment_required_error.py +15 -0
  67. mirascope/api/_generated/errors/service_unavailable_error.py +14 -0
  68. mirascope/api/_generated/errors/too_many_requests_error.py +15 -0
  69. mirascope/api/_generated/errors/unauthorized_error.py +11 -0
  70. mirascope/api/_generated/functions/__init__.py +39 -0
  71. mirascope/api/_generated/functions/client.py +647 -0
  72. mirascope/api/_generated/functions/raw_client.py +1890 -0
  73. mirascope/api/_generated/functions/types/__init__.py +53 -0
  74. mirascope/api/_generated/functions/types/functions_create_request_dependencies_value.py +20 -0
  75. mirascope/api/_generated/functions/types/functions_create_response.py +37 -0
  76. mirascope/api/_generated/functions/types/functions_create_response_dependencies_value.py +20 -0
  77. mirascope/api/_generated/functions/types/functions_find_by_hash_response.py +39 -0
  78. mirascope/api/_generated/functions/types/functions_find_by_hash_response_dependencies_value.py +20 -0
  79. mirascope/api/_generated/functions/types/functions_get_by_env_response.py +53 -0
  80. mirascope/api/_generated/functions/types/functions_get_by_env_response_dependencies_value.py +22 -0
  81. mirascope/api/_generated/functions/types/functions_get_response.py +37 -0
  82. mirascope/api/_generated/functions/types/functions_get_response_dependencies_value.py +20 -0
  83. mirascope/api/_generated/functions/types/functions_list_by_env_response.py +25 -0
  84. mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item.py +56 -0
  85. mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item_dependencies_value.py +22 -0
  86. mirascope/api/_generated/functions/types/functions_list_response.py +21 -0
  87. mirascope/api/_generated/functions/types/functions_list_response_functions_item.py +41 -0
  88. mirascope/api/_generated/functions/types/functions_list_response_functions_item_dependencies_value.py +20 -0
  89. mirascope/api/_generated/health/__init__.py +7 -0
  90. mirascope/api/_generated/health/client.py +92 -0
  91. mirascope/api/_generated/health/raw_client.py +175 -0
  92. mirascope/api/_generated/health/types/__init__.py +8 -0
  93. mirascope/api/_generated/health/types/health_check_response.py +22 -0
  94. mirascope/api/_generated/health/types/health_check_response_status.py +5 -0
  95. mirascope/api/_generated/organization_invitations/__init__.py +33 -0
  96. mirascope/api/_generated/organization_invitations/client.py +546 -0
  97. mirascope/api/_generated/organization_invitations/raw_client.py +1519 -0
  98. mirascope/api/_generated/organization_invitations/types/__init__.py +53 -0
  99. mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response.py +34 -0
  100. mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response_role.py +7 -0
  101. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_request_role.py +7 -0
  102. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response.py +48 -0
  103. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_role.py +7 -0
  104. mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_status.py +7 -0
  105. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response.py +48 -0
  106. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_role.py +7 -0
  107. mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_status.py +7 -0
  108. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item.py +48 -0
  109. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_role.py +7 -0
  110. mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_status.py +7 -0
  111. mirascope/api/_generated/organization_memberships/__init__.py +19 -0
  112. mirascope/api/_generated/organization_memberships/client.py +302 -0
  113. mirascope/api/_generated/organization_memberships/raw_client.py +736 -0
  114. mirascope/api/_generated/organization_memberships/types/__init__.py +27 -0
  115. mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item.py +33 -0
  116. mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item_role.py +7 -0
  117. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_request_role.py +7 -0
  118. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response.py +31 -0
  119. mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response_role.py +7 -0
  120. mirascope/api/_generated/organizations/__init__.py +51 -0
  121. mirascope/api/_generated/organizations/client.py +869 -0
  122. mirascope/api/_generated/organizations/raw_client.py +2593 -0
  123. mirascope/api/_generated/organizations/types/__init__.py +71 -0
  124. mirascope/api/_generated/organizations/types/organizations_create_payment_intent_response.py +24 -0
  125. mirascope/api/_generated/organizations/types/organizations_create_response.py +26 -0
  126. mirascope/api/_generated/organizations/types/organizations_create_response_role.py +5 -0
  127. mirascope/api/_generated/organizations/types/organizations_get_response.py +26 -0
  128. mirascope/api/_generated/organizations/types/organizations_get_response_role.py +5 -0
  129. mirascope/api/_generated/organizations/types/organizations_list_response_item.py +26 -0
  130. mirascope/api/_generated/organizations/types/organizations_list_response_item_role.py +5 -0
  131. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_request_target_plan.py +7 -0
  132. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response.py +47 -0
  133. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item.py +33 -0
  134. mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item_resource.py +7 -0
  135. mirascope/api/_generated/organizations/types/organizations_router_balance_response.py +24 -0
  136. mirascope/api/_generated/organizations/types/organizations_subscription_response.py +53 -0
  137. mirascope/api/_generated/organizations/types/organizations_subscription_response_current_plan.py +7 -0
  138. mirascope/api/_generated/organizations/types/organizations_subscription_response_payment_method.py +26 -0
  139. mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change.py +34 -0
  140. mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change_target_plan.py +7 -0
  141. mirascope/api/_generated/organizations/types/organizations_update_response.py +26 -0
  142. mirascope/api/_generated/organizations/types/organizations_update_response_role.py +5 -0
  143. mirascope/api/_generated/organizations/types/organizations_update_subscription_request_target_plan.py +7 -0
  144. mirascope/api/_generated/organizations/types/organizations_update_subscription_response.py +35 -0
  145. mirascope/api/_generated/project_memberships/__init__.py +25 -0
  146. mirascope/api/_generated/project_memberships/client.py +437 -0
  147. mirascope/api/_generated/project_memberships/raw_client.py +1039 -0
  148. mirascope/api/_generated/project_memberships/types/__init__.py +29 -0
  149. mirascope/api/_generated/project_memberships/types/project_memberships_create_request_role.py +7 -0
  150. mirascope/api/_generated/project_memberships/types/project_memberships_create_response.py +35 -0
  151. mirascope/api/_generated/project_memberships/types/project_memberships_create_response_role.py +7 -0
  152. mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item.py +33 -0
  153. mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item_role.py +7 -0
  154. mirascope/api/_generated/project_memberships/types/project_memberships_update_request_role.py +7 -0
  155. mirascope/api/_generated/project_memberships/types/project_memberships_update_response.py +35 -0
  156. mirascope/api/_generated/project_memberships/types/project_memberships_update_response_role.py +7 -0
  157. mirascope/api/_generated/projects/__init__.py +7 -0
  158. mirascope/api/_generated/projects/client.py +428 -0
  159. mirascope/api/_generated/projects/raw_client.py +1302 -0
  160. mirascope/api/_generated/projects/types/__init__.py +10 -0
  161. mirascope/api/_generated/projects/types/projects_create_response.py +25 -0
  162. mirascope/api/_generated/projects/types/projects_get_response.py +25 -0
  163. mirascope/api/_generated/projects/types/projects_list_response_item.py +25 -0
  164. mirascope/api/_generated/projects/types/projects_update_response.py +25 -0
  165. mirascope/api/_generated/reference.md +4915 -0
  166. mirascope/api/_generated/tags/__init__.py +19 -0
  167. mirascope/api/_generated/tags/client.py +504 -0
  168. mirascope/api/_generated/tags/raw_client.py +1288 -0
  169. mirascope/api/_generated/tags/types/__init__.py +17 -0
  170. mirascope/api/_generated/tags/types/tags_create_response.py +41 -0
  171. mirascope/api/_generated/tags/types/tags_get_response.py +41 -0
  172. mirascope/api/_generated/tags/types/tags_list_response.py +23 -0
  173. mirascope/api/_generated/tags/types/tags_list_response_tags_item.py +41 -0
  174. mirascope/api/_generated/tags/types/tags_update_response.py +41 -0
  175. mirascope/api/_generated/token_cost/__init__.py +7 -0
  176. mirascope/api/_generated/token_cost/client.py +160 -0
  177. mirascope/api/_generated/token_cost/raw_client.py +264 -0
  178. mirascope/api/_generated/token_cost/types/__init__.py +8 -0
  179. mirascope/api/_generated/token_cost/types/token_cost_calculate_request_usage.py +54 -0
  180. mirascope/api/_generated/token_cost/types/token_cost_calculate_response.py +52 -0
  181. mirascope/api/_generated/traces/__init__.py +97 -0
  182. mirascope/api/_generated/traces/client.py +1103 -0
  183. mirascope/api/_generated/traces/raw_client.py +2322 -0
  184. mirascope/api/_generated/traces/types/__init__.py +155 -0
  185. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item.py +29 -0
  186. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource.py +27 -0
  187. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item.py +23 -0
  188. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value.py +38 -0
  189. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_array_value.py +19 -0
  190. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value.py +22 -0
  191. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value_values_item.py +20 -0
  192. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item.py +29 -0
  193. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope.py +31 -0
  194. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item.py +23 -0
  195. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value.py +38 -0
  196. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_array_value.py +19 -0
  197. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value.py +22 -0
  198. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value_values_item.py +22 -0
  199. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item.py +48 -0
  200. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item.py +23 -0
  201. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value.py +38 -0
  202. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_array_value.py +19 -0
  203. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value.py +24 -0
  204. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value_values_item.py +22 -0
  205. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_status.py +20 -0
  206. mirascope/api/_generated/traces/types/traces_create_response.py +24 -0
  207. mirascope/api/_generated/traces/types/traces_create_response_partial_success.py +22 -0
  208. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response.py +60 -0
  209. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_functions_item.py +24 -0
  210. mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_models_item.py +22 -0
  211. mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response.py +33 -0
  212. mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response_spans_item.py +88 -0
  213. mirascope/api/_generated/traces/types/traces_get_trace_detail_response.py +33 -0
  214. mirascope/api/_generated/traces/types/traces_get_trace_detail_response_spans_item.py +88 -0
  215. mirascope/api/_generated/traces/types/traces_list_by_function_hash_response.py +25 -0
  216. mirascope/api/_generated/traces/types/traces_list_by_function_hash_response_traces_item.py +44 -0
  217. mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item.py +26 -0
  218. mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item_operator.py +7 -0
  219. mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_by.py +7 -0
  220. mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_order.py +7 -0
  221. mirascope/api/_generated/traces/types/traces_search_by_env_response.py +26 -0
  222. mirascope/api/_generated/traces/types/traces_search_by_env_response_spans_item.py +50 -0
  223. mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item.py +26 -0
  224. mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item_operator.py +7 -0
  225. mirascope/api/_generated/traces/types/traces_search_request_sort_by.py +7 -0
  226. mirascope/api/_generated/traces/types/traces_search_request_sort_order.py +5 -0
  227. mirascope/api/_generated/traces/types/traces_search_response.py +26 -0
  228. mirascope/api/_generated/traces/types/traces_search_response_spans_item.py +50 -0
  229. mirascope/api/_generated/types/__init__.py +85 -0
  230. mirascope/api/_generated/types/already_exists_error.py +22 -0
  231. mirascope/api/_generated/types/already_exists_error_tag.py +5 -0
  232. mirascope/api/_generated/types/bad_request_error_body.py +50 -0
  233. mirascope/api/_generated/types/click_house_error.py +22 -0
  234. mirascope/api/_generated/types/database_error.py +22 -0
  235. mirascope/api/_generated/types/database_error_tag.py +5 -0
  236. mirascope/api/_generated/types/date.py +3 -0
  237. mirascope/api/_generated/types/http_api_decode_error.py +27 -0
  238. mirascope/api/_generated/types/http_api_decode_error_tag.py +5 -0
  239. mirascope/api/_generated/types/immutable_resource_error.py +22 -0
  240. mirascope/api/_generated/types/internal_server_error_body.py +49 -0
  241. mirascope/api/_generated/types/issue.py +38 -0
  242. mirascope/api/_generated/types/issue_tag.py +10 -0
  243. mirascope/api/_generated/types/not_found_error_body.py +22 -0
  244. mirascope/api/_generated/types/not_found_error_tag.py +5 -0
  245. mirascope/api/_generated/types/number_from_string.py +3 -0
  246. mirascope/api/_generated/types/permission_denied_error.py +22 -0
  247. mirascope/api/_generated/types/permission_denied_error_tag.py +5 -0
  248. mirascope/api/_generated/types/plan_limit_exceeded_error.py +32 -0
  249. mirascope/api/_generated/types/plan_limit_exceeded_error_tag.py +7 -0
  250. mirascope/api/_generated/types/pricing_unavailable_error.py +23 -0
  251. mirascope/api/_generated/types/property_key.py +7 -0
  252. mirascope/api/_generated/types/property_key_key.py +25 -0
  253. mirascope/api/_generated/types/property_key_key_tag.py +5 -0
  254. mirascope/api/_generated/types/rate_limit_error.py +31 -0
  255. mirascope/api/_generated/types/rate_limit_error_tag.py +5 -0
  256. mirascope/api/_generated/types/service_unavailable_error_body.py +24 -0
  257. mirascope/api/_generated/types/service_unavailable_error_tag.py +7 -0
  258. mirascope/api/_generated/types/stripe_error.py +20 -0
  259. mirascope/api/_generated/types/subscription_past_due_error.py +31 -0
  260. mirascope/api/_generated/types/subscription_past_due_error_tag.py +7 -0
  261. mirascope/api/_generated/types/unauthorized_error_body.py +21 -0
  262. mirascope/api/_generated/types/unauthorized_error_tag.py +5 -0
  263. mirascope/api/client.py +255 -0
  264. mirascope/api/settings.py +99 -0
  265. mirascope/llm/__init__.py +290 -15
  266. mirascope/llm/calls/__init__.py +17 -0
  267. mirascope/llm/calls/calls.py +341 -0
  268. mirascope/llm/calls/decorator.py +275 -0
  269. mirascope/llm/content/__init__.py +71 -0
  270. mirascope/llm/content/audio.py +173 -0
  271. mirascope/llm/content/document.py +94 -0
  272. mirascope/llm/content/image.py +206 -0
  273. mirascope/llm/content/text.py +47 -0
  274. mirascope/llm/content/thought.py +58 -0
  275. mirascope/llm/content/tool_call.py +69 -0
  276. mirascope/llm/content/tool_output.py +43 -0
  277. mirascope/llm/context/__init__.py +6 -0
  278. mirascope/llm/context/_utils.py +41 -0
  279. mirascope/llm/context/context.py +24 -0
  280. mirascope/llm/exceptions.py +360 -0
  281. mirascope/llm/formatting/__init__.py +39 -0
  282. mirascope/llm/formatting/format.py +293 -0
  283. mirascope/llm/formatting/from_call_args.py +30 -0
  284. mirascope/llm/formatting/output_parser.py +178 -0
  285. mirascope/llm/formatting/partial.py +131 -0
  286. mirascope/llm/formatting/primitives.py +192 -0
  287. mirascope/llm/formatting/types.py +66 -0
  288. mirascope/llm/mcp/__init__.py +5 -0
  289. mirascope/llm/mcp/mcp_client.py +130 -0
  290. mirascope/llm/messages/__init__.py +35 -0
  291. mirascope/llm/messages/_utils.py +34 -0
  292. mirascope/llm/messages/message.py +190 -0
  293. mirascope/llm/models/__init__.py +21 -0
  294. mirascope/llm/models/models.py +1419 -0
  295. mirascope/llm/models/params.py +72 -0
  296. mirascope/llm/models/thinking_config.py +61 -0
  297. mirascope/llm/prompts/__init__.py +34 -0
  298. mirascope/llm/prompts/_utils.py +31 -0
  299. mirascope/llm/prompts/decorator.py +226 -0
  300. mirascope/llm/prompts/prompts.py +487 -0
  301. mirascope/llm/prompts/protocols.py +65 -0
  302. mirascope/llm/providers/__init__.py +62 -0
  303. mirascope/llm/providers/anthropic/__init__.py +11 -0
  304. mirascope/llm/providers/anthropic/_utils/__init__.py +27 -0
  305. mirascope/llm/providers/anthropic/_utils/beta_decode.py +282 -0
  306. mirascope/llm/providers/anthropic/_utils/beta_encode.py +266 -0
  307. mirascope/llm/providers/anthropic/_utils/decode.py +288 -0
  308. mirascope/llm/providers/anthropic/_utils/encode.py +418 -0
  309. mirascope/llm/providers/anthropic/_utils/errors.py +46 -0
  310. mirascope/llm/providers/anthropic/beta_provider.py +374 -0
  311. mirascope/llm/providers/anthropic/model_id.py +23 -0
  312. mirascope/llm/providers/anthropic/model_info.py +87 -0
  313. mirascope/llm/providers/anthropic/provider.py +479 -0
  314. mirascope/llm/providers/base/__init__.py +14 -0
  315. mirascope/llm/providers/base/_utils.py +253 -0
  316. mirascope/llm/providers/base/base_provider.py +1579 -0
  317. mirascope/llm/providers/base/kwargs.py +12 -0
  318. mirascope/llm/providers/google/__init__.py +6 -0
  319. mirascope/llm/providers/google/_utils/__init__.py +17 -0
  320. mirascope/llm/providers/google/_utils/decode.py +307 -0
  321. mirascope/llm/providers/google/_utils/encode.py +401 -0
  322. mirascope/llm/providers/google/_utils/errors.py +50 -0
  323. mirascope/llm/providers/google/message.py +7 -0
  324. mirascope/llm/providers/google/model_id.py +22 -0
  325. mirascope/llm/providers/google/model_info.py +63 -0
  326. mirascope/llm/providers/google/provider.py +492 -0
  327. mirascope/llm/providers/mirascope/__init__.py +5 -0
  328. mirascope/llm/providers/mirascope/_utils.py +73 -0
  329. mirascope/llm/providers/mirascope/provider.py +349 -0
  330. mirascope/llm/providers/mlx/__init__.py +9 -0
  331. mirascope/llm/providers/mlx/_utils.py +141 -0
  332. mirascope/llm/providers/mlx/encoding/__init__.py +8 -0
  333. mirascope/llm/providers/mlx/encoding/base.py +72 -0
  334. mirascope/llm/providers/mlx/encoding/transformers.py +150 -0
  335. mirascope/llm/providers/mlx/mlx.py +254 -0
  336. mirascope/llm/providers/mlx/model_id.py +17 -0
  337. mirascope/llm/providers/mlx/provider.py +452 -0
  338. mirascope/llm/providers/model_id.py +16 -0
  339. mirascope/llm/providers/ollama/__init__.py +7 -0
  340. mirascope/llm/providers/ollama/provider.py +71 -0
  341. mirascope/llm/providers/openai/__init__.py +15 -0
  342. mirascope/llm/providers/openai/_utils/__init__.py +5 -0
  343. mirascope/llm/providers/openai/_utils/errors.py +46 -0
  344. mirascope/llm/providers/openai/completions/__init__.py +7 -0
  345. mirascope/llm/providers/openai/completions/_utils/__init__.py +15 -0
  346. mirascope/llm/providers/openai/completions/_utils/decode.py +252 -0
  347. mirascope/llm/providers/openai/completions/_utils/encode.py +376 -0
  348. mirascope/llm/providers/openai/completions/base_provider.py +542 -0
  349. mirascope/llm/providers/openai/completions/provider.py +22 -0
  350. mirascope/llm/providers/openai/model_id.py +31 -0
  351. mirascope/llm/providers/openai/model_info.py +303 -0
  352. mirascope/llm/providers/openai/provider.py +441 -0
  353. mirascope/llm/providers/openai/responses/__init__.py +5 -0
  354. mirascope/llm/providers/openai/responses/_utils/__init__.py +15 -0
  355. mirascope/llm/providers/openai/responses/_utils/decode.py +260 -0
  356. mirascope/llm/providers/openai/responses/_utils/encode.py +384 -0
  357. mirascope/llm/providers/openai/responses/provider.py +513 -0
  358. mirascope/llm/providers/provider_id.py +24 -0
  359. mirascope/llm/providers/provider_registry.py +299 -0
  360. mirascope/llm/providers/together/__init__.py +7 -0
  361. mirascope/llm/providers/together/provider.py +40 -0
  362. mirascope/llm/responses/__init__.py +65 -0
  363. mirascope/llm/responses/_utils.py +146 -0
  364. mirascope/llm/responses/base_response.py +103 -0
  365. mirascope/llm/responses/base_stream_response.py +820 -0
  366. mirascope/llm/responses/finish_reason.py +28 -0
  367. mirascope/llm/responses/response.py +366 -0
  368. mirascope/llm/responses/root_response.py +248 -0
  369. mirascope/llm/responses/stream_response.py +581 -0
  370. mirascope/llm/responses/streams.py +363 -0
  371. mirascope/llm/responses/usage.py +95 -0
  372. mirascope/llm/tools/__init__.py +47 -0
  373. mirascope/llm/tools/_utils.py +34 -0
  374. mirascope/llm/tools/decorator.py +184 -0
  375. mirascope/llm/tools/protocols.py +96 -0
  376. mirascope/llm/tools/tool_schema.py +314 -0
  377. mirascope/llm/tools/toolkit.py +160 -0
  378. mirascope/llm/tools/tools.py +263 -0
  379. mirascope/llm/types/__init__.py +22 -0
  380. mirascope/llm/types/dataclass.py +9 -0
  381. mirascope/llm/types/jsonable.py +44 -0
  382. mirascope/llm/types/type_vars.py +19 -0
  383. mirascope/ops/__init__.py +111 -0
  384. mirascope/ops/_internal/__init__.py +5 -0
  385. mirascope/ops/_internal/closure.py +1169 -0
  386. mirascope/ops/_internal/configuration.py +177 -0
  387. mirascope/ops/_internal/context.py +76 -0
  388. mirascope/ops/_internal/exporters/__init__.py +26 -0
  389. mirascope/ops/_internal/exporters/exporters.py +395 -0
  390. mirascope/ops/_internal/exporters/processors.py +104 -0
  391. mirascope/ops/_internal/exporters/types.py +165 -0
  392. mirascope/ops/_internal/exporters/utils.py +29 -0
  393. mirascope/ops/_internal/instrumentation/__init__.py +8 -0
  394. mirascope/ops/_internal/instrumentation/llm/__init__.py +8 -0
  395. mirascope/ops/_internal/instrumentation/llm/common.py +530 -0
  396. mirascope/ops/_internal/instrumentation/llm/cost.py +190 -0
  397. mirascope/ops/_internal/instrumentation/llm/encode.py +238 -0
  398. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/__init__.py +38 -0
  399. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_input_messages.py +31 -0
  400. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_output_messages.py +38 -0
  401. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_system_instructions.py +18 -0
  402. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/shared.py +100 -0
  403. mirascope/ops/_internal/instrumentation/llm/llm.py +161 -0
  404. mirascope/ops/_internal/instrumentation/llm/model.py +1798 -0
  405. mirascope/ops/_internal/instrumentation/llm/response.py +521 -0
  406. mirascope/ops/_internal/instrumentation/llm/serialize.py +300 -0
  407. mirascope/ops/_internal/propagation.py +198 -0
  408. mirascope/ops/_internal/protocols.py +133 -0
  409. mirascope/ops/_internal/session.py +139 -0
  410. mirascope/ops/_internal/spans.py +232 -0
  411. mirascope/ops/_internal/traced_calls.py +375 -0
  412. mirascope/ops/_internal/traced_functions.py +523 -0
  413. mirascope/ops/_internal/tracing.py +353 -0
  414. mirascope/ops/_internal/types.py +13 -0
  415. mirascope/ops/_internal/utils.py +123 -0
  416. mirascope/ops/_internal/versioned_calls.py +512 -0
  417. mirascope/ops/_internal/versioned_functions.py +357 -0
  418. mirascope/ops/_internal/versioning.py +303 -0
  419. mirascope/ops/exceptions.py +21 -0
  420. mirascope-2.0.0.dist-info/METADATA +203 -0
  421. mirascope-2.0.0.dist-info/RECORD +423 -0
  422. {mirascope-1.25.7.dist-info → mirascope-2.0.0.dist-info}/WHEEL +1 -1
  423. {mirascope-1.25.7.dist-info → mirascope-2.0.0.dist-info}/licenses/LICENSE +1 -1
  424. mirascope/beta/__init__.py +0 -3
  425. mirascope/beta/openai/__init__.py +0 -17
  426. mirascope/beta/openai/realtime/__init__.py +0 -13
  427. mirascope/beta/openai/realtime/_utils/__init__.py +0 -3
  428. mirascope/beta/openai/realtime/_utils/_audio.py +0 -74
  429. mirascope/beta/openai/realtime/_utils/_protocols.py +0 -50
  430. mirascope/beta/openai/realtime/realtime.py +0 -500
  431. mirascope/beta/openai/realtime/recording.py +0 -98
  432. mirascope/beta/openai/realtime/tool.py +0 -113
  433. mirascope/beta/rag/__init__.py +0 -24
  434. mirascope/beta/rag/base/__init__.py +0 -22
  435. mirascope/beta/rag/base/chunkers/__init__.py +0 -2
  436. mirascope/beta/rag/base/chunkers/base_chunker.py +0 -37
  437. mirascope/beta/rag/base/chunkers/text_chunker.py +0 -33
  438. mirascope/beta/rag/base/config.py +0 -8
  439. mirascope/beta/rag/base/document.py +0 -11
  440. mirascope/beta/rag/base/embedders.py +0 -35
  441. mirascope/beta/rag/base/embedding_params.py +0 -18
  442. mirascope/beta/rag/base/embedding_response.py +0 -30
  443. mirascope/beta/rag/base/query_results.py +0 -7
  444. mirascope/beta/rag/base/vectorstore_params.py +0 -18
  445. mirascope/beta/rag/base/vectorstores.py +0 -37
  446. mirascope/beta/rag/chroma/__init__.py +0 -11
  447. mirascope/beta/rag/chroma/types.py +0 -62
  448. mirascope/beta/rag/chroma/vectorstores.py +0 -121
  449. mirascope/beta/rag/cohere/__init__.py +0 -11
  450. mirascope/beta/rag/cohere/embedders.py +0 -87
  451. mirascope/beta/rag/cohere/embedding_params.py +0 -29
  452. mirascope/beta/rag/cohere/embedding_response.py +0 -29
  453. mirascope/beta/rag/cohere/py.typed +0 -0
  454. mirascope/beta/rag/openai/__init__.py +0 -11
  455. mirascope/beta/rag/openai/embedders.py +0 -144
  456. mirascope/beta/rag/openai/embedding_params.py +0 -18
  457. mirascope/beta/rag/openai/embedding_response.py +0 -14
  458. mirascope/beta/rag/openai/py.typed +0 -0
  459. mirascope/beta/rag/pinecone/__init__.py +0 -19
  460. mirascope/beta/rag/pinecone/types.py +0 -143
  461. mirascope/beta/rag/pinecone/vectorstores.py +0 -148
  462. mirascope/beta/rag/weaviate/__init__.py +0 -6
  463. mirascope/beta/rag/weaviate/types.py +0 -92
  464. mirascope/beta/rag/weaviate/vectorstores.py +0 -103
  465. mirascope/core/__init__.py +0 -109
  466. mirascope/core/anthropic/__init__.py +0 -31
  467. mirascope/core/anthropic/_call.py +0 -67
  468. mirascope/core/anthropic/_call_kwargs.py +0 -13
  469. mirascope/core/anthropic/_thinking.py +0 -70
  470. mirascope/core/anthropic/_utils/__init__.py +0 -16
  471. mirascope/core/anthropic/_utils/_convert_common_call_params.py +0 -25
  472. mirascope/core/anthropic/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -21
  473. mirascope/core/anthropic/_utils/_convert_message_params.py +0 -102
  474. mirascope/core/anthropic/_utils/_get_json_output.py +0 -31
  475. mirascope/core/anthropic/_utils/_handle_stream.py +0 -113
  476. mirascope/core/anthropic/_utils/_message_param_converter.py +0 -154
  477. mirascope/core/anthropic/_utils/_setup_call.py +0 -146
  478. mirascope/core/anthropic/call_params.py +0 -44
  479. mirascope/core/anthropic/call_response.py +0 -226
  480. mirascope/core/anthropic/call_response_chunk.py +0 -152
  481. mirascope/core/anthropic/dynamic_config.py +0 -40
  482. mirascope/core/anthropic/py.typed +0 -0
  483. mirascope/core/anthropic/stream.py +0 -204
  484. mirascope/core/anthropic/tool.py +0 -101
  485. mirascope/core/azure/__init__.py +0 -31
  486. mirascope/core/azure/_call.py +0 -67
  487. mirascope/core/azure/_call_kwargs.py +0 -13
  488. mirascope/core/azure/_utils/__init__.py +0 -14
  489. mirascope/core/azure/_utils/_convert_common_call_params.py +0 -26
  490. mirascope/core/azure/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -21
  491. mirascope/core/azure/_utils/_convert_message_params.py +0 -121
  492. mirascope/core/azure/_utils/_get_credential.py +0 -33
  493. mirascope/core/azure/_utils/_get_json_output.py +0 -27
  494. mirascope/core/azure/_utils/_handle_stream.py +0 -130
  495. mirascope/core/azure/_utils/_message_param_converter.py +0 -117
  496. mirascope/core/azure/_utils/_setup_call.py +0 -183
  497. mirascope/core/azure/call_params.py +0 -59
  498. mirascope/core/azure/call_response.py +0 -215
  499. mirascope/core/azure/call_response_chunk.py +0 -105
  500. mirascope/core/azure/dynamic_config.py +0 -30
  501. mirascope/core/azure/py.typed +0 -0
  502. mirascope/core/azure/stream.py +0 -147
  503. mirascope/core/azure/tool.py +0 -93
  504. mirascope/core/base/__init__.py +0 -86
  505. mirascope/core/base/_call_factory.py +0 -256
  506. mirascope/core/base/_create.py +0 -253
  507. mirascope/core/base/_extract.py +0 -175
  508. mirascope/core/base/_extract_with_tools.py +0 -189
  509. mirascope/core/base/_partial.py +0 -95
  510. mirascope/core/base/_utils/__init__.py +0 -92
  511. mirascope/core/base/_utils/_base_message_param_converter.py +0 -22
  512. mirascope/core/base/_utils/_base_type.py +0 -26
  513. mirascope/core/base/_utils/_convert_base_model_to_base_tool.py +0 -48
  514. mirascope/core/base/_utils/_convert_base_type_to_base_tool.py +0 -24
  515. mirascope/core/base/_utils/_convert_function_to_base_tool.py +0 -139
  516. mirascope/core/base/_utils/_convert_messages_to_message_params.py +0 -178
  517. mirascope/core/base/_utils/_convert_provider_finish_reason_to_finish_reason.py +0 -20
  518. mirascope/core/base/_utils/_default_tool_docstring.py +0 -6
  519. mirascope/core/base/_utils/_extract_tool_return.py +0 -42
  520. mirascope/core/base/_utils/_fn_is_async.py +0 -24
  521. mirascope/core/base/_utils/_format_template.py +0 -32
  522. mirascope/core/base/_utils/_get_audio_type.py +0 -18
  523. mirascope/core/base/_utils/_get_common_usage.py +0 -20
  524. mirascope/core/base/_utils/_get_create_fn_or_async_create_fn.py +0 -137
  525. mirascope/core/base/_utils/_get_document_type.py +0 -7
  526. mirascope/core/base/_utils/_get_dynamic_configuration.py +0 -69
  527. mirascope/core/base/_utils/_get_fields_from_call_args.py +0 -34
  528. mirascope/core/base/_utils/_get_fn_args.py +0 -23
  529. mirascope/core/base/_utils/_get_image_dimensions.py +0 -39
  530. mirascope/core/base/_utils/_get_image_type.py +0 -26
  531. mirascope/core/base/_utils/_get_metadata.py +0 -17
  532. mirascope/core/base/_utils/_get_possible_user_message_param.py +0 -21
  533. mirascope/core/base/_utils/_get_prompt_template.py +0 -28
  534. mirascope/core/base/_utils/_get_template_values.py +0 -51
  535. mirascope/core/base/_utils/_get_template_variables.py +0 -38
  536. mirascope/core/base/_utils/_get_unsupported_tool_config_keys.py +0 -10
  537. mirascope/core/base/_utils/_is_prompt_template.py +0 -24
  538. mirascope/core/base/_utils/_json_mode_content.py +0 -17
  539. mirascope/core/base/_utils/_messages_decorator.py +0 -121
  540. mirascope/core/base/_utils/_parse_content_template.py +0 -323
  541. mirascope/core/base/_utils/_parse_prompt_messages.py +0 -63
  542. mirascope/core/base/_utils/_pil_image_to_bytes.py +0 -13
  543. mirascope/core/base/_utils/_protocols.py +0 -901
  544. mirascope/core/base/_utils/_setup_call.py +0 -79
  545. mirascope/core/base/_utils/_setup_extract_tool.py +0 -30
  546. mirascope/core/base/call_kwargs.py +0 -13
  547. mirascope/core/base/call_params.py +0 -36
  548. mirascope/core/base/call_response.py +0 -338
  549. mirascope/core/base/call_response_chunk.py +0 -130
  550. mirascope/core/base/dynamic_config.py +0 -82
  551. mirascope/core/base/from_call_args.py +0 -30
  552. mirascope/core/base/merge_decorators.py +0 -59
  553. mirascope/core/base/message_param.py +0 -175
  554. mirascope/core/base/messages.py +0 -116
  555. mirascope/core/base/metadata.py +0 -13
  556. mirascope/core/base/prompt.py +0 -497
  557. mirascope/core/base/response_model_config_dict.py +0 -9
  558. mirascope/core/base/stream.py +0 -479
  559. mirascope/core/base/stream_config.py +0 -11
  560. mirascope/core/base/structured_stream.py +0 -296
  561. mirascope/core/base/tool.py +0 -214
  562. mirascope/core/base/toolkit.py +0 -176
  563. mirascope/core/base/types.py +0 -344
  564. mirascope/core/bedrock/__init__.py +0 -34
  565. mirascope/core/bedrock/_call.py +0 -68
  566. mirascope/core/bedrock/_call_kwargs.py +0 -12
  567. mirascope/core/bedrock/_types.py +0 -104
  568. mirascope/core/bedrock/_utils/__init__.py +0 -14
  569. mirascope/core/bedrock/_utils/_convert_common_call_params.py +0 -39
  570. mirascope/core/bedrock/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
  571. mirascope/core/bedrock/_utils/_convert_message_params.py +0 -111
  572. mirascope/core/bedrock/_utils/_get_json_output.py +0 -30
  573. mirascope/core/bedrock/_utils/_handle_stream.py +0 -104
  574. mirascope/core/bedrock/_utils/_message_param_converter.py +0 -172
  575. mirascope/core/bedrock/_utils/_setup_call.py +0 -258
  576. mirascope/core/bedrock/call_params.py +0 -38
  577. mirascope/core/bedrock/call_response.py +0 -248
  578. mirascope/core/bedrock/call_response_chunk.py +0 -111
  579. mirascope/core/bedrock/dynamic_config.py +0 -37
  580. mirascope/core/bedrock/py.typed +0 -0
  581. mirascope/core/bedrock/stream.py +0 -154
  582. mirascope/core/bedrock/tool.py +0 -100
  583. mirascope/core/cohere/__init__.py +0 -30
  584. mirascope/core/cohere/_call.py +0 -67
  585. mirascope/core/cohere/_call_kwargs.py +0 -11
  586. mirascope/core/cohere/_types.py +0 -20
  587. mirascope/core/cohere/_utils/__init__.py +0 -14
  588. mirascope/core/cohere/_utils/_convert_common_call_params.py +0 -26
  589. mirascope/core/cohere/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -24
  590. mirascope/core/cohere/_utils/_convert_message_params.py +0 -32
  591. mirascope/core/cohere/_utils/_get_json_output.py +0 -30
  592. mirascope/core/cohere/_utils/_handle_stream.py +0 -35
  593. mirascope/core/cohere/_utils/_message_param_converter.py +0 -54
  594. mirascope/core/cohere/_utils/_setup_call.py +0 -150
  595. mirascope/core/cohere/call_params.py +0 -62
  596. mirascope/core/cohere/call_response.py +0 -205
  597. mirascope/core/cohere/call_response_chunk.py +0 -125
  598. mirascope/core/cohere/dynamic_config.py +0 -32
  599. mirascope/core/cohere/py.typed +0 -0
  600. mirascope/core/cohere/stream.py +0 -113
  601. mirascope/core/cohere/tool.py +0 -93
  602. mirascope/core/costs/__init__.py +0 -5
  603. mirascope/core/costs/_anthropic_calculate_cost.py +0 -219
  604. mirascope/core/costs/_azure_calculate_cost.py +0 -11
  605. mirascope/core/costs/_bedrock_calculate_cost.py +0 -15
  606. mirascope/core/costs/_cohere_calculate_cost.py +0 -44
  607. mirascope/core/costs/_gemini_calculate_cost.py +0 -67
  608. mirascope/core/costs/_google_calculate_cost.py +0 -427
  609. mirascope/core/costs/_groq_calculate_cost.py +0 -156
  610. mirascope/core/costs/_litellm_calculate_cost.py +0 -11
  611. mirascope/core/costs/_mistral_calculate_cost.py +0 -64
  612. mirascope/core/costs/_openai_calculate_cost.py +0 -416
  613. mirascope/core/costs/_vertex_calculate_cost.py +0 -67
  614. mirascope/core/costs/_xai_calculate_cost.py +0 -104
  615. mirascope/core/costs/calculate_cost.py +0 -86
  616. mirascope/core/gemini/__init__.py +0 -40
  617. mirascope/core/gemini/_call.py +0 -67
  618. mirascope/core/gemini/_call_kwargs.py +0 -12
  619. mirascope/core/gemini/_utils/__init__.py +0 -14
  620. mirascope/core/gemini/_utils/_convert_common_call_params.py +0 -39
  621. mirascope/core/gemini/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
  622. mirascope/core/gemini/_utils/_convert_message_params.py +0 -156
  623. mirascope/core/gemini/_utils/_get_json_output.py +0 -35
  624. mirascope/core/gemini/_utils/_handle_stream.py +0 -33
  625. mirascope/core/gemini/_utils/_message_param_converter.py +0 -209
  626. mirascope/core/gemini/_utils/_setup_call.py +0 -149
  627. mirascope/core/gemini/call_params.py +0 -52
  628. mirascope/core/gemini/call_response.py +0 -216
  629. mirascope/core/gemini/call_response_chunk.py +0 -100
  630. mirascope/core/gemini/dynamic_config.py +0 -26
  631. mirascope/core/gemini/stream.py +0 -120
  632. mirascope/core/gemini/tool.py +0 -104
  633. mirascope/core/google/__init__.py +0 -29
  634. mirascope/core/google/_call.py +0 -67
  635. mirascope/core/google/_call_kwargs.py +0 -13
  636. mirascope/core/google/_utils/__init__.py +0 -14
  637. mirascope/core/google/_utils/_convert_common_call_params.py +0 -38
  638. mirascope/core/google/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -27
  639. mirascope/core/google/_utils/_convert_message_params.py +0 -297
  640. mirascope/core/google/_utils/_get_json_output.py +0 -37
  641. mirascope/core/google/_utils/_handle_stream.py +0 -58
  642. mirascope/core/google/_utils/_message_param_converter.py +0 -200
  643. mirascope/core/google/_utils/_setup_call.py +0 -201
  644. mirascope/core/google/_utils/_validate_media_type.py +0 -58
  645. mirascope/core/google/call_params.py +0 -22
  646. mirascope/core/google/call_response.py +0 -255
  647. mirascope/core/google/call_response_chunk.py +0 -135
  648. mirascope/core/google/dynamic_config.py +0 -26
  649. mirascope/core/google/stream.py +0 -199
  650. mirascope/core/google/tool.py +0 -146
  651. mirascope/core/groq/__init__.py +0 -30
  652. mirascope/core/groq/_call.py +0 -67
  653. mirascope/core/groq/_call_kwargs.py +0 -13
  654. mirascope/core/groq/_utils/__init__.py +0 -14
  655. mirascope/core/groq/_utils/_convert_common_call_params.py +0 -26
  656. mirascope/core/groq/_utils/_convert_message_params.py +0 -112
  657. mirascope/core/groq/_utils/_get_json_output.py +0 -27
  658. mirascope/core/groq/_utils/_handle_stream.py +0 -123
  659. mirascope/core/groq/_utils/_message_param_converter.py +0 -89
  660. mirascope/core/groq/_utils/_setup_call.py +0 -132
  661. mirascope/core/groq/call_params.py +0 -52
  662. mirascope/core/groq/call_response.py +0 -213
  663. mirascope/core/groq/call_response_chunk.py +0 -104
  664. mirascope/core/groq/dynamic_config.py +0 -29
  665. mirascope/core/groq/py.typed +0 -0
  666. mirascope/core/groq/stream.py +0 -135
  667. mirascope/core/groq/tool.py +0 -80
  668. mirascope/core/litellm/__init__.py +0 -28
  669. mirascope/core/litellm/_call.py +0 -67
  670. mirascope/core/litellm/_utils/__init__.py +0 -5
  671. mirascope/core/litellm/_utils/_setup_call.py +0 -109
  672. mirascope/core/litellm/call_params.py +0 -10
  673. mirascope/core/litellm/call_response.py +0 -24
  674. mirascope/core/litellm/call_response_chunk.py +0 -14
  675. mirascope/core/litellm/dynamic_config.py +0 -8
  676. mirascope/core/litellm/py.typed +0 -0
  677. mirascope/core/litellm/stream.py +0 -86
  678. mirascope/core/litellm/tool.py +0 -13
  679. mirascope/core/mistral/__init__.py +0 -36
  680. mirascope/core/mistral/_call.py +0 -65
  681. mirascope/core/mistral/_call_kwargs.py +0 -19
  682. mirascope/core/mistral/_utils/__init__.py +0 -14
  683. mirascope/core/mistral/_utils/_convert_common_call_params.py +0 -24
  684. mirascope/core/mistral/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -22
  685. mirascope/core/mistral/_utils/_convert_message_params.py +0 -122
  686. mirascope/core/mistral/_utils/_get_json_output.py +0 -34
  687. mirascope/core/mistral/_utils/_handle_stream.py +0 -139
  688. mirascope/core/mistral/_utils/_message_param_converter.py +0 -176
  689. mirascope/core/mistral/_utils/_setup_call.py +0 -164
  690. mirascope/core/mistral/call_params.py +0 -36
  691. mirascope/core/mistral/call_response.py +0 -205
  692. mirascope/core/mistral/call_response_chunk.py +0 -105
  693. mirascope/core/mistral/dynamic_config.py +0 -33
  694. mirascope/core/mistral/py.typed +0 -0
  695. mirascope/core/mistral/stream.py +0 -120
  696. mirascope/core/mistral/tool.py +0 -81
  697. mirascope/core/openai/__init__.py +0 -31
  698. mirascope/core/openai/_call.py +0 -67
  699. mirascope/core/openai/_call_kwargs.py +0 -13
  700. mirascope/core/openai/_utils/__init__.py +0 -14
  701. mirascope/core/openai/_utils/_convert_common_call_params.py +0 -26
  702. mirascope/core/openai/_utils/_convert_message_params.py +0 -148
  703. mirascope/core/openai/_utils/_get_json_output.py +0 -31
  704. mirascope/core/openai/_utils/_handle_stream.py +0 -138
  705. mirascope/core/openai/_utils/_message_param_converter.py +0 -105
  706. mirascope/core/openai/_utils/_setup_call.py +0 -155
  707. mirascope/core/openai/call_params.py +0 -92
  708. mirascope/core/openai/call_response.py +0 -273
  709. mirascope/core/openai/call_response_chunk.py +0 -139
  710. mirascope/core/openai/dynamic_config.py +0 -34
  711. mirascope/core/openai/py.typed +0 -0
  712. mirascope/core/openai/stream.py +0 -185
  713. mirascope/core/openai/tool.py +0 -101
  714. mirascope/core/py.typed +0 -0
  715. mirascope/core/vertex/__init__.py +0 -45
  716. mirascope/core/vertex/_call.py +0 -62
  717. mirascope/core/vertex/_call_kwargs.py +0 -12
  718. mirascope/core/vertex/_utils/__init__.py +0 -14
  719. mirascope/core/vertex/_utils/_convert_common_call_params.py +0 -37
  720. mirascope/core/vertex/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
  721. mirascope/core/vertex/_utils/_convert_message_params.py +0 -171
  722. mirascope/core/vertex/_utils/_get_json_output.py +0 -36
  723. mirascope/core/vertex/_utils/_handle_stream.py +0 -33
  724. mirascope/core/vertex/_utils/_message_param_converter.py +0 -133
  725. mirascope/core/vertex/_utils/_setup_call.py +0 -160
  726. mirascope/core/vertex/call_params.py +0 -24
  727. mirascope/core/vertex/call_response.py +0 -206
  728. mirascope/core/vertex/call_response_chunk.py +0 -99
  729. mirascope/core/vertex/dynamic_config.py +0 -28
  730. mirascope/core/vertex/stream.py +0 -119
  731. mirascope/core/vertex/tool.py +0 -101
  732. mirascope/core/xai/__init__.py +0 -28
  733. mirascope/core/xai/_call.py +0 -67
  734. mirascope/core/xai/_utils/__init__.py +0 -5
  735. mirascope/core/xai/_utils/_setup_call.py +0 -113
  736. mirascope/core/xai/call_params.py +0 -10
  737. mirascope/core/xai/call_response.py +0 -16
  738. mirascope/core/xai/call_response_chunk.py +0 -14
  739. mirascope/core/xai/dynamic_config.py +0 -8
  740. mirascope/core/xai/py.typed +0 -0
  741. mirascope/core/xai/stream.py +0 -57
  742. mirascope/core/xai/tool.py +0 -13
  743. mirascope/experimental/graphs/__init__.py +0 -5
  744. mirascope/experimental/graphs/finite_state_machine.py +0 -714
  745. mirascope/integrations/__init__.py +0 -16
  746. mirascope/integrations/_middleware_factory.py +0 -403
  747. mirascope/integrations/langfuse/__init__.py +0 -3
  748. mirascope/integrations/langfuse/_utils.py +0 -114
  749. mirascope/integrations/langfuse/_with_langfuse.py +0 -70
  750. mirascope/integrations/logfire/__init__.py +0 -3
  751. mirascope/integrations/logfire/_utils.py +0 -225
  752. mirascope/integrations/logfire/_with_logfire.py +0 -63
  753. mirascope/integrations/otel/__init__.py +0 -10
  754. mirascope/integrations/otel/_utils.py +0 -270
  755. mirascope/integrations/otel/_with_hyperdx.py +0 -60
  756. mirascope/integrations/otel/_with_otel.py +0 -59
  757. mirascope/integrations/tenacity.py +0 -14
  758. mirascope/llm/_call.py +0 -401
  759. mirascope/llm/_context.py +0 -384
  760. mirascope/llm/_override.py +0 -3639
  761. mirascope/llm/_protocols.py +0 -500
  762. mirascope/llm/_response_metaclass.py +0 -31
  763. mirascope/llm/call_response.py +0 -158
  764. mirascope/llm/call_response_chunk.py +0 -66
  765. mirascope/llm/stream.py +0 -162
  766. mirascope/llm/tool.py +0 -64
  767. mirascope/mcp/__init__.py +0 -7
  768. mirascope/mcp/_utils.py +0 -288
  769. mirascope/mcp/client.py +0 -167
  770. mirascope/mcp/server.py +0 -356
  771. mirascope/mcp/tools.py +0 -110
  772. mirascope/py.typed +0 -0
  773. mirascope/retries/__init__.py +0 -11
  774. mirascope/retries/fallback.py +0 -131
  775. mirascope/retries/tenacity.py +0 -50
  776. mirascope/tools/__init__.py +0 -37
  777. mirascope/tools/base.py +0 -98
  778. mirascope/tools/system/__init__.py +0 -0
  779. mirascope/tools/system/_docker_operation.py +0 -166
  780. mirascope/tools/system/_file_system.py +0 -267
  781. mirascope/tools/web/__init__.py +0 -0
  782. mirascope/tools/web/_duckduckgo.py +0 -111
  783. mirascope/tools/web/_httpx.py +0 -125
  784. mirascope/tools/web/_parse_url_content.py +0 -94
  785. mirascope/tools/web/_requests.py +0 -54
  786. mirascope/v0/__init__.py +0 -43
  787. mirascope/v0/anthropic.py +0 -54
  788. mirascope/v0/base/__init__.py +0 -12
  789. mirascope/v0/base/calls.py +0 -118
  790. mirascope/v0/base/extractors.py +0 -122
  791. mirascope/v0/base/ops_utils.py +0 -207
  792. mirascope/v0/base/prompts.py +0 -48
  793. mirascope/v0/base/types.py +0 -14
  794. mirascope/v0/base/utils.py +0 -21
  795. mirascope/v0/openai.py +0 -54
  796. mirascope-1.25.7.dist-info/METADATA +0 -169
  797. mirascope-1.25.7.dist-info/RECORD +0 -378
@@ -0,0 +1,820 @@
1
+ """Base class for StreamResponse and AsyncStreamResponse."""
2
+
3
+ from collections.abc import AsyncIterator, Iterator, Sequence
4
+ from dataclasses import dataclass
5
+ from typing import TYPE_CHECKING, Any, Generic, Literal, TypeAlias, TypeVar
6
+
7
+ from ..content import (
8
+ AssistantContentChunk,
9
+ AssistantContentPart,
10
+ Text,
11
+ TextChunk,
12
+ TextEndChunk,
13
+ TextStartChunk,
14
+ Thought,
15
+ ThoughtChunk,
16
+ ThoughtEndChunk,
17
+ ThoughtStartChunk,
18
+ ToolCall,
19
+ ToolCallChunk,
20
+ ToolCallEndChunk,
21
+ ToolCallStartChunk,
22
+ )
23
+ from ..formatting import (
24
+ Format,
25
+ FormattableT,
26
+ Partial,
27
+ is_output_parser,
28
+ )
29
+ from ..messages import AssistantMessage, Message
30
+ from ..tools import FORMAT_TOOL_NAME, ToolkitT
31
+ from ..types import Jsonable
32
+ from .finish_reason import FinishReasonChunk
33
+ from .root_response import RootResponse
34
+ from .streams import (
35
+ AsyncStream,
36
+ AsyncTextStream,
37
+ AsyncThoughtStream,
38
+ AsyncToolCallStream,
39
+ Stream,
40
+ TextStream,
41
+ ThoughtStream,
42
+ ToolCallStream,
43
+ )
44
+ from .usage import Usage, UsageDeltaChunk
45
+
46
+ if TYPE_CHECKING:
47
+ from ..models import Params
48
+ from ..providers import ModelId, ProviderId
49
+
50
+
51
+ StreamResponseT = TypeVar("StreamResponseT", bound="BaseStreamResponse[Any, Any, Any]")
52
+
53
+
54
+ @dataclass(kw_only=True)
55
+ class RawStreamEventChunk:
56
+ """A chunk containing a raw stream event from the underlying provider.
57
+
58
+ Will be accumulated on `StreamResponse.raw` for debugging purposes.
59
+ """
60
+
61
+ type: Literal["raw_stream_event_chunk"] = "raw_stream_event_chunk"
62
+
63
+ raw_stream_event: Any
64
+ """The raw stream event from the underlying provider."""
65
+
66
+
67
+ @dataclass(kw_only=True)
68
+ class RawMessageChunk:
69
+ """A chunk containing provider-specific raw message content that will be added to the `AssistantMessage`.
70
+
71
+ This chunk contains a provider-specific representation of a piece of content that
72
+ will be added to the `AssistantMessage` reconstructed by the containing stream.
73
+ This content should be a Jsonable Python object for serialization purposes.
74
+
75
+ The intention is that this content may be passed as-is back to the provider when the
76
+ generated `AssistantMessage` is being reused in conversation.
77
+ """
78
+
79
+ type: Literal["raw_message_chunk"] = "raw_message_chunk"
80
+
81
+ raw_message: Jsonable
82
+ """The provider-specific raw content.
83
+
84
+ Should be a Jsonable object.
85
+ """
86
+
87
+
88
+ StreamResponseChunk: TypeAlias = (
89
+ AssistantContentChunk
90
+ | FinishReasonChunk
91
+ | RawStreamEventChunk
92
+ | RawMessageChunk
93
+ | UsageDeltaChunk
94
+ )
95
+
96
+ ChunkIterator: TypeAlias = Iterator[StreamResponseChunk]
97
+ """Synchronous iterator yielding chunks with raw data."""
98
+
99
+ AsyncChunkIterator: TypeAlias = AsyncIterator[StreamResponseChunk]
100
+ """Asynchronous iterator yielding chunks with raw data."""
101
+
102
+ ChunkIteratorT = TypeVar("ChunkIteratorT", bound=ChunkIterator | AsyncChunkIterator)
103
+
104
+
105
+ class BaseStreamResponse(
106
+ RootResponse[ToolkitT, FormattableT],
107
+ Generic[ChunkIteratorT, ToolkitT, FormattableT],
108
+ ):
109
+ """Base class underpinning StreamResponse and AsyncStreamResponse.
110
+
111
+ Manages chunk handling logic for both.
112
+ """
113
+
114
+ raw_stream_events: Sequence[Any]
115
+ """The raw stream event chunks from the LLM. Provider-specific."""
116
+
117
+ chunks: Sequence[AssistantContentChunk]
118
+ """All of the Mirascope chunks consumed from the stream."""
119
+
120
+ content: Sequence[AssistantContentPart]
121
+ """The content generated by the LLM.
122
+
123
+ Content is updated in this array as it is consumed by the stream. Text content will
124
+ update with each text chunk (this will mutate the Text object that is returned
125
+ rather than creating a new one). Other content will be added once each part
126
+ is fully streamed.
127
+ """
128
+
129
+ messages: list[Message]
130
+ """The message history, including the most recent assistant message.
131
+
132
+ The most recent assistant message will have all of the completed content that has
133
+ already been consumed from the stream. Text content will be included as each chunk
134
+ is processed; other content will be included only when its corresponding part is
135
+ completed (to avoid partial tool calls and the like). If no content has been
136
+ streamed, then the final assistant message will be present (to maintain turn order
137
+ expectations), but will be empty.
138
+ """
139
+
140
+ texts: Sequence[Text]
141
+ """The text content in the generated response, if any.
142
+
143
+ Text content updates with each text chunk as it streams. The `Text` objects are
144
+ mutated in place rather than creating new ones for each chunk.
145
+ """
146
+
147
+ tool_calls: Sequence[ToolCall]
148
+ """The tools the LLM wants called on its behalf, if any.
149
+
150
+ Tool calls are only added to this sequence once they have been fully streamed
151
+ to avoid partial tool calls in the response.
152
+ """
153
+
154
+ thoughts: Sequence[Thought]
155
+ """The readable thoughts from the model's thinking process, if any.
156
+
157
+ The thoughts may be direct output from the model thinking process, or may be a
158
+ generated summary. (This depends on the provider; newer models tend to summarize.)
159
+
160
+ Thoughts are added to the sequence as they are streamed. The `Thought` objects are
161
+ mutated in place rather than creating new ones for each chunk.
162
+ """
163
+
164
+ consumed: bool = False
165
+ """Whether the stream has been fully consumed.
166
+
167
+ This is True after all chunks have been processed from the underlying iterator.
168
+ When False, more content may be available by calling the stream methods.
169
+ """
170
+
171
+ def __init__(
172
+ self,
173
+ *,
174
+ provider_id: "ProviderId",
175
+ model_id: "ModelId",
176
+ provider_model_name: str,
177
+ params: "Params",
178
+ toolkit: ToolkitT,
179
+ format: Format[FormattableT] | None = None,
180
+ input_messages: Sequence[Message],
181
+ chunk_iterator: ChunkIteratorT,
182
+ usage: Usage | None = None,
183
+ ) -> None:
184
+ """Initialize the BaseStreamResponse.
185
+
186
+ Args:
187
+ provider: The provider name (e.g. "anthropic", "openai").
188
+ model_id: The model identifier that generated the response.
189
+ provider_model_name: Optional provider-specific model name. May include
190
+ provider-specific additional info (like api mode in "gpt-5:responses").
191
+ params: The params used to generate the response (or None).
192
+ toolkit: Toolkit containing all the tools used to generate the response.
193
+ format: The `Format` for the expected structured output format (or None).
194
+ input_messages: The input messages that were sent to the LLM
195
+ usage: Token usage statistics for the response.
196
+
197
+ The BaseStreamResponse will process the tuples to build the chunks and raw lists
198
+ as the stream is consumed.
199
+ """
200
+
201
+ self.provider_id = provider_id
202
+ self.model_id = model_id
203
+ self.provider_model_name = provider_model_name
204
+ self.params = params
205
+ self.toolkit = toolkit
206
+ self.usage = usage
207
+ self.format = format
208
+
209
+ # Internal-only lists which we mutate (append) during chunk processing
210
+ self._chunks: list[AssistantContentChunk] = []
211
+ self._content: list[AssistantContentPart] = []
212
+ self._texts: list[Text] = []
213
+ self._thoughts: list[Thought] = []
214
+ self._tool_calls: list[ToolCall] = []
215
+ self._raw_stream_events: list[Any] = []
216
+ self._last_raw_stream_event_chunk: Any | None = None
217
+
218
+ # Externally-facing references typed as immutable Sequences
219
+ self.chunks = self._chunks
220
+ self.content = self._content
221
+ self.texts = self._texts
222
+ self.thoughts = self._thoughts
223
+ self.tool_calls = self._tool_calls
224
+ self.raw_stream_events = self._raw_stream_events
225
+
226
+ self.finish_reason = None
227
+
228
+ self._assistant_message = AssistantMessage(
229
+ content=self._content,
230
+ provider_id=provider_id,
231
+ model_id=model_id,
232
+ provider_model_name=provider_model_name,
233
+ raw_message=None,
234
+ )
235
+
236
+ self.messages = list(input_messages) + [self._assistant_message]
237
+
238
+ self._chunk_iterator = chunk_iterator
239
+ self._current_content: Text | Thought | None = None
240
+ self._current_tool_calls: dict[str, ToolCall] = {}
241
+
242
+ self._processing_format_tool: bool = False
243
+
244
+ def _transform_format_tool_chunks(
245
+ self, chunk: AssistantContentChunk
246
+ ) -> AssistantContentChunk:
247
+ if chunk.type == "tool_call_start_chunk" and chunk.name.startswith(
248
+ FORMAT_TOOL_NAME
249
+ ):
250
+ self._processing_format_tool = True
251
+ return TextStartChunk()
252
+ if self._processing_format_tool and chunk.type == "tool_call_chunk":
253
+ return TextChunk(delta=chunk.delta)
254
+ if self._processing_format_tool and chunk.type == "tool_call_end_chunk":
255
+ self._processing_format_tool = False
256
+ return TextEndChunk()
257
+ return chunk
258
+
259
+ def _handle_chunk(self, chunk: AssistantContentChunk) -> AssistantContentChunk:
260
+ if self.finish_reason:
261
+ raise RuntimeError(
262
+ f"Stream already finished with reason: {self.finish_reason}"
263
+ )
264
+ chunk = self._transform_format_tool_chunks(chunk)
265
+
266
+ if chunk.content_type == "text":
267
+ self._handle_text_chunk(chunk)
268
+ elif chunk.content_type == "tool_call":
269
+ self._handle_tool_call_chunk(chunk)
270
+ elif chunk.content_type == "thought":
271
+ self._handle_thought_chunk(chunk)
272
+ else:
273
+ raise NotImplementedError
274
+
275
+ self._chunks.append(chunk)
276
+ return chunk
277
+
278
+ def _handle_text_chunk(
279
+ self, chunk: TextStartChunk | TextChunk | TextEndChunk
280
+ ) -> None:
281
+ if chunk.type == "text_start_chunk":
282
+ if self._current_content or self._current_tool_calls:
283
+ raise RuntimeError(
284
+ "Received text_start_chunk while processing another chunk"
285
+ )
286
+ self._current_content = Text(text="")
287
+ # Text gets included in content even when unfinished.
288
+ self._content.append(self._current_content)
289
+ self._texts.append(self._current_content)
290
+
291
+ elif chunk.type == "text_chunk":
292
+ if self._current_content is None or self._current_content.type != "text":
293
+ raise RuntimeError("Received text_chunk while not processing text.")
294
+ self._current_content.text += chunk.delta
295
+
296
+ elif chunk.type == "text_end_chunk":
297
+ if self._current_content is None or self._current_content.type != "text":
298
+ raise RuntimeError("Received text_end_chunk while not processing text.")
299
+ self._current_content = None
300
+
301
+ def _handle_thought_chunk(
302
+ self, chunk: ThoughtStartChunk | ThoughtChunk | ThoughtEndChunk
303
+ ) -> None:
304
+ if chunk.type == "thought_start_chunk":
305
+ if self._current_content or self._current_tool_calls:
306
+ raise RuntimeError(
307
+ "Received thought_start_chunk while processing another chunk"
308
+ )
309
+ self._current_content = Thought(thought="")
310
+ # Thoughts get included even when unfinished.
311
+ self._content.append(self._current_content)
312
+ self._thoughts.append(self._current_content)
313
+
314
+ elif chunk.type == "thought_chunk":
315
+ if self._current_content is None or self._current_content.type != "thought":
316
+ raise RuntimeError(
317
+ "Received thought_chunk while not processing thought."
318
+ )
319
+ self._current_content.thought += chunk.delta
320
+
321
+ elif chunk.type == "thought_end_chunk":
322
+ if self._current_content is None or self._current_content.type != "thought":
323
+ raise RuntimeError(
324
+ "Received thought_end_chunk while not processing thought."
325
+ )
326
+ self._current_content = None
327
+
328
+ def _handle_tool_call_chunk(
329
+ self, chunk: ToolCallStartChunk | ToolCallChunk | ToolCallEndChunk
330
+ ) -> None:
331
+ if chunk.type == "tool_call_start_chunk":
332
+ if self._current_content:
333
+ raise RuntimeError(
334
+ "Received tool_call_start_chunk while processing another chunk"
335
+ )
336
+ if chunk.id in self._current_tool_calls:
337
+ raise RuntimeError("Got tool_call_start_chunk with conflicting id")
338
+ # Create a new tool call and track it by ID
339
+ # Multiple tool calls can be in progress simultaneously (interleaved)
340
+ tool_call = ToolCall(
341
+ id=chunk.id,
342
+ name=chunk.name,
343
+ args="",
344
+ )
345
+ self._current_tool_calls[chunk.id] = tool_call
346
+
347
+ elif chunk.type == "tool_call_chunk":
348
+ # Look up the tool call by ID
349
+ tool_call = self._current_tool_calls.get(chunk.id)
350
+ if tool_call is None:
351
+ raise RuntimeError(
352
+ f"Received tool_call_chunk for unknown tool call ID: {chunk.id}"
353
+ )
354
+ tool_call.args += chunk.delta
355
+
356
+ elif chunk.type == "tool_call_end_chunk":
357
+ # Finalize the tool call
358
+ tool_call = self._current_tool_calls.get(chunk.id)
359
+ if tool_call is None:
360
+ raise RuntimeError(
361
+ f"Received tool_call_end_chunk for unknown tool call ID: {chunk.id}"
362
+ )
363
+ if not tool_call.args:
364
+ tool_call.args = "{}"
365
+ self._content.append(tool_call)
366
+ self._tool_calls.append(tool_call)
367
+ del self._current_tool_calls[chunk.id]
368
+
369
+ def _pretty_chunk(self, chunk: AssistantContentChunk, spacer: str) -> str:
370
+ match chunk.type:
371
+ case "text_start_chunk":
372
+ return spacer
373
+ case "text_chunk":
374
+ return chunk.delta
375
+ case "tool_call_start_chunk":
376
+ return spacer + f"**ToolCall ({chunk.name}):** "
377
+ case "tool_call_chunk":
378
+ return chunk.delta
379
+ case "thought_start_chunk":
380
+ return spacer + "**Thinking:**\n "
381
+ case "thought_chunk":
382
+ return chunk.delta.replace("\n", "\n ") # Indent every line
383
+ case _:
384
+ return ""
385
+
386
+
387
+ class BaseSyncStreamResponse(BaseStreamResponse[ChunkIterator, ToolkitT, FormattableT]):
388
+ """A base class for synchronous Stream Responses."""
389
+
390
+ def streams(self) -> Iterator[Stream]:
391
+ """Returns an iterator that yields streams for each content part in the response.
392
+
393
+ Returns:
394
+ Iterator[Stream]: Synchronous iterator yielding Stream objects
395
+
396
+ Each content part in the response will correspond to one stream, which will yield
397
+ chunks of content as they come in from the underlying LLM.
398
+
399
+ Fully iterating through this iterator will fully consume the underlying stream,
400
+ updating the Response with all collected content.
401
+
402
+ As content is consumed, it is cached on the StreamResponse. If a new iterator
403
+ is constructed via calling `streams()`, it will start by replaying the cached
404
+ content from the response, and (if there is still more content to consume from
405
+ the LLM), it will proceed to consume it once it has iterated through all the
406
+ cached chunks.
407
+ """
408
+ chunk_iter = self.chunk_stream()
409
+
410
+ for start_chunk in chunk_iter:
411
+ # At the start of this loop, we always expect to find a start chunk. Then,
412
+ # before proceeding, we will collect from the stream we create (in case the
413
+ # user did not exhaust it), which ensures we will be expecting a start chunk
414
+ # again on the next iteration
415
+ match start_chunk.type:
416
+ case "text_start_chunk":
417
+
418
+ def text_stream_iterator() -> Iterator[TextChunk]:
419
+ for chunk in chunk_iter:
420
+ if chunk.type == "text_chunk":
421
+ yield chunk
422
+ else:
423
+ return # Stream finished
424
+
425
+ stream = TextStream(chunk_iterator=text_stream_iterator())
426
+ yield stream
427
+
428
+ case "thought_start_chunk":
429
+
430
+ def thought_stream_iterator() -> Iterator[ThoughtChunk]:
431
+ for chunk in chunk_iter:
432
+ if chunk.type == "thought_chunk":
433
+ yield chunk
434
+ else:
435
+ return # Stream finished
436
+
437
+ stream = ThoughtStream(chunk_iterator=thought_stream_iterator())
438
+ yield stream
439
+
440
+ case "tool_call_start_chunk":
441
+ tool_id = start_chunk.id
442
+ tool_name = start_chunk.name
443
+
444
+ def tool_call_stream_iterator() -> Iterator[ToolCallChunk]:
445
+ for chunk in chunk_iter:
446
+ if chunk.type == "tool_call_chunk":
447
+ yield chunk
448
+ else:
449
+ return # Stream finished
450
+
451
+ stream = ToolCallStream(
452
+ tool_id=tool_id,
453
+ tool_name=tool_name,
454
+ chunk_iterator=tool_call_stream_iterator(),
455
+ )
456
+ yield stream
457
+
458
+ case _: # pragma: no cover
459
+ raise RuntimeError(f"Expected start chunk, got: {start_chunk.type}")
460
+
461
+ # Before continuing to the next stream, make sure the last stream is consumed
462
+ # (If the user did not do so when we yielded it)
463
+ stream.collect()
464
+
465
+ def chunk_stream(
466
+ self,
467
+ ) -> Iterator[AssistantContentChunk]:
468
+ """Returns an iterator that yields content chunks as they are received.
469
+
470
+ Returns:
471
+ Iterator[AssistantContentChunk]: Synchronous iterator yielding chunks
472
+
473
+ This provides access to the Mirascope chunk data including start, delta, and end chunks
474
+ for each content type (text, thought, tool_call). Unlike the streams() method
475
+ that groups chunks by content part, this yields individual chunks as they arrive.
476
+
477
+ Fully iterating through this iterator will fully consume the underlying stream,
478
+ updating the Response with all collected content.
479
+
480
+ As chunks are consumed, they are cached on the StreamResponse. If a new iterator
481
+ is constructed via calling `chunk_stream()`, it will start by replaying the cached
482
+ chunks from the response, and (if there is still more content to consume from
483
+ the LLM), it will proceed to consume it once it has iterated through all the
484
+ cached chunks.
485
+ """
486
+ for chunk in self.chunks:
487
+ yield chunk
488
+
489
+ if self.consumed:
490
+ return
491
+
492
+ for chunk in self._chunk_iterator:
493
+ if chunk.type == "raw_stream_event_chunk":
494
+ self._raw_stream_events.append(chunk.raw_stream_event)
495
+ elif chunk.type == "raw_message_chunk":
496
+ self._assistant_message.raw_message = chunk.raw_message
497
+ elif chunk.type == "finish_reason_chunk":
498
+ self.finish_reason = chunk.finish_reason
499
+ elif chunk.type == "usage_delta_chunk":
500
+ if self.usage is None:
501
+ self.usage = Usage()
502
+ self.usage.input_tokens += chunk.input_tokens
503
+ self.usage.output_tokens += chunk.output_tokens
504
+ self.usage.cache_read_tokens += chunk.cache_read_tokens
505
+ self.usage.cache_write_tokens += chunk.cache_write_tokens
506
+ self.usage.reasoning_tokens += chunk.reasoning_tokens
507
+ else:
508
+ yield self._handle_chunk(chunk)
509
+
510
+ self.consumed = True
511
+
512
+ def finish(self) -> None:
513
+ """Finish streaming all of this response's content."""
514
+ for _ in self.chunk_stream():
515
+ pass
516
+
517
+ def text_stream(self, sep: str = "\n") -> Iterator[str]:
518
+ """Stream only the text content from the response.
519
+
520
+ Args:
521
+ sep: Separator to yield between text parts. Defaults to newline.
522
+
523
+ Returns:
524
+ Iterator[str]: Iterator yielding text delta strings
525
+
526
+ Yields text deltas as they arrive, ignoring thoughts, tool calls, and other
527
+ content types. Ideal for displaying text to users in real-time.
528
+
529
+ If you concatenate the strings from `.text_stream()`, it will be equivalent to
530
+ calling `.text(sep=sep)` on the fully consumed response.
531
+ """
532
+ for stream in self.streams():
533
+ if stream.content_type == "text":
534
+ yield from stream
535
+ yield sep
536
+
537
+ def pretty_stream(self) -> Iterator[str]:
538
+ """Stream a readable representation of the stream_response as text.
539
+
540
+ Returns:
541
+ Iterator[str]: Iterator yielding string chunks depicting the content
542
+
543
+ Iterating through the pretty stream will populate the stream response by consuming
544
+ the underlying iterator (if it hasn't been consumed already). Calling `.pretty_stream()`
545
+ will always return a fresh iterator that begins from the start of the stream.
546
+
547
+ If you concatenate the text from `.pretty_stream()`, it will be equivalent to the
548
+ text generated by calling `.pretty()` (assuming the response was fully consumed
549
+ at the time when you call `.pretty()`).
550
+ """
551
+ printed = False
552
+
553
+ for chunk in self.chunk_stream():
554
+ pretty = self._pretty_chunk(chunk, "\n\n" if printed else "")
555
+ if pretty != "":
556
+ printed = True
557
+ yield pretty
558
+
559
+ def structured_stream(
560
+ self,
561
+ ) -> Iterator[Partial[FormattableT]]:
562
+ """Drive the stream forward, yielding partial formatted outputs as they arrive.
563
+
564
+ This method consumes the underlying stream chunk by chunk, yielding parsed
565
+ partial outputs each time new content arrives. Each yielded value is a
566
+ Partial[FormattableT] with optional fields that may be None until fully received.
567
+
568
+ Example:
569
+ >>> response = recommend_book.stream("fantasy")
570
+ >>> for partial in response.structured_stream():
571
+ >>> print(f"Title so far: {partial.title}")
572
+ >>> book = response.parse() # Get final complete result
573
+
574
+ Fully iterating through this iterator will fully consume the underlying stream,
575
+ updating the Response with all collected content.
576
+
577
+ Yields:
578
+ Partial[FormattableT]: Partial objects with fields populated as they arrive.
579
+ Fields not yet received will be None.
580
+
581
+ Raises:
582
+ ValueError: If format parameter not set.
583
+ NotImplementedError: If format uses OutputParser (not supported).
584
+ """
585
+ if self.format is None:
586
+ raise ValueError("structured_stream() requires format parameter")
587
+
588
+ if is_output_parser(self.format.formattable):
589
+ raise NotImplementedError(
590
+ "structured_stream() not supported for OutputParser. "
591
+ "Use BaseModel or primitive types."
592
+ )
593
+
594
+ for chunk in self.chunk_stream():
595
+ if chunk.type == "text_chunk":
596
+ partial = self.parse(partial=True)
597
+ if partial:
598
+ yield partial
599
+
600
+
601
+ class BaseAsyncStreamResponse(
602
+ BaseStreamResponse[AsyncChunkIterator, ToolkitT, FormattableT]
603
+ ):
604
+ """A base class for asynchronous Stream Responses."""
605
+
606
+ async def streams(self) -> AsyncIterator[AsyncStream]:
607
+ """Returns an async iterator that yields streams for each content part in the response.
608
+
609
+ Returns:
610
+ AsyncIterator[AsyncStream]: Async iterator yielding AsyncStream objects
611
+
612
+ Each content part in the response will correspond to one stream, which will yield
613
+ chunks of content as they come in from the underlying LLM.
614
+
615
+ Fully iterating through this iterator will fully consume the underlying stream,
616
+ updating the Response with all collected content.
617
+
618
+ As content is consumed, it is cached on the AsyncStreamResponse. If a new iterator
619
+ is constructed via calling `streams()`, it will start by replaying the cached
620
+ content from the response, and (if there is still more content to consume from
621
+ the LLM), it will proceed to consume it once it has iterated through all the
622
+ cached chunks.
623
+ """
624
+ chunk_iter = self.chunk_stream()
625
+
626
+ async for start_chunk in chunk_iter:
627
+ # At the start of this loop, we always expect to find a start chunk. Then,
628
+ # before proceeding, we will collect from the stream we create (in case the
629
+ # user did not exhaust it), which ensures we will be expecting a start chunk
630
+ # again on the next iteration
631
+ match start_chunk.type:
632
+ case "text_start_chunk":
633
+
634
+ async def text_stream_iterator() -> AsyncIterator[TextChunk]:
635
+ async for chunk in chunk_iter:
636
+ if chunk.type == "text_chunk":
637
+ yield chunk
638
+ else:
639
+ return # Stream finished
640
+
641
+ stream = AsyncTextStream(chunk_iterator=text_stream_iterator())
642
+ yield stream
643
+
644
+ case "thought_start_chunk":
645
+
646
+ async def thought_stream_iterator() -> AsyncIterator[ThoughtChunk]:
647
+ async for chunk in chunk_iter:
648
+ if chunk.type == "thought_chunk":
649
+ yield chunk
650
+ else:
651
+ return # Stream finished
652
+
653
+ stream = AsyncThoughtStream(
654
+ chunk_iterator=thought_stream_iterator()
655
+ )
656
+ yield stream
657
+
658
+ case "tool_call_start_chunk":
659
+ tool_id = start_chunk.id
660
+ tool_name = start_chunk.name
661
+
662
+ async def tool_call_stream_iterator() -> AsyncIterator[
663
+ ToolCallChunk
664
+ ]:
665
+ async for chunk in chunk_iter:
666
+ if chunk.type == "tool_call_chunk":
667
+ yield chunk
668
+ else:
669
+ return # Stream finished
670
+
671
+ stream = AsyncToolCallStream(
672
+ tool_id=tool_id,
673
+ tool_name=tool_name,
674
+ chunk_iterator=tool_call_stream_iterator(),
675
+ )
676
+ yield stream
677
+
678
+ case _: # pragma: no cover
679
+ raise RuntimeError(f"Expected start chunk, got: {start_chunk.type}")
680
+
681
+ # Before continuing to the next stream, make sure the last stream is consumed
682
+ # (If the user did not do so when we yielded it)
683
+ await stream.collect()
684
+
685
+ async def chunk_stream(
686
+ self,
687
+ ) -> AsyncIterator[AssistantContentChunk]:
688
+ """Returns an async iterator that yields content chunks as they are received.
689
+
690
+ Returns:
691
+ AsyncIterator[AssistantContentChunk]: Async iterator yielding chunks
692
+
693
+ This provides access to the Mirascope chunk data including start, delta, and end chunks
694
+ for each content type (text, thinking, tool_call). Unlike the streams() method
695
+ that groups chunks by content part, this yields individual chunks as they arrive.
696
+
697
+ Fully iterating through this iterator will fully consume the underlying stream,
698
+ updating the Response with all collected content.
699
+
700
+ As chunks are consumed, they are cached on the AsyncStreamResponse. If a new iterator
701
+ is constructed via calling `chunk_stream()`, it will start by replaying the cached
702
+ chunks from the response, and (if there is still more content to consume from
703
+ the LLM), it will proceed to consume it once it has iterated through all the
704
+ cached chunks.
705
+ """
706
+
707
+ for chunk in self.chunks:
708
+ yield chunk
709
+
710
+ if self.consumed:
711
+ return
712
+
713
+ async for chunk in self._chunk_iterator:
714
+ if chunk.type == "raw_stream_event_chunk":
715
+ self._raw_stream_events.append(chunk.raw_stream_event)
716
+ elif chunk.type == "raw_message_chunk":
717
+ self._assistant_message.raw_message = chunk.raw_message
718
+ elif chunk.type == "finish_reason_chunk":
719
+ self.finish_reason = chunk.finish_reason
720
+ elif chunk.type == "usage_delta_chunk":
721
+ if self.usage is None:
722
+ self.usage = Usage()
723
+ self.usage.input_tokens += chunk.input_tokens
724
+ self.usage.output_tokens += chunk.output_tokens
725
+ self.usage.cache_read_tokens += chunk.cache_read_tokens
726
+ self.usage.cache_write_tokens += chunk.cache_write_tokens
727
+ self.usage.reasoning_tokens += chunk.reasoning_tokens
728
+ else:
729
+ yield self._handle_chunk(chunk)
730
+
731
+ self.consumed = True
732
+
733
+ async def finish(self) -> None:
734
+ """Finish streaming all of this response's content."""
735
+ async for _ in self.chunk_stream():
736
+ pass
737
+
738
+ async def text_stream(self, sep: str = "\n") -> AsyncIterator[str]:
739
+ """Stream only the text content from the response.
740
+
741
+ Args:
742
+ sep: Separator to yield between text parts. Defaults to newline.
743
+
744
+ Returns:
745
+ AsyncIterator[str]: Async iterator yielding text delta strings
746
+
747
+ Yields text deltas as they arrive, ignoring thoughts, tool calls, and other
748
+ content types. Ideal for displaying text to users in real-time.
749
+
750
+ If you concatenate the strings from `.text_stream()`, it will be equivalent to
751
+ calling `.text(sep=sep)` on the fully consumed response.
752
+ """
753
+ async for stream in self.streams():
754
+ if stream.content_type == "text":
755
+ async for delta in stream:
756
+ yield delta
757
+ yield sep
758
+
759
+ async def pretty_stream(self) -> AsyncIterator[str]:
760
+ """Stream a readable representation of the stream_response as text.
761
+
762
+ Returns:
763
+ AsyncIterator[str]: Async iterator yielding string chunks depicting the content
764
+
765
+ Iterating through the pretty stream will populate the stream response by consuming
766
+ the underlying iterator (if it hasn't been consumed already). Calling `.pretty_stream()`
767
+ will always return a fresh iterator that begins from the start of the stream.
768
+
769
+ If you concatenate the text from `.pretty_stream()`, it will be equivalent to the
770
+ text generated by calling `.pretty()` (assuming the response was fully consumed
771
+ at the time when you call `.pretty()`).
772
+ """
773
+ printed = False
774
+
775
+ async for chunk in self.chunk_stream():
776
+ pretty = self._pretty_chunk(chunk, "\n\n" if printed else "")
777
+ if pretty != "":
778
+ printed = True
779
+ yield pretty
780
+
781
+ async def structured_stream(
782
+ self,
783
+ ) -> AsyncIterator[Partial[FormattableT]]:
784
+ """Drive the stream forward, yielding partial formatted outputs as they arrive.
785
+
786
+ This method consumes the underlying stream chunk by chunk, yielding parsed
787
+ partial outputs each time new content arrives. Each yielded value is a
788
+ Partial[FormattableT] with optional fields that may be None until fully received.
789
+
790
+ Example:
791
+ >>> response = await recommend_book.stream("fantasy")
792
+ >>> async for partial in response.structured_stream():
793
+ >>> print(f"Title so far: {partial.title}")
794
+ >>> book = response.parse() # Get final complete result
795
+
796
+ Fully iterating through this iterator will fully consume the underlying stream,
797
+ updating the Response with all collected content.
798
+
799
+ Yields:
800
+ Partial[FormattableT]: Partial objects with fields populated as they arrive.
801
+ Fields not yet received will be None.
802
+
803
+ Raises:
804
+ ValueError: If format parameter not set.
805
+ NotImplementedError: If format uses OutputParser (not supported).
806
+ """
807
+ if self.format is None:
808
+ raise ValueError("structured_stream() requires format parameter")
809
+
810
+ if is_output_parser(self.format.formattable):
811
+ raise NotImplementedError(
812
+ "structured_stream() not supported for OutputParser. "
813
+ "Use BaseModel or primitive types."
814
+ )
815
+
816
+ async for chunk in self.chunk_stream():
817
+ if chunk.type == "text_chunk":
818
+ partial = self.parse(partial=True)
819
+ if partial:
820
+ yield partial