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.
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/CHANGELOG.md +6 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/PKG-INFO +1 -1
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/observability.md +51 -43
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/tools/random_numbers.py +3 -2
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/__init__.py +3 -1
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/ext/mlflow.py +4 -1
- flowra-0.0.25.dev35/flowra/version.py +2 -0
- flowra-0.0.24.dev33/flowra/version.py +0 -2
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.claude/commands/update-pricing.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.env.example +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.github/workflows/master.yml +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.github/workflows/publish.yml +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.github/workflows/pull_request.yml +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.github/workflows/pull_request_e2e.yml +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.gitignore +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/.python-version +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/CLAUDE.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/LICENSE +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/Makefile +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/README.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/context7.json +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/agents.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/getting-started.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/agent.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/architecture.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/ext/mlflow.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/ext/otel.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/ext/tracing-guide.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/ext.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/lib/anthropic.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/lib.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/llm.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/patterns.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/internal/tools.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/llm.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/patterns.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/flowing_context.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/hooks_redesign.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/mlflow_context_migration.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/model_fallback.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/otel_integration.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/pricing_complexity.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/provider_extensions.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/spawn_strategies.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/strands_comparison.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/tool_error_signals.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/tool_search_tool.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/research/voice_stt.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/review_prompts/step1_structure.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/review_prompts/step2_code_style.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/review_prompts/step3_documentation.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/review_prompts/step4_doc_readability.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/review_prompts/step5_doc_audit.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/review_prompts/step6_tests.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/todo.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/docs/tools.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/TRACING_COMBINATIONS.md +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/agent_as_tool.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/app_agent.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/console_chat.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/agents_custom.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/agents_parallel.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/getting_started_chat.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/getting_started_streaming.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/getting_started_tools.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/llm_streaming.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/llm_structured_output.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/docs/tools_service_injection.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/escalation.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/llm_logging.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/llm_routing.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/menu_agent.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/menu_agent_class.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/mlflow_demo.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/mlflow_dual_export_demo.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/mlflow_nested_demo.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/mlflow_otel_both_demo.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/mlflow_otel_nested_demo.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/mlflow_parallel_demo.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/model_registry.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/otel_demo.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/otel_jaeger_demo.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/otel_nested_demo.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/otel_visualize.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/race.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/span_crash_demo.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/span_demo.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/system_prompt.txt +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/tools/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/tools/calculator.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/tools/switch_model.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/examples/tui_chat.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/_sentinel.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/agent.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/agent_arg.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/compiler.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/contract.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/init_params.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/instance.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/step_params.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/step_validation.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/steps.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/type_helpers.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/type_registry.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/model.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/registry.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/step.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/step_arg.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/step_helpers.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/actions.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/context.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/flowing_registry.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/hooks.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/interrupt.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/interrupt_helpers.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/spawn.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/flow/timeout.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/engine.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/execution.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/instance_factory.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/runtime.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/scope.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/serialization.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/spans.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/runtime/spawn_tree.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/services.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/state/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/state/markers.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/state/store.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/state/values.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/storage/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/storage/file.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/storage/in_memory.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/storage/session_storage.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/ext/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/ext/otel.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/anthropic/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/anthropic/cache.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/anthropic/presets.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/anthropic/tool_search.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/chat/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/chat/agent.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/chat/config.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/chat/hook_events.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/chat/spec.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/config_value.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/llm_call/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/llm_call/agent.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/llm_call/spec.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/llm_config.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/observability/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/observability/llm_hooks.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/agent.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/config.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/context.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/hook_events.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/spec.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/tool_call/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/tool_call/agent.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/tool_call/agent_tool.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/lib/tool_loop/tool_call/context.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/base.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/blocks.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/messages.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/pricing/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/pricing/anthropic.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/pricing/google.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/pricing/openai.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/provider.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/providers/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/providers/anthropic_vertex.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/providers/google_vertex.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/providers/openai.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/request.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/response.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/schema_formatting.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/schema_validation.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/stream.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/llm/tools.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/py.typed +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/tools/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/tools/local_tool.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/tools/mcp_connection.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/tools/tool_arg.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/tools/tool_group.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/tools/tool_registry.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/tools/types.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/pyproject.toml +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/definition/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/definition/compile/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/definition/compile/test_compile.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/definition/compile/test_type_helpers.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/definition/test_agent.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/definition/test_registry.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/definition/test_step_helpers.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_agent_def.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_context.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_flowing_registry.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_flowing_registry_tasks.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_flowing_sync.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_hooks.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_interrupt.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_spans.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_timeout.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/flow/test_with_interrupt.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_engine.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_engine_spans.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_hook_context.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_persistence.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_runtime.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_scope.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_serialization.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/runtime/test_spec_in_constructor.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/state/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/state/test_values.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/storage/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/storage/test_file.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/storage/test_in_memory.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/agent/test_missing_scenarios.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/ext/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/ext/test_mlflow.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/ext/test_otel.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/anthropic/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/anthropic/test_anthropic.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/test_chat_agent.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/test_config_value.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/test_llm_call_agent.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/test_matches_tool_filter.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/test_tool_call_agent.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/test_tool_call_agent_call_agent.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/test_tool_loop_agent.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/lib/tool_loop/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/pricing/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/pricing/test_anthropic.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/pricing/test_google.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/pricing/test_openai.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/providers/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/providers/test_anthropic_e2e.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/providers/test_anthropic_vertex.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/providers/test_google_vertex.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/providers/test_google_vertex_e2e.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/providers/test_openai_e2e.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/providers/test_openai_provider.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/test_cost_breakdown.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/test_metadata.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/test_response.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/test_schema_formatting.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/test_schema_validation.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/llm/test_stream.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/tools/__init__.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/tools/test_local_tool.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/tools/test_mcp_connection.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/tools/test_tool_group.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tests/tools/test_tool_registry.py +0 -0
- {flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/tools/sync_pricing.py +0 -0
- {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.
|
|
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 `
|
|
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 `
|
|
11
|
+
handlers via `runtime.hooks.on()`:
|
|
12
12
|
|
|
13
13
|
```python
|
|
14
|
-
from flowra.agent import
|
|
14
|
+
from flowra.agent import AgentRuntime
|
|
15
15
|
from flowra.lib.observability import TextDeltaEvent
|
|
16
16
|
|
|
17
|
-
|
|
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
|
-
|
|
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
|
-
`
|
|
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
|
|
78
|
+
from flowra.agent import AgentRuntime, AgentSpan
|
|
78
79
|
|
|
79
|
-
|
|
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
|
|
113
|
+
from flowra.agent import AgentRuntime, AgentSpan, StepSpan
|
|
113
114
|
from flowra.lib.observability import LLMCallSpan, ToolCallSpan
|
|
114
115
|
|
|
115
|
-
|
|
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
|
|
157
|
-
from flowra.ext.mlflow import
|
|
157
|
+
from flowra.agent import AgentRuntime
|
|
158
|
+
from flowra.ext.mlflow import MLFLOW_TRACING
|
|
158
159
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
192
|
-
|
|
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
|
|
211
|
-
from flowra.ext.otel import
|
|
209
|
+
from flowra.agent import AgentRuntime
|
|
210
|
+
from flowra.ext.otel import OTEL_TRACING
|
|
212
211
|
|
|
213
|
-
|
|
214
|
-
|
|
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
|
-
|
|
252
|
-
|
|
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.
|
|
276
|
+
from flowra.agent import AgentRuntime
|
|
277
|
+
from flowra.ext.mlflow import MLFLOW_TRACING
|
|
278
278
|
|
|
279
|
-
|
|
280
|
-
|
|
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.
|
|
294
|
+
from flowra.agent import AgentRuntime
|
|
295
|
+
from flowra.ext.otel import OTEL_TRACING
|
|
295
296
|
|
|
296
|
-
|
|
297
|
-
|
|
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
|
-
|
|
345
|
-
|
|
346
|
-
|
|
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 `
|
|
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
|
-
|
|
361
|
-
|
|
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
|
|
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 = ", "
|
|
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
|
-
|
|
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)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/step_validation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flowra-0.0.24.dev33 → flowra-0.0.25.dev35}/flowra/agent/definition/compile/type_registry.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|