tactus 0.25.0__tar.gz → 0.26.0__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.
- {tactus-0.25.0 → tactus-0.26.0}/CHANGELOG.md +8 -0
- {tactus-0.25.0 → tactus-0.26.0}/PKG-INFO +16 -1
- {tactus-0.25.0 → tactus-0.26.0}/README.md +15 -0
- {tactus-0.25.0 → tactus-0.26.0}/SPECIFICATION.md +18 -0
- {tactus-0.25.0 → tactus-0.26.0}/pyproject.toml +1 -1
- {tactus-0.25.0 → tactus-0.26.0}/tactus/__init__.py +1 -1
- {tactus-0.25.0 → tactus-0.26.0}/tactus/adapters/cli_hitl.py +2 -2
- tactus-0.26.0/tactus/adapters/cost_collector_log.py +56 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/cli/app.py +99 -10
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/config_manager.py +2 -2
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/dsl_stubs.py +51 -43
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/execution_context.py +2 -2
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/lua_sandbox.py +2 -2
- {tactus-0.25.0 → tactus-0.26.0}/tactus/docker/Dockerfile +4 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/dspy/agent.py +22 -7
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/handles.py +12 -12
- {tactus-0.25.0 → tactus-0.26.0}/tactus/sandbox/container_runner.py +122 -5
- {tactus-0.25.0 → tactus-0.26.0}/tactus/sandbox/docker_manager.py +16 -4
- {tactus-0.25.0 → tactus-0.26.0}/tactus/sandbox/entrypoint.py +30 -2
- tactus-0.26.0/tactus/stdlib/io/fs.py +154 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/stdlib/loader.py +1 -1
- {tactus-0.25.0 → tactus-0.26.0}/tests/cli/test_cli.py +73 -0
- {tactus-0.25.0 → tactus-0.26.0}/.claude/agents.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/.github/workflows/desktop-release.yml +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/.github/workflows/release.yml +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/.gitignore +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/.tactus/config.yml.example +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/AGENTS.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/IMPLEMENTATION.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/LICENSE +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/Makefile +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/TECHNICAL_DEBT.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/behave.ini +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/docs/AGENTS.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/docs/BDD_TESTING.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/docs/CONFIGURATION.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/docs/DURABILITY.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/docs/FILE_IO.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/docs/SANDBOXING.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/docs/STREAMING.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/docs/TOOLS.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/docs/TOOL_ROADMAP.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/.tactus/config.yml +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/01-basics-hello-world.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/02-basics-simple-logic.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/03-basics-parameters.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/04-basics-simple-agent.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/05-basics-multi-model.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/06-basics-streaming.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/07-basics-bedrock.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/08-basics-models.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/09-basics-google-gemini.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/10-feature-state.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/11-feature-message-history.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/12-feature-structured-output.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/13-feature-session.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/14-feature-per-turn-tools-simple.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/14-feature-per-turn-tools.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/15-feature-local-tools.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/16-feature-toolsets-advanced.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/17-feature-toolsets-dsl.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/18-feature-lua-tools-individual.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/18-feature-lua-tools-inline.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/18-feature-lua-tools-toolset.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/19-feature-direct-tool-calls.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/20-bdd-complete.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/20-bdd-complete.tac.bak2 +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/21-bdd-passing.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/21-bdd-passing.tac.bak2 +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/30-eval-simple.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/31-eval-demo.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/32-eval-success-rate.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/33-eval-thresholds.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/34-eval-dataset.jsonl +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/34-eval-dataset.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/35-eval-trace.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/35-eval-trace.tac.bak2 +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/36-eval-advanced.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/37-eval-comprehensive.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/37-eval-comprehensive.tac.bak2 +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/39-model-simple.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/40-mcp-test.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/40-model-text-classifier.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/41-mcp-simple.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/41-model-pytorch.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/43-sub-procedure-simple.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/44-sub-procedure-composition.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/45-sub-procedure-recursive.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/46-checkpoint-explicit.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/47-checkpoint-expensive-ops.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/48-script-mode-simple.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/50-inputs-showcase.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/51-inputs-calculator.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/52-file-io-basics.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/53-tsv-file-io.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/54-json-file-io.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/55-parquet-file-io.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/56-hdf5-file-io.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/57-excel-file-io.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/58-text-file-io.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/60-tool-sources.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/61-inline-toolset-lua.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/62-mcp-toolset-by-server.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/63-toolset-import-from-file.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/64-require-modules.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/65-optional-state-demo.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/70-mocking-static.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/71-mocking-temporal.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/72-mocking-conditional.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/99-misc-test-loading.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/README.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/app_config.ini +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/data/sample.csv +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/demo_output.json +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/helpers/math_module.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/helpers/product.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/helpers/string_module.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/helpers/sum.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/helpers/text_tools.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/inventory_summary.tsv +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/mock-config.json +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/models/README.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/models/create_sentiment_model.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/output_summary.txt +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/test-raw-module.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/test-raw-streaming.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/tools/calculations.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/tools/data_analysis.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/tools/search.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/with_dependencies/README.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/with_dependencies/simple_http_test.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/examples/with_dependencies/time_lookup.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/01_state_management.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/02_checkpointing.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/03_human_in_the_loop.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/04_control_flow.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/05_tool_integration.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/06_retry_logic.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/07_file_operations.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/08_agent_primitives.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/09_workflow_execution.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/10_lua_integration.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/11_storage_backends.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/12_json_operations.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/13_logging.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/14_stage_and_step_tracking.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/15_procedure_calls.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/16_session_management.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/17_lua_dsl_validation.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/18_example_procedures.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/19_ide_server.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/20_parameters.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/21_outputs.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/23_prompts.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/24_bdd_specifications.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/25_bdd_custom_steps.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/26_bdd_evaluation.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/27_default_settings.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/28_custom_prompts.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/29_execution_settings.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/30_session_filters.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/31_matchers.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/32_result_object.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/33_output_type.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/42_model_primitive.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/43_sub_procedure_checkpointing.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/46_explicit_checkpoint.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/48_script_mode.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/51_dspy_lm_config.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/52_dspy_signature.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/53_dspy_module.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/54_dspy_history.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/55_dspy_prediction.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/56_dspy_agent.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/57_chat_assistant.feature +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/documentation/IDE_SERVER_BEHAVIOR.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/documentation/Lua DSL/README.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/environment.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/agent_primitives_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/chat_assistant_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/checkpointing_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/control_flow_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/dspy_agent_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/dspy_history_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/dspy_lm_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/dspy_module_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/dspy_prediction_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/dspy_signature_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/example_procedures_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/file_operations_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/human_in_the_loop_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/ide_server_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/json_operations_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/logging_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/lua_dsl_validation_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/lua_integration_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/mocking_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/procedure_calls_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/result_and_output_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/retry_logic_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/session_management_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/stage_tracking_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/state_management_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/storage_backend_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/support/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/support/harnesses.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/tool_integration_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/features/steps/workflow_execution_steps.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/scripts/audit_examples_mocking.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/scripts/convert_examples.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/start-web-ide.sh +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/adapters/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/adapters/cli_log.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/adapters/file_storage.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/adapters/http_callback_log.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/adapters/ide_log.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/adapters/lua_tools.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/adapters/mcp.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/adapters/mcp_manager.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/adapters/memory.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/adapters/plugins.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/backends/http_backend.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/backends/model_backend.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/backends/pytorch_backend.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/cli/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/cli/commands/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/dependencies/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/dependencies/registry.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/exceptions.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/message_history_manager.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/mocking.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/output_validator.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/registry.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/runtime.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/template_resolver.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/core/yaml_parser.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/docker/entrypoint.sh +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/dspy/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/dspy/config.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/dspy/history.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/dspy/module.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/dspy/prediction.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/dspy/signature.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/ide/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/ide/coding_assistant.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/ide/server.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/control.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/file.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/human.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/json.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/log.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/message_history.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/model.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/procedure.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/procedure_callable.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/retry.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/session.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/stage.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/state.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/step.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/system.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/tool.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/tool_handle.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/primitives/toolset.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/protocols/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/protocols/chat_recorder.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/protocols/config.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/protocols/cost.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/protocols/hitl.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/protocols/log_handler.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/protocols/models.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/protocols/result.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/protocols/storage.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/providers/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/providers/base.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/providers/bedrock.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/providers/google.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/providers/openai.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/sandbox/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/sandbox/config.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/sandbox/protocol.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/stdlib/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/stdlib/io/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/stdlib/io/csv.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/stdlib/io/excel.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/stdlib/io/file.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/stdlib/io/hdf5.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/stdlib/io/json.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/stdlib/io/parquet.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/stdlib/io/tsv.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/stdlib/tac/tactus/tools/done.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/stdlib/tac/tactus/tools/log.tac +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/README.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/behave_integration.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/context.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/eval_models.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/evaluation_runner.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/evaluators.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/events.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/gherkin_parser.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/mock_agent.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/mock_dependencies.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/mock_hitl.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/mock_registry.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/mock_tools.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/models.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/pydantic_eval_runner.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/steps/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/steps/builtin.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/steps/custom.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/steps/registry.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/testing/test_runner.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/tracing/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/tracing/trace_manager.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/utils/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/utils/cost_calculator.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/utils/model_pricing.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/utils/safe_file_library.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/utils/safe_libraries.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/LuaLexerBase.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/LuaParserBase.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/README.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/error_listener.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/generated/LuaLexer.interp +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/generated/LuaLexer.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/generated/LuaLexer.tokens +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/generated/LuaLexerBase.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/generated/LuaParser.interp +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/generated/LuaParser.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/generated/LuaParser.tokens +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/generated/LuaParserBase.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/generated/LuaParserVisitor.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/generated/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/grammar/LuaLexer.g4 +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/grammar/LuaParser.g4 +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/semantic_visitor.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus/validation/validator.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/.gitignore +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/README.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/RUN_ELECTRON.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/SETUP_COMPLETE.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/backend/hook-lupa.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/backend/tactus_backend.spec +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/package-lock.json +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/package.json +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/preload/preload.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/preload/tsconfig.json +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/rebuild-and-test.sh +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/scripts/build-backend.js +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/scripts/build-frontend.js +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/src/backend-manager.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/src/main.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/src/menu.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-desktop/tsconfig.json +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/ARCHITECTURE.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/CHANGELOG.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/DEV_MODE.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/QUICK_START.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/README.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/RESTART_INSTRUCTIONS.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/TROUBLESHOOTING.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/backend/README.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/backend/assistant_service.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/backend/assistant_tools.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/backend/chat_server.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/backend/config_server.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/backend/events.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/backend/logging_capture.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/backend/lsp_server.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/backend/requirements.txt +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/backend/tactus_lsp_handler.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/backend/test_lsp_server.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/backend/text_editor_tool.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/dev.sh +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/.storybook/main.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/.storybook/preview.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/.storybook/vitest.setup.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/README.md +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/demo.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/index.html +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/jest.config.js +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/package-lock.json +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/package.json +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/postcss.config.js +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/App.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/Editor.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/LSPClient.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/LSPClientHTTP.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/TactusLanguage.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/commands/registry.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/AboutDialog.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ChatSidebar.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/CheckpointSummary.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/CollapsibleRun.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/Duration.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/Duration.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/FileTree.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/FileTree.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/MessageFeed.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/PreferencesView.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ProcedureInputsDisplay.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ProcedureInputsDisplay.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ProcedureInputsModal.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ProcedureInputsModal.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ProcedureTab.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ProcedureTab.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ResizeHandle.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ResultsSidebar.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ResultsSidebar.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/TestOptionsModal.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/Timestamp.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/Timestamp.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/TopMenuBar.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/chat/ChatInterface.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/chat/MessageInput.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/chat/MessageList.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/debugger/CheckpointDetails.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/debugger/CheckpointDetails.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/debugger/CheckpointList.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/debugger/CheckpointList.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/debugger/DebuggerPanel.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/debugger/DebuggerPanel.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/debugger/RunSelector.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/debugger/RunSelector.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/debugger/StatisticsPanel.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/debugger/StatisticsPanel.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/AgentStreamingComponent.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/BaseEventComponent.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/CheckpointEventComponent.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/CollapsibleTestScenario.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/ContainerStatusEventComponent.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/CostEventComponent.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/CostEventComponent.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/EvaluationEventComponent.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/EvaluationEventComponent.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/EventRenderer.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/ExecutionEventComponent.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/ExecutionEventComponent.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/ExecutionSummaryEventComponent.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/ExecutionSummaryEventComponent.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/LoadingEventComponent.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/LoadingEventComponent.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/LogCluster.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/LogEventComponent.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/LogEventComponent.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/OutputEventComponent.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/OutputEventComponent.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/TestEventComponent.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/TestEventComponent.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/TestProgressContainer.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/ToolCallEventComponent.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/ValidationEventComponent.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/events/ValidationEventComponent.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/metadata/AgentsSection.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/metadata/EvaluationsSection.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/metadata/MetadataSections.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/metadata/OutputsSection.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/metadata/ParametersSection.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/metadata/SpecificationsSection.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/metadata/StagesSection.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/metadata/ToolsSection.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/preferences/ConfigFieldView.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/preferences/SourceBadge.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/preferences/YamlCodeEditor.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/scenarios/EvaluateScenarios.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/scenarios/RunScenarios.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/scenarios/TestScenarios.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/scenarios/ValidationScenarios.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/theme-provider.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/ai/conversation.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/ai/message.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/ai/prompt-input.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/badge.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/button.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/dialog.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/dropdown-menu.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/input.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/label.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/logo.stories.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/logo.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/menubar.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/scroll-area.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/select.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/separator.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/switch.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/tabs.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/components/ui/tooltip.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/hooks/useChatSSE.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/hooks/useEventStream.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/hooks/useTracing.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/index.css +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/lib/utils.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/main.tsx +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/types/events.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/types/metadata.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/types/preferences.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/types/results.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/types/tracing.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/utils/yamlSync.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/validation/TactusValidator.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/validation/generated/LuaParser.interp +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/validation/generated/LuaParser.tokens +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/validation/types.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/src/vite-env.d.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/tailwind.config.js +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/tsconfig.json +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/tsconfig.node.json +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/vite.config.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/frontend/vitest.shims.d.ts +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/package.json +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tactus-ide/start-dev.sh +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/adapters/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/adapters/test_lua_tools_adapter.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/adapters/test_plugins.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/cli/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/cli/test_cli_inputs.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/conftest.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/core/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/core/test_config_manager.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/core/test_determinism_safety.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/core/test_lua_sandbox_security.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/core/test_runtime_inputs.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/core/test_script_mode.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/dspy/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/dspy/test_module_parameter.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/dspy/test_streaming.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/fixtures/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/fixtures/test_mcp_server.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/integration/test_named_procedures.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/mocks/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/mocks/llm_mocks.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/primitives/test_checkpoint_primitive.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/primitives/test_retry_primitive.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/primitives/test_state_primitive.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/primitives/test_system_alert.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/primitives/test_tool_primitive.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/primitives/test_toolset_dsl.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/stdlib/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/stdlib/test_loader.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/stdlib/test_require_python.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/test_checkpoints_integration.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/test_mcp_integration.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/test_tracing.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/testing/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/testing/conftest.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/testing/test_all_examples.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/testing/test_e2e.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/testing/test_gherkin_parser.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/testing/test_integration.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/testing/test_models.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/testing/test_runtime_integration.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/testing/test_step_registry.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/utils/__init__.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/utils/test_safe_file_library.py +0 -0
- {tactus-0.25.0 → tactus-0.26.0}/tests/validation/__init__.py +0 -0
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- version list -->
|
|
4
4
|
|
|
5
|
+
## v0.26.0 (2026-01-11)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- Improve logging UX and fs helpers (#26) ([#26](https://github.com/AnthusAI/Tactus/pull/26),
|
|
10
|
+
[`a2a8704`](https://github.com/AnthusAI/Tactus/commit/a2a8704c1a0ab3b2cad45b9514af2152d12faa3b))
|
|
11
|
+
|
|
12
|
+
|
|
5
13
|
## v0.25.0 (2026-01-11)
|
|
6
14
|
|
|
7
15
|
### Features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tactus
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.26.0
|
|
4
4
|
Summary: Tactus: Lua-based DSL for agentic workflows
|
|
5
5
|
Project-URL: Homepage, https://github.com/AnthusAI/Tactus
|
|
6
6
|
Project-URL: Documentation, https://github.com/AnthusAI/Tactus/tree/main/docs
|
|
@@ -1488,6 +1488,21 @@ tactus run workflow.tac # If procedure has required inputs, you'll be prompted
|
|
|
1488
1488
|
tactus run workflow.tac --storage file --storage-path ./data
|
|
1489
1489
|
```
|
|
1490
1490
|
|
|
1491
|
+
#### Logging Options
|
|
1492
|
+
|
|
1493
|
+
The `run` command supports filtering and formatting logs:
|
|
1494
|
+
|
|
1495
|
+
```bash
|
|
1496
|
+
# Show less/more output
|
|
1497
|
+
tactus run workflow.tac --log-level warning
|
|
1498
|
+
tactus run workflow.tac --log-level debug
|
|
1499
|
+
|
|
1500
|
+
# Choose a log format
|
|
1501
|
+
tactus run workflow.tac --log-format rich # default, grouped timestamps
|
|
1502
|
+
tactus run workflow.tac --log-format terminal # no timestamps, higher-signal terminal output
|
|
1503
|
+
tactus run workflow.tac --log-format raw # one-line-per-record, timestamped (CloudWatch-friendly)
|
|
1504
|
+
```
|
|
1505
|
+
|
|
1491
1506
|
The CLI automatically parses parameter types:
|
|
1492
1507
|
- **Strings**: Direct values or quoted strings
|
|
1493
1508
|
- **Numbers**: Integers or floats are auto-detected
|
|
@@ -1437,6 +1437,21 @@ tactus run workflow.tac # If procedure has required inputs, you'll be prompted
|
|
|
1437
1437
|
tactus run workflow.tac --storage file --storage-path ./data
|
|
1438
1438
|
```
|
|
1439
1439
|
|
|
1440
|
+
#### Logging Options
|
|
1441
|
+
|
|
1442
|
+
The `run` command supports filtering and formatting logs:
|
|
1443
|
+
|
|
1444
|
+
```bash
|
|
1445
|
+
# Show less/more output
|
|
1446
|
+
tactus run workflow.tac --log-level warning
|
|
1447
|
+
tactus run workflow.tac --log-level debug
|
|
1448
|
+
|
|
1449
|
+
# Choose a log format
|
|
1450
|
+
tactus run workflow.tac --log-format rich # default, grouped timestamps
|
|
1451
|
+
tactus run workflow.tac --log-format terminal # no timestamps, higher-signal terminal output
|
|
1452
|
+
tactus run workflow.tac --log-format raw # one-line-per-record, timestamped (CloudWatch-friendly)
|
|
1453
|
+
```
|
|
1454
|
+
|
|
1440
1455
|
The CLI automatically parses parameter types:
|
|
1441
1456
|
- **Strings**: Direct values or quoted strings
|
|
1442
1457
|
- **Numbers**: Integers or floats are auto-detected
|
|
@@ -2457,6 +2457,24 @@ File.write(path, contents)
|
|
|
2457
2457
|
File.exists(path)
|
|
2458
2458
|
```
|
|
2459
2459
|
|
|
2460
|
+
### Filesystem Helpers (stdlib)
|
|
2461
|
+
|
|
2462
|
+
Workflows sometimes need to enumerate files within the sandboxed working directory (for example, iterating over documents to lint or review). Use the filesystem helper module:
|
|
2463
|
+
|
|
2464
|
+
```lua
|
|
2465
|
+
local fs = require("tactus.io.fs")
|
|
2466
|
+
|
|
2467
|
+
-- List entries in a directory (relative paths)
|
|
2468
|
+
local entries = fs.list_dir("chapters", {files_only = true, sort = true})
|
|
2469
|
+
|
|
2470
|
+
-- Glob files (relative paths)
|
|
2471
|
+
local qmd_files = fs.glob("chapters/*.qmd", {sort = true})
|
|
2472
|
+
```
|
|
2473
|
+
|
|
2474
|
+
**Security model:** Paths are restricted to the procedure working directory; absolute paths and path traversal (`..`) are rejected.
|
|
2475
|
+
|
|
2476
|
+
**Determinism:** Filesystem contents can change between runs; wrap file enumeration and reads in `Step.checkpoint()` for durable workflows.
|
|
2477
|
+
|
|
2460
2478
|
---
|
|
2461
2479
|
|
|
2462
2480
|
## Matchers
|
|
@@ -32,7 +32,7 @@ class CLIHITLHandler:
|
|
|
32
32
|
console: Rich Console instance (creates new one if not provided)
|
|
33
33
|
"""
|
|
34
34
|
self.console = console or Console()
|
|
35
|
-
logger.
|
|
35
|
+
logger.debug("CLIHITLHandler initialized")
|
|
36
36
|
|
|
37
37
|
def request_interaction(self, procedure_id: str, request: HITLRequest) -> HITLResponse:
|
|
38
38
|
"""
|
|
@@ -45,7 +45,7 @@ class CLIHITLHandler:
|
|
|
45
45
|
Returns:
|
|
46
46
|
HITLResponse with user's response
|
|
47
47
|
"""
|
|
48
|
-
logger.
|
|
48
|
+
logger.debug(f"HITL request: {request.request_type} - {request.message}")
|
|
49
49
|
|
|
50
50
|
# Display the request in a panel
|
|
51
51
|
self.console.print()
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Cost-only log handler for headless/sandbox runs.
|
|
3
|
+
|
|
4
|
+
Collects CostEvent instances so the runtime can report total_cost/total_tokens,
|
|
5
|
+
without enabling streaming UI behavior.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
import json
|
|
12
|
+
from typing import List
|
|
13
|
+
|
|
14
|
+
from tactus.protocols.models import CostEvent, LogEvent
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class CostCollectorLogHandler:
|
|
20
|
+
"""
|
|
21
|
+
Minimal LogHandler for sandbox runs.
|
|
22
|
+
|
|
23
|
+
This is useful in environments like Docker sandboxes where stdout is reserved
|
|
24
|
+
for protocol output, but we still want:
|
|
25
|
+
- accurate cost accounting (CostEvent)
|
|
26
|
+
- basic procedure logging (LogEvent) via stderr/Python logging
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
supports_streaming = False
|
|
30
|
+
|
|
31
|
+
def __init__(self):
|
|
32
|
+
self.cost_events: List[CostEvent] = []
|
|
33
|
+
logger.debug("CostCollectorLogHandler initialized")
|
|
34
|
+
|
|
35
|
+
def log(self, event: LogEvent) -> None:
|
|
36
|
+
if isinstance(event, CostEvent):
|
|
37
|
+
self.cost_events.append(event)
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
# Preserve useful procedure logs even when no IDE callback is present.
|
|
41
|
+
if isinstance(event, LogEvent):
|
|
42
|
+
event_logger = logging.getLogger(event.logger_name or "procedure")
|
|
43
|
+
|
|
44
|
+
msg = event.message
|
|
45
|
+
if event.context:
|
|
46
|
+
msg = f"{msg}\nContext: {json.dumps(event.context, indent=2, default=str)}"
|
|
47
|
+
|
|
48
|
+
level = (event.level or "INFO").upper()
|
|
49
|
+
if level == "DEBUG":
|
|
50
|
+
event_logger.debug(msg)
|
|
51
|
+
elif level in ("WARN", "WARNING"):
|
|
52
|
+
event_logger.warning(msg)
|
|
53
|
+
elif level == "ERROR":
|
|
54
|
+
event_logger.error(msg)
|
|
55
|
+
else:
|
|
56
|
+
event_logger.info(msg)
|
|
@@ -134,15 +134,92 @@ def load_tactus_config():
|
|
|
134
134
|
return {}
|
|
135
135
|
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
""
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
logging.
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
137
|
+
_LOG_LEVELS = {
|
|
138
|
+
"debug": logging.DEBUG,
|
|
139
|
+
"info": logging.INFO,
|
|
140
|
+
"warning": logging.WARNING,
|
|
141
|
+
"warn": logging.WARNING,
|
|
142
|
+
"error": logging.ERROR,
|
|
143
|
+
"critical": logging.CRITICAL,
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
_LOG_FORMATS = {"rich", "terminal", "raw"}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class _TerminalLogHandler(logging.Handler):
|
|
150
|
+
"""Minimal, high-signal terminal logger (no timestamps/levels)."""
|
|
151
|
+
|
|
152
|
+
def __init__(self, console: Console):
|
|
153
|
+
super().__init__()
|
|
154
|
+
self._console = console
|
|
155
|
+
self.setFormatter(logging.Formatter("%(message)s"))
|
|
156
|
+
|
|
157
|
+
def emit(self, record: logging.LogRecord) -> None:
|
|
158
|
+
try:
|
|
159
|
+
message = self.format(record)
|
|
160
|
+
|
|
161
|
+
# Make procedure-level logs the most prominent.
|
|
162
|
+
if record.name.startswith("procedure"):
|
|
163
|
+
style = "bold"
|
|
164
|
+
elif record.levelno >= logging.ERROR:
|
|
165
|
+
style = "bold red"
|
|
166
|
+
elif record.levelno >= logging.WARNING:
|
|
167
|
+
style = "yellow"
|
|
168
|
+
elif record.levelno <= logging.DEBUG:
|
|
169
|
+
style = "dim"
|
|
170
|
+
else:
|
|
171
|
+
style = ""
|
|
172
|
+
|
|
173
|
+
self._console.print(message, style=style, markup=False, highlight=False)
|
|
174
|
+
except Exception:
|
|
175
|
+
self.handleError(record)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def setup_logging(
|
|
179
|
+
verbose: bool = False,
|
|
180
|
+
log_level: Optional[str] = None,
|
|
181
|
+
log_format: str = "rich",
|
|
182
|
+
) -> None:
|
|
183
|
+
"""Setup CLI logging (level + format)."""
|
|
184
|
+
if log_level is None:
|
|
185
|
+
level = logging.DEBUG if verbose else logging.INFO
|
|
186
|
+
else:
|
|
187
|
+
key = str(log_level).strip().lower()
|
|
188
|
+
if key not in _LOG_LEVELS:
|
|
189
|
+
raise typer.BadParameter(
|
|
190
|
+
f"Invalid --log-level '{log_level}'. "
|
|
191
|
+
f"Use one of: {', '.join(sorted(_LOG_LEVELS.keys()))}"
|
|
192
|
+
)
|
|
193
|
+
level = _LOG_LEVELS[key]
|
|
194
|
+
|
|
195
|
+
fmt = (log_format or "rich").strip().lower()
|
|
196
|
+
if fmt not in _LOG_FORMATS:
|
|
197
|
+
raise typer.BadParameter(
|
|
198
|
+
f"Invalid --log-format '{log_format}'. Use one of: {', '.join(sorted(_LOG_FORMATS))}"
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
# Default: rich logs (group repeated timestamps).
|
|
202
|
+
if fmt == "rich":
|
|
203
|
+
handler: logging.Handler = RichHandler(
|
|
204
|
+
console=console,
|
|
205
|
+
show_path=False,
|
|
206
|
+
rich_tracebacks=True,
|
|
207
|
+
omit_repeated_times=True,
|
|
208
|
+
)
|
|
209
|
+
handler.setFormatter(logging.Formatter("%(message)s"))
|
|
210
|
+
logging.basicConfig(level=level, format="%(message)s", handlers=[handler], force=True)
|
|
211
|
+
return
|
|
212
|
+
|
|
213
|
+
# Raw logs: one line per entry, CloudWatch-friendly.
|
|
214
|
+
if fmt == "raw":
|
|
215
|
+
handler = logging.StreamHandler(stream=sys.stderr)
|
|
216
|
+
handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(name)s: %(message)s"))
|
|
217
|
+
logging.basicConfig(level=level, handlers=[handler], force=True)
|
|
218
|
+
return
|
|
219
|
+
|
|
220
|
+
# Terminal logs: no timestamps/levels, color by signal.
|
|
221
|
+
handler = _TerminalLogHandler(console)
|
|
222
|
+
logging.basicConfig(level=level, handlers=[handler], force=True)
|
|
146
223
|
|
|
147
224
|
|
|
148
225
|
def _parse_value(value_str: str, field_type: str) -> Any:
|
|
@@ -352,6 +429,12 @@ def run(
|
|
|
352
429
|
None, envvar="OPENAI_API_KEY", help="OpenAI API key"
|
|
353
430
|
),
|
|
354
431
|
verbose: bool = typer.Option(False, "--verbose", "-v", help="Enable verbose logging"),
|
|
432
|
+
log_level: Optional[str] = typer.Option(
|
|
433
|
+
None, "--log-level", help="Log level: debug, info, warning, error, critical"
|
|
434
|
+
),
|
|
435
|
+
log_format: str = typer.Option(
|
|
436
|
+
"rich", "--log-format", help="Log format: rich (default), terminal, raw"
|
|
437
|
+
),
|
|
355
438
|
param: Optional[list[str]] = typer.Option(None, help="Parameters in format key=value"),
|
|
356
439
|
interactive: bool = typer.Option(
|
|
357
440
|
False, "--interactive", "-i", help="Interactively prompt for all inputs"
|
|
@@ -399,7 +482,7 @@ def run(
|
|
|
399
482
|
# Use real implementation for specific tools while mocking others
|
|
400
483
|
tactus run workflow.tac --mock-all --real done
|
|
401
484
|
"""
|
|
402
|
-
setup_logging(verbose)
|
|
485
|
+
setup_logging(verbose=verbose, log_level=log_level, log_format=log_format)
|
|
403
486
|
|
|
404
487
|
# Check if file exists
|
|
405
488
|
if not workflow_file.exists():
|
|
@@ -530,6 +613,12 @@ def run(
|
|
|
530
613
|
sandbox_config_dict["enabled"] = sandbox
|
|
531
614
|
sandbox_config = SandboxConfig(**sandbox_config_dict)
|
|
532
615
|
|
|
616
|
+
# Pass logging preferences through to the sandbox container so container stderr matches CLI UX.
|
|
617
|
+
sandbox_config.env.setdefault(
|
|
618
|
+
"TACTUS_LOG_LEVEL", str(log_level or ("debug" if verbose else "info"))
|
|
619
|
+
)
|
|
620
|
+
sandbox_config.env.setdefault("TACTUS_LOG_FORMAT", str(log_format))
|
|
621
|
+
|
|
533
622
|
# Check Docker availability
|
|
534
623
|
docker_available, docker_reason = is_docker_available()
|
|
535
624
|
|
|
@@ -150,7 +150,7 @@ class ConfigManager:
|
|
|
150
150
|
sidecar_config = self._load_yaml_file(sidecar_path)
|
|
151
151
|
if sidecar_config:
|
|
152
152
|
configs.append(("sidecar", sidecar_config))
|
|
153
|
-
logger.
|
|
153
|
+
logger.debug(f"Loaded sidecar config: {sidecar_path}")
|
|
154
154
|
|
|
155
155
|
# Store for debugging
|
|
156
156
|
self.loaded_configs = configs
|
|
@@ -158,7 +158,7 @@ class ConfigManager:
|
|
|
158
158
|
# Merge all configs (later configs override earlier ones)
|
|
159
159
|
merged = self._merge_configs([c[1] for c in configs])
|
|
160
160
|
|
|
161
|
-
logger.
|
|
161
|
+
logger.debug(f"Merged configuration from {len(configs)} source(s)")
|
|
162
162
|
return merged
|
|
163
163
|
|
|
164
164
|
def _find_sidecar_config(self, tac_path: Path) -> Optional[Path]:
|
|
@@ -915,43 +915,49 @@ def create_dsl_stubs(
|
|
|
915
915
|
if not isinstance(mock_config, dict):
|
|
916
916
|
continue
|
|
917
917
|
|
|
918
|
-
#
|
|
919
|
-
|
|
920
|
-
|
|
918
|
+
# Tool mocks use explicit keys.
|
|
919
|
+
tool_mock_keys = {"returns", "temporal", "conditional", "error"}
|
|
920
|
+
if any(k in mock_config for k in tool_mock_keys):
|
|
921
|
+
# Convert DSL syntax to MockConfig format
|
|
922
|
+
processed_config = {}
|
|
923
|
+
|
|
924
|
+
# Static mocking with 'returns' key
|
|
925
|
+
if "returns" in mock_config:
|
|
926
|
+
processed_config["output"] = mock_config["returns"]
|
|
927
|
+
|
|
928
|
+
# Temporal mocking
|
|
929
|
+
elif "temporal" in mock_config:
|
|
930
|
+
processed_config["temporal"] = mock_config["temporal"]
|
|
931
|
+
|
|
932
|
+
# Conditional mocking
|
|
933
|
+
elif "conditional" in mock_config:
|
|
934
|
+
# Convert DSL conditional format to MockManager format
|
|
935
|
+
conditionals = []
|
|
936
|
+
for cond in mock_config["conditional"]:
|
|
937
|
+
if isinstance(cond, dict) and "when" in cond and "returns" in cond:
|
|
938
|
+
conditionals.append({"when": cond["when"], "return": cond["returns"]})
|
|
939
|
+
processed_config["conditional_mocks"] = conditionals
|
|
940
|
+
|
|
941
|
+
# Error simulation
|
|
942
|
+
elif "error" in mock_config:
|
|
943
|
+
processed_config["error"] = mock_config["error"]
|
|
944
|
+
|
|
945
|
+
# Register the tool mock configuration
|
|
946
|
+
builder.register_mock(name, processed_config)
|
|
947
|
+
continue
|
|
948
|
+
|
|
949
|
+
# Agent mocks can be message-only, tool_calls-only, or both.
|
|
950
|
+
if any(k in mock_config for k in ("tool_calls", "message", "data")):
|
|
921
951
|
agent_config = {
|
|
922
952
|
"tool_calls": mock_config.get("tool_calls", []),
|
|
923
953
|
"message": mock_config.get("message", ""),
|
|
954
|
+
"data": mock_config.get("data"),
|
|
924
955
|
}
|
|
925
956
|
builder.register_agent_mock(name, agent_config)
|
|
926
957
|
continue
|
|
927
958
|
|
|
928
|
-
# Otherwise,
|
|
929
|
-
|
|
930
|
-
processed_config = {}
|
|
931
|
-
|
|
932
|
-
# Static mocking with 'returns' key
|
|
933
|
-
if "returns" in mock_config:
|
|
934
|
-
processed_config["output"] = mock_config["returns"]
|
|
935
|
-
|
|
936
|
-
# Temporal mocking
|
|
937
|
-
elif "temporal" in mock_config:
|
|
938
|
-
processed_config["temporal"] = mock_config["temporal"]
|
|
939
|
-
|
|
940
|
-
# Conditional mocking
|
|
941
|
-
elif "conditional" in mock_config:
|
|
942
|
-
# Convert DSL conditional format to MockManager format
|
|
943
|
-
conditionals = []
|
|
944
|
-
for cond in mock_config["conditional"]:
|
|
945
|
-
if isinstance(cond, dict) and "when" in cond and "returns" in cond:
|
|
946
|
-
conditionals.append({"when": cond["when"], "return": cond["returns"]})
|
|
947
|
-
processed_config["conditional_mocks"] = conditionals
|
|
948
|
-
|
|
949
|
-
# Error simulation
|
|
950
|
-
elif "error" in mock_config:
|
|
951
|
-
processed_config["error"] = mock_config["error"]
|
|
952
|
-
|
|
953
|
-
# Register the tool mock configuration
|
|
954
|
-
builder.register_mock(name, processed_config)
|
|
959
|
+
# Otherwise, ignore unknown mock config.
|
|
960
|
+
continue
|
|
955
961
|
|
|
956
962
|
def _history(messages=None):
|
|
957
963
|
"""
|
|
@@ -1413,14 +1419,14 @@ def create_dsl_stubs(
|
|
|
1413
1419
|
|
|
1414
1420
|
logger = logging.getLogger(__name__)
|
|
1415
1421
|
|
|
1416
|
-
logger.
|
|
1422
|
+
logger.debug(
|
|
1417
1423
|
f"[AGENT_CREATION] Agent '{agent_name}': runtime_context={bool(_runtime_context)}, skip_agents={_runtime_context.get('skip_agents', 'N/A') if _runtime_context else 'N/A'}, has_log_handler={('log_handler' in _runtime_context) if _runtime_context else False}"
|
|
1418
1424
|
)
|
|
1419
1425
|
|
|
1420
1426
|
if _runtime_context and not _runtime_context.get("skip_agents", False):
|
|
1421
1427
|
from tactus.dspy.agent import create_dspy_agent
|
|
1422
1428
|
|
|
1423
|
-
logger.
|
|
1429
|
+
logger.debug(f"[AGENT_CREATION] Attempting immediate creation for agent '{agent_name}'")
|
|
1424
1430
|
|
|
1425
1431
|
try:
|
|
1426
1432
|
# Create the actual agent primitive NOW
|
|
@@ -1450,7 +1456,7 @@ def create_dsl_stubs(
|
|
|
1450
1456
|
handle._set_primitive(
|
|
1451
1457
|
agent_primitive, execution_context=_runtime_context.get("execution_context")
|
|
1452
1458
|
)
|
|
1453
|
-
logger.
|
|
1459
|
+
logger.debug(
|
|
1454
1460
|
f"[AGENT_CREATION] Agent '{agent_name}' created immediately during declaration, has_log_handler={hasattr(agent_primitive, 'log_handler') and agent_primitive.log_handler is not None}"
|
|
1455
1461
|
)
|
|
1456
1462
|
|
|
@@ -1458,7 +1464,9 @@ def create_dsl_stubs(
|
|
|
1458
1464
|
if "_created_agents" not in _runtime_context:
|
|
1459
1465
|
_runtime_context["_created_agents"] = {}
|
|
1460
1466
|
_runtime_context["_created_agents"][agent_name] = agent_primitive
|
|
1461
|
-
logger.
|
|
1467
|
+
logger.debug(
|
|
1468
|
+
f"[AGENT_CREATION] Stored agent '{agent_name}' in _created_agents dict"
|
|
1469
|
+
)
|
|
1462
1470
|
|
|
1463
1471
|
except Exception as e:
|
|
1464
1472
|
logger.error(
|
|
@@ -1567,14 +1575,14 @@ def create_dsl_stubs(
|
|
|
1567
1575
|
|
|
1568
1576
|
logger = logging.getLogger(__name__)
|
|
1569
1577
|
|
|
1570
|
-
logger.
|
|
1578
|
+
logger.debug(
|
|
1571
1579
|
f"[AGENT_CREATION] Agent '{temp_name}': runtime_context={bool(_runtime_context)}, skip_agents={_runtime_context.get('skip_agents', 'N/A') if _runtime_context else 'N/A'}, has_log_handler={('log_handler' in _runtime_context) if _runtime_context else False}"
|
|
1572
1580
|
)
|
|
1573
1581
|
|
|
1574
1582
|
if _runtime_context and not _runtime_context.get("skip_agents", False):
|
|
1575
1583
|
from tactus.dspy.agent import create_dspy_agent
|
|
1576
1584
|
|
|
1577
|
-
logger.
|
|
1585
|
+
logger.debug(f"[AGENT_CREATION] Attempting immediate creation for agent '{temp_name}'")
|
|
1578
1586
|
|
|
1579
1587
|
try:
|
|
1580
1588
|
# Create the actual agent primitive NOW
|
|
@@ -1593,7 +1601,7 @@ def create_dsl_stubs(
|
|
|
1593
1601
|
if "log_handler" in _runtime_context:
|
|
1594
1602
|
agent_config["log_handler"] = _runtime_context["log_handler"]
|
|
1595
1603
|
|
|
1596
|
-
logger.
|
|
1604
|
+
logger.debug(
|
|
1597
1605
|
f"[AGENT_CREATION] Creating agent immediately: name={temp_name}, has_log_handler={'log_handler' in agent_config}"
|
|
1598
1606
|
)
|
|
1599
1607
|
agent_primitive = create_dspy_agent(
|
|
@@ -1607,7 +1615,7 @@ def create_dsl_stubs(
|
|
|
1607
1615
|
handle._set_primitive(
|
|
1608
1616
|
agent_primitive, execution_context=_runtime_context.get("execution_context")
|
|
1609
1617
|
)
|
|
1610
|
-
logger.
|
|
1618
|
+
logger.debug(
|
|
1611
1619
|
f"[AGENT_CREATION] Agent '{temp_name}' created immediately during declaration, has_log_handler={hasattr(agent_primitive, 'log_handler') and agent_primitive.log_handler is not None}"
|
|
1612
1620
|
)
|
|
1613
1621
|
|
|
@@ -1615,7 +1623,7 @@ def create_dsl_stubs(
|
|
|
1615
1623
|
if "_created_agents" not in _runtime_context:
|
|
1616
1624
|
_runtime_context["_created_agents"] = {}
|
|
1617
1625
|
_runtime_context["_created_agents"][temp_name] = agent_primitive
|
|
1618
|
-
logger.
|
|
1626
|
+
logger.debug(f"[AGENT_CREATION] Stored agent '{temp_name}' in _created_agents dict")
|
|
1619
1627
|
|
|
1620
1628
|
except Exception as e:
|
|
1621
1629
|
import traceback
|
|
@@ -1757,13 +1765,13 @@ def _make_binding_callback(
|
|
|
1757
1765
|
old_name = value.name
|
|
1758
1766
|
if old_name.startswith("_temp_agent_"):
|
|
1759
1767
|
# Rename the agent handle
|
|
1760
|
-
callback_logger.
|
|
1768
|
+
callback_logger.debug(f"[AGENT_RENAME] Renaming agent '{old_name}' to '{name}'")
|
|
1761
1769
|
value.name = name
|
|
1762
1770
|
|
|
1763
1771
|
# Also rename the underlying primitive if it exists
|
|
1764
1772
|
if value._primitive is not None:
|
|
1765
1773
|
value._primitive.name = name
|
|
1766
|
-
callback_logger.
|
|
1774
|
+
callback_logger.debug(
|
|
1767
1775
|
f"[AGENT_RENAME] Updated primitive name: '{old_name}' -> '{name}'"
|
|
1768
1776
|
)
|
|
1769
1777
|
|
|
@@ -1777,7 +1785,7 @@ def _make_binding_callback(
|
|
|
1777
1785
|
if hasattr(builder, "registry") and old_name in builder.registry.agents:
|
|
1778
1786
|
agent_data = builder.registry.agents.pop(old_name)
|
|
1779
1787
|
builder.registry.agents[name] = agent_data
|
|
1780
|
-
callback_logger.
|
|
1788
|
+
callback_logger.debug(
|
|
1781
1789
|
f"[AGENT_RENAME] Re-registered agent '{name}' in builder.registry.agents"
|
|
1782
1790
|
)
|
|
1783
1791
|
|
|
@@ -1786,7 +1794,7 @@ def _make_binding_callback(
|
|
|
1786
1794
|
if old_name in runtime_context["_created_agents"]:
|
|
1787
1795
|
agent_primitive = runtime_context["_created_agents"].pop(old_name)
|
|
1788
1796
|
runtime_context["_created_agents"][name] = agent_primitive
|
|
1789
|
-
callback_logger.
|
|
1797
|
+
callback_logger.debug(
|
|
1790
1798
|
f"[AGENT_RENAME] Updated _created_agents dict: '{old_name}' -> '{name}'"
|
|
1791
1799
|
)
|
|
1792
1800
|
|
|
@@ -187,7 +187,7 @@ class BaseExecutionContext(ExecutionContext):
|
|
|
187
187
|
On replay, returns cached result from execution log.
|
|
188
188
|
On first execution, runs fn(), records in log, and returns result.
|
|
189
189
|
"""
|
|
190
|
-
logger.
|
|
190
|
+
logger.debug(
|
|
191
191
|
f"[CHECKPOINT] checkpoint() called, type={checkpoint_type}, has_log_handler={self.log_handler is not None}"
|
|
192
192
|
)
|
|
193
193
|
current_position = self.metadata.replay_index
|
|
@@ -259,7 +259,7 @@ class BaseExecutionContext(ExecutionContext):
|
|
|
259
259
|
source_location=source_location,
|
|
260
260
|
procedure_id=self.procedure_id,
|
|
261
261
|
)
|
|
262
|
-
logger.
|
|
262
|
+
logger.debug(
|
|
263
263
|
f"[CHECKPOINT] Emitting CheckpointCreatedEvent: position={current_position}, type={checkpoint_type}, duration_ms={duration_ms}"
|
|
264
264
|
)
|
|
265
265
|
self.log_handler.log(event)
|
|
@@ -73,7 +73,7 @@ class LuaSandbox:
|
|
|
73
73
|
# Setup safe globals
|
|
74
74
|
self._setup_safe_globals()
|
|
75
75
|
|
|
76
|
-
logger.
|
|
76
|
+
logger.debug("Lua sandbox initialized successfully")
|
|
77
77
|
|
|
78
78
|
def _attribute_filter(self, obj, attr_name, is_setting):
|
|
79
79
|
"""
|
|
@@ -274,7 +274,7 @@ class LuaSandbox:
|
|
|
274
274
|
self.lua.globals()["math"] = safe_math_table
|
|
275
275
|
self.lua.globals()["os"] = safe_os_table
|
|
276
276
|
|
|
277
|
-
logger.
|
|
277
|
+
logger.debug("Installed safe math and os libraries with determinism checking")
|
|
278
278
|
return # Skip default os.date setup below
|
|
279
279
|
|
|
280
280
|
# Add safe subset of os module (only date function for timestamps)
|
|
@@ -36,6 +36,10 @@ COPY pyproject.toml ./
|
|
|
36
36
|
COPY README.md ./
|
|
37
37
|
COPY tactus/ ./tactus/
|
|
38
38
|
|
|
39
|
+
# Ensure the non-root runtime user can read the codebase even if the host
|
|
40
|
+
# working tree has restrictive permissions (e.g., umask 077).
|
|
41
|
+
RUN chmod -R a+rX /app/tactus
|
|
42
|
+
|
|
39
43
|
# Install Tactus and its dependencies
|
|
40
44
|
RUN pip install --no-cache-dir -e .
|
|
41
45
|
|
|
@@ -191,11 +191,19 @@ class DSPyAgentHandle:
|
|
|
191
191
|
if response and hasattr(response, "_hidden_params"):
|
|
192
192
|
total_cost = response._hidden_params.get("response_cost")
|
|
193
193
|
|
|
194
|
-
if total_cost is None and
|
|
194
|
+
if total_cost is None and total_tokens > 0:
|
|
195
195
|
try:
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
196
|
+
# We already have token counts, so compute cost from tokens to avoid relying
|
|
197
|
+
# on provider-specific response object shapes.
|
|
198
|
+
from litellm.cost_calculator import cost_per_token
|
|
199
|
+
|
|
200
|
+
prompt_cost, completion_cost = cost_per_token(
|
|
201
|
+
model=str(model) if model is not None else "",
|
|
202
|
+
prompt_tokens=prompt_tokens,
|
|
203
|
+
completion_tokens=completion_tokens,
|
|
204
|
+
call_type="completion",
|
|
205
|
+
)
|
|
206
|
+
total_cost = float(prompt_cost) + float(completion_cost)
|
|
199
207
|
except Exception as e:
|
|
200
208
|
logger.warning(f"[COST] Agent '{self.name}': failed to calculate cost: {e}")
|
|
201
209
|
total_cost = 0.0
|
|
@@ -326,6 +334,7 @@ class DSPyAgentHandle:
|
|
|
326
334
|
|
|
327
335
|
Streaming is enabled when:
|
|
328
336
|
- log_handler is available (for emitting events)
|
|
337
|
+
- log_handler supports streaming events
|
|
329
338
|
- disable_streaming is False
|
|
330
339
|
- No structured output schema (streaming only works with plain text)
|
|
331
340
|
|
|
@@ -337,6 +346,14 @@ class DSPyAgentHandle:
|
|
|
337
346
|
logger.debug(f"[STREAMING] Agent '{self.name}': no log_handler, streaming disabled")
|
|
338
347
|
return False
|
|
339
348
|
|
|
349
|
+
# Allow log handlers to opt out of streaming (e.g., cost-only collectors)
|
|
350
|
+
supports_streaming = getattr(self.log_handler, "supports_streaming", True)
|
|
351
|
+
if not supports_streaming:
|
|
352
|
+
logger.debug(
|
|
353
|
+
f"[STREAMING] Agent '{self.name}': log_handler supports_streaming=False, streaming disabled"
|
|
354
|
+
)
|
|
355
|
+
return False
|
|
356
|
+
|
|
340
357
|
# Respect explicit disable flag
|
|
341
358
|
if self.disable_streaming:
|
|
342
359
|
logger.debug(
|
|
@@ -673,9 +690,7 @@ class DSPyAgentHandle:
|
|
|
673
690
|
result = worker({message = "Process this task"})
|
|
674
691
|
print(result.response)
|
|
675
692
|
"""
|
|
676
|
-
logger.
|
|
677
|
-
f"[CHECKPOINT] DSPyAgentHandle.__call__ invoked directly for agent '{self.name}' - THIS BYPASSES AgentHandle checkpoint logic!"
|
|
678
|
-
)
|
|
693
|
+
logger.debug(f"Agent '{self.name}' invoked via __call__()")
|
|
679
694
|
inputs = inputs or {}
|
|
680
695
|
|
|
681
696
|
# Handle string input as a convenience: Agent("message") -> Agent({message="message"})
|