tactus 0.26.0__tar.gz → 0.28.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.
Files changed (586) hide show
  1. {tactus-0.26.0 → tactus-0.28.0}/.github/workflows/release.yml +10 -4
  2. {tactus-0.26.0 → tactus-0.28.0}/.gitignore +2 -0
  3. {tactus-0.26.0 → tactus-0.28.0}/CHANGELOG.md +64 -0
  4. {tactus-0.26.0 → tactus-0.28.0}/Makefile +9 -0
  5. {tactus-0.26.0 → tactus-0.28.0}/PKG-INFO +118 -15
  6. {tactus-0.26.0 → tactus-0.28.0}/README.md +117 -14
  7. {tactus-0.26.0 → tactus-0.28.0}/docs/CONFIGURATION.md +45 -11
  8. {tactus-0.26.0 → tactus-0.28.0}/docs/DURABILITY.md +2 -2
  9. {tactus-0.26.0 → tactus-0.28.0}/docs/SANDBOXING.md +83 -31
  10. {tactus-0.26.0 → tactus-0.28.0}/docs/TOOLS.md +100 -13
  11. {tactus-0.26.0 → tactus-0.28.0}/docs/TOOL_ROADMAP.md +1 -1
  12. tactus-0.28.0/examples/01-basics-hello-world.tac +15 -0
  13. {tactus-0.26.0 → tactus-0.28.0}/examples/05-basics-multi-model.tac +2 -2
  14. {tactus-0.26.0 → tactus-0.28.0}/examples/06-basics-streaming.tac +7 -0
  15. {tactus-0.26.0 → tactus-0.28.0}/examples/07-basics-bedrock.tac +9 -2
  16. {tactus-0.26.0 → tactus-0.28.0}/examples/09-basics-google-gemini.tac +14 -2
  17. {tactus-0.26.0 → tactus-0.28.0}/examples/12-feature-structured-output.tac +6 -8
  18. {tactus-0.26.0 → tactus-0.28.0}/examples/14-feature-per-turn-tools-simple.tac +10 -1
  19. {tactus-0.26.0 → tactus-0.28.0}/examples/15-feature-local-tools.tac +11 -1
  20. {tactus-0.26.0 → tactus-0.28.0}/examples/16-feature-toolsets-advanced.tac +2 -2
  21. {tactus-0.26.0 → tactus-0.28.0}/examples/17-feature-toolsets-dsl.tac +1 -2
  22. {tactus-0.26.0 → tactus-0.28.0}/examples/18-feature-lua-tools-individual.tac +1 -1
  23. {tactus-0.26.0 → tactus-0.28.0}/examples/18-feature-lua-tools-inline.tac +1 -1
  24. {tactus-0.26.0 → tactus-0.28.0}/examples/18-feature-lua-tools-toolset.tac +1 -1
  25. {tactus-0.26.0 → tactus-0.28.0}/examples/40-model-text-classifier.tac +9 -18
  26. {tactus-0.26.0 → tactus-0.28.0}/examples/41-model-pytorch.tac +9 -20
  27. {tactus-0.26.0 → tactus-0.28.0}/examples/44-sub-procedure-composition.tac +11 -19
  28. {tactus-0.26.0 → tactus-0.28.0}/examples/60-tool-sources.tac +27 -3
  29. {tactus-0.26.0 → tactus-0.28.0}/examples/61-inline-toolset-lua.tac +4 -3
  30. {tactus-0.26.0 → tactus-0.28.0}/examples/62-mcp-toolset-by-server.tac +2 -2
  31. {tactus-0.26.0 → tactus-0.28.0}/examples/63-toolset-import-from-file.tac +3 -3
  32. {tactus-0.26.0 → tactus-0.28.0}/examples/65-optional-state-demo.tac +4 -6
  33. tactus-0.28.0/examples/66-host-tools-via-broker.tac +36 -0
  34. tactus-0.28.0/examples/67-host-tool-source.tac +41 -0
  35. {tactus-0.26.0 → tactus-0.28.0}/examples/71-mocking-temporal.tac +21 -0
  36. {tactus-0.26.0 → tactus-0.28.0}/examples/72-mocking-conditional.tac +24 -1
  37. {tactus-0.26.0 → tactus-0.28.0}/examples/99-misc-test-loading.tac +2 -2
  38. {tactus-0.26.0 → tactus-0.28.0}/features/18_example_procedures.feature +1 -1
  39. {tactus-0.26.0 → tactus-0.28.0}/features/32_result_object.feature +8 -6
  40. {tactus-0.26.0 → tactus-0.28.0}/features/steps/example_procedures_steps.py +14 -10
  41. {tactus-0.26.0 → tactus-0.28.0}/features/steps/result_and_output_steps.py +7 -7
  42. tactus-0.28.0/planning/BROKER_AND_TOOL_RUNNERS.md +617 -0
  43. {tactus-0.26.0 → tactus-0.28.0}/pyproject.toml +9 -1
  44. {tactus-0.26.0 → tactus-0.28.0}/tactus/__init__.py +1 -1
  45. tactus-0.28.0/tactus/adapters/broker_log.py +76 -0
  46. {tactus-0.26.0 → tactus-0.28.0}/tactus/adapters/cli_log.py +0 -25
  47. tactus-0.28.0/tactus/broker/__init__.py +12 -0
  48. tactus-0.28.0/tactus/broker/client.py +247 -0
  49. tactus-0.28.0/tactus/broker/protocol.py +183 -0
  50. tactus-0.28.0/tactus/broker/server.py +517 -0
  51. tactus-0.28.0/tactus/broker/stdio.py +12 -0
  52. {tactus-0.26.0 → tactus-0.28.0}/tactus/cli/app.py +38 -2
  53. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/dsl_stubs.py +238 -22
  54. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/output_validator.py +6 -3
  55. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/registry.py +8 -1
  56. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/runtime.py +62 -24
  57. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/yaml_parser.py +1 -11
  58. {tactus-0.26.0 → tactus-0.28.0}/tactus/docker/entrypoint.sh +3 -2
  59. {tactus-0.26.0 → tactus-0.28.0}/tactus/dspy/agent.py +224 -118
  60. tactus-0.28.0/tactus/dspy/broker_lm.py +181 -0
  61. {tactus-0.26.0 → tactus-0.28.0}/tactus/dspy/config.py +21 -8
  62. {tactus-0.26.0 → tactus-0.28.0}/tactus/dspy/prediction.py +71 -5
  63. {tactus-0.26.0 → tactus-0.28.0}/tactus/ide/server.py +37 -142
  64. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/__init__.py +2 -0
  65. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/handles.py +34 -7
  66. tactus-0.28.0/tactus/primitives/host.py +94 -0
  67. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/log.py +4 -0
  68. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/model.py +20 -2
  69. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/procedure.py +106 -51
  70. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/tool.py +0 -2
  71. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/tool_handle.py +3 -1
  72. {tactus-0.26.0 → tactus-0.28.0}/tactus/protocols/__init__.py +0 -7
  73. {tactus-0.26.0 → tactus-0.28.0}/tactus/protocols/log_handler.py +2 -2
  74. {tactus-0.26.0 → tactus-0.28.0}/tactus/protocols/models.py +1 -1
  75. {tactus-0.26.0 → tactus-0.28.0}/tactus/sandbox/config.py +50 -6
  76. tactus-0.28.0/tactus/sandbox/container_runner.py +1050 -0
  77. {tactus-0.26.0 → tactus-0.28.0}/tactus/sandbox/entrypoint.py +30 -17
  78. {tactus-0.26.0 → tactus-0.28.0}/tactus/sandbox/protocol.py +0 -9
  79. {tactus-0.26.0 → tactus-0.28.0}/tactus/stdlib/tac/tactus/tools/done.tac +3 -3
  80. {tactus-0.26.0 → tactus-0.28.0}/tactus/stdlib/tac/tactus/tools/log.tac +1 -0
  81. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/README.md +0 -4
  82. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/context.py +0 -1
  83. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/mock_agent.py +80 -23
  84. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/test_runner.py +0 -18
  85. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/semantic_visitor.py +32 -22
  86. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/backend/test_lsp_server.py +4 -4
  87. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/MessageFeed.tsx +1 -27
  88. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/EventRenderer.tsx +3 -9
  89. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/types/events.ts +0 -8
  90. tactus-0.28.0/test-ci.sh +5 -0
  91. tactus-0.28.0/tests/broker/test_broker_host_tool_source.py +39 -0
  92. tactus-0.28.0/tests/broker/test_broker_integration.py +111 -0
  93. tactus-0.28.0/tests/broker/test_broker_tcp_integration.py +112 -0
  94. tactus-0.28.0/tests/broker/test_broker_tcp_unit.py +187 -0
  95. tactus-0.28.0/tests/broker/test_brokered_lm_unit.py +72 -0
  96. {tactus-0.26.0 → tactus-0.28.0}/tests/cli/test_cli.py +2 -1
  97. {tactus-0.26.0 → tactus-0.28.0}/tests/cli/test_cli_inputs.py +11 -10
  98. {tactus-0.26.0 → tactus-0.28.0}/tests/core/test_script_mode.py +1 -1
  99. tactus-0.28.0/tests/dspy/test_mock_field_normalization.py +121 -0
  100. {tactus-0.26.0 → tactus-0.28.0}/tests/dspy/test_module_parameter.py +4 -4
  101. tactus-0.28.0/tests/dspy/test_prediction_messages.py +114 -0
  102. tactus-0.28.0/tests/primitives/test_host_primitive.py +32 -0
  103. {tactus-0.26.0 → tactus-0.28.0}/tests/primitives/test_system_alert.py +0 -2
  104. tactus-0.28.0/tests/sandbox/test_container_runner.py +170 -0
  105. tactus-0.28.0/tests/sandbox/test_docker_sandbox_smoke.py +98 -0
  106. tactus-0.28.0/tests/test_checkpoints_integration.py +59 -0
  107. {tactus-0.26.0 → tactus-0.28.0}/tests/test_mcp_integration.py +5 -2
  108. {tactus-0.26.0 → tactus-0.28.0}/tests/testing/test_all_examples.py +13 -3
  109. tactus-0.28.0/tests/validation/test_tool_curried_syntax_disallowed.py +57 -0
  110. tactus-0.26.0/examples/01-basics-hello-world.tac +0 -8
  111. tactus-0.26.0/tactus/sandbox/container_runner.py +0 -584
  112. tactus-0.26.0/tests/test_checkpoints_integration.py +0 -104
  113. {tactus-0.26.0 → tactus-0.28.0}/.claude/agents.md +0 -0
  114. {tactus-0.26.0 → tactus-0.28.0}/.github/workflows/desktop-release.yml +0 -0
  115. {tactus-0.26.0 → tactus-0.28.0}/.tactus/config.yml.example +0 -0
  116. {tactus-0.26.0 → tactus-0.28.0}/AGENTS.md +0 -0
  117. {tactus-0.26.0 → tactus-0.28.0}/IMPLEMENTATION.md +0 -0
  118. {tactus-0.26.0 → tactus-0.28.0}/LICENSE +0 -0
  119. {tactus-0.26.0 → tactus-0.28.0}/SPECIFICATION.md +0 -0
  120. {tactus-0.26.0 → tactus-0.28.0}/TECHNICAL_DEBT.md +0 -0
  121. {tactus-0.26.0 → tactus-0.28.0}/behave.ini +0 -0
  122. {tactus-0.26.0 → tactus-0.28.0}/docs/AGENTS.md +0 -0
  123. {tactus-0.26.0 → tactus-0.28.0}/docs/BDD_TESTING.md +0 -0
  124. {tactus-0.26.0 → tactus-0.28.0}/docs/FILE_IO.md +0 -0
  125. {tactus-0.26.0 → tactus-0.28.0}/docs/STREAMING.md +0 -0
  126. {tactus-0.26.0 → tactus-0.28.0}/examples/.tactus/config.yml +0 -0
  127. {tactus-0.26.0 → tactus-0.28.0}/examples/02-basics-simple-logic.tac +0 -0
  128. {tactus-0.26.0 → tactus-0.28.0}/examples/03-basics-parameters.tac +0 -0
  129. {tactus-0.26.0 → tactus-0.28.0}/examples/04-basics-simple-agent.tac +0 -0
  130. {tactus-0.26.0 → tactus-0.28.0}/examples/08-basics-models.tac +0 -0
  131. {tactus-0.26.0 → tactus-0.28.0}/examples/10-feature-state.tac +0 -0
  132. {tactus-0.26.0 → tactus-0.28.0}/examples/11-feature-message-history.tac +0 -0
  133. {tactus-0.26.0 → tactus-0.28.0}/examples/13-feature-session.tac +0 -0
  134. {tactus-0.26.0 → tactus-0.28.0}/examples/14-feature-per-turn-tools.tac +0 -0
  135. {tactus-0.26.0 → tactus-0.28.0}/examples/19-feature-direct-tool-calls.tac +0 -0
  136. {tactus-0.26.0 → tactus-0.28.0}/examples/20-bdd-complete.tac +0 -0
  137. {tactus-0.26.0 → tactus-0.28.0}/examples/20-bdd-complete.tac.bak2 +0 -0
  138. {tactus-0.26.0 → tactus-0.28.0}/examples/21-bdd-passing.tac +0 -0
  139. {tactus-0.26.0 → tactus-0.28.0}/examples/21-bdd-passing.tac.bak2 +0 -0
  140. {tactus-0.26.0 → tactus-0.28.0}/examples/30-eval-simple.tac +0 -0
  141. {tactus-0.26.0 → tactus-0.28.0}/examples/31-eval-demo.tac +0 -0
  142. {tactus-0.26.0 → tactus-0.28.0}/examples/32-eval-success-rate.tac +0 -0
  143. {tactus-0.26.0 → tactus-0.28.0}/examples/33-eval-thresholds.tac +0 -0
  144. {tactus-0.26.0 → tactus-0.28.0}/examples/34-eval-dataset.jsonl +0 -0
  145. {tactus-0.26.0 → tactus-0.28.0}/examples/34-eval-dataset.tac +0 -0
  146. {tactus-0.26.0 → tactus-0.28.0}/examples/35-eval-trace.tac +0 -0
  147. {tactus-0.26.0 → tactus-0.28.0}/examples/35-eval-trace.tac.bak2 +0 -0
  148. {tactus-0.26.0 → tactus-0.28.0}/examples/36-eval-advanced.tac +0 -0
  149. {tactus-0.26.0 → tactus-0.28.0}/examples/37-eval-comprehensive.tac +0 -0
  150. {tactus-0.26.0 → tactus-0.28.0}/examples/37-eval-comprehensive.tac.bak2 +0 -0
  151. {tactus-0.26.0 → tactus-0.28.0}/examples/39-model-simple.tac +0 -0
  152. {tactus-0.26.0 → tactus-0.28.0}/examples/40-mcp-test.tac +0 -0
  153. {tactus-0.26.0 → tactus-0.28.0}/examples/41-mcp-simple.tac +0 -0
  154. {tactus-0.26.0 → tactus-0.28.0}/examples/43-sub-procedure-simple.tac +0 -0
  155. {tactus-0.26.0 → tactus-0.28.0}/examples/45-sub-procedure-recursive.tac +0 -0
  156. {tactus-0.26.0 → tactus-0.28.0}/examples/46-checkpoint-explicit.tac +0 -0
  157. {tactus-0.26.0 → tactus-0.28.0}/examples/47-checkpoint-expensive-ops.tac +0 -0
  158. {tactus-0.26.0 → tactus-0.28.0}/examples/48-script-mode-simple.tac +0 -0
  159. {tactus-0.26.0 → tactus-0.28.0}/examples/50-inputs-showcase.tac +0 -0
  160. {tactus-0.26.0 → tactus-0.28.0}/examples/51-inputs-calculator.tac +0 -0
  161. {tactus-0.26.0 → tactus-0.28.0}/examples/52-file-io-basics.tac +0 -0
  162. {tactus-0.26.0 → tactus-0.28.0}/examples/53-tsv-file-io.tac +0 -0
  163. {tactus-0.26.0 → tactus-0.28.0}/examples/54-json-file-io.tac +0 -0
  164. {tactus-0.26.0 → tactus-0.28.0}/examples/55-parquet-file-io.tac +0 -0
  165. {tactus-0.26.0 → tactus-0.28.0}/examples/56-hdf5-file-io.tac +0 -0
  166. {tactus-0.26.0 → tactus-0.28.0}/examples/57-excel-file-io.tac +0 -0
  167. {tactus-0.26.0 → tactus-0.28.0}/examples/58-text-file-io.tac +0 -0
  168. {tactus-0.26.0 → tactus-0.28.0}/examples/64-require-modules.tac +0 -0
  169. {tactus-0.26.0 → tactus-0.28.0}/examples/70-mocking-static.tac +0 -0
  170. {tactus-0.26.0 → tactus-0.28.0}/examples/README.md +0 -0
  171. {tactus-0.26.0 → tactus-0.28.0}/examples/app_config.ini +0 -0
  172. {tactus-0.26.0 → tactus-0.28.0}/examples/data/sample.csv +0 -0
  173. {tactus-0.26.0 → tactus-0.28.0}/examples/demo_output.json +0 -0
  174. {tactus-0.26.0 → tactus-0.28.0}/examples/helpers/math_module.tac +0 -0
  175. {tactus-0.26.0 → tactus-0.28.0}/examples/helpers/product.tac +0 -0
  176. {tactus-0.26.0 → tactus-0.28.0}/examples/helpers/string_module.tac +0 -0
  177. {tactus-0.26.0 → tactus-0.28.0}/examples/helpers/sum.tac +0 -0
  178. {tactus-0.26.0 → tactus-0.28.0}/examples/helpers/text_tools.tac +0 -0
  179. {tactus-0.26.0 → tactus-0.28.0}/examples/inventory_summary.tsv +0 -0
  180. {tactus-0.26.0 → tactus-0.28.0}/examples/mock-config.json +0 -0
  181. {tactus-0.26.0 → tactus-0.28.0}/examples/models/README.md +0 -0
  182. {tactus-0.26.0 → tactus-0.28.0}/examples/models/create_sentiment_model.py +0 -0
  183. {tactus-0.26.0 → tactus-0.28.0}/examples/output_summary.txt +0 -0
  184. {tactus-0.26.0 → tactus-0.28.0}/examples/test-raw-module.tac +0 -0
  185. {tactus-0.26.0 → tactus-0.28.0}/examples/test-raw-streaming.tac +0 -0
  186. {tactus-0.26.0 → tactus-0.28.0}/examples/tools/calculations.py +0 -0
  187. {tactus-0.26.0 → tactus-0.28.0}/examples/tools/data_analysis.py +0 -0
  188. {tactus-0.26.0 → tactus-0.28.0}/examples/tools/search.py +0 -0
  189. {tactus-0.26.0 → tactus-0.28.0}/examples/with_dependencies/README.md +0 -0
  190. {tactus-0.26.0 → tactus-0.28.0}/examples/with_dependencies/simple_http_test.tac +0 -0
  191. {tactus-0.26.0 → tactus-0.28.0}/examples/with_dependencies/time_lookup.tac +0 -0
  192. {tactus-0.26.0 → tactus-0.28.0}/features/01_state_management.feature +0 -0
  193. {tactus-0.26.0 → tactus-0.28.0}/features/02_checkpointing.feature +0 -0
  194. {tactus-0.26.0 → tactus-0.28.0}/features/03_human_in_the_loop.feature +0 -0
  195. {tactus-0.26.0 → tactus-0.28.0}/features/04_control_flow.feature +0 -0
  196. {tactus-0.26.0 → tactus-0.28.0}/features/05_tool_integration.feature +0 -0
  197. {tactus-0.26.0 → tactus-0.28.0}/features/06_retry_logic.feature +0 -0
  198. {tactus-0.26.0 → tactus-0.28.0}/features/07_file_operations.feature +0 -0
  199. {tactus-0.26.0 → tactus-0.28.0}/features/08_agent_primitives.feature +0 -0
  200. {tactus-0.26.0 → tactus-0.28.0}/features/09_workflow_execution.feature +0 -0
  201. {tactus-0.26.0 → tactus-0.28.0}/features/10_lua_integration.feature +0 -0
  202. {tactus-0.26.0 → tactus-0.28.0}/features/11_storage_backends.feature +0 -0
  203. {tactus-0.26.0 → tactus-0.28.0}/features/12_json_operations.feature +0 -0
  204. {tactus-0.26.0 → tactus-0.28.0}/features/13_logging.feature +0 -0
  205. {tactus-0.26.0 → tactus-0.28.0}/features/14_stage_and_step_tracking.feature +0 -0
  206. {tactus-0.26.0 → tactus-0.28.0}/features/15_procedure_calls.feature +0 -0
  207. {tactus-0.26.0 → tactus-0.28.0}/features/16_session_management.feature +0 -0
  208. {tactus-0.26.0 → tactus-0.28.0}/features/17_lua_dsl_validation.feature +0 -0
  209. {tactus-0.26.0 → tactus-0.28.0}/features/19_ide_server.feature +0 -0
  210. {tactus-0.26.0 → tactus-0.28.0}/features/20_parameters.feature +0 -0
  211. {tactus-0.26.0 → tactus-0.28.0}/features/21_outputs.feature +0 -0
  212. {tactus-0.26.0 → tactus-0.28.0}/features/23_prompts.feature +0 -0
  213. {tactus-0.26.0 → tactus-0.28.0}/features/24_bdd_specifications.feature +0 -0
  214. {tactus-0.26.0 → tactus-0.28.0}/features/25_bdd_custom_steps.feature +0 -0
  215. {tactus-0.26.0 → tactus-0.28.0}/features/26_bdd_evaluation.feature +0 -0
  216. {tactus-0.26.0 → tactus-0.28.0}/features/27_default_settings.feature +0 -0
  217. {tactus-0.26.0 → tactus-0.28.0}/features/28_custom_prompts.feature +0 -0
  218. {tactus-0.26.0 → tactus-0.28.0}/features/29_execution_settings.feature +0 -0
  219. {tactus-0.26.0 → tactus-0.28.0}/features/30_session_filters.feature +0 -0
  220. {tactus-0.26.0 → tactus-0.28.0}/features/31_matchers.feature +0 -0
  221. {tactus-0.26.0 → tactus-0.28.0}/features/33_output_type.feature +0 -0
  222. {tactus-0.26.0 → tactus-0.28.0}/features/42_model_primitive.feature +0 -0
  223. {tactus-0.26.0 → tactus-0.28.0}/features/43_sub_procedure_checkpointing.feature +0 -0
  224. {tactus-0.26.0 → tactus-0.28.0}/features/46_explicit_checkpoint.feature +0 -0
  225. {tactus-0.26.0 → tactus-0.28.0}/features/48_script_mode.feature +0 -0
  226. {tactus-0.26.0 → tactus-0.28.0}/features/51_dspy_lm_config.feature +0 -0
  227. {tactus-0.26.0 → tactus-0.28.0}/features/52_dspy_signature.feature +0 -0
  228. {tactus-0.26.0 → tactus-0.28.0}/features/53_dspy_module.feature +0 -0
  229. {tactus-0.26.0 → tactus-0.28.0}/features/54_dspy_history.feature +0 -0
  230. {tactus-0.26.0 → tactus-0.28.0}/features/55_dspy_prediction.feature +0 -0
  231. {tactus-0.26.0 → tactus-0.28.0}/features/56_dspy_agent.feature +0 -0
  232. {tactus-0.26.0 → tactus-0.28.0}/features/57_chat_assistant.feature +0 -0
  233. {tactus-0.26.0 → tactus-0.28.0}/features/documentation/IDE_SERVER_BEHAVIOR.md +0 -0
  234. {tactus-0.26.0 → tactus-0.28.0}/features/documentation/Lua DSL/README.md +0 -0
  235. {tactus-0.26.0 → tactus-0.28.0}/features/environment.py +0 -0
  236. {tactus-0.26.0 → tactus-0.28.0}/features/steps/agent_primitives_steps.py +0 -0
  237. {tactus-0.26.0 → tactus-0.28.0}/features/steps/chat_assistant_steps.py +0 -0
  238. {tactus-0.26.0 → tactus-0.28.0}/features/steps/checkpointing_steps.py +0 -0
  239. {tactus-0.26.0 → tactus-0.28.0}/features/steps/control_flow_steps.py +0 -0
  240. {tactus-0.26.0 → tactus-0.28.0}/features/steps/dspy_agent_steps.py +0 -0
  241. {tactus-0.26.0 → tactus-0.28.0}/features/steps/dspy_history_steps.py +0 -0
  242. {tactus-0.26.0 → tactus-0.28.0}/features/steps/dspy_lm_steps.py +0 -0
  243. {tactus-0.26.0 → tactus-0.28.0}/features/steps/dspy_module_steps.py +0 -0
  244. {tactus-0.26.0 → tactus-0.28.0}/features/steps/dspy_prediction_steps.py +0 -0
  245. {tactus-0.26.0 → tactus-0.28.0}/features/steps/dspy_signature_steps.py +0 -0
  246. {tactus-0.26.0 → tactus-0.28.0}/features/steps/file_operations_steps.py +0 -0
  247. {tactus-0.26.0 → tactus-0.28.0}/features/steps/human_in_the_loop_steps.py +0 -0
  248. {tactus-0.26.0 → tactus-0.28.0}/features/steps/ide_server_steps.py +0 -0
  249. {tactus-0.26.0 → tactus-0.28.0}/features/steps/json_operations_steps.py +0 -0
  250. {tactus-0.26.0 → tactus-0.28.0}/features/steps/logging_steps.py +0 -0
  251. {tactus-0.26.0 → tactus-0.28.0}/features/steps/lua_dsl_validation_steps.py +0 -0
  252. {tactus-0.26.0 → tactus-0.28.0}/features/steps/lua_integration_steps.py +0 -0
  253. {tactus-0.26.0 → tactus-0.28.0}/features/steps/mocking_steps.py +0 -0
  254. {tactus-0.26.0 → tactus-0.28.0}/features/steps/procedure_calls_steps.py +0 -0
  255. {tactus-0.26.0 → tactus-0.28.0}/features/steps/retry_logic_steps.py +0 -0
  256. {tactus-0.26.0 → tactus-0.28.0}/features/steps/session_management_steps.py +0 -0
  257. {tactus-0.26.0 → tactus-0.28.0}/features/steps/stage_tracking_steps.py +0 -0
  258. {tactus-0.26.0 → tactus-0.28.0}/features/steps/state_management_steps.py +0 -0
  259. {tactus-0.26.0 → tactus-0.28.0}/features/steps/storage_backend_steps.py +0 -0
  260. {tactus-0.26.0 → tactus-0.28.0}/features/steps/support/__init__.py +0 -0
  261. {tactus-0.26.0 → tactus-0.28.0}/features/steps/support/harnesses.py +0 -0
  262. {tactus-0.26.0 → tactus-0.28.0}/features/steps/tool_integration_steps.py +0 -0
  263. {tactus-0.26.0 → tactus-0.28.0}/features/steps/workflow_execution_steps.py +0 -0
  264. {tactus-0.26.0 → tactus-0.28.0}/scripts/audit_examples_mocking.py +0 -0
  265. {tactus-0.26.0 → tactus-0.28.0}/scripts/convert_examples.py +0 -0
  266. {tactus-0.26.0 → tactus-0.28.0}/start-web-ide.sh +0 -0
  267. {tactus-0.26.0 → tactus-0.28.0}/tactus/adapters/__init__.py +0 -0
  268. {tactus-0.26.0 → tactus-0.28.0}/tactus/adapters/cli_hitl.py +0 -0
  269. {tactus-0.26.0 → tactus-0.28.0}/tactus/adapters/cost_collector_log.py +0 -0
  270. {tactus-0.26.0 → tactus-0.28.0}/tactus/adapters/file_storage.py +0 -0
  271. {tactus-0.26.0 → tactus-0.28.0}/tactus/adapters/http_callback_log.py +0 -0
  272. {tactus-0.26.0 → tactus-0.28.0}/tactus/adapters/ide_log.py +0 -0
  273. {tactus-0.26.0 → tactus-0.28.0}/tactus/adapters/lua_tools.py +0 -0
  274. {tactus-0.26.0 → tactus-0.28.0}/tactus/adapters/mcp.py +0 -0
  275. {tactus-0.26.0 → tactus-0.28.0}/tactus/adapters/mcp_manager.py +0 -0
  276. {tactus-0.26.0 → tactus-0.28.0}/tactus/adapters/memory.py +0 -0
  277. {tactus-0.26.0 → tactus-0.28.0}/tactus/adapters/plugins.py +0 -0
  278. {tactus-0.26.0 → tactus-0.28.0}/tactus/backends/http_backend.py +0 -0
  279. {tactus-0.26.0 → tactus-0.28.0}/tactus/backends/model_backend.py +0 -0
  280. {tactus-0.26.0 → tactus-0.28.0}/tactus/backends/pytorch_backend.py +0 -0
  281. {tactus-0.26.0 → tactus-0.28.0}/tactus/cli/__init__.py +0 -0
  282. {tactus-0.26.0 → tactus-0.28.0}/tactus/cli/commands/__init__.py +0 -0
  283. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/__init__.py +0 -0
  284. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/config_manager.py +0 -0
  285. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/dependencies/__init__.py +0 -0
  286. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/dependencies/registry.py +0 -0
  287. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/exceptions.py +0 -0
  288. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/execution_context.py +0 -0
  289. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/lua_sandbox.py +0 -0
  290. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/message_history_manager.py +0 -0
  291. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/mocking.py +0 -0
  292. {tactus-0.26.0 → tactus-0.28.0}/tactus/core/template_resolver.py +0 -0
  293. {tactus-0.26.0 → tactus-0.28.0}/tactus/docker/Dockerfile +0 -0
  294. {tactus-0.26.0 → tactus-0.28.0}/tactus/dspy/__init__.py +0 -0
  295. {tactus-0.26.0 → tactus-0.28.0}/tactus/dspy/history.py +0 -0
  296. {tactus-0.26.0 → tactus-0.28.0}/tactus/dspy/module.py +0 -0
  297. {tactus-0.26.0 → tactus-0.28.0}/tactus/dspy/signature.py +0 -0
  298. {tactus-0.26.0 → tactus-0.28.0}/tactus/ide/__init__.py +0 -0
  299. {tactus-0.26.0 → tactus-0.28.0}/tactus/ide/coding_assistant.py +0 -0
  300. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/control.py +0 -0
  301. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/file.py +0 -0
  302. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/human.py +0 -0
  303. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/json.py +0 -0
  304. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/message_history.py +0 -0
  305. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/procedure_callable.py +0 -0
  306. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/retry.py +0 -0
  307. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/session.py +0 -0
  308. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/stage.py +0 -0
  309. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/state.py +0 -0
  310. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/step.py +0 -0
  311. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/system.py +0 -0
  312. {tactus-0.26.0 → tactus-0.28.0}/tactus/primitives/toolset.py +0 -0
  313. {tactus-0.26.0 → tactus-0.28.0}/tactus/protocols/chat_recorder.py +0 -0
  314. {tactus-0.26.0 → tactus-0.28.0}/tactus/protocols/config.py +0 -0
  315. {tactus-0.26.0 → tactus-0.28.0}/tactus/protocols/cost.py +0 -0
  316. {tactus-0.26.0 → tactus-0.28.0}/tactus/protocols/hitl.py +0 -0
  317. {tactus-0.26.0 → tactus-0.28.0}/tactus/protocols/result.py +0 -0
  318. {tactus-0.26.0 → tactus-0.28.0}/tactus/protocols/storage.py +0 -0
  319. {tactus-0.26.0 → tactus-0.28.0}/tactus/providers/__init__.py +0 -0
  320. {tactus-0.26.0 → tactus-0.28.0}/tactus/providers/base.py +0 -0
  321. {tactus-0.26.0 → tactus-0.28.0}/tactus/providers/bedrock.py +0 -0
  322. {tactus-0.26.0 → tactus-0.28.0}/tactus/providers/google.py +0 -0
  323. {tactus-0.26.0 → tactus-0.28.0}/tactus/providers/openai.py +0 -0
  324. {tactus-0.26.0 → tactus-0.28.0}/tactus/sandbox/__init__.py +0 -0
  325. {tactus-0.26.0 → tactus-0.28.0}/tactus/sandbox/docker_manager.py +0 -0
  326. {tactus-0.26.0 → tactus-0.28.0}/tactus/stdlib/__init__.py +0 -0
  327. {tactus-0.26.0 → tactus-0.28.0}/tactus/stdlib/io/__init__.py +0 -0
  328. {tactus-0.26.0 → tactus-0.28.0}/tactus/stdlib/io/csv.py +0 -0
  329. {tactus-0.26.0 → tactus-0.28.0}/tactus/stdlib/io/excel.py +0 -0
  330. {tactus-0.26.0 → tactus-0.28.0}/tactus/stdlib/io/file.py +0 -0
  331. {tactus-0.26.0 → tactus-0.28.0}/tactus/stdlib/io/fs.py +0 -0
  332. {tactus-0.26.0 → tactus-0.28.0}/tactus/stdlib/io/hdf5.py +0 -0
  333. {tactus-0.26.0 → tactus-0.28.0}/tactus/stdlib/io/json.py +0 -0
  334. {tactus-0.26.0 → tactus-0.28.0}/tactus/stdlib/io/parquet.py +0 -0
  335. {tactus-0.26.0 → tactus-0.28.0}/tactus/stdlib/io/tsv.py +0 -0
  336. {tactus-0.26.0 → tactus-0.28.0}/tactus/stdlib/loader.py +0 -0
  337. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/__init__.py +0 -0
  338. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/behave_integration.py +0 -0
  339. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/eval_models.py +0 -0
  340. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/evaluation_runner.py +0 -0
  341. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/evaluators.py +0 -0
  342. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/events.py +0 -0
  343. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/gherkin_parser.py +0 -0
  344. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/mock_dependencies.py +0 -0
  345. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/mock_hitl.py +0 -0
  346. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/mock_registry.py +0 -0
  347. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/mock_tools.py +0 -0
  348. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/models.py +0 -0
  349. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/pydantic_eval_runner.py +0 -0
  350. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/steps/__init__.py +0 -0
  351. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/steps/builtin.py +0 -0
  352. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/steps/custom.py +0 -0
  353. {tactus-0.26.0 → tactus-0.28.0}/tactus/testing/steps/registry.py +0 -0
  354. {tactus-0.26.0 → tactus-0.28.0}/tactus/tracing/__init__.py +0 -0
  355. {tactus-0.26.0 → tactus-0.28.0}/tactus/tracing/trace_manager.py +0 -0
  356. {tactus-0.26.0 → tactus-0.28.0}/tactus/utils/__init__.py +0 -0
  357. {tactus-0.26.0 → tactus-0.28.0}/tactus/utils/cost_calculator.py +0 -0
  358. {tactus-0.26.0 → tactus-0.28.0}/tactus/utils/model_pricing.py +0 -0
  359. {tactus-0.26.0 → tactus-0.28.0}/tactus/utils/safe_file_library.py +0 -0
  360. {tactus-0.26.0 → tactus-0.28.0}/tactus/utils/safe_libraries.py +0 -0
  361. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/LuaLexerBase.py +0 -0
  362. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/LuaParserBase.py +0 -0
  363. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/README.md +0 -0
  364. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/__init__.py +0 -0
  365. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/error_listener.py +0 -0
  366. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/generated/LuaLexer.interp +0 -0
  367. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/generated/LuaLexer.py +0 -0
  368. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/generated/LuaLexer.tokens +0 -0
  369. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/generated/LuaLexerBase.py +0 -0
  370. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/generated/LuaParser.interp +0 -0
  371. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/generated/LuaParser.py +0 -0
  372. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/generated/LuaParser.tokens +0 -0
  373. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/generated/LuaParserBase.py +0 -0
  374. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/generated/LuaParserVisitor.py +0 -0
  375. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/generated/__init__.py +0 -0
  376. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/grammar/LuaLexer.g4 +0 -0
  377. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/grammar/LuaParser.g4 +0 -0
  378. {tactus-0.26.0 → tactus-0.28.0}/tactus/validation/validator.py +0 -0
  379. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/.gitignore +0 -0
  380. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/README.md +0 -0
  381. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/RUN_ELECTRON.md +0 -0
  382. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/SETUP_COMPLETE.md +0 -0
  383. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/backend/hook-lupa.py +0 -0
  384. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/backend/tactus_backend.spec +0 -0
  385. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/package-lock.json +0 -0
  386. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/package.json +0 -0
  387. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/preload/preload.ts +0 -0
  388. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/preload/tsconfig.json +0 -0
  389. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/rebuild-and-test.sh +0 -0
  390. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/scripts/build-backend.js +0 -0
  391. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/scripts/build-frontend.js +0 -0
  392. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/src/backend-manager.ts +0 -0
  393. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/src/main.ts +0 -0
  394. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/src/menu.ts +0 -0
  395. {tactus-0.26.0 → tactus-0.28.0}/tactus-desktop/tsconfig.json +0 -0
  396. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/ARCHITECTURE.md +0 -0
  397. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/CHANGELOG.md +0 -0
  398. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/DEV_MODE.md +0 -0
  399. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/QUICK_START.md +0 -0
  400. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/README.md +0 -0
  401. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/RESTART_INSTRUCTIONS.md +0 -0
  402. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/TROUBLESHOOTING.md +0 -0
  403. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/backend/README.md +0 -0
  404. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/backend/assistant_service.py +0 -0
  405. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/backend/assistant_tools.py +0 -0
  406. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/backend/chat_server.py +0 -0
  407. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/backend/config_server.py +0 -0
  408. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/backend/events.py +0 -0
  409. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/backend/logging_capture.py +0 -0
  410. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/backend/lsp_server.py +0 -0
  411. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/backend/requirements.txt +0 -0
  412. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/backend/tactus_lsp_handler.py +0 -0
  413. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/backend/text_editor_tool.py +0 -0
  414. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/dev.sh +0 -0
  415. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/.storybook/main.ts +0 -0
  416. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/.storybook/preview.ts +0 -0
  417. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/.storybook/vitest.setup.ts +0 -0
  418. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/README.md +0 -0
  419. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/demo.ts +0 -0
  420. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/index.html +0 -0
  421. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/jest.config.js +0 -0
  422. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/package-lock.json +0 -0
  423. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/package.json +0 -0
  424. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/postcss.config.js +0 -0
  425. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/App.tsx +0 -0
  426. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/Editor.tsx +0 -0
  427. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/LSPClient.ts +0 -0
  428. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/LSPClientHTTP.ts +0 -0
  429. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/TactusLanguage.ts +0 -0
  430. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/commands/registry.ts +0 -0
  431. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/AboutDialog.tsx +0 -0
  432. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ChatSidebar.tsx +0 -0
  433. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/CheckpointSummary.tsx +0 -0
  434. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/CollapsibleRun.tsx +0 -0
  435. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/Duration.stories.tsx +0 -0
  436. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/Duration.tsx +0 -0
  437. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/FileTree.stories.tsx +0 -0
  438. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/FileTree.tsx +0 -0
  439. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/PreferencesView.tsx +0 -0
  440. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ProcedureInputsDisplay.stories.tsx +0 -0
  441. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ProcedureInputsDisplay.tsx +0 -0
  442. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ProcedureInputsModal.stories.tsx +0 -0
  443. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ProcedureInputsModal.tsx +0 -0
  444. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ProcedureTab.stories.tsx +0 -0
  445. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ProcedureTab.tsx +0 -0
  446. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ResizeHandle.tsx +0 -0
  447. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ResultsSidebar.stories.tsx +0 -0
  448. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ResultsSidebar.tsx +0 -0
  449. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/TestOptionsModal.tsx +0 -0
  450. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/Timestamp.stories.tsx +0 -0
  451. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/Timestamp.tsx +0 -0
  452. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/TopMenuBar.stories.tsx +0 -0
  453. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/chat/ChatInterface.tsx +0 -0
  454. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/chat/MessageInput.tsx +0 -0
  455. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/chat/MessageList.tsx +0 -0
  456. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/debugger/CheckpointDetails.stories.tsx +0 -0
  457. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/debugger/CheckpointDetails.tsx +0 -0
  458. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/debugger/CheckpointList.stories.tsx +0 -0
  459. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/debugger/CheckpointList.tsx +0 -0
  460. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/debugger/DebuggerPanel.stories.tsx +0 -0
  461. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/debugger/DebuggerPanel.tsx +0 -0
  462. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/debugger/RunSelector.stories.tsx +0 -0
  463. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/debugger/RunSelector.tsx +0 -0
  464. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/debugger/StatisticsPanel.stories.tsx +0 -0
  465. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/debugger/StatisticsPanel.tsx +0 -0
  466. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/AgentStreamingComponent.tsx +0 -0
  467. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/BaseEventComponent.tsx +0 -0
  468. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/CheckpointEventComponent.tsx +0 -0
  469. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/CollapsibleTestScenario.tsx +0 -0
  470. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/ContainerStatusEventComponent.tsx +0 -0
  471. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/CostEventComponent.stories.tsx +0 -0
  472. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/CostEventComponent.tsx +0 -0
  473. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/EvaluationEventComponent.stories.tsx +0 -0
  474. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/EvaluationEventComponent.tsx +0 -0
  475. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/ExecutionEventComponent.stories.tsx +0 -0
  476. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/ExecutionEventComponent.tsx +0 -0
  477. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/ExecutionSummaryEventComponent.stories.tsx +0 -0
  478. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/ExecutionSummaryEventComponent.tsx +0 -0
  479. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/LoadingEventComponent.stories.tsx +0 -0
  480. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/LoadingEventComponent.tsx +0 -0
  481. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/LogCluster.tsx +0 -0
  482. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/LogEventComponent.stories.tsx +0 -0
  483. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/LogEventComponent.tsx +0 -0
  484. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/OutputEventComponent.stories.tsx +0 -0
  485. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/OutputEventComponent.tsx +0 -0
  486. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/TestEventComponent.stories.tsx +0 -0
  487. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/TestEventComponent.tsx +0 -0
  488. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/TestProgressContainer.tsx +0 -0
  489. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/ToolCallEventComponent.tsx +0 -0
  490. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/ValidationEventComponent.stories.tsx +0 -0
  491. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/events/ValidationEventComponent.tsx +0 -0
  492. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/metadata/AgentsSection.tsx +0 -0
  493. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/metadata/EvaluationsSection.tsx +0 -0
  494. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/metadata/MetadataSections.stories.tsx +0 -0
  495. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/metadata/OutputsSection.tsx +0 -0
  496. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/metadata/ParametersSection.tsx +0 -0
  497. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/metadata/SpecificationsSection.tsx +0 -0
  498. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/metadata/StagesSection.tsx +0 -0
  499. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/metadata/ToolsSection.tsx +0 -0
  500. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/preferences/ConfigFieldView.tsx +0 -0
  501. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/preferences/SourceBadge.tsx +0 -0
  502. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/preferences/YamlCodeEditor.tsx +0 -0
  503. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/scenarios/EvaluateScenarios.stories.tsx +0 -0
  504. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/scenarios/RunScenarios.stories.tsx +0 -0
  505. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/scenarios/TestScenarios.stories.tsx +0 -0
  506. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/scenarios/ValidationScenarios.stories.tsx +0 -0
  507. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/theme-provider.tsx +0 -0
  508. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/ai/conversation.tsx +0 -0
  509. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/ai/message.tsx +0 -0
  510. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/ai/prompt-input.tsx +0 -0
  511. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/badge.tsx +0 -0
  512. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/button.tsx +0 -0
  513. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/dialog.tsx +0 -0
  514. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/dropdown-menu.tsx +0 -0
  515. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/input.tsx +0 -0
  516. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/label.tsx +0 -0
  517. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/logo.stories.tsx +0 -0
  518. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/logo.tsx +0 -0
  519. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/menubar.tsx +0 -0
  520. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/scroll-area.tsx +0 -0
  521. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/select.tsx +0 -0
  522. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/separator.tsx +0 -0
  523. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/switch.tsx +0 -0
  524. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/tabs.tsx +0 -0
  525. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/components/ui/tooltip.tsx +0 -0
  526. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/hooks/useChatSSE.ts +0 -0
  527. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/hooks/useEventStream.ts +0 -0
  528. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/hooks/useTracing.ts +0 -0
  529. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/index.css +0 -0
  530. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/lib/utils.ts +0 -0
  531. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/main.tsx +0 -0
  532. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/types/metadata.ts +0 -0
  533. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/types/preferences.ts +0 -0
  534. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/types/results.ts +0 -0
  535. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/types/tracing.ts +0 -0
  536. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/utils/yamlSync.ts +0 -0
  537. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/validation/TactusValidator.ts +0 -0
  538. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/validation/generated/LuaParser.interp +0 -0
  539. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/validation/generated/LuaParser.tokens +0 -0
  540. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/validation/types.ts +0 -0
  541. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/src/vite-env.d.ts +0 -0
  542. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/tailwind.config.js +0 -0
  543. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/tsconfig.json +0 -0
  544. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/tsconfig.node.json +0 -0
  545. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/vite.config.ts +0 -0
  546. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/frontend/vitest.shims.d.ts +0 -0
  547. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/package.json +0 -0
  548. {tactus-0.26.0 → tactus-0.28.0}/tactus-ide/start-dev.sh +0 -0
  549. {tactus-0.26.0 → tactus-0.28.0}/tests/__init__.py +0 -0
  550. {tactus-0.26.0 → tactus-0.28.0}/tests/adapters/__init__.py +0 -0
  551. {tactus-0.26.0 → tactus-0.28.0}/tests/adapters/test_lua_tools_adapter.py +0 -0
  552. {tactus-0.26.0 → tactus-0.28.0}/tests/adapters/test_plugins.py +0 -0
  553. {tactus-0.26.0 → tactus-0.28.0}/tests/cli/__init__.py +0 -0
  554. {tactus-0.26.0 → tactus-0.28.0}/tests/conftest.py +0 -0
  555. {tactus-0.26.0 → tactus-0.28.0}/tests/core/__init__.py +0 -0
  556. {tactus-0.26.0 → tactus-0.28.0}/tests/core/test_config_manager.py +0 -0
  557. {tactus-0.26.0 → tactus-0.28.0}/tests/core/test_determinism_safety.py +0 -0
  558. {tactus-0.26.0 → tactus-0.28.0}/tests/core/test_lua_sandbox_security.py +0 -0
  559. {tactus-0.26.0 → tactus-0.28.0}/tests/core/test_runtime_inputs.py +0 -0
  560. {tactus-0.26.0 → tactus-0.28.0}/tests/dspy/__init__.py +0 -0
  561. {tactus-0.26.0 → tactus-0.28.0}/tests/dspy/test_streaming.py +0 -0
  562. {tactus-0.26.0 → tactus-0.28.0}/tests/fixtures/__init__.py +0 -0
  563. {tactus-0.26.0 → tactus-0.28.0}/tests/fixtures/test_mcp_server.py +0 -0
  564. {tactus-0.26.0 → tactus-0.28.0}/tests/integration/test_named_procedures.py +0 -0
  565. {tactus-0.26.0 → tactus-0.28.0}/tests/mocks/__init__.py +0 -0
  566. {tactus-0.26.0 → tactus-0.28.0}/tests/mocks/llm_mocks.py +0 -0
  567. {tactus-0.26.0 → tactus-0.28.0}/tests/primitives/test_checkpoint_primitive.py +0 -0
  568. {tactus-0.26.0 → tactus-0.28.0}/tests/primitives/test_retry_primitive.py +0 -0
  569. {tactus-0.26.0 → tactus-0.28.0}/tests/primitives/test_state_primitive.py +0 -0
  570. {tactus-0.26.0 → tactus-0.28.0}/tests/primitives/test_tool_primitive.py +0 -0
  571. {tactus-0.26.0 → tactus-0.28.0}/tests/primitives/test_toolset_dsl.py +0 -0
  572. {tactus-0.26.0 → tactus-0.28.0}/tests/stdlib/__init__.py +0 -0
  573. {tactus-0.26.0 → tactus-0.28.0}/tests/stdlib/test_loader.py +0 -0
  574. {tactus-0.26.0 → tactus-0.28.0}/tests/stdlib/test_require_python.py +0 -0
  575. {tactus-0.26.0 → tactus-0.28.0}/tests/test_tracing.py +0 -0
  576. {tactus-0.26.0 → tactus-0.28.0}/tests/testing/__init__.py +0 -0
  577. {tactus-0.26.0 → tactus-0.28.0}/tests/testing/conftest.py +0 -0
  578. {tactus-0.26.0 → tactus-0.28.0}/tests/testing/test_e2e.py +0 -0
  579. {tactus-0.26.0 → tactus-0.28.0}/tests/testing/test_gherkin_parser.py +0 -0
  580. {tactus-0.26.0 → tactus-0.28.0}/tests/testing/test_integration.py +0 -0
  581. {tactus-0.26.0 → tactus-0.28.0}/tests/testing/test_models.py +0 -0
  582. {tactus-0.26.0 → tactus-0.28.0}/tests/testing/test_runtime_integration.py +0 -0
  583. {tactus-0.26.0 → tactus-0.28.0}/tests/testing/test_step_registry.py +0 -0
  584. {tactus-0.26.0 → tactus-0.28.0}/tests/utils/__init__.py +0 -0
  585. {tactus-0.26.0 → tactus-0.28.0}/tests/utils/test_safe_file_library.py +0 -0
  586. {tactus-0.26.0 → tactus-0.28.0}/tests/validation/__init__.py +0 -0
@@ -3,11 +3,13 @@ name: Release
3
3
  on:
4
4
  push:
5
5
  branches:
6
- - main
6
+ - '**'
7
+ pull_request:
8
+ branches:
9
+ - '**'
7
10
 
8
11
  permissions:
9
- contents: write
10
- id-token: write
12
+ contents: read
11
13
 
12
14
  jobs:
13
15
  quality-checks:
@@ -38,7 +40,7 @@ jobs:
38
40
  run: black --check tactus/ tests/ features/steps/
39
41
 
40
42
  - name: Run pytest tests
41
- run: pytest tests/ -v --tb=short -m "not integration"
43
+ run: pytest tests/ -v --tb=short -m "not integration" -n0
42
44
 
43
45
  - name: Run behave BDD tests
44
46
  run: behave
@@ -47,6 +49,10 @@ jobs:
47
49
  name: Semantic Release
48
50
  runs-on: ubuntu-latest
49
51
  needs: quality-checks
52
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
53
+ permissions:
54
+ contents: write
55
+ id-token: write
50
56
 
51
57
  steps:
52
58
  - name: Checkout code
@@ -39,6 +39,8 @@ progress.output
39
39
  .tac/
40
40
  tmp/
41
41
  examples/output/
42
+ _recovery/
43
+ .tactus-broker/
42
44
 
43
45
  *storybook.log
44
46
  storybook-static
@@ -2,6 +2,70 @@
2
2
 
3
3
  <!-- version list -->
4
4
 
5
+ ## v0.28.0 (2026-01-14)
6
+
7
+ ### Bug Fixes
8
+
9
+ - Correct test assertions for protocol changes
10
+ ([`79b1bdb`](https://github.com/AnthusAI/Tactus/commit/79b1bdb6d4fd1e5c6dd5e7bd0089d2049d05ede8))
11
+
12
+ - Disallow curried Tool syntax (#27) ([#27](https://github.com/AnthusAI/Tactus/pull/27),
13
+ [`e5b25c2`](https://github.com/AnthusAI/Tactus/commit/e5b25c23f1ba50e1fed1b8a13fef77c172ed48ab))
14
+
15
+ - Enable TCP broker streaming with length-prefixed protocol
16
+ ([`68d4d91`](https://github.com/AnthusAI/Tactus/commit/68d4d915316928b9ce180737259363b49f38788b))
17
+
18
+ - Mark broker integration tests to skip in CI
19
+ ([`a34de74`](https://github.com/AnthusAI/Tactus/commit/a34de74f083a229c7e6480ac80984808e9d76207))
20
+
21
+ - Mark TCP broker integration tests to skip in CI
22
+ ([`e8ecfa5`](https://github.com/AnthusAI/Tactus/commit/e8ecfa5216c19b7339e342c2e8682265f25a2808))
23
+
24
+ - Update DSPy agent tests for TactusResult API changes
25
+ ([`aeb16f0`](https://github.com/AnthusAI/Tactus/commit/aeb16f0d0bd45481840bdc26cb1ecc1b4d46c8a7))
26
+
27
+ - Update TCP unit tests for length-prefixed protocol
28
+ ([`803bcd8`](https://github.com/AnthusAI/Tactus/commit/803bcd87b294082b2e598be4c299a8840f2be6f6))
29
+
30
+ - **agent**: Make Raw the default module and case-insensitive matching
31
+ ([`0cac3fa`](https://github.com/AnthusAI/Tactus/commit/0cac3fa75b3ee49b6e87221eea5d232b9e751ca7))
32
+
33
+ - **agent**: Return TactusResult with value and cost stats
34
+ ([`c83f92d`](https://github.com/AnthusAI/Tactus/commit/c83f92dd561b553f7db8cf32cb9a93e9dfad1b20))
35
+
36
+ - **broker**: Handle async event emission from sync threads
37
+ ([`340e288`](https://github.com/AnthusAI/Tactus/commit/340e28891bcaefb174d5d2babb34a16f0c3abd84))
38
+
39
+ ### Chores
40
+
41
+ - Update GitHub Actions workflow for release process
42
+ ([`310a5a5`](https://github.com/AnthusAI/Tactus/commit/310a5a5e07028257b04811d5a8e8e1fca2d34d90))
43
+
44
+ ### Code Style
45
+
46
+ - Run black on test_mock_field_normalization.py
47
+ ([`4522f4b`](https://github.com/AnthusAI/Tactus/commit/4522f4b7e2e093d3041cea086d84efcece5cb06f))
48
+
49
+ ### Documentation
50
+
51
+ - Update sandboxing and broker defaults
52
+ ([`9ac4dcc`](https://github.com/AnthusAI/Tactus/commit/9ac4dcc7f65b54ab1a516d190afc748c933ee6e8))
53
+
54
+ ### Features
55
+
56
+ - Add default current directory volume mount
57
+ ([`095c687`](https://github.com/AnthusAI/Tactus/commit/095c687c3758c01c2c93929f929a2e00045e831b))
58
+
59
+
60
+ ## v0.27.0 (2026-01-11)
61
+
62
+ ### Features
63
+
64
+ - **broker**: Brokered sandbox runtime MVP (secretless runtime container) (#24)
65
+ ([#24](https://github.com/AnthusAI/Tactus/pull/24),
66
+ [`f922432`](https://github.com/AnthusAI/Tactus/commit/f922432da5a881c5eceb7c1410276ab45264ddaa))
67
+
68
+
5
69
  ## v0.26.0 (2026-01-11)
6
70
 
7
71
  ### Features
@@ -1,4 +1,5 @@
1
1
  .PHONY: help generate-parsers generate-python-parser generate-typescript-parser test-parsers clean-generated dev-ide test-examples test-examples-fast test-examples-parallel test-examples-bdd
2
+ .PHONY: test-docker-sandbox
2
3
 
3
4
  help:
4
5
  @echo "Tactus Parser Generation and Testing"
@@ -17,6 +18,9 @@ help:
17
18
  @echo " test-examples-parallel - Test examples in parallel for speed"
18
19
  @echo " test-examples-bdd - Test only examples with BDD specifications"
19
20
  @echo ""
21
+ @echo "Docker Sandbox Testing:"
22
+ @echo " test-docker-sandbox - Run opt-in Docker sandbox smoke tests"
23
+ @echo ""
20
24
  @echo "Requirements:"
21
25
  @echo " - Docker must be running (for parser generation)"
22
26
  @echo " - Python 3.11+ with dependencies installed"
@@ -113,6 +117,11 @@ test-examples-bdd:
113
117
  @echo "Testing examples with BDD specifications..."
114
118
  pytest tests/testing/test_all_examples.py::TestAllExamples::test_example_bdd_specs -v --tb=short
115
119
 
120
+ # Docker sandbox integration tests (dev-only, opt-in)
121
+ test-docker-sandbox:
122
+ @echo "Running Docker sandbox integration tests (opt-in)..."
123
+ @echo "Pre-req: tactus sandbox rebuild --force"
124
+ TACTUS_RUN_DOCKER_TESTS=1 pytest -m docker -v --tb=short
116
125
 
117
126
 
118
127
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tactus
3
- Version: 0.26.0
3
+ Version: 0.28.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
@@ -636,6 +636,22 @@ researcher({
636
636
 
637
637
  See `examples/14-feature-per-turn-tools.tac` for a complete working example.
638
638
 
639
+ ### Checkpointed Steps (Determinism)
640
+
641
+ For durable execution, any operation that touches external state (randomness, time, APIs not in tools) must be checkpointed. Tactus provides `Step.checkpoint` for this:
642
+
643
+ ```lua
644
+ -- Non-deterministic operation wrapped in checkpoint
645
+ local data = Step.checkpoint(function()
646
+ return http_get("https://api.example.com/data")
647
+ end)
648
+
649
+ -- On replay, the function is NOT called again.
650
+ -- The previously saved 'data' is returned immediately.
651
+ ```
652
+
653
+ This ensures that when a procedure resumes after a pause (e.g. waiting for a human), it doesn't re-execute side effects or get different random values.
654
+
639
655
  ### File I/O Operations
640
656
 
641
657
  Tactus provides safe file I/O operations for reading and writing data files, with all operations restricted to the current working directory for security.
@@ -1085,6 +1101,60 @@ default_provider: openai
1085
1101
  default_model: gpt-4o
1086
1102
  ```
1087
1103
 
1104
+ ### DSPy Integration
1105
+
1106
+ Tactus provides first-class support for **DSPy Modules and Signatures**, enabling you to build declarative, self-optimizing AI components directly within your agent workflows.
1107
+
1108
+ **Modules & Signatures:**
1109
+
1110
+ Instead of hand-tuning prompts, define what you want the model to do using typed signatures:
1111
+
1112
+ ```lua
1113
+ -- Configure the Language Model for DSPy
1114
+ LM("openai/gpt-4o")
1115
+
1116
+ -- Define a module with a typed signature
1117
+ summarizer = Module {
1118
+ signature = "text -> summary",
1119
+ strategy = "chain_of_thought" -- Use Chain of Thought reasoning
1120
+ }
1121
+
1122
+ -- Or define complex signatures with specific fields
1123
+ classifier = Module {
1124
+ signature = Signature {
1125
+ input = {
1126
+ text = field.string{description = "The customer email to classify"}
1127
+ },
1128
+ output = {
1129
+ category = field.string{description = "Support category (Billing, Tech, Sales)"},
1130
+ priority = field.string{description = "Priority level (Low, High, Critical)"}
1131
+ }
1132
+ },
1133
+ strategy = "predict"
1134
+ }
1135
+ ```
1136
+
1137
+ **Using Modules:**
1138
+
1139
+ Modules are callable just like Agents or Tools:
1140
+
1141
+ ```lua
1142
+ Procedure {
1143
+ function(input)
1144
+ -- Call the module
1145
+ local result = classifier({text = input.email})
1146
+
1147
+ if result.priority == "Critical" then
1148
+ human_escalation({context = result})
1149
+ else
1150
+ auto_responder({category = result.category})
1151
+ end
1152
+ end
1153
+ }
1154
+ ```
1155
+
1156
+ This brings the power of DSPy's programmable LLM interfaces into Tactus's durable, orchestrated environment.
1157
+
1088
1158
  ### Asynchronous Execution
1089
1159
 
1090
1160
  Tactus is built on **async I/O** from the ground up, making it ideal for LLM-based workflows where you spend most of your time waiting for API responses.
@@ -1275,6 +1345,21 @@ Then reference them in your procedure:
1275
1345
  local approved = Human.approve("confirm_publish")
1276
1346
  ```
1277
1347
 
1348
+ **System Alerts:**
1349
+
1350
+ Send alerts to your monitoring infrastructure (Datadog, PagerDuty) directly from the workflow:
1351
+
1352
+ ```lua
1353
+ System.alert({
1354
+ message = "Failure rate exceeded threshold",
1355
+ level = "error", -- info, warning, error, critical
1356
+ context = {
1357
+ current_rate = 0.15,
1358
+ threshold = 0.05
1359
+ }
1360
+ })
1361
+ ```
1362
+
1278
1363
  ### Cost Tracking & Metrics
1279
1364
 
1280
1365
  Tactus provides **comprehensive cost and performance tracking** for all LLM calls. Every agent interaction is monitored with detailed metrics, giving you complete visibility into costs, performance, and behavior.
@@ -1360,20 +1445,37 @@ The AI agent space is crowded. This section explains how Tactus differs from alt
1360
1445
 
1361
1446
  ### DSPy
1362
1447
 
1363
- [DSPy](https://dspy.ai) (Declarative Self-improving Python) treats prompting as a compilation target. You define typed signatures and let optimizers automatically discover effective prompts, few-shot examples, or fine-tuning strategies. DSPy excels at tasks where you have training data and clear metrics—classification, RAG, information extraction—and want to programmatically iterate on prompt quality without manual tuning.
1448
+ [DSPy](https://dspy.ai) (Declarative Self-improving Python) is the engine that powers Tactus's intelligence layer. Tactus integrates DSPy directly, allowing you to define DSPy Modules, Signatures, and Optimizers within your `.tac` files using a clean Lua syntax.
1449
+
1450
+ While DSPy provides the primitives for programming with language models (optimizing prompts, few-shot examples, and reasoning steps), Tactus provides the **orchestration layer** that makes these components production-ready:
1364
1451
 
1365
- Tactus takes a different approach: rather than optimizing prompts automatically, it provides a token-efficient, sandboxed language that serves as a safe platform for user-contributed or AI-generated code. Where DSPy hides control flow behind module composition, Tactus makes it explicit—you write the loops, conditionals, and error handling while agents handle intelligence within each turn.
1452
+ - **Durability**: Tactus handles checkpointing and resuming DSPy module calls transparently.
1453
+ - **Orchestration**: Tactus manages the control flow (loops, conditionals) around your DSPy modules.
1454
+ - **Human-in-the-Loop**: Tactus allows humans to inspect, approve, or correct DSPy module outputs.
1455
+ - **Sandboxing**: Tactus runs DSPy components in a safe, sandboxed environment suitable for user-contributed code.
1456
+
1457
+ You can use Tactus to define standard DSPy modules:
1458
+
1459
+ ```lua
1460
+ -- Define a DSPy Module with a typed signature
1461
+ qa = Module {
1462
+ signature = "question -> answer",
1463
+ strategy = "chain_of_thought"
1464
+ }
1465
+
1466
+ -- Invoke it as part of a durable workflow
1467
+ local result = qa({question = "How does this work?"})
1468
+ ```
1366
1469
 
1367
- The frameworks are complementary: you could use DSPy to optimize the prompts that go into a Tactus agent's `system_prompt`, then use Tactus to orchestrate those optimized agents in a durable, human-in-the-loop workflow.
1470
+ Tactus and DSPy work together: DSPy handles the *thinking* (optimizing how to get the best answer), while Tactus handles the *doing* (ensuring the workflow completes reliably, even if it takes days).
1368
1471
 
1369
- | | DSPy | Tactus |
1370
- |-|------|--------|
1371
- | **Core idea** | Programming, not prompting | Token-efficient, AI-manipulable orchestration language |
1372
- | **Optimization** | Automatic (optimizers) | Manual or agent-driven self-evolution |
1373
- | **Control flow** | Declarative composition | Imperative Lua DSL |
1374
- | **Human-in-the-loop** | Not built-in | First-class citizen |
1375
- | **Durability** | Caching | Checkpointing + replay |
1376
- | **Target** | Researchers optimizing prompts | Engineers building production workflows |
1472
+ | | DSPy (Python) | Tactus (Lua) |
1473
+ |---|---|---|
1474
+ | **Role** | Intelligence Engine | Orchestration Engine |
1475
+ | **Focus** | Prompt optimization, reasoning | Durability, HITL, Sandboxing |
1476
+ | **Definition** | Python classes | Lua DSL primitives |
1477
+ | **State** | In-memory | Persisted & Resumable |
1478
+ | **Optimization** | Automatic (Teleprompters) | Agent-driven or Manual |
1377
1479
 
1378
1480
  ### LangGraph
1379
1481
 
@@ -1409,17 +1511,18 @@ The major AI companies have released their own agent frameworks:
1409
1511
 
1410
1512
  - **[Meta Llama Stack](https://ai.meta.com/blog/meta-llama-3-1/)** — Standardized interfaces for building agentic applications with Llama models. More of an API specification than a workflow framework.
1411
1513
 
1412
- These frameworks are valuable if you're committed to a specific vendor's ecosystem. Tactus is model-agnostic (via Pydantic-AI) and designed to run anywhere—local, cloud, or AWS Lambda Durable Functions.
1514
+ These frameworks are valuable if you're committed to a specific vendor's ecosystem. Tactus is model-agnostic (via [DSPy](https://dspy.ai)) and designed to run anywhere—local, cloud, or AWS Lambda Durable Functions.
1413
1515
 
1414
1516
  ### Other Tools
1415
1517
 
1416
- - **[Pydantic-AI](https://github.com/pydantic/pydantic-ai)** — Type-safe LLM integration that Tactus uses under the hood. Tactus adds orchestration, HITL, and durability on top.
1518
+ - **[Pydantic-AI](https://github.com/pydantic/pydantic-ai)** — Used for type-safe tool definitions and message structures.
1417
1519
 
1418
1520
  - **[Guidance](https://github.com/guidance-ai/guidance)** (Microsoft) — Interleaves constrained generation with control flow. Focuses on token-level control during generation rather than workflow orchestration.
1419
1521
 
1420
1522
  ## Complete Feature List
1421
1523
 
1422
1524
  - **Durable Execution**: Automatic position-based checkpointing for all operations (agent turns, model predictions, sub-procedure calls, HITL interactions) with replay-based recovery—resume from exactly where you left off after crashes, timeouts, or pauses
1525
+ - **DSPy Integration**: First-class support for DSPy Modules and Signatures, enabling declarative machine learning components and prompt optimization alongside agentic workflows
1423
1526
  - **Model Primitive**: First-class support for ML inference (PyTorch, HTTP, HuggingFace Transformers) with automatic checkpointing—distinct from conversational agents for classification, prediction, and transformation tasks
1424
1527
  - **Script Mode**: Write procedures without explicit `main` definitions—top-level `input`/`output` declarations and code automatically wrapped as the main procedure
1425
1528
  - **State Management**: Typed, schema-validated persistent state with automatic initialization from defaults and runtime validation
@@ -1434,7 +1537,7 @@ These frameworks are valuable if you're committed to a specific vendor's ecosyst
1434
1537
  - **Context Engineering**: Fine-grained control over conversation history per agent
1435
1538
  - **Typed Input/Output**: JSON Schema validation with UI generation support using `input`/`output`/`state` declarations
1436
1539
  - **Pluggable Backends**: Storage, HITL, and chat recording via Pydantic protocols
1437
- - **LLM Integration**: Works with OpenAI and Bedrock via [pydantic-ai](https://github.com/pydantic/pydantic-ai)
1540
+ - **LLM Integration**: Works with OpenAI and Bedrock via [DSPy](https://dspy.ai)
1438
1541
  - **Standalone CLI**: Run workflows without any infrastructure
1439
1542
  - **Type-Safe**: Pydantic models throughout for validation and type safety
1440
1543
 
@@ -585,6 +585,22 @@ researcher({
585
585
 
586
586
  See `examples/14-feature-per-turn-tools.tac` for a complete working example.
587
587
 
588
+ ### Checkpointed Steps (Determinism)
589
+
590
+ For durable execution, any operation that touches external state (randomness, time, APIs not in tools) must be checkpointed. Tactus provides `Step.checkpoint` for this:
591
+
592
+ ```lua
593
+ -- Non-deterministic operation wrapped in checkpoint
594
+ local data = Step.checkpoint(function()
595
+ return http_get("https://api.example.com/data")
596
+ end)
597
+
598
+ -- On replay, the function is NOT called again.
599
+ -- The previously saved 'data' is returned immediately.
600
+ ```
601
+
602
+ This ensures that when a procedure resumes after a pause (e.g. waiting for a human), it doesn't re-execute side effects or get different random values.
603
+
588
604
  ### File I/O Operations
589
605
 
590
606
  Tactus provides safe file I/O operations for reading and writing data files, with all operations restricted to the current working directory for security.
@@ -1034,6 +1050,60 @@ default_provider: openai
1034
1050
  default_model: gpt-4o
1035
1051
  ```
1036
1052
 
1053
+ ### DSPy Integration
1054
+
1055
+ Tactus provides first-class support for **DSPy Modules and Signatures**, enabling you to build declarative, self-optimizing AI components directly within your agent workflows.
1056
+
1057
+ **Modules & Signatures:**
1058
+
1059
+ Instead of hand-tuning prompts, define what you want the model to do using typed signatures:
1060
+
1061
+ ```lua
1062
+ -- Configure the Language Model for DSPy
1063
+ LM("openai/gpt-4o")
1064
+
1065
+ -- Define a module with a typed signature
1066
+ summarizer = Module {
1067
+ signature = "text -> summary",
1068
+ strategy = "chain_of_thought" -- Use Chain of Thought reasoning
1069
+ }
1070
+
1071
+ -- Or define complex signatures with specific fields
1072
+ classifier = Module {
1073
+ signature = Signature {
1074
+ input = {
1075
+ text = field.string{description = "The customer email to classify"}
1076
+ },
1077
+ output = {
1078
+ category = field.string{description = "Support category (Billing, Tech, Sales)"},
1079
+ priority = field.string{description = "Priority level (Low, High, Critical)"}
1080
+ }
1081
+ },
1082
+ strategy = "predict"
1083
+ }
1084
+ ```
1085
+
1086
+ **Using Modules:**
1087
+
1088
+ Modules are callable just like Agents or Tools:
1089
+
1090
+ ```lua
1091
+ Procedure {
1092
+ function(input)
1093
+ -- Call the module
1094
+ local result = classifier({text = input.email})
1095
+
1096
+ if result.priority == "Critical" then
1097
+ human_escalation({context = result})
1098
+ else
1099
+ auto_responder({category = result.category})
1100
+ end
1101
+ end
1102
+ }
1103
+ ```
1104
+
1105
+ This brings the power of DSPy's programmable LLM interfaces into Tactus's durable, orchestrated environment.
1106
+
1037
1107
  ### Asynchronous Execution
1038
1108
 
1039
1109
  Tactus is built on **async I/O** from the ground up, making it ideal for LLM-based workflows where you spend most of your time waiting for API responses.
@@ -1224,6 +1294,21 @@ Then reference them in your procedure:
1224
1294
  local approved = Human.approve("confirm_publish")
1225
1295
  ```
1226
1296
 
1297
+ **System Alerts:**
1298
+
1299
+ Send alerts to your monitoring infrastructure (Datadog, PagerDuty) directly from the workflow:
1300
+
1301
+ ```lua
1302
+ System.alert({
1303
+ message = "Failure rate exceeded threshold",
1304
+ level = "error", -- info, warning, error, critical
1305
+ context = {
1306
+ current_rate = 0.15,
1307
+ threshold = 0.05
1308
+ }
1309
+ })
1310
+ ```
1311
+
1227
1312
  ### Cost Tracking & Metrics
1228
1313
 
1229
1314
  Tactus provides **comprehensive cost and performance tracking** for all LLM calls. Every agent interaction is monitored with detailed metrics, giving you complete visibility into costs, performance, and behavior.
@@ -1309,20 +1394,37 @@ The AI agent space is crowded. This section explains how Tactus differs from alt
1309
1394
 
1310
1395
  ### DSPy
1311
1396
 
1312
- [DSPy](https://dspy.ai) (Declarative Self-improving Python) treats prompting as a compilation target. You define typed signatures and let optimizers automatically discover effective prompts, few-shot examples, or fine-tuning strategies. DSPy excels at tasks where you have training data and clear metrics—classification, RAG, information extraction—and want to programmatically iterate on prompt quality without manual tuning.
1397
+ [DSPy](https://dspy.ai) (Declarative Self-improving Python) is the engine that powers Tactus's intelligence layer. Tactus integrates DSPy directly, allowing you to define DSPy Modules, Signatures, and Optimizers within your `.tac` files using a clean Lua syntax.
1398
+
1399
+ While DSPy provides the primitives for programming with language models (optimizing prompts, few-shot examples, and reasoning steps), Tactus provides the **orchestration layer** that makes these components production-ready:
1313
1400
 
1314
- Tactus takes a different approach: rather than optimizing prompts automatically, it provides a token-efficient, sandboxed language that serves as a safe platform for user-contributed or AI-generated code. Where DSPy hides control flow behind module composition, Tactus makes it explicit—you write the loops, conditionals, and error handling while agents handle intelligence within each turn.
1401
+ - **Durability**: Tactus handles checkpointing and resuming DSPy module calls transparently.
1402
+ - **Orchestration**: Tactus manages the control flow (loops, conditionals) around your DSPy modules.
1403
+ - **Human-in-the-Loop**: Tactus allows humans to inspect, approve, or correct DSPy module outputs.
1404
+ - **Sandboxing**: Tactus runs DSPy components in a safe, sandboxed environment suitable for user-contributed code.
1405
+
1406
+ You can use Tactus to define standard DSPy modules:
1407
+
1408
+ ```lua
1409
+ -- Define a DSPy Module with a typed signature
1410
+ qa = Module {
1411
+ signature = "question -> answer",
1412
+ strategy = "chain_of_thought"
1413
+ }
1414
+
1415
+ -- Invoke it as part of a durable workflow
1416
+ local result = qa({question = "How does this work?"})
1417
+ ```
1315
1418
 
1316
- The frameworks are complementary: you could use DSPy to optimize the prompts that go into a Tactus agent's `system_prompt`, then use Tactus to orchestrate those optimized agents in a durable, human-in-the-loop workflow.
1419
+ Tactus and DSPy work together: DSPy handles the *thinking* (optimizing how to get the best answer), while Tactus handles the *doing* (ensuring the workflow completes reliably, even if it takes days).
1317
1420
 
1318
- | | DSPy | Tactus |
1319
- |-|------|--------|
1320
- | **Core idea** | Programming, not prompting | Token-efficient, AI-manipulable orchestration language |
1321
- | **Optimization** | Automatic (optimizers) | Manual or agent-driven self-evolution |
1322
- | **Control flow** | Declarative composition | Imperative Lua DSL |
1323
- | **Human-in-the-loop** | Not built-in | First-class citizen |
1324
- | **Durability** | Caching | Checkpointing + replay |
1325
- | **Target** | Researchers optimizing prompts | Engineers building production workflows |
1421
+ | | DSPy (Python) | Tactus (Lua) |
1422
+ |---|---|---|
1423
+ | **Role** | Intelligence Engine | Orchestration Engine |
1424
+ | **Focus** | Prompt optimization, reasoning | Durability, HITL, Sandboxing |
1425
+ | **Definition** | Python classes | Lua DSL primitives |
1426
+ | **State** | In-memory | Persisted & Resumable |
1427
+ | **Optimization** | Automatic (Teleprompters) | Agent-driven or Manual |
1326
1428
 
1327
1429
  ### LangGraph
1328
1430
 
@@ -1358,17 +1460,18 @@ The major AI companies have released their own agent frameworks:
1358
1460
 
1359
1461
  - **[Meta Llama Stack](https://ai.meta.com/blog/meta-llama-3-1/)** — Standardized interfaces for building agentic applications with Llama models. More of an API specification than a workflow framework.
1360
1462
 
1361
- These frameworks are valuable if you're committed to a specific vendor's ecosystem. Tactus is model-agnostic (via Pydantic-AI) and designed to run anywhere—local, cloud, or AWS Lambda Durable Functions.
1463
+ These frameworks are valuable if you're committed to a specific vendor's ecosystem. Tactus is model-agnostic (via [DSPy](https://dspy.ai)) and designed to run anywhere—local, cloud, or AWS Lambda Durable Functions.
1362
1464
 
1363
1465
  ### Other Tools
1364
1466
 
1365
- - **[Pydantic-AI](https://github.com/pydantic/pydantic-ai)** — Type-safe LLM integration that Tactus uses under the hood. Tactus adds orchestration, HITL, and durability on top.
1467
+ - **[Pydantic-AI](https://github.com/pydantic/pydantic-ai)** — Used for type-safe tool definitions and message structures.
1366
1468
 
1367
1469
  - **[Guidance](https://github.com/guidance-ai/guidance)** (Microsoft) — Interleaves constrained generation with control flow. Focuses on token-level control during generation rather than workflow orchestration.
1368
1470
 
1369
1471
  ## Complete Feature List
1370
1472
 
1371
1473
  - **Durable Execution**: Automatic position-based checkpointing for all operations (agent turns, model predictions, sub-procedure calls, HITL interactions) with replay-based recovery—resume from exactly where you left off after crashes, timeouts, or pauses
1474
+ - **DSPy Integration**: First-class support for DSPy Modules and Signatures, enabling declarative machine learning components and prompt optimization alongside agentic workflows
1372
1475
  - **Model Primitive**: First-class support for ML inference (PyTorch, HTTP, HuggingFace Transformers) with automatic checkpointing—distinct from conversational agents for classification, prediction, and transformation tasks
1373
1476
  - **Script Mode**: Write procedures without explicit `main` definitions—top-level `input`/`output` declarations and code automatically wrapped as the main procedure
1374
1477
  - **State Management**: Typed, schema-validated persistent state with automatic initialization from defaults and runtime validation
@@ -1383,7 +1486,7 @@ These frameworks are valuable if you're committed to a specific vendor's ecosyst
1383
1486
  - **Context Engineering**: Fine-grained control over conversation history per agent
1384
1487
  - **Typed Input/Output**: JSON Schema validation with UI generation support using `input`/`output`/`state` declarations
1385
1488
  - **Pluggable Backends**: Storage, HITL, and chat recording via Pydantic protocols
1386
- - **LLM Integration**: Works with OpenAI and Bedrock via [pydantic-ai](https://github.com/pydantic/pydantic-ai)
1489
+ - **LLM Integration**: Works with OpenAI and Bedrock via [DSPy](https://dspy.ai)
1387
1490
  - **Standalone CLI**: Run workflows without any infrastructure
1388
1491
  - **Type-Safe**: Pydantic models throughout for validation and type safety
1389
1492
 
@@ -131,32 +131,69 @@ Control network access for procedures:
131
131
 
132
132
  ```yaml
133
133
  sandbox:
134
- network: "bridge" # Network mode (default: bridge)
134
+ network: "none" # Network mode (default: none)
135
135
 
136
136
  # Options:
137
137
  # - "bridge": Default Docker bridge (allows outbound connections)
138
- # - "none": No network access (most secure, but can't call LLM APIs)
138
+ # - "none": No network access in the runtime container (most secure)
139
139
  # - "host": Use host network (not recommended for security)
140
140
  # - "custom-network": Use a custom Docker network
141
141
  ```
142
142
 
143
- **Security consideration**: Default `bridge` mode allows outbound connections (needed for LLM API calls), but agents could potentially exfiltrate data. See [Sandboxing Guide: Threat Model](./SANDBOXING.md#threat-model) for details.
143
+ With the brokered sandbox runtime, `network: none` can still support LLM calls because the runtime talks to a host-side broker over the configured broker transport (default: `stdio`).
144
+
145
+ If you enable runtime networking (`network != none`), treat that as higher risk and enforce egress controls so the runtime can only reach the broker. See [Sandboxing Guide: Threat Model](./SANDBOXING.md#threat-model).
146
+
147
+ ### Broker Transport
148
+
149
+ Control how the secretless runtime container communicates with the host broker:
150
+
151
+ ```yaml
152
+ sandbox:
153
+ broker_transport: "stdio" # default (works with network: none)
154
+ ```
155
+
156
+ Options:
157
+ - `stdio`: Local Docker MVP; container stays networkless and communicates via the docker attach stdio channel
158
+ - `tcp`: Remote-style connectivity; requires `sandbox.network != none`
159
+ - `tls`: Same as `tcp` but wrapped in TLS; requires `sandbox.network != none`
144
160
 
145
161
  ### Volume Mounts
146
162
 
147
- Mount host directories into the container:
163
+ **Default behavior**: Tactus automatically mounts your current directory to `/workspace:rw`, making it easy for procedures to read and write project files. This is safe because:
164
+ - Container isolation prevents access outside the mounted directory
165
+ - Git provides version control and rollback capability
166
+ - You can review all changes before committing
167
+
168
+ To disable the default mount:
169
+
170
+ ```yaml
171
+ sandbox:
172
+ mount_current_dir: false # Disable automatic current directory mount
173
+ ```
174
+
175
+ **Additional volume mounts**: Mount other host directories into the container:
148
176
 
149
177
  ```yaml
150
178
  sandbox:
151
179
  volumes:
152
180
  - "/host/data:/data:ro" # Read-only mount
153
181
  - "/host/outputs:/outputs:rw" # Read-write mount
154
- - "/shared/config:/config:ro"
182
+ - "../other-repo:/external:ro" # Relative paths supported
155
183
  ```
156
184
 
185
+ **Path resolution**:
186
+ - Relative paths (e.g., `./data`, `../repo`) resolve from the procedure directory
187
+ - `~` expands to your home directory
188
+ - Absolute paths used as-is
189
+
190
+ **Volume modes**:
191
+ - `:ro` - Read-only (safer when you don't need writes)
192
+ - `:rw` - Read-write (default if not specified)
193
+
157
194
  **Default mounts** (always included):
158
- - Workspace: Temporary directory at `/workspace` (ephemeral, destroyed after run)
159
- - MCP Servers: `~/.tactus/mcp-servers` at `/mcp-servers` (read-only)
195
+ - Current directory: `.:/workspace:rw` (unless `mount_current_dir: false`)
196
+ - MCP Servers: `~/.tactus/mcp-servers` at `/mcp-servers` (read-only, if exists)
160
197
 
161
198
  ### Environment Variables
162
199
 
@@ -170,10 +207,7 @@ sandbox:
170
207
  LOG_LEVEL: "info"
171
208
  ```
172
209
 
173
- **Automatically passed through** (no configuration needed):
174
- - `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GOOGLE_API_KEY`
175
- - `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_DEFAULT_REGION`, `AWS_SESSION_TOKEN`
176
- - `AZURE_OPENAI_API_KEY`, `AZURE_OPENAI_ENDPOINT`
210
+ Tactus intentionally blocks common secret env vars from entering the runtime container. For LLM calls, provide credentials to the host/broker side (for example via your shell environment or host-side config loading), not via `sandbox.env`.
177
211
 
178
212
  ### Per-Procedure Sandbox Configuration
179
213
 
@@ -1097,7 +1097,7 @@ class AgentPrimitive:
1097
1097
  )
1098
1098
  return {
1099
1099
  "output": result.output,
1100
- "messages": self.messages
1100
+ "messages": self.messages + result.new_messages()
1101
1101
  }
1102
1102
  ```
1103
1103
 
@@ -1390,4 +1390,4 @@ result = await runtime.execute(
1390
1390
 
1391
1391
  4. **Observability**: Integration with Logfire/OpenTelemetry for tracing?
1392
1392
 
1393
- 5. **Error recovery**: Retry policies, dead letter queues, manual intervention?
1393
+ 5. **Error recovery**: Retry policies, dead letter queues, manual intervention?