flowra 0.0.24.dev33__tar.gz → 0.0.25.dev35__tar.gz

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 (272) hide show
  1. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/CHANGELOG.md +6 -0
  2. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/PKG-INFO +1 -1
  3. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/observability.md +51 -43
  4. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/tools/random_numbers.py +3 -2
  5. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/__init__.py +3 -1
  6. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/ext/mlflow.py +4 -1
  7. flowra-0.0.25.dev35/flowra/version.py +2 -0
  8. flowra-0.0.24.dev33/flowra/version.py +0 -2
  9. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.claude/commands/update-pricing.md +0 -0
  10. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.env.example +0 -0
  11. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.github/workflows/master.yml +0 -0
  12. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.github/workflows/publish.yml +0 -0
  13. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.github/workflows/pull_request.yml +0 -0
  14. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.github/workflows/pull_request_e2e.yml +0 -0
  15. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.gitignore +0 -0
  16. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.python-version +0 -0
  17. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/CLAUDE.md +0 -0
  18. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/LICENSE +0 -0
  19. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/Makefile +0 -0
  20. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/README.md +0 -0
  21. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/context7.json +0 -0
  22. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/agents.md +0 -0
  23. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/getting-started.md +0 -0
  24. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/agent.md +0 -0
  25. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/architecture.md +0 -0
  26. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/ext/mlflow.md +0 -0
  27. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/ext/otel.md +0 -0
  28. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/ext/tracing-guide.md +0 -0
  29. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/ext.md +0 -0
  30. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/lib/anthropic.md +0 -0
  31. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/lib.md +0 -0
  32. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/llm.md +0 -0
  33. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/patterns.md +0 -0
  34. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/tools.md +0 -0
  35. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/llm.md +0 -0
  36. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/patterns.md +0 -0
  37. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/flowing_context.md +0 -0
  38. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/hooks_redesign.md +0 -0
  39. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/mlflow_context_migration.md +0 -0
  40. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/model_fallback.md +0 -0
  41. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/otel_integration.md +0 -0
  42. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/pricing_complexity.md +0 -0
  43. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/provider_extensions.md +0 -0
  44. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/spawn_strategies.md +0 -0
  45. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/strands_comparison.md +0 -0
  46. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/tool_error_signals.md +0 -0
  47. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/tool_search_tool.md +0 -0
  48. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/voice_stt.md +0 -0
  49. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/review_prompts/step1_structure.md +0 -0
  50. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/review_prompts/step2_code_style.md +0 -0
  51. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/review_prompts/step3_documentation.md +0 -0
  52. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/review_prompts/step4_doc_readability.md +0 -0
  53. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/review_prompts/step5_doc_audit.md +0 -0
  54. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/review_prompts/step6_tests.md +0 -0
  55. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/todo.md +0 -0
  56. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/tools.md +0 -0
  57. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/TRACING_COMBINATIONS.md +0 -0
  58. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/__init__.py +0 -0
  59. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/agent_as_tool.py +0 -0
  60. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/app_agent.py +0 -0
  61. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/console_chat.py +0 -0
  62. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/__init__.py +0 -0
  63. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/agents_custom.py +0 -0
  64. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/agents_parallel.py +0 -0
  65. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/getting_started_chat.py +0 -0
  66. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/getting_started_streaming.py +0 -0
  67. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/getting_started_tools.py +0 -0
  68. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/llm_streaming.py +0 -0
  69. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/llm_structured_output.py +0 -0
  70. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/tools_service_injection.py +0 -0
  71. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/escalation.py +0 -0
  72. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/llm_logging.py +0 -0
  73. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/llm_routing.py +0 -0
  74. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/menu_agent.py +0 -0
  75. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/menu_agent_class.py +0 -0
  76. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/mlflow_demo.py +0 -0
  77. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/mlflow_dual_export_demo.py +0 -0
  78. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/mlflow_nested_demo.py +0 -0
  79. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/mlflow_otel_both_demo.py +0 -0
  80. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/mlflow_otel_nested_demo.py +0 -0
  81. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/mlflow_parallel_demo.py +0 -0
  82. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/model_registry.py +0 -0
  83. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/otel_demo.py +0 -0
  84. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/otel_jaeger_demo.py +0 -0
  85. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/otel_nested_demo.py +0 -0
  86. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/otel_visualize.py +0 -0
  87. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/race.py +0 -0
  88. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/span_crash_demo.py +0 -0
  89. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/span_demo.py +0 -0
  90. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/system_prompt.txt +0 -0
  91. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/tools/__init__.py +0 -0
  92. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/tools/calculator.py +0 -0
  93. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/tools/switch_model.py +0 -0
  94. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/tui_chat.py +0 -0
  95. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/__init__.py +0 -0
  96. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/_sentinel.py +0 -0
  97. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/__init__.py +0 -0
  98. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/agent.py +0 -0
  99. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/agent_arg.py +0 -0
  100. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/__init__.py +0 -0
  101. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/compiler.py +0 -0
  102. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/contract.py +0 -0
  103. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/init_params.py +0 -0
  104. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/instance.py +0 -0
  105. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/step_params.py +0 -0
  106. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/step_validation.py +0 -0
  107. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/steps.py +0 -0
  108. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/type_helpers.py +0 -0
  109. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/type_registry.py +0 -0
  110. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/model.py +0 -0
  111. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/registry.py +0 -0
  112. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/step.py +0 -0
  113. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/step_arg.py +0 -0
  114. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/step_helpers.py +0 -0
  115. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/__init__.py +0 -0
  116. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/actions.py +0 -0
  117. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/context.py +0 -0
  118. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/flowing_registry.py +0 -0
  119. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/hooks.py +0 -0
  120. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/interrupt.py +0 -0
  121. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/interrupt_helpers.py +0 -0
  122. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/spawn.py +0 -0
  123. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/timeout.py +0 -0
  124. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/__init__.py +0 -0
  125. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/engine.py +0 -0
  126. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/execution.py +0 -0
  127. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/instance_factory.py +0 -0
  128. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/runtime.py +0 -0
  129. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/scope.py +0 -0
  130. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/serialization.py +0 -0
  131. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/spans.py +0 -0
  132. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/spawn_tree.py +0 -0
  133. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/services.py +0 -0
  134. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/state/__init__.py +0 -0
  135. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/state/markers.py +0 -0
  136. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/state/store.py +0 -0
  137. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/state/values.py +0 -0
  138. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/storage/__init__.py +0 -0
  139. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/storage/file.py +0 -0
  140. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/storage/in_memory.py +0 -0
  141. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/storage/session_storage.py +0 -0
  142. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/ext/__init__.py +0 -0
  143. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/ext/otel.py +0 -0
  144. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/__init__.py +0 -0
  145. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/anthropic/__init__.py +0 -0
  146. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/anthropic/cache.py +0 -0
  147. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/anthropic/presets.py +0 -0
  148. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/anthropic/tool_search.py +0 -0
  149. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/chat/__init__.py +0 -0
  150. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/chat/agent.py +0 -0
  151. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/chat/config.py +0 -0
  152. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/chat/hook_events.py +0 -0
  153. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/chat/spec.py +0 -0
  154. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/config_value.py +0 -0
  155. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/llm_call/__init__.py +0 -0
  156. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/llm_call/agent.py +0 -0
  157. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/llm_call/spec.py +0 -0
  158. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/llm_config.py +0 -0
  159. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/observability/__init__.py +0 -0
  160. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/observability/llm_hooks.py +0 -0
  161. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/__init__.py +0 -0
  162. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/agent.py +0 -0
  163. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/config.py +0 -0
  164. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/context.py +0 -0
  165. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/hook_events.py +0 -0
  166. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/spec.py +0 -0
  167. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/tool_call/__init__.py +0 -0
  168. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/tool_call/agent.py +0 -0
  169. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/tool_call/agent_tool.py +0 -0
  170. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/tool_call/context.py +0 -0
  171. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/__init__.py +0 -0
  172. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/base.py +0 -0
  173. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/blocks.py +0 -0
  174. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/messages.py +0 -0
  175. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/pricing/__init__.py +0 -0
  176. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/pricing/anthropic.py +0 -0
  177. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/pricing/google.py +0 -0
  178. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/pricing/openai.py +0 -0
  179. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/provider.py +0 -0
  180. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/providers/__init__.py +0 -0
  181. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/providers/anthropic_vertex.py +0 -0
  182. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/providers/google_vertex.py +0 -0
  183. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/providers/openai.py +0 -0
  184. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/request.py +0 -0
  185. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/response.py +0 -0
  186. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/schema_formatting.py +0 -0
  187. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/schema_validation.py +0 -0
  188. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/stream.py +0 -0
  189. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/tools.py +0 -0
  190. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/py.typed +0 -0
  191. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/tools/__init__.py +0 -0
  192. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/tools/local_tool.py +0 -0
  193. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/tools/mcp_connection.py +0 -0
  194. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/tools/tool_arg.py +0 -0
  195. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/tools/tool_group.py +0 -0
  196. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/tools/tool_registry.py +0 -0
  197. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/tools/types.py +0 -0
  198. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/pyproject.toml +0 -0
  199. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/__init__.py +0 -0
  200. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/__init__.py +0 -0
  201. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/definition/__init__.py +0 -0
  202. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/definition/compile/__init__.py +0 -0
  203. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/definition/compile/test_compile.py +0 -0
  204. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/definition/compile/test_type_helpers.py +0 -0
  205. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/definition/test_agent.py +0 -0
  206. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/definition/test_registry.py +0 -0
  207. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/definition/test_step_helpers.py +0 -0
  208. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/__init__.py +0 -0
  209. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_agent_def.py +0 -0
  210. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_context.py +0 -0
  211. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_flowing_registry.py +0 -0
  212. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_flowing_registry_tasks.py +0 -0
  213. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_flowing_sync.py +0 -0
  214. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_hooks.py +0 -0
  215. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_interrupt.py +0 -0
  216. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_spans.py +0 -0
  217. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_timeout.py +0 -0
  218. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_with_interrupt.py +0 -0
  219. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/__init__.py +0 -0
  220. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_engine.py +0 -0
  221. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_engine_spans.py +0 -0
  222. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_hook_context.py +0 -0
  223. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_persistence.py +0 -0
  224. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_runtime.py +0 -0
  225. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_scope.py +0 -0
  226. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_serialization.py +0 -0
  227. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_spec_in_constructor.py +0 -0
  228. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/state/__init__.py +0 -0
  229. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/state/test_values.py +0 -0
  230. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/storage/__init__.py +0 -0
  231. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/storage/test_file.py +0 -0
  232. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/storage/test_in_memory.py +0 -0
  233. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/test_missing_scenarios.py +0 -0
  234. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/ext/__init__.py +0 -0
  235. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/ext/test_mlflow.py +0 -0
  236. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/ext/test_otel.py +0 -0
  237. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/__init__.py +0 -0
  238. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/anthropic/__init__.py +0 -0
  239. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/anthropic/test_anthropic.py +0 -0
  240. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/test_chat_agent.py +0 -0
  241. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/test_config_value.py +0 -0
  242. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/test_llm_call_agent.py +0 -0
  243. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/test_matches_tool_filter.py +0 -0
  244. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/test_tool_call_agent.py +0 -0
  245. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/test_tool_call_agent_call_agent.py +0 -0
  246. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/test_tool_loop_agent.py +0 -0
  247. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/tool_loop/__init__.py +0 -0
  248. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/__init__.py +0 -0
  249. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/pricing/__init__.py +0 -0
  250. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/pricing/test_anthropic.py +0 -0
  251. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/pricing/test_google.py +0 -0
  252. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/pricing/test_openai.py +0 -0
  253. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/providers/__init__.py +0 -0
  254. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/providers/test_anthropic_e2e.py +0 -0
  255. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/providers/test_anthropic_vertex.py +0 -0
  256. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/providers/test_google_vertex.py +0 -0
  257. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/providers/test_google_vertex_e2e.py +0 -0
  258. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/providers/test_openai_e2e.py +0 -0
  259. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/providers/test_openai_provider.py +0 -0
  260. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/test_cost_breakdown.py +0 -0
  261. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/test_metadata.py +0 -0
  262. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/test_response.py +0 -0
  263. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/test_schema_formatting.py +0 -0
  264. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/test_schema_validation.py +0 -0
  265. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/test_stream.py +0 -0
  266. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/tools/__init__.py +0 -0
  267. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/tools/test_local_tool.py +0 -0
  268. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/tools/test_mcp_connection.py +0 -0
  269. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/tools/test_tool_group.py +0 -0
  270. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/tools/test_tool_registry.py +0 -0
  271. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tools/sync_pricing.py +0 -0
  272. {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/uv.lock +0 -0
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org).
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.0.24] - 2026-03-24
11
+
10
12
  ### Added
11
13
  - **`FlowingRegistry`** — replaces `FlowingContextVar`. Registry of flowing variables
12
14
  with `on_enter`/`on_exit` callbacks that fire on context switches, keeping external
@@ -25,6 +27,10 @@ and this project adheres to [Semantic Versioning](https://semver.org).
25
27
  - **`experiment_name`** in `MLFLOW_TRACING.install()` is now optional (`None` by default).
26
28
  When `None`, no MLflow experiment is created — useful when flowra spans are always
27
29
  children of externally created spans (no `mlflow.db` side effect).
30
+ - **MLflow tool output** — JSON tool results are now parsed into structured dicts
31
+ for display in MLflow UI, instead of escaped strings.
32
+ - **`GoogleVertexProvider.aclose()`** — now properly closes async client via
33
+ `client.aio.aclose()`, fixing "Event loop is closed" errors.
28
34
 
29
35
  ### Removed
30
36
  - **`FlowingContextVar`** — replaced by `FlowingRegistry`/`FlowingVar`.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flowra
3
- Version: 0.0.24.dev33
3
+ Version: 0.0.25.dev35
4
4
  Summary: Flowra — flow infrastructure for building stateful LLM agents
5
5
  Project-URL: Repository, https://github.com/anna-money/flowra
6
6
  Project-URL: Changelog, https://github.com/anna-money/flowra/blob/master/CHANGELOG.md
@@ -2,20 +2,20 @@
2
2
 
3
3
  Flowra provides two observability mechanisms: **events** (point-in-time
4
4
  notifications) and **spans** (start/end pairs for operations). Both are
5
- delivered via `HookSubscription`. On top of these primitives, Flowra ships
5
+ delivered via `runtime.hooks`. On top of these primitives, Flowra ships
6
6
  integrations with MLflow and OpenTelemetry.
7
7
 
8
8
  ## Events
9
9
 
10
10
  Events are point-in-time notifications emitted during agent execution. Register
11
- handlers via `HookSubscription.on()`:
11
+ handlers via `runtime.hooks.on()`:
12
12
 
13
13
  ```python
14
- from flowra.agent import HookSubscription
14
+ from flowra.agent import AgentRuntime
15
15
  from flowra.lib.observability import TextDeltaEvent
16
16
 
17
- hooks = HookSubscription()
18
- hooks.on(TextDeltaEvent, lambda e: print(e.data.text, end="", flush=True))
17
+ runtime = AgentRuntime(agents={...}, services={...})
18
+ runtime.hooks.on(TextDeltaEvent, lambda e: print(e.data.text, end="", flush=True))
19
19
  ```
20
20
 
21
21
  Some events are **mutable** — your handler can modify the event data to influence
@@ -52,7 +52,7 @@ Every event is wrapped in `Event[T]` with a `context` field — the execution
52
52
  path from root to the agent that emitted the event:
53
53
 
54
54
  ```python
55
- from flowra.agent import Event
55
+ from flowra.agent import AgentRuntime, Event
56
56
  from flowra.lib.tool_loop import BeforeToolCallEvent
57
57
 
58
58
  def on_before_tool(event: Event[BeforeToolCallEvent]) -> None:
@@ -60,7 +60,8 @@ def on_before_tool(event: Event[BeforeToolCallEvent]) -> None:
60
60
  tool_name = event.data.tool_use.name
61
61
  print(f"[{agent_path}] calling {tool_name}")
62
62
 
63
- hooks.on(BeforeToolCallEvent, on_before_tool)
63
+ runtime = AgentRuntime(agents={...}, services={...})
64
+ runtime.hooks.on(BeforeToolCallEvent, on_before_tool)
64
65
  ```
65
66
 
66
67
  Use `event.context.find_spec(SpecType)` to walk the execution stack and find
@@ -70,13 +71,13 @@ active.
70
71
  ## Spans
71
72
 
72
73
  Spans track operations with a start and end. Register handlers via
73
- `HookSubscription.on_span()`. The handler receives the span at open time and
74
+ `runtime.hooks.on_span()`. The handler receives the span at open time and
74
75
  returns a callback that's invoked at close time:
75
76
 
76
77
  ```python
77
- from flowra.agent import AgentSpan, HookSubscription
78
+ from flowra.agent import AgentRuntime, AgentSpan
78
79
 
79
- hooks = HookSubscription()
80
+ runtime = AgentRuntime(agents={...}, services={...})
80
81
 
81
82
  def on_agent(span: AgentSpan):
82
83
  print(f"▶ agent started: {span.agent_info.path}")
@@ -84,7 +85,7 @@ def on_agent(span: AgentSpan):
84
85
  print(f"◀ agent ended: {span.agent_info.path} result={span.result}")
85
86
  return on_end
86
87
 
87
- hooks.on_span(AgentSpan, on_agent)
88
+ runtime.hooks.on_span(AgentSpan, on_agent)
88
89
  ```
89
90
 
90
91
  ### Span types
@@ -109,10 +110,10 @@ and populated before close.
109
110
  ### Example: console span tree
110
111
 
111
112
  ```python
112
- from flowra.agent import AgentSpan, StepSpan, HookSubscription
113
+ from flowra.agent import AgentRuntime, AgentSpan, StepSpan
113
114
  from flowra.lib.observability import LLMCallSpan, ToolCallSpan
114
115
 
115
- hooks = HookSubscription()
116
+ runtime = AgentRuntime(agents={...}, services={...})
116
117
  indent = 0
117
118
 
118
119
  def on_agent(span: AgentSpan):
@@ -140,9 +141,9 @@ def on_tool(span: ToolCallSpan):
140
141
  print(" " * indent + f" → {span.result.content[:80]}")
141
142
  return on_end
142
143
 
143
- hooks.on_span(AgentSpan, on_agent)
144
- hooks.on_span(LLMCallSpan, on_llm)
145
- hooks.on_span(ToolCallSpan, on_tool)
144
+ runtime.hooks.on_span(AgentSpan, on_agent)
145
+ runtime.hooks.on_span(LLMCallSpan, on_llm)
146
+ runtime.hooks.on_span(ToolCallSpan, on_tool)
146
147
  ```
147
148
 
148
149
  ## MLflow integration
@@ -153,17 +154,15 @@ and session grouping.
153
154
  **Install:** `pip install flowra[mlflow]`
154
155
 
155
156
  ```python
156
- from flowra.agent import HookSubscription
157
- from flowra.ext.mlflow import install_mlflow_tracing
157
+ from flowra.agent import AgentRuntime
158
+ from flowra.ext.mlflow import MLFLOW_TRACING
158
159
 
159
- hooks = HookSubscription()
160
- install_mlflow_tracing(
161
- hooks,
160
+ runtime = AgentRuntime(agents={...}, services={...})
161
+ MLFLOW_TRACING.install(
162
+ runtime,
162
163
  experiment_name="my-experiment",
163
164
  session_id="chat-session-123", # groups multi-turn traces together
164
165
  )
165
-
166
- # pass hooks to AgentRuntime via services={HookSubscription: hooks, ...}
167
166
  ```
168
167
 
169
168
  ### What gets traced
@@ -188,8 +187,8 @@ uv run mlflow ui --port 5050
188
187
  ### Parameters
189
188
 
190
189
  ```python
191
- install_mlflow_tracing(
192
- hooks,
190
+ MLFLOW_TRACING.install(
191
+ runtime,
193
192
  experiment_name="flowra",
194
193
  session_id="chat-123", # or a callable: lambda: current_session_id
195
194
  trace_agents=True,
@@ -207,11 +206,11 @@ Works with any OTel backend — Jaeger, Grafana Tempo, Datadog, Honeycomb, etc.
207
206
  **Install:** `pip install flowra[otel]`
208
207
 
209
208
  ```python
210
- from flowra.agent import HookSubscription
211
- from flowra.ext.otel import install_otel_tracing
209
+ from flowra.agent import AgentRuntime
210
+ from flowra.ext.otel import OTEL_TRACING
212
211
 
213
- hooks = HookSubscription()
214
- install_otel_tracing(hooks)
212
+ runtime = AgentRuntime(agents={...}, services={...})
213
+ OTEL_TRACING.install(runtime)
215
214
  ```
216
215
 
217
216
  You configure your own `TracerProvider` and exporter — Flowra just creates spans.
@@ -248,8 +247,8 @@ OTel spans include standard GenAI attributes:
248
247
  ### Parameters
249
248
 
250
249
  ```python
251
- install_otel_tracing(
252
- hooks,
250
+ OTEL_TRACING.install(
251
+ runtime,
253
252
  tracer_name="flowra",
254
253
  trace_agents=True,
255
254
  trace_steps=True,
@@ -274,10 +273,11 @@ detects it via `mlflow.get_current_active_span()` and nests inside:
274
273
 
275
274
  ```python
276
275
  import mlflow
277
- from flowra.ext.mlflow import install_mlflow_tracing
276
+ from flowra.agent import AgentRuntime
277
+ from flowra.ext.mlflow import MLFLOW_TRACING
278
278
 
279
- hooks = HookSubscription()
280
- install_mlflow_tracing(hooks, experiment_name="my-experiment")
279
+ runtime = AgentRuntime(agents={...}, services={...})
280
+ MLFLOW_TRACING.install(runtime, experiment_name="my-experiment")
281
281
 
282
282
  # External MLflow span — flowra spans become children
283
283
  with mlflow.start_span(name="my_business_logic"):
@@ -291,10 +291,11 @@ via `trace.get_current_span()` and nests inside:
291
291
 
292
292
  ```python
293
293
  from opentelemetry import trace
294
- from flowra.ext.otel import install_otel_tracing
294
+ from flowra.agent import AgentRuntime
295
+ from flowra.ext.otel import OTEL_TRACING
295
296
 
296
- hooks = HookSubscription()
297
- install_otel_tracing(hooks)
297
+ runtime = AgentRuntime(agents={...}, services={...})
298
+ OTEL_TRACING.install(runtime)
298
299
 
299
300
  app_tracer = trace.get_tracer("my_app")
300
301
 
@@ -341,15 +342,19 @@ Two independent span trees — MLflow for LLM-specific analysis, OTel for
341
342
  distributed tracing. Traces are not linked (different trace IDs).
342
343
 
343
344
  ```python
344
- hooks = HookSubscription()
345
- install_mlflow_tracing(hooks, experiment_name="my-experiment")
346
- install_otel_tracing(hooks)
345
+ from flowra.agent import AgentRuntime
346
+ from flowra.ext.mlflow import MLFLOW_TRACING
347
+ from flowra.ext.otel import OTEL_TRACING
348
+
349
+ runtime = AgentRuntime(agents={...}, services={...})
350
+ MLFLOW_TRACING.install(runtime, experiment_name="my-experiment")
351
+ OTEL_TRACING.install(runtime)
347
352
  ```
348
353
 
349
354
  ### MLflow with OTel export
350
355
 
351
356
  MLflow is built on OTel internally. With dual export enabled, MLflow sends
352
- spans to both backends — no `install_otel_tracing` needed. Single trace ID
357
+ spans to both backends — no `OTEL_TRACING.install()` needed. Single trace ID
353
358
  shared between both.
354
359
 
355
360
  Trade-off: MLflow uses its own attribute names (`mlflow.chat.tokenUsage`, etc.)
@@ -357,8 +362,11 @@ rather than `gen_ai.*`, so OTel backends won't recognize them as standard GenAI
357
362
  spans.
358
363
 
359
364
  ```python
360
- hooks = HookSubscription()
361
- install_mlflow_tracing(hooks, experiment_name="my-experiment")
365
+ from flowra.agent import AgentRuntime
366
+ from flowra.ext.mlflow import MLFLOW_TRACING
367
+
368
+ runtime = AgentRuntime(agents={...}, services={...})
369
+ MLFLOW_TRACING.install(runtime, experiment_name="my-experiment")
362
370
  ```
363
371
 
364
372
  ```bash
@@ -2,6 +2,7 @@
2
2
 
3
3
  import asyncio
4
4
  import dataclasses
5
+ import json
5
6
  import logging
6
7
  import random
7
8
 
@@ -22,7 +23,7 @@ class RandomNumbersParams:
22
23
 
23
24
  @tool("random_numbers")
24
25
  async def random_numbers(params: RandomNumbersParams, interrupt: InterruptToken) -> str:
25
- """Generate random integers. Returns them comma-separated."""
26
+ """Generate random integers. Returns JSON with the numbers array."""
26
27
  log.info(
27
28
  "TOOL random_numbers(count=%d, min=%d, max=%d) — sleeping %.1fs",
28
29
  params.count,
@@ -37,6 +38,6 @@ async def random_numbers(params: RandomNumbersParams, interrupt: InterruptToken)
37
38
  except TimeoutError:
38
39
  pass
39
40
  nums = [random.randint(params.min, params.max) for _ in range(params.count)]
40
- result = ", ".join(str(n) for n in nums)
41
+ result = json.dumps({"numbers": nums, "count": len(nums), "range": {"min": params.min, "max": params.max}})
41
42
  log.info("TOOL random_numbers => %s", result[:120])
42
43
  return result
@@ -29,7 +29,7 @@ from .flow import (
29
29
  from .runtime import AgentRuntime, AgentSpan, StepSpan
30
30
  from .services import ServiceLocator
31
31
  from .state import FORK, NEW_SCOPE, AgentStore, AppendOnlyList, Scalar
32
- from .storage import FileSessionStorage, InMemorySessionSnapshot, InMemorySessionStorage
32
+ from .storage import ChangeSet, FileSessionStorage, InMemorySessionSnapshot, InMemorySessionStorage, SessionStorage
33
33
 
34
34
  __all__ = [
35
35
  "FORK",
@@ -43,6 +43,7 @@ __all__ = [
43
43
  "AppendOnlyList",
44
44
  "CallAgent",
45
45
  "CallStep",
46
+ "ChangeSet",
46
47
  "ChildOutput",
47
48
  "Event",
48
49
  "ExecutionContext",
@@ -63,6 +64,7 @@ __all__ = [
63
64
  "InterruptedError",
64
65
  "Scalar",
65
66
  "ServiceLocator",
67
+ "SessionStorage",
66
68
  "Spawn",
67
69
  "SpawnChild",
68
70
  "StepSpan",
@@ -322,7 +322,10 @@ def _make_tool_handler(
322
322
  detach_span_from_context(context_token)
323
323
  outputs: dict[str, Any] = {}
324
324
  if span.result is not None:
325
- outputs["content"] = span.result.content
325
+ try:
326
+ outputs["content"] = json.loads(span.result.content)
327
+ except (json.JSONDecodeError, TypeError):
328
+ outputs["content"] = span.result.content
326
329
  outputs["is_error"] = span.result.is_error
327
330
  if span.error_kind is not None:
328
331
  outputs["error_kind"] = str(span.error_kind)
@@ -0,0 +1,2 @@
1
+ # Updated by CI/CD pipeline
2
+ __version__ = "0.0.25.dev35"
@@ -1,2 +0,0 @@
1
- # Updated by CI/CD pipeline
2
- __version__ = "0.0.24.dev33"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes