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