mirascope 1.25.6__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.6.dist-info → mirascope-2.0.0.dist-info}/WHEEL +1 -1
  423. {mirascope-1.25.6.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 -142
  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.6.dist-info/METADATA +0 -169
  797. mirascope-1.25.6.dist-info/RECORD +0 -378
@@ -1,714 +0,0 @@
1
- """The `FiniteStateMachine` Class Implementation."""
2
-
3
- import contextvars
4
- import inspect
5
- from collections.abc import Callable, Coroutine
6
- from functools import wraps
7
- from types import TracebackType
8
- from typing import Any, Generic, ParamSpec, Protocol, overload
9
-
10
- from typing_extensions import TypeVar
11
-
12
- NoneType = type(None)
13
- _DepsT = TypeVar("_DepsT", default=None)
14
-
15
-
16
- class RunContext(Generic[_DepsT]):
17
- """The runtime context for the Finite State Machine (FSM).
18
-
19
- This class is used to store the state of the FSM and the data that is passed between
20
- nodes. Consumers of the FSM can update the context as needed to change the state of
21
- the FSM or pass information between nodes.
22
-
23
- At a minimum the `RunContext` should know:
24
- - The necessary dependencies for running the FSM.
25
- - The current state of the FSM.
26
- - The inputs to the current node being run.
27
- - The transition edges of the FSM.
28
- - Data that is shared between nodes.
29
- - The state history of the FSM execution.
30
- - Error states and fallback handling.
31
- - The queue of incoming requests and their context.
32
-
33
- The last point is important. For the FSM to be efficient, we must enable running
34
- nodes in parallel. This means that we need to be able to queue incoming requests
35
- and their context, and then run the nodes in parallel up to the set thread limit.
36
-
37
- Attributes:
38
- state (...): The current state of the FSM.
39
- inputs (...): The inputs to the current node being run.
40
- transitions (...): The transition edges of the FSM.
41
- data (...): Data that is shared between nodes.
42
- state_history (...): The state history of the FSM execution.
43
- error_states (...): Error states and fallback handling.
44
- """
45
-
46
- deps: _DepsT
47
-
48
- def __init__(self, deps: _DepsT, **data: dict[str, Any]) -> None:
49
- self.deps = deps
50
- for key, value in data.items():
51
- setattr(self, key, value)
52
-
53
-
54
- # Use ContextVar instead of thread-local for async compatibility
55
- # This automatically propagates across async boundaries
56
- _CONTEXT_VAR: contextvars.ContextVar[RunContext[Any] | None] = contextvars.ContextVar(
57
- "fsm_context", default=None
58
- )
59
-
60
-
61
- class FSMContextManager(Generic[_DepsT]):
62
- """Context manager for FSM contexts that supports both sync and async patterns.
63
-
64
- This class implements both the synchronous context manager protocol
65
- (__enter__/__exit__) and the asynchronous context manager protocol
66
- (__aenter__/__aexit__), allowing it to be used with both `with` and
67
- `async with` statements.
68
-
69
- The context manager handles setting and resetting the context variable
70
- that stores the RunContext, ensuring proper propagation through async code.
71
-
72
- NOTE: This simplified implementation has some limitations with complex nested
73
- async calls across context boundaries. For nested nodes calling other nodes
74
- asynchronously after a context exit, the context may not be properly preserved.
75
- In these cases, using a compiled machine is recommended.
76
-
77
- NOTE: We implement stubs using the sync case because the async case is currently
78
- the same and does not require separate implementations. In the future we may update
79
- this to handle more complex async cases where the context e.g. pulls from an
80
- external source or something.
81
-
82
- Attributes:
83
- ctx: The RunContext that will be set as active during the context.
84
- token: The token returned by _CONTEXT_VAR.set() that is used to restore
85
- the previous context when exiting.
86
- """
87
-
88
- ctx: RunContext[_DepsT]
89
- token: contextvars.Token | None = None
90
-
91
- def __init__(self, ctx: RunContext[_DepsT]) -> None:
92
- """Initialize a new FSMContextManager.
93
-
94
- Args:
95
- ctx: The RunContext to use during this context.
96
- """
97
- self.ctx = ctx
98
-
99
- def __enter__(self) -> RunContext[_DepsT]:
100
- """Enter the context manager (synchronous).
101
-
102
- Sets the RunContext as the current context and returns it.
103
-
104
- Returns:
105
- The RunContext for use within the `with` block.
106
- """
107
- self.token = _CONTEXT_VAR.set(self.ctx)
108
- return self.ctx
109
-
110
- def __exit__(
111
- self,
112
- exc_type: type[BaseException],
113
- exc_val: BaseException | None,
114
- exc_tb: TracebackType | None,
115
- ) -> None:
116
- """Exit the context manager (synchronous).
117
-
118
- Restores the previous context that was active before entering.
119
-
120
- Args:
121
- exc_type: The exception type if an exception was raised in the with block.
122
- exc_val: The exception value if an exception was raised in the with block.
123
- exc_tb: The traceback if an exception was raised in the with block.
124
- """
125
- if self.token is not None:
126
- _CONTEXT_VAR.reset(self.token)
127
- self.token = None
128
-
129
- async def __aenter__(self) -> RunContext[_DepsT]:
130
- """Enter the context manager (asynchronous).
131
-
132
- Same as __enter__ but for use with `async with`.
133
-
134
- Returns:
135
- The RunContext for use within the `async with` block.
136
- """
137
- return self.__enter__()
138
-
139
- async def __aexit__(
140
- self,
141
- exc_type: type[BaseException],
142
- exc_val: BaseException | None,
143
- exc_tb: TracebackType | None,
144
- ) -> None:
145
- """Exit the context manager (asynchronous).
146
-
147
- Same as __exit__ but for use with `async with`.
148
-
149
- Args:
150
- exc_type: The exception type if an exception was raised in the with block.
151
- exc_val: The exception value if an exception was raised in the with block.
152
- exc_tb: The traceback if an exception was raised in the with block.
153
- """
154
- self.__exit__(exc_type, exc_val, exc_tb)
155
-
156
-
157
- class FSMContextError(Exception):
158
- """Raised when a node is executed outside of a context manager."""
159
-
160
- pass
161
-
162
-
163
- _NodeDecoratedFunctionP = ParamSpec("_NodeDecoratedFunctionP")
164
- _NodeDecoratedFunctionR = TypeVar("_NodeDecoratedFunctionR", covariant=True)
165
-
166
-
167
- class NodeDecoratedFunction(
168
- Protocol[_NodeDecoratedFunctionP, _NodeDecoratedFunctionR, _DepsT]
169
- ):
170
- """The protocol for functions decorated with the `node` decorator.
171
-
172
- This protocol enables enforcing that the first argument of any `node` decorated
173
- function must be `ctx: RunContext` to ensure that the function can access the global
174
- context of the FSM.
175
- """
176
-
177
- __name__: str
178
-
179
- def __call__(
180
- self,
181
- ctx: RunContext[_DepsT],
182
- *args: _NodeDecoratedFunctionP.args,
183
- **kwargs: _NodeDecoratedFunctionP.kwargs,
184
- ) -> _NodeDecoratedFunctionR: ...
185
-
186
-
187
- _NodeDecoratorP = ParamSpec("_NodeDecoratorP")
188
- _NodeDecoratorR = TypeVar("_NodeDecoratorR")
189
-
190
-
191
- class NodeDecorator(Protocol[_DepsT]):
192
- """The `node` decorator protocol.
193
-
194
- This protocol enables overloading the `node` function such that it can detect and
195
- type async functions correctly. The `node` decorator is used to register a function
196
- as a node in the FSM, so the resulting function when run uncompiled should run just
197
- as the original function would (and thus required matching type hints).
198
- """
199
-
200
- @overload
201
- def __call__(
202
- self,
203
- fn: NodeDecoratedFunction[
204
- _NodeDecoratorP, Coroutine[Any, Any, _NodeDecoratorR], _DepsT
205
- ],
206
- ) -> Callable[_NodeDecoratorP, Coroutine[Any, Any, _NodeDecoratorR]]: ...
207
-
208
- @overload
209
- def __call__(
210
- self, fn: NodeDecoratedFunction[_NodeDecoratorP, _NodeDecoratorR, _DepsT]
211
- ) -> Callable[_NodeDecoratorP, _NodeDecoratorR]: ...
212
-
213
- def __call__(
214
- self,
215
- fn: NodeDecoratedFunction[
216
- _NodeDecoratorP,
217
- _NodeDecoratorR | Coroutine[Any, Any, _NodeDecoratorR],
218
- _DepsT,
219
- ],
220
- ) -> Callable[
221
- _NodeDecoratorP, _NodeDecoratorR | Coroutine[Any, Any, _NodeDecoratorR]
222
- ]: ...
223
-
224
-
225
- _P = ParamSpec("_P")
226
- _R = TypeVar("_R")
227
-
228
-
229
- class FiniteStateMachine(Generic[_DepsT]):
230
- '''Automatical Finite State Machine (FSM) compiled from the code execution graph.
231
-
232
- This class provides a global `RunContext` and a `node` decorator that gives function
233
- it decorates access to the global context. The context is used to store the state
234
- of the FSM and the data that is passed between nodes. This means that the consumer
235
- of this class can update the context as needed to change the state of the FSM or
236
- pass information between nodes.
237
-
238
- Let's consider a very simple example of a FSM that increments a given value until it
239
- is divisible by a given divisor. The FSM has two nodes: `increment` and
240
- `divisible_by`. The `increment` node increments the given value by 1, and the
241
- `divisible_by` node checks if the value is divisible by the given divisor. If it is,
242
- the FSM returns the number of increments, otherwise it increments and divides again.
243
-
244
- The FSM might look something like this:
245
-
246
- +-----------+ +-----------+
247
- | increment | ----> | divide | <---- start value
248
- | | <---- | | ----> number of increments
249
- +-----------+ +-----------+
250
-
251
- The FSM has two nodes:
252
- - `increment`: Increments the given value by 1.
253
- - `divisible_by`: Checks if the value is divisible by the given divisor.
254
-
255
- Now, it would be fairly straightforward to implement this FSM by defining the nodes
256
- and the edges between them. However, the FSM can get very complex very quickly, and
257
- it would be nice to have a way to automatically compile the FSM from the code so
258
- that we can build arbitrarily complex systems without having to worry how to
259
- structure them. Once compiled, the code can be run as a finite state machine.
260
-
261
- What if we could just define the code?
262
-
263
- Example:
264
-
265
- ```python
266
- from dataclasses import dataclass
267
-
268
- @dataclass
269
- class Deps:
270
- operations: int = 0
271
-
272
- fsm = FiniteStateMachine(deps_type=Deps)
273
-
274
- @fsm.node()
275
- async def increment(ctx: RunContext[Deps], value: int) -> int:
276
- ctx.deps.operations += 1
277
- return value + 1
278
-
279
- @fsm.node()
280
- async def divide(ctx: RunContext[Deps], value: int, divisor: int) -> int:
281
- ctx.deps.operations += 1
282
- return value // divisor
283
-
284
- @fsm.node()
285
- async def reach_zero(ctx: RunContext[Deps], value: int, divisor: int) -> int:
286
- while value != 0:
287
- value = await increment(value)
288
- value = await divide(value, divisor)
289
- return ctx.deps.operations
290
-
291
- # in async running loop
292
- async with fsm.context(deps=Deps(0)) as ctx:
293
- operations = await reach_zero(5, 3)
294
- print(f"Operations: {operations}")
295
- ```
296
-
297
- What about an FSM that represents a librarian?
298
-
299
- Example:
300
-
301
- ```python
302
- import asyncio
303
- from dataclasses import dataclass
304
-
305
- from mirascope import BaseMessageParam, Messages, llm
306
- from mirascope import graphs as g
307
-
308
-
309
- @dataclass
310
- class Book
311
- title: str
312
- author: str
313
-
314
-
315
- @dataclass
316
- class Library:
317
- librarian: str
318
- messages: list[BaseMessageParam]
319
- all_books: list[Book]
320
- available_books: dict[str, bool]
321
-
322
-
323
- machine = g.FiniteStateMachine(deps_type=Library)
324
-
325
-
326
- @machine.node()
327
- @llm.tool()
328
- def all_books(ctx: g.RunContext[Library]) -> list[Book]:
329
- """Returns the titles of all books the library owns."""
330
- return ctx.deps.all_books
331
-
332
-
333
- @machine.node()
334
- @llm.tool()
335
- def book_is_available(ctx: g.RunContext[Library], title: str) -> str:
336
- """Returns the author of the book with the given title."""
337
- return ctx.deps.available_books[title]
338
-
339
-
340
- @machine.node()
341
- @llm.call("openai", "gpt-4o-mini", tools=[all_books, book_is_available])
342
- async def answer_question(ctx: g.RunContext[Library]) -> str:
343
- return f"You are a librarian named {ctx.deps.librarian}"
344
-
345
-
346
- @machine.node()
347
- async def handle_tools(ctx: g.RunContext[Library], tools: list[Tool]) -> None:
348
- tool_tasks = [tool.call() for tool in tools]
349
- tool_outputs = asyncio.gather(*tool_tasks)
350
- tools_and_outputs = [(tool, output) for tool, output in zip(tools, tools_outputs, strict=True)]
351
- ctx.deps.messages += llm.CallResponse.tool_message_params(tools_and_outputs)
352
-
353
- @machine.node()
354
- async def librarian(ctx: g.RunContext[Library], question: str) -> llm.CallResponse:
355
- response = await answer_question(question)
356
- if response.user_message_param:
357
- ctx.deps.messages.append(response.user_message_param)
358
- ctx.deps.messages.append(response.message_param)
359
- if tools := response.tools:
360
- await handle_tools(tools)
361
- return await answer_question("")
362
- return response
363
-
364
-
365
- agent = machine.compile(start=librarian)
366
-
367
- response = agent.run(
368
- "Do you carry The Name of the Wind? Is it available?",
369
- deps=Library(
370
- librarian="Mira",
371
- all_books=[
372
- Book("The Name of the Wind", "Patrick Rothfuss"),
373
- Book("Mistborn: The Final Empire", "Brandon Sanderson"),
374
- ],
375
- available_books={
376
- "The Name of the Wind": True,
377
- "Mistborn: The Final Empire": False,
378
- },
379
- )
380
- )
381
- print(response.content)
382
- ```
383
-
384
- Ultimately each node is fairly self-contained except for `librarian`, which can be
385
- thought of as it's own little sub-FSM or controller. The `librarian` node is the
386
- entry point to the FSM and is responsible for handling the incoming question,
387
- calling the `answer_question` node, and then handling the tools that are returned.
388
- The `answer_question` node is responsible for answering the question, and the
389
- `handle_tools` node is responsible for calling the tools and then returning the
390
- results.
391
-
392
- The compiled graph might look something like this:
393
-
394
- +-----------------+ +-------------------+
395
- question --> | answer_question | ----> | _handle_response_ | --> response
396
- +-----------------+ +-------------------+
397
- ^ |
398
- | v
399
- +-------------------+
400
- | handle_tools |
401
- +-------------------+
402
-
403
-
404
- Inside the `librarian` function, really all we're doing is calling `answer_question`
405
- and then handling the response such that we either call any requested tools and call
406
- `answer_question` again, or we return the response. This is a very simple example,
407
- but it shows how we can build an efficient FSM without having to worry about the
408
- nitty gritty details of how the FSM is structured.
409
-
410
- We get to code. The FSM then builds itself.
411
- '''
412
-
413
- _deps_type: type[_DepsT]
414
-
415
- def __init__(self, *, deps_type: type[_DepsT] = NoneType) -> None:
416
- """Initializes an instance of `FiniteStateMachine`."""
417
- self._deps_type = deps_type
418
-
419
- def context(self, *, deps: _DepsT) -> FSMContextManager[_DepsT]:
420
- """Creates a context manager for the FSM that handles both sync and async.
421
-
422
- This method returns an instance of FSMContextManager which can be used with both
423
- `with` and `async with` statements. The context manager sets up a RunContext
424
- that all node-decorated functions will use while the context is active. The
425
- context is stored using contextvars.ContextVar which properly propagates through
426
- async code, allowing context to be maintained across await points and between
427
- nodes so long as each node is called within the context.
428
-
429
- Example:
430
-
431
- Synchronous usage:
432
- ```python
433
- with fsm.context(deps=Deps()) as ctx:
434
- result = increment(5) # ctx is automatically passed
435
- ```
436
-
437
- Example:
438
-
439
- Asynchronous usage:
440
- ```python
441
- async with fsm.context(deps=Deps()) as ctx:
442
- result = await async_increment(5) # ctx is automatically passed
443
- ```
444
-
445
- Args:
446
- deps: The dependencies for the FSM.
447
-
448
- Returns:
449
- An FSMContextManager instance that supports both `with` and `async with`.
450
- """
451
- ctx = RunContext(deps=deps)
452
- return FSMContextManager(ctx)
453
-
454
- def node(self) -> NodeDecorator[_DepsT]:
455
- """Registers the given function as a node in the FSM.
456
-
457
- This decorator transforms a function that requires a RunContext as its first
458
- parameter into a function that can be called without explicitly passing the
459
- context. The context is retrieved from contextvars.ContextVar which properly
460
- propagates through async code, ensuring that context is maintained across
461
- await points.
462
-
463
- This means that when a node calls another node, even asynchronously, the context
464
- is automatically propagated without any special handling. This allows for
465
- building complex node graphs with proper context flow.
466
-
467
- If the decorated function is called outside of a context manager, a
468
- FSMContextError will be raised.
469
-
470
- Returns:
471
- A decorator that registers the given function as a node in the FSM.
472
- """
473
-
474
- @overload
475
- def decorator(
476
- fn: NodeDecoratedFunction[_P, Coroutine[Any, Any, _R], _DepsT],
477
- ) -> Callable[_P, Coroutine[Any, Any, _R]]: ...
478
-
479
- @overload
480
- def decorator(
481
- fn: NodeDecoratedFunction[_P, _R, _DepsT],
482
- ) -> Callable[_P, _R]: ...
483
-
484
- def decorator(
485
- fn: NodeDecoratedFunction[_P, _R | Coroutine[Any, Any, _R], _DepsT],
486
- ) -> Callable[_P, _R | Coroutine[Any, Any, _R]]:
487
- @wraps(fn)
488
- def context_wrapper(
489
- *args: _P.args, **kwargs: _P.kwargs
490
- ) -> _R | Coroutine[Any, Any, _R]:
491
- context = _CONTEXT_VAR.get()
492
- if context is None:
493
- raise FSMContextError(
494
- f"Node `{fn.__name__}` called outside of a context manager. "
495
- f"Use 'with fsm.context(deps=...)' to provide a context."
496
- )
497
-
498
- if inspect.iscoroutinefunction(fn):
499
- # For async functions, just create and return a coroutine with the
500
- # context management inside so we handle contextvars correctly
501
- @wraps(fn)
502
- async def inner_async() -> _R:
503
- async with FSMContextManager(context):
504
- return await fn(context, *args, **kwargs) # pyright: ignore [reportGeneralTypeIssues]
505
-
506
- return inner_async()
507
-
508
- return fn(context, *args, **kwargs)
509
-
510
- return context_wrapper
511
-
512
- return decorator
513
-
514
- def compile(
515
- self,
516
- start: Callable[_P, _R],
517
- *,
518
- deps: _DepsT = None,
519
- ) -> "CompiledMachine[_P, _R, _DepsT]":
520
- """Returns the compiled FSM.
521
-
522
- Compiles the FSM and returns a CompiledMachine that can be used to run the FSM.
523
- The CompiledMachine will use the provided start function as the entry point to
524
- the FSM and will create a RunContext with the provided dependencies.
525
-
526
- Args:
527
- start: The entry point to the FSM.
528
- deps: The dependencies for the FSM.
529
-
530
- Returns:
531
- A CompiledMachine that can be used to run the FSM.
532
- """
533
- return CompiledMachine(fsm=self, start=start, deps=deps)
534
-
535
-
536
- class CompiledMachine(Generic[_P, _R, _DepsT]):
537
- """The compiled Finite State Machine (FSM).
538
-
539
- This class represents a compiled FSM that can be run with a specific start function.
540
- The FSM will use the provided start function as the entry point and will create a
541
- RunContext with the provided dependencies when run.
542
-
543
- Attributes:
544
- fsm: The FiniteStateMachine that was compiled.
545
- start: The entry point to the FSM.
546
- deps: The dependencies for the FSM.
547
- """
548
-
549
- fsm: FiniteStateMachine[_DepsT]
550
- start: Callable[_P, _R]
551
- deps: _DepsT
552
-
553
- def __init__(
554
- self,
555
- *,
556
- fsm: FiniteStateMachine[_DepsT],
557
- start: Callable[_P, _R],
558
- deps: _DepsT = None,
559
- ) -> None:
560
- """Initializes an instance of `CompiledMachine`."""
561
- self.fsm = fsm
562
- self.start = start
563
- self.deps = deps
564
-
565
- def run(self, *args: _P.args, **kwargs: _P.kwargs) -> _R:
566
- """Runs the FSM synchronously.
567
-
568
- This method runs the FSM using the specified start function and dependencies.
569
- It sets up a context manager to provide the RunContext for all node-decorated
570
- functions called during the execution of the FSM.
571
-
572
- This method should only be used with synchronous start functions. For async
573
- functions, use `run_async` instead.
574
-
575
- Args:
576
- *args: The positional arguments to pass to the start function.
577
- **kwargs: The keyword arguments to pass to the start function.
578
-
579
- Returns:
580
- The result of running the FSM.
581
-
582
- Raises:
583
- FSMContextError: If the start function or any node-decorated function is
584
- called outside of a context manager.
585
- RuntimeError: If called with an async function as the start function.
586
- """
587
- if inspect.iscoroutinefunction(self.start):
588
- raise RuntimeError(
589
- f"Cannot use run() with async function {self.start.__name__}. "
590
- f"Use run_async() instead."
591
- )
592
-
593
- with self.fsm.context(deps=self.deps):
594
- return self.start(*args, **kwargs)
595
-
596
- async def run_async(self, *args: _P.args, **kwargs: _P.kwargs) -> _R:
597
- """Runs the FSM asynchronously.
598
-
599
- This method runs the FSM using the specified start function and dependencies.
600
- It sets up an async context manager to provide the RunContext for all node-decorated
601
- functions called during the execution of the FSM.
602
-
603
- This method should only be used with asynchronous start functions. For synchronous
604
- functions, use `run` instead.
605
-
606
- Args:
607
- *args: The positional arguments to pass to the start function.
608
- **kwargs: The keyword arguments to pass to the start function.
609
-
610
- Returns:
611
- The result of running the FSM.
612
-
613
- Raises:
614
- FSMContextError: If the start function or any node-decorated function is
615
- called outside of a context manager.
616
- RuntimeError: If called with a sync function as the start function.
617
- """
618
- async with self.fsm.context(deps=self.deps):
619
- result = self.start(*args, **kwargs)
620
- if inspect.isawaitable(result):
621
- return await result
622
- return result
623
-
624
-
625
- async def main() -> None:
626
- from dataclasses import dataclass
627
-
628
- @dataclass
629
- class Deps:
630
- operations: int = 0
631
-
632
- fsm = FiniteStateMachine(deps_type=Deps)
633
-
634
- # Example 1: Using the FSM with synchronous functions
635
- print("Example 1: Using the FSM with synchronous functions")
636
-
637
- @fsm.node()
638
- def increment(ctx: RunContext[Deps], value: int) -> int:
639
- ctx.deps.operations += 1
640
- return value + 1
641
-
642
- @fsm.node()
643
- def divide(ctx: RunContext[Deps], value: int, divisor: int) -> int:
644
- ctx.deps.operations += 1
645
- return value // divisor
646
-
647
- @fsm.node()
648
- def reach_zero(ctx: RunContext[Deps], value: int, divisor: int) -> int:
649
- while value != 0:
650
- value = increment(value)
651
- value = divide(value, divisor)
652
- return ctx.deps.operations
653
-
654
- with fsm.context(deps=Deps(0)):
655
- operations = reach_zero(5, 3)
656
- print(f"Operations: {operations}")
657
-
658
- # Example 2: Run the compiled sync machine
659
- print("\nExample 2: Run the compiled sync machine")
660
- machine = fsm.compile(start=reach_zero, deps=Deps(0))
661
- num_operations = machine.run(value=5, divisor=3)
662
- print(f"Compiled sync operations: {num_operations}")
663
-
664
- # # Define async nodes
665
- @fsm.node()
666
- async def async_increment(ctx: RunContext[Deps], value: int) -> int:
667
- ctx.deps.operations += 1
668
- return value + 1
669
-
670
- @fsm.node()
671
- async def async_divide(ctx: RunContext[Deps], value: int, divisor: int) -> int:
672
- ctx.deps.operations += 1
673
- return value // divisor
674
-
675
- @fsm.node()
676
- async def async_reach_zero(ctx: RunContext[Deps], value: int, divisor: int) -> int:
677
- while value != 0:
678
- value = await async_increment(value)
679
- value = await async_divide(value, divisor)
680
- return ctx.deps.operations
681
-
682
- # Example 3: Using synchronous context with async functions within boundaries
683
- print("\nExample 3: Synchronous context with async functions")
684
- with fsm.context(deps=Deps(0)):
685
- operations = await async_reach_zero(5, 3)
686
- print(f"Async operations in sync context: {operations}")
687
-
688
- # Example 3.5: Using asynchronous context with async functions within boundaries
689
- print("\nExample 3.5: Asynchronous context with async functions")
690
- async with fsm.context(deps=Deps(0)):
691
- operations = await async_reach_zero(5, 3)
692
- print(f"Async operations in async context: {operations}")
693
-
694
- # Example 4: Demonstrate context preservation across await boundaries
695
- print("\nContext preservation example:")
696
- async with fsm.context(deps=Deps(0)):
697
- # Create the coroutine task inside the context
698
- operations_task = async_reach_zero(5, 3)
699
- print("Task created inside context manager")
700
- # But await it outside the context - this will work because we preserve the context
701
- operations = await operations_task
702
- print(f"Task awaited outside context, operations: {operations}")
703
-
704
- # Example 5: Run the compiled async machine
705
- print("\nCompiled async machine example:")
706
- async_machine = fsm.compile(start=async_reach_zero, deps=Deps(0))
707
- async_num_operations = await async_machine.run_async(value=5, divisor=3)
708
- print(f"Compiled async operations: {async_num_operations}")
709
-
710
-
711
- if __name__ == "__main__":
712
- import asyncio
713
-
714
- asyncio.run(main())