phronomy 0.27.0 → 0.28.0

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 (475) hide show
  1. checksums.yaml +4 -4
  2. data/.mutant.yml +9 -9
  3. data/CHANGELOG.md +52 -0
  4. data/CONTRIBUTING.md +8 -8
  5. data/README.md +9 -3
  6. data/benchmark/bench_agent_invoke.rb +25 -50
  7. data/benchmark/bench_context_assembler.rb +14 -11
  8. data/benchmark/bench_regression.rb +1 -1
  9. data/benchmark/bench_tool_schema.rb +1 -1
  10. data/docs/architecture/agent-chat-and-state-ownership.md +7 -1
  11. data/docs/architecture/agent-transition-ownership.md +13 -89
  12. data/docs/architecture/backend-groups.md +152 -0
  13. data/docs/architecture/before-llm-input.md +3 -3
  14. data/docs/architecture/context-management.md +1 -1
  15. data/docs/architecture/execution-abstraction-review.md +88 -0
  16. data/docs/architecture/execution-boundaries.md +28 -0
  17. data/docs/architecture/execution-metadata-and-values.md +6 -0
  18. data/docs/architecture/multi-agent-handoff.md +6 -5
  19. data/docs/architecture/persistence.md +27 -9
  20. data/docs/architecture/r8-unit1.md +104 -0
  21. data/docs/architecture/r8-unit10.md +72 -0
  22. data/docs/architecture/r8-unit11.md +71 -0
  23. data/docs/architecture/r8-unit12.md +67 -0
  24. data/docs/architecture/r8-unit13.md +61 -0
  25. data/docs/architecture/r8-unit14.md +72 -0
  26. data/docs/architecture/r8-unit15.md +65 -0
  27. data/docs/architecture/r8-unit16.md +54 -0
  28. data/docs/architecture/r8-unit17.md +73 -0
  29. data/docs/architecture/r8-unit18.md +92 -0
  30. data/docs/architecture/r8-unit19.md +61 -0
  31. data/docs/architecture/r8-unit2.md +55 -0
  32. data/docs/architecture/r8-unit20.md +51 -0
  33. data/docs/architecture/r8-unit21.md +79 -0
  34. data/docs/architecture/r8-unit22.md +74 -0
  35. data/docs/architecture/r8-unit23.md +81 -0
  36. data/docs/architecture/r8-unit3.md +130 -0
  37. data/docs/architecture/r8-unit4.md +79 -0
  38. data/docs/architecture/r8-unit5.md +115 -0
  39. data/docs/architecture/r8-unit6.md +71 -0
  40. data/docs/architecture/r8-unit7.md +70 -0
  41. data/docs/architecture/r8-unit8.md +78 -0
  42. data/docs/architecture/r8-unit9.md +73 -0
  43. data/docs/architecture/refactoring-closure.md +10 -1
  44. data/docs/architecture/remaining-refactoring-plan.md +16 -0
  45. data/docs/architecture/storage-execution-boundaries.md +54 -0
  46. data/docs/architecture/tool-schema-recording-gap.md +6 -0
  47. data/docs/architecture/tracing.md +1 -1
  48. data/docs/architecture/workflow-terminal-ownership-design.md +2 -2
  49. data/docs/architecture.md +24 -11
  50. data/docs/decisions/015-tool-public-facade-and-rbs-boundary.md +3 -3
  51. data/docs/decisions/027-llm-adapter-provider-boundary.md +2 -0
  52. data/docs/decisions/030-agent-handoff-domain-and-durable-responsibility.md +2 -0
  53. data/docs/decisions/031-durable-multi-agent-coordination.md +2 -0
  54. data/docs/decisions/032-storage-backend-composition.md +5 -0
  55. data/docs/decisions/034-handoff-runner-coordination-ownership.md +2 -0
  56. data/docs/decisions/035-tool-executor-capability-ownership.md +1 -1
  57. data/docs/decisions/038-responsibility-based-source-layout.md +14 -0
  58. data/docs/decisions/039-runtime-configuration-lifecycle-ownership.md +8 -0
  59. data/docs/decisions/040-configuration-default-composition.md +12 -1
  60. data/docs/decisions/045-worker-input-restriction-ownership.md +4 -0
  61. data/docs/decisions/051-execution-outcome-worker-ownership.md +2 -0
  62. data/docs/decisions/056-workflow-terminal-policy-ownership.md +1 -1
  63. data/docs/decisions/058-neutral-storage-primitives.md +5 -0
  64. data/docs/decisions/059-backend-contracts-and-async-clients.md +74 -0
  65. data/docs/decisions/060-runtime-settings-and-application-configuration.md +86 -0
  66. data/docs/decisions/061-persistence-failure-contracts.md +89 -0
  67. data/docs/decisions/062-content-store-service.md +52 -0
  68. data/docs/decisions/063-execution-contracts-and-services.md +88 -0
  69. data/docs/decisions/064-agent-execution-and-multi-agent-responsibility.md +36 -0
  70. data/docs/decisions/065-vector-and-embeddings-common-operations.md +38 -0
  71. data/docs/decisions/066-llm-and-tool-operation-contracts.md +20 -0
  72. data/docs/decisions/067-agent-progress-and-engine-connection.md +29 -0
  73. data/docs/decisions/068-agent-tool-child-progress-and-tool-operation.md +36 -0
  74. data/docs/decisions/README.md +18 -1
  75. data/docs/execution-boundaries-preview.md +45 -0
  76. data/docs/features.md +8 -3
  77. data/docs/getting-started.md +9 -6
  78. data/docs/migrations/0.22.md +2 -2
  79. data/docs/migrations/durable-semantic-coordination-v2.md +2 -0
  80. data/docs/migrations/handoff-runner-multi-agent.md +2 -0
  81. data/docs/migrations/persistence-failure-contracts.md +67 -0
  82. data/docs/migrations/r8-unit10.md +36 -0
  83. data/docs/migrations/r8-unit11.md +33 -0
  84. data/docs/migrations/r8-unit12.md +31 -0
  85. data/docs/migrations/r8-unit13.md +36 -0
  86. data/docs/migrations/r8-unit14.md +31 -0
  87. data/docs/migrations/r8-unit15.md +31 -0
  88. data/docs/migrations/r8-unit16.md +26 -0
  89. data/docs/migrations/r8-unit17.md +28 -0
  90. data/docs/migrations/r8-unit18.md +29 -0
  91. data/docs/migrations/r8-unit19.md +28 -0
  92. data/docs/migrations/r8-unit20.md +24 -0
  93. data/docs/migrations/r8-unit21.md +28 -0
  94. data/docs/migrations/r8-unit22.md +29 -0
  95. data/docs/migrations/r8-unit23.md +20 -0
  96. data/docs/migrations/r8-unit4.md +67 -0
  97. data/docs/migrations/r8-unit5.md +75 -0
  98. data/docs/migrations/r8-unit6.md +109 -0
  99. data/docs/migrations/r8-unit7.md +31 -0
  100. data/docs/migrations/r8-unit8.md +33 -0
  101. data/docs/migrations/r8-unit9.md +28 -0
  102. data/docs/migrations/storage-async-client.md +103 -0
  103. data/docs/migrations/vector-async-clients.md +110 -0
  104. data/docs/persistence-backends.md +38 -21
  105. data/docs/runtime-and-concurrency.md +26 -1
  106. data/lib/phronomy/agent/admission.rb +78 -0
  107. data/lib/phronomy/agent/{lifecycle_contract/agent_already_exists_error.rb → agent_already_exists_error.rb} +1 -1
  108. data/lib/phronomy/agent/{lifecycle_contract/agent_busy_error.rb → agent_busy_error.rb} +1 -1
  109. data/lib/phronomy/agent/{lifecycle_contract/agent_purged_error.rb → agent_purged_error.rb} +1 -1
  110. data/lib/phronomy/{recovery → agent/api}/execution_rehydration_required_error.rb +1 -1
  111. data/lib/phronomy/agent/async_event_api.rb +37 -32
  112. data/lib/phronomy/agent/base.rb +74 -72
  113. data/lib/phronomy/agent/before_llm_input.rb +64 -0
  114. data/lib/phronomy/agent/composition/run_once.rb +1 -1
  115. data/lib/phronomy/agent/{context_assembly/context_candidate_resolver.rb → context_candidate_resolver.rb} +2 -2
  116. data/lib/phronomy/agent/{context_assembly/context_assembler.rb → context_preparation.rb} +35 -221
  117. data/lib/phronomy/agent/control_request.rb +21 -0
  118. data/lib/phronomy/agent/execution/agent_execution.rb +1 -1
  119. data/lib/phronomy/agent/execution/agent_invocation.rb +27 -53
  120. data/lib/phronomy/agent/execution/approval_resume_commit.rb +1 -1
  121. data/lib/phronomy/agent/execution/dispatch_preparation.rb +17 -127
  122. data/lib/phronomy/agent/execution/exact_execution.rb +44 -23
  123. data/lib/phronomy/agent/execution/execution_cancellation.rb +8 -4
  124. data/lib/phronomy/agent/execution/execution_coordinator.rb +214 -395
  125. data/lib/phronomy/agent/execution/execution_metadata.rb +1 -0
  126. data/lib/phronomy/agent/execution/execution_outcome_committer.rb +70 -126
  127. data/lib/phronomy/agent/execution/execution_registry.rb +6 -2
  128. data/lib/phronomy/agent/execution/execution_session_runner.rb +22 -27
  129. data/lib/phronomy/agent/execution/initial_preparation.rb +18 -116
  130. data/lib/phronomy/agent/execution/{agent_invocation_session_builder.rb → invocation_actions.rb} +54 -194
  131. data/lib/phronomy/agent/execution/invocation_transitions.rb +39 -1
  132. data/lib/phronomy/agent/execution/runtime_record_encoder.rb +7 -7
  133. data/lib/phronomy/agent/execution_change.rb +161 -0
  134. data/lib/phronomy/agent/execution_environment.rb +36 -0
  135. data/lib/phronomy/agent/execution_extension_state.rb +21 -0
  136. data/lib/phronomy/agent/execution_observation.rb +35 -0
  137. data/lib/phronomy/agent/filterable.rb +182 -0
  138. data/lib/phronomy/agent/handoff/{handoff_context.rb → transfer_context.rb} +4 -4
  139. data/lib/phronomy/agent/handoff/{handoff_projection.rb → transfer_projection.rb} +14 -33
  140. data/lib/phronomy/{llm_contract/transport_error.rb → agent/handoff_error.rb} +1 -1
  141. data/lib/phronomy/agent/journal/journal_projection.rb +1 -1
  142. data/lib/phronomy/agent/knowledge_item.rb +13 -0
  143. data/lib/phronomy/agent/lifecycle/agent_root.rb +1 -1
  144. data/lib/phronomy/agent/lifecycle/ownership_registry.rb +18 -23
  145. data/lib/phronomy/agent/persistence/agent_repository.rb +29 -21
  146. data/lib/phronomy/agent/persistence/cancellation_repository.rb +51 -0
  147. data/lib/phronomy/agent/persistence/codec.rb +1 -21
  148. data/lib/phronomy/agent/persistence/execution_repository.rb +57 -41
  149. data/lib/phronomy/agent/persistence/journal_repository.rb +27 -18
  150. data/lib/phronomy/agent/persistence/records.rb +33 -0
  151. data/lib/phronomy/agent/persistence/retention_repository.rb +70 -0
  152. data/lib/phronomy/agent/persistence/storage_schema.rb +7 -2
  153. data/lib/phronomy/agent/persistence/watermark.rb +13 -11
  154. data/lib/phronomy/agent/recovery/invocation_restorer.rb +13 -21
  155. data/lib/phronomy/agent/recovery/recovery_coordinator/continuation.rb +10 -9
  156. data/lib/phronomy/agent/recovery/recovery_coordinator/installation.rb +27 -27
  157. data/lib/phronomy/agent/recovery/recovery_coordinator/resolution.rb +19 -21
  158. data/lib/phronomy/agent/recovery/recovery_coordinator.rb +23 -16
  159. data/lib/phronomy/agent/recovery/recovery_rules.rb +119 -0
  160. data/lib/phronomy/agent/recovery/recovery_support.rb +8 -11
  161. data/lib/phronomy/agent/reserved_execution.rb +16 -0
  162. data/lib/phronomy/agent/retention.rb +17 -0
  163. data/lib/phronomy/agent/runtime_binding/engine_environment.rb +60 -0
  164. data/lib/phronomy/agent/runtime_binding/engine_session_builder.rb +34 -0
  165. data/lib/phronomy/agent/runtime_binding/phase_machine_builder.rb +64 -0
  166. data/lib/phronomy/agent/runtime_binding/tool_session_builder.rb +34 -0
  167. data/lib/phronomy/agent/{context_assembly/ruby_llm_materializer.rb → runtime_input.rb} +18 -35
  168. data/lib/phronomy/agent/{context_assembly/saved_context_reader.rb → saved_context_reader.rb} +6 -4
  169. data/lib/phronomy/agent/settings.rb +47 -0
  170. data/lib/phronomy/agent/{context_assembly/state_writer.rb → state_writer.rb} +4 -3
  171. data/lib/phronomy/agent/store.rb +253 -0
  172. data/lib/phronomy/agent/{lifecycle_contract/stream_callback_error.rb → stream_callback_error.rb} +1 -1
  173. data/lib/phronomy/agent/tool_execution/tool_binding.rb +4 -64
  174. data/lib/phronomy/agent/tool_execution/tool_invocation.rb +50 -219
  175. data/lib/phronomy/agent/tool_execution/tool_invocation_actions.rb +107 -0
  176. data/lib/phronomy/agent/tool_execution/tool_invocation_transitions.rb +70 -0
  177. data/lib/phronomy/configuration/runtime_settings.rb +49 -0
  178. data/lib/phronomy/content_store/storage_schema.rb +1 -0
  179. data/lib/phronomy/content_store/stored_contents.rb +2 -1
  180. data/lib/phronomy/context/assembly.rb +202 -0
  181. data/lib/phronomy/{llm_contract/context_budget_exceeded_error.rb → context/budget_exceeded_error.rb} +3 -1
  182. data/lib/phronomy/context/candidate.rb +51 -0
  183. data/lib/phronomy/context/constraint.rb +47 -0
  184. data/lib/phronomy/{agent/context_contract → context}/context_plan.rb +1 -1
  185. data/lib/phronomy/{agent/context_contract → context}/context_plan_validator.rb +3 -3
  186. data/lib/phronomy/{agent/context_contract → context}/context_policy.rb +1 -1
  187. data/lib/phronomy/{agent/context_contract → context}/context_policy_input.rb +1 -1
  188. data/lib/phronomy/{agent/context_assembly → context}/context_policy_input_builder.rb +1 -1
  189. data/lib/phronomy/context/default_policy.rb +140 -0
  190. data/lib/phronomy/context/final_budget_validator.rb +33 -0
  191. data/lib/phronomy/{agent/context_contract → context}/llm_input_build_context.rb +1 -1
  192. data/lib/phronomy/{agent/context_contract → context}/llm_input_manifest.rb +19 -19
  193. data/lib/phronomy/{agent/context_contract → context}/llm_input_patch.rb +1 -1
  194. data/lib/phronomy/context/manifest_error.rb +10 -0
  195. data/lib/phronomy/context/prompt_template.rb +98 -0
  196. data/lib/phronomy/{vector_store → documents}/loader/base.rb +1 -1
  197. data/lib/phronomy/{vector_store → documents}/loader/csv_loader.rb +2 -2
  198. data/lib/phronomy/{vector_store → documents}/loader/markdown_loader.rb +3 -3
  199. data/lib/phronomy/{vector_store → documents}/loader/plain_text_loader.rb +2 -2
  200. data/lib/phronomy/{vector_store → documents}/splitter/base.rb +1 -1
  201. data/lib/phronomy/{vector_store → documents}/splitter/fixed_size_splitter.rb +2 -2
  202. data/lib/phronomy/{vector_store → documents}/splitter/recursive_splitter.rb +2 -2
  203. data/lib/phronomy/embeddings/async/async_client.rb +44 -0
  204. data/lib/phronomy/embeddings/backends/ruby_llm_embeddings.rb +48 -0
  205. data/lib/phronomy/embeddings/base.rb +43 -0
  206. data/lib/phronomy/embeddings/invalid_result_error.rb +11 -0
  207. data/lib/phronomy/embeddings/transport_error.rb +11 -0
  208. data/lib/phronomy/engine/concurrency/offload_pool.rb +36 -21
  209. data/lib/phronomy/engine/concurrency/pool_registry.rb +47 -12
  210. data/lib/phronomy/engine/diagnostics.rb +1 -1
  211. data/lib/phronomy/engine/event_loop.rb +7 -7
  212. data/lib/phronomy/engine/execution_binding.rb +23 -0
  213. data/lib/phronomy/engine/execution_receiver_binding.rb +43 -0
  214. data/lib/phronomy/engine/fsm_protocol.rb +1 -6
  215. data/lib/phronomy/engine/fsm_session.rb +3 -3
  216. data/lib/phronomy/engine/metrics.rb +16 -14
  217. data/lib/phronomy/engine/runtime/timer_queue.rb +1 -1
  218. data/lib/phronomy/engine/runtime.rb +25 -12
  219. data/lib/phronomy/engine/terminal_decision.rb +7 -0
  220. data/lib/phronomy/execution/async_operation.rb +41 -0
  221. data/lib/phronomy/{engine → execution}/blocking.rb +2 -2
  222. data/lib/phronomy/{engine → execution}/concurrency/cancellation_token.rb +1 -1
  223. data/lib/phronomy/{engine → execution}/concurrency/deadline.rb +0 -17
  224. data/lib/phronomy/{engine → execution}/concurrency/physical_completion_task.rb +1 -1
  225. data/lib/phronomy/{engine → execution}/concurrency/result_collector.rb +1 -1
  226. data/lib/phronomy/{engine → execution}/concurrency/result_composition.rb +33 -12
  227. data/lib/phronomy/{engine/concurrency/subscriptions.rb → execution/concurrency/result_subscriptions.rb} +14 -18
  228. data/lib/phronomy/execution/concurrency/subscriptions.rb +25 -0
  229. data/lib/phronomy/{engine → execution}/execution.rb +61 -27
  230. data/lib/phronomy/execution/execution_receiver.rb +78 -0
  231. data/lib/phronomy/execution/execution_scope_state.rb +35 -0
  232. data/lib/phronomy/{engine → execution}/invocation_context.rb +0 -15
  233. data/lib/phronomy/execution/invocation_controls.rb +73 -0
  234. data/lib/phronomy/execution/runnable.rb +24 -0
  235. data/lib/phronomy/{engine → execution}/task_result.rb +3 -3
  236. data/lib/phronomy/execution/wait_policy.rb +24 -0
  237. data/lib/phronomy/filter/{contract/filter_block_error.rb → filter_block_error.rb} +1 -1
  238. data/lib/phronomy/generation/generator_verifier/agent_operation.rb +65 -0
  239. data/lib/phronomy/generation/generator_verifier/default_parser.rb +27 -0
  240. data/lib/phronomy/generation/generator_verifier/workflow_builder.rb +2 -2
  241. data/lib/phronomy/generation/generator_verifier.rb +7 -7
  242. data/lib/phronomy/llm_adapter/async/async_client.rb +47 -0
  243. data/lib/phronomy/{llm_contract → llm_adapter}/authentication_error.rb +3 -1
  244. data/lib/phronomy/llm_adapter/backends/ruby_llm.rb +183 -0
  245. data/lib/phronomy/llm_adapter/base.rb +49 -68
  246. data/lib/phronomy/{llm_contract → llm_adapter}/context_length_error.rb +3 -1
  247. data/lib/phronomy/llm_adapter/invalid_result_error.rb +10 -0
  248. data/lib/phronomy/llm_adapter/message.rb +62 -0
  249. data/lib/phronomy/{llm_contract → llm_adapter}/rate_limit_error.rb +3 -1
  250. data/lib/phronomy/llm_adapter/request.rb +79 -0
  251. data/lib/phronomy/llm_adapter/response.rb +36 -0
  252. data/lib/phronomy/llm_adapter/stream_chunk.rb +18 -0
  253. data/lib/phronomy/llm_adapter/token_usage.rb +64 -0
  254. data/lib/phronomy/llm_adapter/transport_error.rb +9 -0
  255. data/lib/phronomy/llm_adapter.rb +3 -16
  256. data/lib/phronomy/multi_agent/admission_registry.rb +1 -8
  257. data/lib/phronomy/multi_agent/durable_subagent_coordinator.rb +108 -84
  258. data/lib/phronomy/multi_agent/execution_environment.rb +29 -0
  259. data/lib/phronomy/{agent/handoff → multi_agent}/handoff.rb +2 -2
  260. data/lib/phronomy/{agent/handoff → multi_agent}/handoff_capability_factory.rb +21 -2
  261. data/lib/phronomy/multi_agent/handoff_participant.rb +79 -0
  262. data/lib/phronomy/{agent/handoff → multi_agent}/handoff_policy.rb +1 -1
  263. data/lib/phronomy/multi_agent/handoff_runner.rb +77 -100
  264. data/lib/phronomy/{agent/handoff → multi_agent}/handoff_state.rb +1 -1
  265. data/lib/phronomy/multi_agent/orchestrator.rb +61 -75
  266. data/lib/phronomy/multi_agent/persistence/codec.rb +20 -0
  267. data/lib/phronomy/multi_agent/persistence/handoff_state_repository.rb +77 -0
  268. data/lib/phronomy/multi_agent/persistence/records.rb +27 -0
  269. data/lib/phronomy/multi_agent/persistence/storage_schema.rb +21 -0
  270. data/lib/phronomy/multi_agent/persistence/team_execution_repository.rb +58 -42
  271. data/lib/phronomy/multi_agent/persistence/team_repository.rb +29 -21
  272. data/lib/phronomy/multi_agent/reserved_child_admission.rb +88 -0
  273. data/lib/phronomy/multi_agent/runtime_binding/engine_environment.rb +35 -0
  274. data/lib/phronomy/multi_agent/shared_state.rb +2 -2
  275. data/lib/phronomy/multi_agent/store.rb +156 -0
  276. data/lib/phronomy/multi_agent/team_coordinator.rb +83 -74
  277. data/lib/phronomy/multi_agent/team_ownership_registry.rb +2 -12
  278. data/lib/phronomy/output_parser/parse_error.rb +7 -0
  279. data/lib/phronomy/persistence/content_repository.rb +26 -0
  280. data/lib/phronomy/persistence/errors.rb +16 -0
  281. data/lib/phronomy/persistence/migration/initial_format_migration.rb +2 -2
  282. data/lib/phronomy/persistence/persistence.rb +23 -0
  283. data/lib/phronomy/persistence/save_outcome.rb +24 -0
  284. data/lib/phronomy/persistence/snapshot_comparison.rb +81 -0
  285. data/lib/phronomy/persistence/storage_boundary.rb +32 -0
  286. data/lib/phronomy/persistence/transaction.rb +86 -0
  287. data/lib/phronomy/persistence_composition/storage_schema.rb +9 -4
  288. data/lib/phronomy/persistence_composition/stores.rb +34 -0
  289. data/lib/phronomy/persistence_composition/unit4_migration.rb +276 -0
  290. data/lib/phronomy/runtime_composition/agent_defaults.rb +5 -1
  291. data/lib/phronomy/runtime_composition/configuration.rb +146 -0
  292. data/lib/phronomy/runtime_composition/evaluation_defaults.rb +7 -0
  293. data/lib/phronomy/runtime_composition/execution_defaults.rb +5 -0
  294. data/lib/phronomy/runtime_composition/generation_defaults.rb +6 -0
  295. data/lib/phronomy/runtime_composition/global_configuration.rb +38 -0
  296. data/lib/phronomy/runtime_composition/multi_agent_defaults.rb +9 -0
  297. data/lib/phronomy/runtime_composition/workflow_defaults.rb +4 -0
  298. data/lib/phronomy/storage/async/async_client.rb +60 -0
  299. data/lib/phronomy/storage/backend.rb +8 -2
  300. data/lib/phronomy/testing/eval/metrics.rb +1 -1
  301. data/lib/phronomy/testing/eval/scorer/llm_judge.rb +19 -3
  302. data/lib/phronomy/testing/persistence_contract/a_content_store.rb +2 -2
  303. data/lib/phronomy/testing/persistence_contract/a_journal_repository.rb +6 -6
  304. data/lib/phronomy/testing/persistence_contract/a_persistence_backend.rb +55 -52
  305. data/lib/phronomy/testing/persistence_contract/a_workflow_state_repository.rb +3 -3
  306. data/lib/phronomy/testing/persistence_contract/an_agent_repository.rb +7 -7
  307. data/lib/phronomy/testing/persistence_contract/an_execution_repository.rb +11 -11
  308. data/lib/phronomy/testing/persistence_contract/coordination_repositories.rb +57 -51
  309. data/lib/phronomy/testing/persistence_contract/neutral_storage_primitives.rb +1 -1
  310. data/lib/phronomy/testing/persistence_contract/storage_transaction_boundaries.rb +23 -22
  311. data/lib/phronomy/tool/authorization.rb +77 -0
  312. data/lib/phronomy/tool/base.rb +549 -9
  313. data/lib/phronomy/tool/call_request.rb +40 -0
  314. data/lib/phronomy/{agent/tool_execution/tool_definition_set.rb → tool/definition_set.rb} +7 -8
  315. data/lib/phronomy/tool/operation.rb +88 -0
  316. data/lib/phronomy/tool/schema.rb +214 -0
  317. data/lib/phronomy/tool/settings.rb +31 -0
  318. data/lib/phronomy/tool/tool_error.rb +7 -0
  319. data/lib/phronomy/tool/tool_executor.rb +58 -0
  320. data/lib/phronomy/tools/agent.rb +22 -90
  321. data/lib/phronomy/tools/mcp.rb +21 -14
  322. data/lib/phronomy/tools/vector_search.rb +4 -4
  323. data/lib/phronomy/tracing/automatic.rb +11 -6
  324. data/lib/phronomy/tracing/base.rb +1 -1
  325. data/lib/phronomy/tracing/observation.rb +37 -0
  326. data/lib/phronomy/tracing/settings.rb +36 -0
  327. data/lib/phronomy/vector_store/{async_backend.rb → async/async_client.rb} +35 -29
  328. data/lib/phronomy/vector_store/{in_memory.rb → backends/in_memory.rb} +12 -10
  329. data/lib/phronomy/vector_store/{pgvector.rb → backends/pgvector.rb} +44 -16
  330. data/lib/phronomy/vector_store/{redis_search.rb → backends/redis_search.rb} +74 -37
  331. data/lib/phronomy/vector_store/base.rb +118 -49
  332. data/lib/phronomy/vector_store/invalid_result_error.rb +12 -0
  333. data/lib/phronomy/vector_store.rb +2 -17
  334. data/lib/phronomy/version.rb +1 -1
  335. data/lib/phronomy/workflow/completion.rb +11 -0
  336. data/lib/phronomy/workflow/execution/workflow.rb +7 -7
  337. data/lib/phronomy/workflow/execution/workflow_action_rules.rb +67 -0
  338. data/lib/phronomy/workflow/execution/workflow_context.rb +2 -2
  339. data/lib/phronomy/workflow/execution/workflow_execution_environment.rb +27 -0
  340. data/lib/phronomy/workflow/execution/workflow_execution_registry.rb +3 -5
  341. data/lib/phronomy/workflow/execution/workflow_runner.rb +58 -79
  342. data/lib/phronomy/workflow/execution/workflow_settings.rb +28 -0
  343. data/lib/phronomy/workflow/persistence/state_repository.rb +28 -22
  344. data/lib/phronomy/workflow/persistence/storage_schema.rb +13 -0
  345. data/lib/phronomy/workflow/runtime_binding/workflow_engine_environment.rb +38 -0
  346. data/lib/phronomy/workflow/runtime_binding/workflow_phase_machine_builder.rb +156 -0
  347. data/lib/phronomy/workflow/{execution → runtime_binding}/workflow_terminal_policy.rb +4 -4
  348. data/lib/phronomy.rb +57 -16
  349. data/scripts/api_snapshot.rb +35 -15
  350. data/sig/_private/phronomy/agent/settings.rbs +19 -0
  351. data/sig/_private/phronomy/configuration/runtime_settings.rbs +20 -0
  352. data/sig/_private/phronomy/llm_adapter/async/async_client.rbs +10 -0
  353. data/sig/_private/phronomy/multi_agent/store.rbs +8 -0
  354. data/sig/_private/phronomy/persistence/storage_boundary.rbs +7 -0
  355. data/sig/_private/phronomy/tool/settings.rbs +13 -0
  356. data/sig/_private/phronomy/tracing/settings.rbs +15 -0
  357. data/sig/_private/phronomy/workflow/execution/workflow_settings.rbs +13 -0
  358. data/sig/phronomy/agent/admission.rbs +19 -0
  359. data/sig/phronomy/agent/execution_contract.rbs +132 -0
  360. data/sig/phronomy/agent/execution_environment.rbs +20 -0
  361. data/sig/phronomy/agent/store.rbs +73 -0
  362. data/sig/phronomy/agent.rbs +14 -138
  363. data/sig/phronomy/common.rbs +7 -0
  364. data/sig/phronomy/content_store/contracts.rbs +13 -0
  365. data/sig/phronomy/context.rbs +152 -0
  366. data/sig/phronomy/embeddings/async/async_client.rbs +9 -0
  367. data/sig/phronomy/embeddings/base.rbs +17 -0
  368. data/sig/phronomy/engine/concurrency/timer_bindings.rbs +22 -0
  369. data/sig/phronomy/engine/control_bindings.rbs +11 -0
  370. data/sig/phronomy/engine/control_protocols.rbs +23 -0
  371. data/sig/phronomy/engine/execution_binding.rbs +6 -0
  372. data/sig/phronomy/engine/execution_receiver.rbs +15 -0
  373. data/sig/phronomy/engine/observability.rbs +13 -0
  374. data/sig/phronomy/execution/async_operation.rbs +7 -0
  375. data/sig/phronomy/execution/blocking.rbs +5 -0
  376. data/sig/phronomy/execution/concurrency/cancellation_token.rbs +13 -0
  377. data/sig/phronomy/execution/concurrency/deadline.rbs +10 -0
  378. data/sig/phronomy/execution/concurrency/result_composition.rbs +7 -0
  379. data/sig/phronomy/execution/control_protocols.rbs +18 -0
  380. data/sig/phronomy/execution/errors.rbs +7 -0
  381. data/sig/phronomy/execution/execution.rbs +41 -0
  382. data/sig/phronomy/execution/execution_receiver.rbs +40 -0
  383. data/sig/phronomy/execution/execution_scope_state.rbs +9 -0
  384. data/sig/phronomy/execution/invocation_context.rbs +18 -0
  385. data/sig/phronomy/execution/invocation_controls.rbs +13 -0
  386. data/sig/phronomy/execution/task_result.rbs +29 -0
  387. data/sig/phronomy/extensions.rbs +0 -21
  388. data/sig/phronomy/handoff.rbs +10 -4
  389. data/sig/phronomy/llm_adapter/backends/ruby_llm.rbs +6 -0
  390. data/sig/phronomy/llm_adapter/base.rbs +14 -0
  391. data/sig/phronomy/llm_adapter/usage.rbs +14 -0
  392. data/sig/phronomy/llm_adapter/values.rbs +43 -0
  393. data/sig/phronomy/llm_context_window.rbs +10 -0
  394. data/sig/phronomy/multi_agent/reserved_child_admission.rbs +8 -0
  395. data/sig/phronomy/multi_agent/store.rbs +54 -0
  396. data/sig/phronomy/multi_agent.rbs +6 -3
  397. data/sig/phronomy/persistence/errors.rbs +18 -0
  398. data/sig/phronomy/persistence/migration.rbs +13 -0
  399. data/sig/phronomy/persistence/transaction.rbs +19 -0
  400. data/sig/phronomy/persistence.rbs +1 -99
  401. data/sig/phronomy/persistence_composition.rbs +19 -0
  402. data/sig/phronomy/runtime_composition/configuration.rbs +36 -0
  403. data/sig/phronomy/storage/async/async_client.rbs +8 -0
  404. data/sig/phronomy/storage/backends/in_memory.rbs +9 -0
  405. data/sig/phronomy/{storage.rbs → storage/contracts.rbs} +2 -16
  406. data/sig/phronomy/tool.rbs +48 -4
  407. data/sig/phronomy/tracing/observation.rbs +7 -0
  408. data/sig/phronomy/vector_store/async/async_client.rbs +13 -0
  409. data/sig/phronomy/vector_store/base.rbs +23 -0
  410. data/sig/phronomy/workflow/execution/workflow_execution_environment.rbs +14 -0
  411. data/sig/phronomy/workflow/runtime_binding/workflow_terminal_policy.rbs +7 -0
  412. data/sig/phronomy/workflow/store.rbs +8 -0
  413. data/sig/phronomy/workflow.rbs +1 -1
  414. data/sig/phronomy.rbs +0 -49
  415. metadata +318 -117
  416. data/lib/phronomy/agent/concerns/before_llm_input.rb +0 -66
  417. data/lib/phronomy/agent/concerns/error_translation.rb +0 -45
  418. data/lib/phronomy/agent/concerns/filterable.rb +0 -184
  419. data/lib/phronomy/agent/context/capability/base.rb +0 -548
  420. data/lib/phronomy/agent/context/capability/tool_executor.rb +0 -62
  421. data/lib/phronomy/agent/context/instruction/prompt_template.rb +0 -102
  422. data/lib/phronomy/agent/context_assembly/runtime_chat_builder.rb +0 -36
  423. data/lib/phronomy/agent/context_assembly/token_budget_resolver.rb +0 -22
  424. data/lib/phronomy/agent/context_parts/validators/final_budget_validator.rb +0 -37
  425. data/lib/phronomy/agent/context_policies/default.rb +0 -142
  426. data/lib/phronomy/agent/execution/phase_machine_builder.rb +0 -101
  427. data/lib/phronomy/agent/execution/provider_call_outcome.rb +0 -106
  428. data/lib/phronomy/agent/handoff/handoff_execution_coordinator.rb +0 -15
  429. data/lib/phronomy/agent/handoff/handoff_outcome_committer.rb +0 -131
  430. data/lib/phronomy/agent/handoff/handoff_request.rb +0 -45
  431. data/lib/phronomy/agent/lifecycle_contract/handoff_error.rb +0 -7
  432. data/lib/phronomy/agent/persistence/handoff_state_repository.rb +0 -58
  433. data/lib/phronomy/agent/persistence/queries.rb +0 -61
  434. data/lib/phronomy/agent/selection/candidate.rb +0 -53
  435. data/lib/phronomy/agent/selection/constraint.rb +0 -49
  436. data/lib/phronomy/agent/tool_execution/tool_call_intercepted.rb +0 -29
  437. data/lib/phronomy/agent/tool_execution/tool_invocation_session_builder.rb +0 -276
  438. data/lib/phronomy/configuration/configuration.rb +0 -68
  439. data/lib/phronomy/configuration/global_configuration.rb +0 -26
  440. data/lib/phronomy/engine/concurrency/cancellation_scope.rb +0 -124
  441. data/lib/phronomy/engine/concurrency/operation_binding.rb +0 -43
  442. data/lib/phronomy/engine/execution_receiver.rb +0 -65
  443. data/lib/phronomy/engine/runnable.rb +0 -54
  444. data/lib/phronomy/llm_adapter/ruby_llm.rb +0 -47
  445. data/lib/phronomy/llm_contract/token_usage.rb +0 -85
  446. data/lib/phronomy/multi_agent/persistence/queries.rb +0 -30
  447. data/lib/phronomy/multi_agent/storage_contract/team_storage_schema.rb +0 -15
  448. data/lib/phronomy/output_parser/contract/parse_error.rb +0 -7
  449. data/lib/phronomy/persistence/api/persistence.rb +0 -140
  450. data/lib/phronomy/persistence_composition/repositories.rb +0 -77
  451. data/lib/phronomy/recovery/recovery.rb +0 -186
  452. data/lib/phronomy/tool/contract/tool_error.rb +0 -7
  453. data/lib/phronomy/vector_store/embeddings/base.rb +0 -44
  454. data/lib/phronomy/vector_store/embeddings/ruby_llm_embeddings.rb +0 -47
  455. data/lib/phronomy/workflow/phase_machine_builder.rb +0 -205
  456. data/lib/phronomy/workflow/storage_contract/workflow_storage_schema.rb +0 -9
  457. data/sig/phronomy/execution_receiver.rbs +0 -34
  458. data/sig/phronomy/llm_adapter.rbs +0 -11
  459. data/sig/phronomy/runtime.rbs +0 -76
  460. /data/lib/phronomy/agent/{context_assembly/context_importer.rb → context_importer.rb} +0 -0
  461. /data/lib/phronomy/{engine → execution}/backpressure_error.rb +0 -0
  462. /data/lib/phronomy/{engine → execution}/cancellation_error.rb +0 -0
  463. /data/lib/phronomy/{engine → execution}/concurrency/worker_input_restricted.rb +0 -0
  464. /data/lib/phronomy/{engine → execution}/event_loop_reentrancy_error.rb +0 -0
  465. /data/lib/phronomy/{engine → execution}/execution_cancellation_error.rb +0 -0
  466. /data/lib/phronomy/{engine → execution}/execution_timeout_error.rb +0 -0
  467. /data/lib/phronomy/{engine → execution}/invalid_async_entry_action_error.rb +0 -0
  468. /data/lib/phronomy/{engine → execution}/invalid_async_transition_action_error.rb +0 -0
  469. /data/lib/phronomy/{engine → execution}/invalid_async_workflow_action_error.rb +0 -0
  470. /data/lib/phronomy/{engine → execution}/pool_shutdown_error.rb +0 -0
  471. /data/lib/phronomy/{engine → execution}/recursion_limit_error.rb +0 -0
  472. /data/lib/phronomy/{engine → execution}/runtime_shutdown_error.rb +0 -0
  473. /data/lib/phronomy/{engine → execution}/runtime_shutdown_reentrancy_error.rb +0 -0
  474. /data/lib/phronomy/{engine → execution}/scheduler_reentrancy_error.rb +0 -0
  475. /data/lib/phronomy/{engine → execution}/timeout_error.rb +0 -0
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../engine/concurrency/worker_input_restricted"
3
+ require_relative "../../execution/concurrency/worker_input_restricted"
4
4
 
5
5
  require "time"
6
6
  require "securerandom"
@@ -14,7 +14,7 @@ module Phronomy
14
14
  StartCommand = Data.define(
15
15
  :coordinator, :input, :config, :mode,
16
16
  :approval_policy, :approval_listener, :on_event, :result_task,
17
- :admission_token
17
+ :admission_token, :controls
18
18
  )
19
19
  ResumeCommand = Data.define(
20
20
  :coordinator, :execution_id, :approval_request_id,
@@ -39,10 +39,7 @@ module Phronomy
39
39
  InitialPreparationCommand = InitialPreparation::Command
40
40
  ProviderDispatchPreparationCommand = DispatchPreparation::ProviderCommand
41
41
  ToolDispatchPreparationCommand = DispatchPreparation::ToolCommand
42
- ProviderDispatchPreparationReconciliationCommand = DispatchPreparation::ProviderReconciliationCommand
43
- ToolDispatchPreparationReconciliationCommand = DispatchPreparation::ToolReconciliationCommand
44
42
  ResumeCommitCommand = ApprovalResumeCommit::Command
45
- HandoffTerminalView = ExecutionOutcomeCommitter::HandoffTerminalView
46
43
  TerminalView = ExecutionOutcomeCommitter::TerminalView
47
44
  TerminalCommitCommand = ExecutionOutcomeCommitter::Command
48
45
  TerminalDelivery = Data.define(
@@ -55,8 +52,6 @@ module Phronomy
55
52
  InitialPreparationResult = InitialPreparation::Result
56
53
  ProviderDispatchPreparationResult = DispatchPreparation::ProviderResult
57
54
  ToolDispatchPreparationResult = DispatchPreparation::ToolResult
58
- ProviderDispatchPreparationReconciliationResult = DispatchPreparation::ProviderReconciliationResult
59
- ToolDispatchPreparationReconciliationResult = DispatchPreparation::ToolReconciliationResult
60
55
  ResumeCommitResult = ApprovalResumeCommit::Result
61
56
  TerminalOutcome = ExecutionOutcomeCommitter::Outcome
62
57
 
@@ -73,12 +68,6 @@ module Phronomy
73
68
  ToolDispatchPreparationReady = Data.define(
74
69
  :coordinator, :operation, :result, :error
75
70
  )
76
- ProviderDispatchPreparationReconciliationReady = Data.define(
77
- :coordinator, :command, :result, :error
78
- )
79
- ToolDispatchPreparationReconciliationReady = Data.define(
80
- :coordinator, :command, :result, :error
81
- )
82
71
  ResumeCommitReady = Data.define(
83
72
  :coordinator, :request, :operation, :result, :error
84
73
  )
@@ -90,9 +79,6 @@ module Phronomy
90
79
  :source_error, :fsm_session_id
91
80
  )
92
81
 
93
- PreparationOutcomeUnknownError = DispatchPreparation::OutcomeUnknownError
94
- private_constant :PreparationOutcomeUnknownError
95
-
96
82
  def initialize(agent)
97
83
  @agent = agent
98
84
  @initial_preparation = InitialPreparation.new(agent: agent, persistence: agent.persistence)
@@ -108,14 +94,10 @@ module Phronomy
108
94
  @agent.send(:__assert_live_agent!)
109
95
  @agent.send(:_reject_removed_generic_identity_keys!, config)
110
96
  result_task = Phronomy::TaskResult.deferred(name: "agent-#{@agent.agent_id}-#{mode}")
111
- if config[:invocation_context]
112
- binding = Phronomy::Concurrency::OperationBinding.new(
113
- invocation_context: config[:invocation_context],
114
- cancellation_token: config[:cancellation_token]
115
- )
116
- binding.bind(result_task)
117
- config = config.merge(cancellation_token: binding.token)
118
- end
97
+ controls = Phronomy::InvocationControls.attach(result_task,
98
+ invocation_context: config[:invocation_context],
99
+ cancellation_token: config[:cancellation_token])
100
+ config = config.merge(cancellation_token: controls.token)
119
101
  command = StartCommand.new(
120
102
  coordinator: self,
121
103
  input: input,
@@ -125,14 +107,15 @@ module Phronomy
125
107
  approval_listener: approval_listener,
126
108
  on_event: on_event,
127
109
  result_task: result_task,
128
- admission_token: Object.new.freeze
110
+ admission_token: Object.new.freeze,
111
+ controls: controls
129
112
  )
130
- unless post_control(Phronomy::Runtime.instance, command)
113
+ unless post_control(@agent.__execution_environment, command)
131
114
  fail_task(result_task, runtime_rejected_error(:start))
132
115
  end
133
116
  result_task
134
117
  rescue => error
135
- fail_task(result_task, translated(error)) if defined?(result_task) && result_task
118
+ fail_task(result_task, error) if defined?(result_task) && result_task
136
119
  result_task
137
120
  end
138
121
 
@@ -155,12 +138,12 @@ module Phronomy
155
138
  config: config.dup.freeze,
156
139
  result_task: result_task
157
140
  )
158
- unless post_control(Phronomy::Runtime.instance, command)
141
+ unless post_control(@agent.__execution_environment, command)
159
142
  fail_task(result_task, runtime_rejected_error(:resume))
160
143
  end
161
144
  result_task
162
145
  rescue => error
163
- fail_task(result_task, translated(error)) if defined?(result_task) && result_task
146
+ fail_task(result_task, error) if defined?(result_task) && result_task
164
147
  result_task
165
148
  end
166
149
 
@@ -178,7 +161,7 @@ module Phronomy
178
161
  submit_provider_dispatch_preparation(operation)
179
162
  nil
180
163
  rescue => error
181
- event_sink.post(:llm_setup_failed, translated(error))
164
+ event_sink.post(:llm_setup_failed, error)
182
165
  nil
183
166
  end
184
167
 
@@ -193,13 +176,13 @@ module Phronomy
193
176
  submit_tool_dispatch_preparation(operation)
194
177
  nil
195
178
  rescue => error
196
- event_sink.post(:tool_setup_failed, translated(error))
179
+ event_sink.post(:tool_setup_failed, error)
197
180
  nil
198
181
  end
199
182
 
200
183
  def submit_provider_dispatch_preparation(operation)
201
- runtime = Phronomy::Runtime.instance
202
- task = runtime.offload.submit(on_full: :raise) do
184
+ environment = @agent.__execution_environment
185
+ task = environment.submit(on_full: :raise) do
203
186
  @dispatch_preparation.prepare_provider(operation)
204
187
  end
205
188
  task.on_complete do |result, error|
@@ -209,8 +192,8 @@ module Phronomy
209
192
  result: result,
210
193
  error: error
211
194
  )
212
- unless post_control(runtime, ready)
213
- Phronomy.configuration.logger&.warn(
195
+ unless post_control(environment, ready)
196
+ Phronomy::RuntimeSettings.current.logger&.warn(
214
197
  "[Phronomy] EventLoop rejected Provider dispatch preparation result for " \
215
198
  "#{operation.execution_id}"
216
199
  )
@@ -219,8 +202,8 @@ module Phronomy
219
202
  end
220
203
 
221
204
  def submit_tool_dispatch_preparation(operation)
222
- runtime = Phronomy::Runtime.instance
223
- task = runtime.offload.submit(on_full: :raise) do
205
+ environment = @agent.__execution_environment
206
+ task = environment.submit(on_full: :raise) do
224
207
  @dispatch_preparation.prepare_tools(operation)
225
208
  end
226
209
  task.on_complete do |result, error|
@@ -230,8 +213,8 @@ module Phronomy
230
213
  result: result,
231
214
  error: error
232
215
  )
233
- unless post_control(runtime, ready)
234
- Phronomy.configuration.logger&.warn(
216
+ unless post_control(environment, ready)
217
+ Phronomy::RuntimeSettings.current.logger&.warn(
235
218
  "[Phronomy] EventLoop rejected Tool dispatch preparation result for " \
236
219
  "#{operation.execution_id}"
237
220
  )
@@ -239,70 +222,12 @@ module Phronomy
239
222
  end
240
223
  end
241
224
 
242
- def submit_provider_dispatch_preparation_reconciliation(operation, uncertainty)
243
- # simplecov:disable
244
- runtime = Phronomy::Runtime.instance
245
- command = ProviderDispatchPreparationReconciliationCommand.new(
246
- operation: operation,
247
- intended_result: uncertainty.intended_result,
248
- original_error: uncertainty.original_error
249
- )
250
- task = runtime.offload.submit(on_full: :raise) do
251
- @dispatch_preparation.reconcile_provider(command)
252
- end
253
- task.on_complete do |result, error|
254
- ready = ProviderDispatchPreparationReconciliationReady.new(
255
- coordinator: self,
256
- command: command,
257
- result: result,
258
- error: error
259
- )
260
- unless post_control(runtime, ready)
261
- Phronomy.configuration.logger&.warn(
262
- "[Phronomy] EventLoop rejected Provider dispatch reconciliation result for #{operation.execution_id}"
263
- )
264
- end
265
- end
266
- rescue => error
267
- mark_barrier_recovery_required(operation, error)
268
- # simplecov:enable
269
- end
270
-
271
- def submit_tool_dispatch_preparation_reconciliation(operation, uncertainty)
272
- # simplecov:disable
273
- runtime = Phronomy::Runtime.instance
274
- command = ToolDispatchPreparationReconciliationCommand.new(
275
- operation: operation,
276
- intended_result: uncertainty.intended_result,
277
- original_error: uncertainty.original_error
278
- )
279
- task = runtime.offload.submit(on_full: :raise) do
280
- @dispatch_preparation.reconcile_tools(command)
281
- end
282
- task.on_complete do |result, error|
283
- ready = ToolDispatchPreparationReconciliationReady.new(
284
- coordinator: self,
285
- command: command,
286
- result: result,
287
- error: error
288
- )
289
- unless post_control(runtime, ready)
290
- Phronomy.configuration.logger&.warn(
291
- "[Phronomy] EventLoop rejected Tool dispatch reconciliation result for #{operation.execution_id}"
292
- )
293
- end
294
- end
295
- rescue => error
296
- mark_barrier_recovery_required(operation, error)
297
- # simplecov:enable
298
- end
299
-
300
225
  # Every control message is delivered by EventLoop. This method is the only
301
226
  # coordinator entry point allowed to advance Phronomy-managed live state.
302
227
  # @api private
303
228
  def deliver_on_event_loop(command)
304
- event_loop = Phronomy::Runtime.instance.event_loop
305
- assert_event_loop!(event_loop)
229
+ environment = @agent.__execution_environment
230
+ assert_event_loop!(environment)
306
231
 
307
232
  case command
308
233
  when StartCommand
@@ -322,10 +247,6 @@ module Phronomy
322
247
  apply_provider_dispatch_preparation_on_event_loop(command)
323
248
  when ToolDispatchPreparationReady
324
249
  apply_tool_dispatch_preparation_on_event_loop(command)
325
- when ProviderDispatchPreparationReconciliationReady
326
- apply_provider_dispatch_preparation_reconciliation_on_event_loop(command)
327
- when ToolDispatchPreparationReconciliationReady
328
- apply_tool_dispatch_preparation_reconciliation_on_event_loop(command)
329
250
  when ResumeCommand
330
251
  begin_resume_on_event_loop(command)
331
252
  when ResumeCommitReady
@@ -346,13 +267,8 @@ module Phronomy
346
267
  # ----------------------------------------------------------------------
347
268
 
348
269
  def begin_start_on_event_loop(request)
349
- runtime = Phronomy::Runtime.instance
350
- event_loop = runtime.event_loop
351
- scope = request.config[:invocation_context]&.__execution_scope
352
- if scope && (!scope.__open? || request.config[:cancellation_token]&.cancelled?)
353
- deliver_start_failure_on_event_loop(request, scope.__cancellation_error)
354
- return
355
- end
270
+ environment = @agent.__execution_environment
271
+ request.controls.check_start!
356
272
  root = @agent.agent_root
357
273
  if root.lifecycle_status == :closed
358
274
  deliver_start_failure_on_event_loop(
@@ -365,7 +281,7 @@ module Phronomy
365
281
  @agent.send(:__assert_live_agent!)
366
282
  admitted = false
367
283
  submitted = false
368
- Phronomy::Agent::ExecutionRegistry.for(event_loop).admit_agent_execution(
284
+ environment.registry.admit_agent_execution(
369
285
  @agent.agent_id,
370
286
  owner_token: request.admission_token
371
287
  )
@@ -378,7 +294,7 @@ module Phronomy
378
294
  @agent.send(:__assert_live_agent!)
379
295
 
380
296
  operation = capture_initial_preparation(request, root)
381
- task = runtime.offload.submit(on_full: :raise) do
297
+ task = environment.submit(on_full: :raise) do
382
298
  @initial_preparation.prepare(operation)
383
299
  end
384
300
  submitted = true
@@ -390,23 +306,23 @@ module Phronomy
390
306
  error: error
391
307
  )
392
308
  fail_task(request.result_task, runtime_rejected_error(:initial_preparation)) unless
393
- post_control(runtime, ready)
309
+ post_control(environment, ready)
394
310
  end
395
311
  rescue => error
396
312
  if admitted
397
313
  if submitted
398
- Phronomy::Agent::ExecutionRegistry.for(event_loop).mark_agent_admission_recovery_required(
314
+ environment.registry.mark_agent_admission_recovery_required(
399
315
  @agent.agent_id,
400
316
  owner_token: request.admission_token
401
317
  )
402
318
  else
403
- Phronomy::Agent::ExecutionRegistry.for(event_loop).release_agent_execution_admission(
319
+ environment.registry.release_agent_execution_admission(
404
320
  @agent.agent_id,
405
321
  owner_token: request.admission_token
406
322
  )
407
323
  end
408
324
  end
409
- deliver_start_failure_on_event_loop(request, translated(error))
325
+ deliver_start_failure_on_event_loop(request, error)
410
326
  end
411
327
 
412
328
  def capture_initial_preparation(request, root)
@@ -426,9 +342,9 @@ module Phronomy
426
342
  def initial_preparation_replayable?(input, config, approval_policy)
427
343
  return false unless input.is_a?(String)
428
344
  return false unless approval_policy.nil?
429
- if config.key?(:phronomy_handoff_bindings) ||
430
- config.key?(:phronomy_handoff_context)
431
- return false unless config[:phronomy_coordination]&.fetch("kind", nil) == "handoff"
345
+ if config.key?(:phronomy_control_bindings) ||
346
+ config.key?(:phronomy_transfer_context)
347
+ return false unless config[:phronomy_execution_participant]
432
348
  end
433
349
 
434
350
  invocation_context = config[:invocation_context]
@@ -442,40 +358,40 @@ module Phronomy
442
358
 
443
359
  def apply_initial_preparation_on_event_loop(ready)
444
360
  request = ready.request
445
- event_loop = Phronomy::Runtime.instance.event_loop
361
+ environment = @agent.__execution_environment
446
362
  if ready.error
447
- Phronomy::Agent::ExecutionRegistry.for(event_loop).mark_agent_admission_recovery_required(
363
+ environment.registry.mark_agent_admission_recovery_required(
448
364
  @agent.agent_id,
449
365
  owner_token: request.admission_token
450
366
  )
451
- deliver_start_failure_on_event_loop(request, translated(ready.error))
367
+ deliver_start_failure_on_event_loop(request, ready.error)
452
368
  return
453
369
  end
454
370
 
455
371
  result = ready.result
456
372
  case result.admission_outcome
457
373
  when :not_established
458
- Phronomy::Agent::ExecutionRegistry.for(event_loop).release_agent_execution_admission(
374
+ environment.registry.release_agent_execution_admission(
459
375
  @agent.agent_id,
460
376
  owner_token: request.admission_token
461
377
  )
462
378
  deliver_start_failure_on_event_loop(request, result.error)
463
379
  return
464
380
  when :outcome_unknown, :recovery_required
465
- Phronomy::Agent::ExecutionRegistry.for(event_loop).mark_agent_admission_recovery_required(
381
+ environment.registry.mark_agent_admission_recovery_required(
466
382
  @agent.agent_id,
467
383
  owner_token: request.admission_token
468
384
  )
469
385
  deliver_start_failure_on_event_loop(request, result.error)
470
386
  return
471
387
  when :active, :terminal
472
- Phronomy::Agent::ExecutionRegistry.for(event_loop).bind_agent_execution_admission(
388
+ environment.registry.bind_agent_execution_admission(
473
389
  @agent.agent_id,
474
390
  owner_token: request.admission_token,
475
391
  execution_id: result.execution.execution_id
476
392
  )
477
393
  else
478
- Phronomy::Agent::ExecutionRegistry.for(event_loop).mark_agent_admission_recovery_required(
394
+ environment.registry.mark_agent_admission_recovery_required(
479
395
  @agent.agent_id,
480
396
  owner_token: request.admission_token
481
397
  )
@@ -488,7 +404,7 @@ module Phronomy
488
404
  appended_records: result.appended_records
489
405
  )
490
406
  if result.admission_outcome == :terminal
491
- Phronomy::Agent::ExecutionRegistry.for(event_loop).release_agent_execution_admission(
407
+ environment.registry.release_agent_execution_admission(
492
408
  @agent.agent_id,
493
409
  execution_id: result.execution.execution_id
494
410
  )
@@ -508,8 +424,7 @@ module Phronomy
508
424
  end
509
425
 
510
426
  def register_initial_session_on_event_loop(request, prepared)
511
- runtime = Phronomy::Runtime.instance
512
- event_loop = runtime.event_loop
427
+ environment = @agent.__execution_environment
513
428
  Phronomy::Tracing::Automatic.observe_task(
514
429
  request.result_task,
515
430
  "agent.execution",
@@ -525,17 +440,17 @@ module Phronomy
525
440
  phronomy_filtered_input: prepared.filtered_input,
526
441
  execution_id: prepared.execution.execution_id
527
442
  )
528
- session = Agent::AgentInvocationSessionBuilder.build(
443
+ invocation = Agent::AgentInvocation.new(
529
444
  agent: @agent,
530
445
  input: prepared.filtered_input,
531
446
  config: effective_config,
532
447
  approval_policy: request.approval_policy,
533
448
  approval_listener: request.approval_listener,
534
449
  mode: request.mode,
535
- on_event: request.on_event,
536
- runtime: runtime
450
+ event_listener: request.on_event
537
451
  )
538
- Phronomy::Agent::ExecutionRegistry.for(event_loop).install_agent_execution(
452
+ session = environment.build_agent_session(invocation: invocation)
453
+ environment.registry.install_agent_execution(
539
454
  execution_id: prepared.execution.execution_id,
540
455
  agent: @agent,
541
456
  coordinator: self,
@@ -545,17 +460,17 @@ module Phronomy
545
460
  invocation: session.context,
546
461
  fsm_session_id: session.id
547
462
  )
548
- Phronomy::Agent::ExecutionRegistry.for(event_loop).register_agent_completion_waiter(
463
+ environment.registry.register_agent_completion_waiter(
549
464
  prepared.execution.execution_id,
550
465
  request.result_task
551
466
  )
552
- execution_session_runner(runtime).register(
467
+ execution_session_runner(environment).register(
553
468
  session, request.result_task
554
469
  )
555
470
  # simplecov:disable
556
471
  rescue => _error
557
- Phronomy::Agent::ExecutionRegistry.for(event_loop).release_agent_execution(prepared.execution.execution_id) if
558
- event_loop&.current? && Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_state(prepared.execution.execution_id)
472
+ environment.registry.release_agent_execution(prepared.execution.execution_id) if
473
+ environment&.executing? && environment.registry.agent_execution_state(prepared.execution.execution_id)
559
474
  raise
560
475
  end
561
476
  # simplecov:enable
@@ -587,10 +502,9 @@ module Phronomy
587
502
  result_task,
588
503
  load_completion:
589
504
  )
590
- runtime = Phronomy::Runtime.instance
591
- event_loop = runtime.event_loop
592
- assert_event_loop!(event_loop)
593
- state = Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_state(execution.execution_id)
505
+ environment = @agent.__execution_environment
506
+ assert_event_loop!(environment)
507
+ state = environment.registry.agent_execution_state(execution.execution_id)
594
508
  unless state && state.agent.equal?(@agent) &&
595
509
  state.execution.execution_revision == execution.execution_revision &&
596
510
  state.execution.status == :preparing &&
@@ -608,7 +522,7 @@ module Phronomy
608
522
  root: @agent.agent_root,
609
523
  journal_records: @agent.send(:_journal_records_snapshot)
610
524
  )
611
- task = runtime.offload.submit(on_full: :raise) do
525
+ task = environment.submit(on_full: :raise) do
612
526
  @initial_preparation.recover(operation)
613
527
  end
614
528
  task.on_complete do |result, error|
@@ -621,7 +535,7 @@ module Phronomy
621
535
  result: result,
622
536
  error: error
623
537
  )
624
- unless post_control(runtime, ready)
538
+ unless post_control(environment, ready)
625
539
  rejected = runtime_rejected_error(:initial_preparation_recovery)
626
540
  fail_task(result_task, rejected)
627
541
  load_completion.fail(rejected)
@@ -630,24 +544,24 @@ module Phronomy
630
544
  rescue => error
631
545
  # simplecov:disable
632
546
  begin
633
- if defined?(event_loop) && event_loop.current?
547
+ if defined?(environment) && environment.executing?
634
548
  release_initial_preparation_recovery_runtime_state(
635
- event_loop,
549
+ environment,
636
550
  execution.execution_id
637
551
  )
638
552
  end
639
553
  rescue
640
554
  nil
641
555
  end
642
- translated_error = translated(error)
556
+ translated_error = error
643
557
  fail_task(result_task, translated_error)
644
558
  load_completion.fail(translated_error)
645
559
  # simplecov:enable
646
560
  end
647
561
 
648
562
  def apply_initial_preparation_recovery_on_event_loop(ready)
649
- event_loop = Phronomy::Runtime.instance.event_loop
650
- state = Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_state(ready.execution_id)
563
+ environment = @agent.__execution_environment
564
+ state = environment.registry.agent_execution_state(ready.execution_id)
651
565
  unless state && state.agent.equal?(@agent) &&
652
566
  state.execution.execution_revision == ready.expected_execution_revision &&
653
567
  state.execution.status == :preparing &&
@@ -662,10 +576,10 @@ module Phronomy
662
576
 
663
577
  if ready.error
664
578
  release_initial_preparation_recovery_runtime_state(
665
- event_loop,
579
+ environment,
666
580
  ready.execution_id
667
581
  )
668
- error = translated(ready.error)
582
+ error = ready.error
669
583
  fail_task(ready.result_task, error)
670
584
  ready.load_completion.fail(error)
671
585
  return
@@ -674,17 +588,17 @@ module Phronomy
674
588
  result = ready.result
675
589
  case result.admission_outcome
676
590
  when :terminal
677
- settle_failed_preparation_recovery_on_event_loop(ready, event_loop)
591
+ settle_failed_preparation_recovery_on_event_loop(ready, environment)
678
592
  ready.load_completion.complete(@agent)
679
593
  when :active
680
- restart_prepared_execution_on_event_loop(ready, event_loop)
594
+ restart_prepared_execution_on_event_loop(ready, environment)
681
595
  ready.load_completion.complete(@agent)
682
596
  else
683
597
  error = Phronomy::ExecutionRehydrationRequiredError.new(
684
598
  "unexpected initial preparation Recovery outcome: #{result.admission_outcome.inspect}"
685
599
  )
686
600
  release_initial_preparation_recovery_runtime_state(
687
- event_loop,
601
+ environment,
688
602
  ready.execution_id
689
603
  )
690
604
  fail_task(ready.result_task, error)
@@ -694,30 +608,30 @@ module Phronomy
694
608
  # simplecov:disable
695
609
  begin
696
610
  release_initial_preparation_recovery_runtime_state(
697
- event_loop,
611
+ environment,
698
612
  ready.execution_id
699
613
  )
700
614
  rescue
701
615
  nil
702
616
  end
703
- translated_error = translated(error)
617
+ translated_error = error
704
618
  fail_task(ready.result_task, translated_error)
705
619
  ready.load_completion.fail(translated_error)
706
620
  # simplecov:enable
707
621
  end
708
622
 
709
- def settle_failed_preparation_recovery_on_event_loop(ready, event_loop)
623
+ def settle_failed_preparation_recovery_on_event_loop(ready, environment)
710
624
  result = ready.result
711
625
  apply_agent_live_state(
712
626
  root: result.root,
713
627
  appended_records: result.appended_records
714
628
  )
715
- Phronomy::Agent::ExecutionRegistry.for(event_loop).replace_agent_execution(
629
+ environment.registry.replace_agent_execution(
716
630
  ready.execution_id,
717
631
  execution: result.execution
718
632
  )
719
- Phronomy::Agent::ExecutionRegistry.for(event_loop).release_agent_execution(ready.execution_id)
720
- Phronomy::Agent::ExecutionRegistry.for(event_loop).release_agent_execution_admission(
633
+ environment.registry.release_agent_execution(ready.execution_id)
634
+ environment.registry.release_agent_execution_admission(
721
635
  @agent.agent_id,
722
636
  execution_id: ready.execution_id
723
637
  )
@@ -736,13 +650,13 @@ module Phronomy
736
650
  )
737
651
  end
738
652
 
739
- def restart_prepared_execution_on_event_loop(ready, event_loop)
653
+ def restart_prepared_execution_on_event_loop(ready, environment)
740
654
  result = ready.result
741
655
  apply_agent_live_state(
742
656
  root: result.root,
743
657
  appended_records: result.appended_records
744
658
  )
745
- Phronomy::Agent::ExecutionRegistry.for(event_loop).release_agent_execution(ready.execution_id)
659
+ environment.registry.release_agent_execution(ready.execution_id)
746
660
  mode = (
747
661
  result.execution.metadata[ExecutionMetadata::INVOCATION_MODE_KEY] ||
748
662
  "invoke"
@@ -756,7 +670,8 @@ module Phronomy
756
670
  approval_listener: nil,
757
671
  on_event: @agent.send(:_phronomy_event_listener),
758
672
  result_task: ready.result_task,
759
- admission_token: Object.new.freeze
673
+ admission_token: Object.new.freeze,
674
+ controls: nil
760
675
  )
761
676
  begin
762
677
  register_initial_session_on_event_loop(request, result)
@@ -770,12 +685,12 @@ module Phronomy
770
685
  end
771
686
 
772
687
  def release_initial_preparation_recovery_runtime_state(
773
- event_loop,
688
+ environment,
774
689
  execution_id
775
690
  )
776
- state = Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_state(execution_id)
777
- Phronomy::Agent::ExecutionRegistry.for(event_loop).release_agent_execution(execution_id) if state
778
- Phronomy::Agent::ExecutionRegistry.for(event_loop).release_agent_execution_admission(
691
+ state = environment.registry.agent_execution_state(execution_id)
692
+ environment.registry.release_agent_execution(execution_id) if state
693
+ environment.registry.release_agent_execution_admission(
779
694
  @agent.agent_id,
780
695
  execution_id: execution_id
781
696
  )
@@ -786,11 +701,11 @@ module Phronomy
786
701
  # ----------------------------------------------------------------------
787
702
 
788
703
  def dispatch_preparation_state!(invocation, event_sink, phase:, kind:)
789
- event_loop = Phronomy::Runtime.instance.event_loop
790
- assert_event_loop!(event_loop)
791
- state = ExecutionRegistry.for(event_loop).agent_execution_state(invocation.execution_id)
704
+ environment = @agent.__execution_environment
705
+ assert_event_loop!(environment)
706
+ state = environment.registry.agent_execution_state(invocation.execution_id)
792
707
  validate_live_session!(state, invocation, event_sink.fsm_session_id)
793
- unless event_loop.fsm_session_state(event_sink.fsm_session_id) == phase
708
+ unless environment.session_phase(event_sink.fsm_session_id) == phase
794
709
  raise Phronomy::Error,
795
710
  "#{kind} dispatch preparation requires the owning FSMSession to be in #{phase.inspect}"
796
711
  end
@@ -827,7 +742,8 @@ module Phronomy
827
742
  root: @agent.agent_root,
828
743
  execution: state.execution,
829
744
  runtime_snapshot: invocation.runtime_snapshot,
830
- tool_batch_snapshot: tool_batch_snapshot
745
+ tool_batch_snapshot: tool_batch_snapshot,
746
+ invocation_config: invocation.config.dup.freeze
831
747
  )
832
748
  end
833
749
 
@@ -842,13 +758,10 @@ module Phronomy
842
758
  return unless state
843
759
 
844
760
  if ready.error
845
- if ready.error.is_a?(PreparationOutcomeUnknownError)
846
- submit_provider_dispatch_preparation_reconciliation(
847
- operation,
848
- ready.error
849
- )
761
+ if ready.error.is_a?(Phronomy::ExecutionRehydrationRequiredError)
762
+ mark_barrier_recovery_required(operation, ready.error)
850
763
  else
851
- state.invocation.event_sink.post(:llm_setup_failed, translated(ready.error))
764
+ state.invocation.event_sink.post(:llm_setup_failed, ready.error)
852
765
  end
853
766
  return
854
767
  end
@@ -859,7 +772,7 @@ module Phronomy
859
772
  state
860
773
  )
861
774
  rescue => error
862
- state&.invocation&.event_sink&.post(:llm_setup_failed, translated(error))
775
+ state&.invocation&.event_sink&.post(:llm_setup_failed, error)
863
776
  end
864
777
 
865
778
  def apply_tool_dispatch_preparation_on_event_loop(ready)
@@ -873,13 +786,10 @@ module Phronomy
873
786
  return unless state
874
787
 
875
788
  if ready.error
876
- if ready.error.is_a?(PreparationOutcomeUnknownError)
877
- submit_tool_dispatch_preparation_reconciliation(
878
- operation,
879
- ready.error
880
- )
789
+ if ready.error.is_a?(Phronomy::ExecutionRehydrationRequiredError)
790
+ mark_barrier_recovery_required(operation, ready.error)
881
791
  else
882
- state.invocation.event_sink.post(:tool_setup_failed, translated(ready.error))
792
+ state.invocation.event_sink.post(:tool_setup_failed, ready.error)
883
793
  end
884
794
  return
885
795
  end
@@ -890,7 +800,7 @@ module Phronomy
890
800
  state
891
801
  )
892
802
  rescue => error
893
- state&.invocation&.event_sink&.post(:tool_setup_failed, translated(error))
803
+ state&.invocation&.event_sink&.post(:tool_setup_failed, error)
894
804
  end
895
805
 
896
806
  def apply_confirmed_provider_dispatch_preparation_on_event_loop(
@@ -898,15 +808,15 @@ module Phronomy
898
808
  result,
899
809
  state
900
810
  )
901
- event_loop = Phronomy::Runtime.instance.event_loop
811
+ environment = @agent.__execution_environment
902
812
  if result.runtime_projection
903
- Phronomy::Agent::ExecutionRegistry.for(event_loop).replace_agent_execution(
813
+ environment.registry.replace_agent_execution(
904
814
  operation.execution_id,
905
815
  execution: result.execution,
906
816
  runtime_projection: result.runtime_projection
907
817
  )
908
818
  else
909
- Phronomy::Agent::ExecutionRegistry.for(event_loop).replace_agent_execution(
819
+ environment.registry.replace_agent_execution(
910
820
  operation.execution_id,
911
821
  execution: result.execution
912
822
  )
@@ -914,13 +824,13 @@ module Phronomy
914
824
  state.invocation.acknowledge_runtime_snapshot(operation.runtime_snapshot)
915
825
 
916
826
  if result.error
917
- state.invocation.event_sink.post(:llm_setup_failed, translated(result.error))
827
+ state.invocation.event_sink.post(:llm_setup_failed, result.error)
918
828
  return
919
829
  end
920
830
 
921
- Agent::AgentInvocationSessionBuilder.start_prepared_provider_call(
831
+ Agent::InvocationActions.start_prepared_provider_call(
922
832
  agent: @agent,
923
- runtime: Phronomy::Runtime.instance,
833
+ environment: @agent.__execution_environment,
924
834
  event_sink: state.invocation.event_sink,
925
835
  invocation: state.invocation,
926
836
  projection: result.runtime_projection,
@@ -933,106 +843,27 @@ module Phronomy
933
843
  result,
934
844
  state
935
845
  )
936
- event_loop = Phronomy::Runtime.instance.event_loop
937
- Phronomy::Agent::ExecutionRegistry.for(event_loop).replace_agent_execution(
846
+ environment = @agent.__execution_environment
847
+ environment.registry.replace_agent_execution(
938
848
  operation.execution_id,
939
849
  execution: result.execution
940
850
  )
941
851
  state.invocation.acknowledge_runtime_snapshot(operation.runtime_snapshot)
942
- Agent::AgentInvocationSessionBuilder.start_prepared_tool_dispatch(
943
- runtime: Phronomy::Runtime.instance,
852
+ Agent::InvocationActions.start_prepared_tool_dispatch(
853
+ environment: @agent.__execution_environment,
944
854
  event_sink: state.invocation.event_sink,
945
855
  invocation: state.invocation
946
856
  )
947
857
  end
948
858
 
949
- def apply_provider_dispatch_preparation_reconciliation_on_event_loop(ready)
950
- command = ready.command
951
- operation = command.operation
952
- state = authoritative_state_for_operation(
953
- execution_id: operation.execution_id,
954
- fsm_session_id: operation.fsm_session_id,
955
- expected_execution_revision: operation.expected_execution_revision,
956
- expected_fsm_state: :calling_llm
957
- )
958
- return unless state
959
-
960
- if ready.error
961
- mark_barrier_recovery_required(operation, ready.error)
962
- return
963
- end
964
-
965
- case ready.result.disposition
966
- when :committed
967
- apply_confirmed_provider_dispatch_preparation_on_event_loop(
968
- operation,
969
- ready.result.preparation_result,
970
- state
971
- )
972
- when :not_committed
973
- state.invocation.event_sink.post(
974
- :llm_setup_failed,
975
- translated(command.original_error)
976
- )
977
- when :conflict
978
- mark_barrier_recovery_required(operation, command.original_error)
979
- else
980
- raise Phronomy::Error,
981
- "unknown Provider dispatch reconciliation disposition: " \
982
- "#{ready.result.disposition.inspect}"
983
- end
984
- rescue => error
985
- mark_barrier_recovery_required(operation, error)
986
- end
987
-
988
- def apply_tool_dispatch_preparation_reconciliation_on_event_loop(ready)
989
- command = ready.command
990
- operation = command.operation
991
- state = authoritative_state_for_operation(
992
- execution_id: operation.execution_id,
993
- fsm_session_id: operation.fsm_session_id,
994
- expected_execution_revision: operation.expected_execution_revision,
995
- expected_fsm_state: :dispatching_tools
996
- )
997
- return unless state
998
-
999
- if ready.error
1000
- mark_barrier_recovery_required(operation, ready.error)
1001
- return
1002
- end
1003
-
1004
- case ready.result.disposition
1005
- when :committed
1006
- apply_confirmed_tool_dispatch_preparation_on_event_loop(
1007
- operation,
1008
- ready.result.preparation_result,
1009
- state
1010
- )
1011
- when :not_committed
1012
- state.invocation.event_sink.post(
1013
- :tool_setup_failed,
1014
- translated(command.original_error)
1015
- )
1016
- when :conflict
1017
- mark_barrier_recovery_required(operation, command.original_error)
1018
- else
1019
- raise Phronomy::Error,
1020
- "unknown Tool dispatch reconciliation disposition: " \
1021
- "#{ready.result.disposition.inspect}"
1022
- end
1023
- rescue => error
1024
- mark_barrier_recovery_required(operation, error)
1025
- # simplecov:enable
1026
- end
1027
-
1028
859
  def mark_barrier_recovery_required(operation, error)
1029
- event_loop = Phronomy::Runtime.instance.event_loop
1030
- Phronomy::Agent::ExecutionRegistry.for(event_loop).mark_agent_execution_admission(
860
+ environment = @agent.__execution_environment
861
+ environment.registry.mark_agent_execution_admission(
1031
862
  @agent.agent_id,
1032
863
  execution_id: operation.execution_id,
1033
864
  state: :recovery_required
1034
865
  )
1035
- Phronomy.configuration.logger&.warn(
866
+ Phronomy::RuntimeSettings.current.logger&.warn(
1036
867
  "[Phronomy] causal durable barrier requires recovery for " \
1037
868
  "#{operation.execution_id}: #{error.class}: #{error.message}"
1038
869
  )
@@ -1043,9 +874,8 @@ module Phronomy
1043
874
  # ----------------------------------------------------------------------
1044
875
 
1045
876
  def begin_resume_on_event_loop(request)
1046
- runtime = Phronomy::Runtime.instance
1047
- event_loop = runtime.event_loop
1048
- state = Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_state(request.execution_id)
877
+ environment = @agent.__execution_environment
878
+ state = environment.registry.agent_execution_state(request.execution_id)
1049
879
  unless state
1050
880
  fail_task(
1051
881
  request.result_task,
@@ -1081,13 +911,13 @@ module Phronomy
1081
911
  operation = capture_approval_resume(state, request)
1082
912
  resume_transition_started = false
1083
913
  submitted = false
1084
- Phronomy::Agent::ExecutionRegistry.for(event_loop).mark_agent_execution_admission(
914
+ environment.registry.mark_agent_execution_admission(
1085
915
  @agent.agent_id,
1086
916
  execution_id: state.execution_id,
1087
917
  state: :resuming
1088
918
  )
1089
919
  resume_transition_started = true
1090
- task = runtime.offload.submit(on_full: :raise) do
920
+ task = environment.submit(on_full: :raise) do
1091
921
  @approval_resume_commit.commit(operation)
1092
922
  end
1093
923
  submitted = true
@@ -1100,17 +930,17 @@ module Phronomy
1100
930
  error: error
1101
931
  )
1102
932
  fail_task(request.result_task, runtime_rejected_error(:resume_commit)) unless
1103
- post_control(runtime, ready)
933
+ post_control(environment, ready)
1104
934
  end
1105
935
  rescue => error
1106
936
  if resume_transition_started
1107
- Phronomy::Agent::ExecutionRegistry.for(event_loop).mark_agent_execution_admission(
937
+ environment.registry.mark_agent_execution_admission(
1108
938
  @agent.agent_id,
1109
939
  execution_id: state.execution_id,
1110
940
  state: submitted ? :recovery_required : :suspended
1111
941
  )
1112
942
  end
1113
- fail_task(request.result_task, translated(error))
943
+ fail_task(request.result_task, error)
1114
944
  raise unless resume_transition_started
1115
945
  end
1116
946
 
@@ -1134,8 +964,8 @@ module Phronomy
1134
964
  def apply_resume_commit_on_event_loop(ready)
1135
965
  request = ready.request
1136
966
  operation = ready.operation
1137
- event_loop = Phronomy::Runtime.instance.event_loop
1138
- state = Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_state(operation.execution_id)
967
+ environment = @agent.__execution_environment
968
+ state = environment.registry.agent_execution_state(operation.execution_id)
1139
969
  unless state && state.agent.equal?(@agent) &&
1140
970
  state.execution.execution_revision == operation.expected_execution_revision &&
1141
971
  state.execution.status == :suspended
@@ -1149,23 +979,23 @@ module Phronomy
1149
979
  end
1150
980
 
1151
981
  if ready.error
1152
- Phronomy::Agent::ExecutionRegistry.for(event_loop).mark_agent_execution_admission(
982
+ environment.registry.mark_agent_execution_admission(
1153
983
  @agent.agent_id,
1154
984
  execution_id: operation.execution_id,
1155
985
  state: :recovery_required
1156
986
  )
1157
- fail_task(request.result_task, translated(ready.error))
987
+ fail_task(request.result_task, ready.error)
1158
988
  return
1159
989
  end
1160
990
 
1161
- install_resumed_execution_on_event_loop(ready, event_loop)
991
+ install_resumed_execution_on_event_loop(ready, environment)
1162
992
  observe_resumed_execution(ready, state)
1163
- execution_session_runner(Phronomy::Runtime.instance).resume_approval(
993
+ execution_session_runner(@agent.__execution_environment).resume_approval(
1164
994
  state.invocation, request.result_task,
1165
995
  approved: request.approved, config: request.config
1166
996
  )
1167
997
  rescue => error
1168
- state = Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_state(operation.execution_id) if event_loop&.current?
998
+ state = environment.registry.agent_execution_state(operation.execution_id) if environment&.executing?
1169
999
  if state
1170
1000
  begin_terminal_commit_on_event_loop(
1171
1001
  state,
@@ -1175,24 +1005,24 @@ module Phronomy
1175
1005
  fsm_session_id: state.fsm_session_id
1176
1006
  )
1177
1007
  else
1178
- fail_task(request.result_task, translated(error))
1008
+ fail_task(request.result_task, error)
1179
1009
  end
1180
1010
  end
1181
1011
 
1182
- def install_resumed_execution_on_event_loop(ready, event_loop)
1012
+ def install_resumed_execution_on_event_loop(ready, environment)
1183
1013
  request = ready.request
1184
1014
  operation = ready.operation
1185
1015
  apply_agent_live_state(root: ready.result.root, appended_records: [])
1186
- Phronomy::Agent::ExecutionRegistry.for(event_loop).mark_agent_execution_admission(
1016
+ environment.registry.mark_agent_execution_admission(
1187
1017
  @agent.agent_id,
1188
1018
  execution_id: operation.execution_id,
1189
1019
  state: :executing
1190
1020
  )
1191
- Phronomy::Agent::ExecutionRegistry.for(event_loop).replace_agent_execution(
1021
+ environment.registry.replace_agent_execution(
1192
1022
  operation.execution_id,
1193
1023
  execution: ready.result.execution
1194
1024
  )
1195
- Phronomy::Agent::ExecutionRegistry.for(event_loop).register_agent_completion_waiter(
1025
+ environment.registry.register_agent_completion_waiter(
1196
1026
  operation.execution_id,
1197
1027
  request.result_task
1198
1028
  )
@@ -1227,20 +1057,20 @@ module Phronomy
1227
1057
  raise Phronomy::ExecutionRehydrationRequiredError,
1228
1058
  "initial preparation continuation requires a :preparing execution"
1229
1059
  end
1230
- ExecutionRegistry.for(Phronomy::Runtime.instance.event_loop).mark_agent_execution_admission(
1060
+ @agent.__execution_environment.registry.mark_agent_execution_admission(
1231
1061
  @agent.agent_id, execution_id: state.execution_id, state: :executing
1232
1062
  )
1233
1063
  start_initial_preparation_recovery_on_event_loop(
1234
1064
  state.execution, command.result_task, load_completion: command.load_completion
1235
1065
  )
1236
1066
  rescue => error
1237
- fail_task(command.result_task, translated(error))
1238
- command.load_completion.fail(translated(error))
1067
+ fail_task(command.result_task, error)
1068
+ command.load_completion.fail(error)
1239
1069
  end
1240
1070
 
1241
1071
  def continue_recovered_on_event_loop(command)
1242
- runtime = Phronomy::Runtime.instance
1243
- registry = ExecutionRegistry.for(runtime.event_loop)
1072
+ environment = @agent.__execution_environment
1073
+ registry = environment.registry
1244
1074
  state = recovered_execution_state!(command)
1245
1075
  validate_recovered_continuation!(state.execution, command.continuation)
1246
1076
  invocation = command.invocation
@@ -1265,7 +1095,7 @@ module Phronomy
1265
1095
  registry.mark_agent_execution_admission(@agent.agent_id,
1266
1096
  execution_id: state.execution_id, state: :executing)
1267
1097
  registry.register_agent_completion_waiter(state.execution_id, command.result_task)
1268
- runner = execution_session_runner(runtime)
1098
+ runner = execution_session_runner(environment)
1269
1099
  case command.continuation
1270
1100
  when :approval_rejection
1271
1101
  runner.resume_approval(invocation, command.result_task, approved: false, config: {})
@@ -1281,7 +1111,7 @@ module Phronomy
1281
1111
  end
1282
1112
 
1283
1113
  def recovered_execution_state!(command)
1284
- state = ExecutionRegistry.for(Phronomy::Runtime.instance.event_loop).agent_execution_state(command.execution_id)
1114
+ state = @agent.__execution_environment.registry.agent_execution_state(command.execution_id)
1285
1115
  unless command.coordinator.equal?(self) && state && state.agent.equal?(@agent) &&
1286
1116
  state.coordinator.equal?(self) && state.execution.active? &&
1287
1117
  state.execution.execution_revision == command.expected_execution_revision &&
@@ -1292,8 +1122,8 @@ module Phronomy
1292
1122
  state
1293
1123
  end
1294
1124
 
1295
- def execution_session_runner(runtime)
1296
- ExecutionSessionRunner.new(runtime: runtime, on_complete: ->(**result) {
1125
+ def execution_session_runner(environment)
1126
+ ExecutionSessionRunner.new(environment: environment, on_complete: ->(**result) {
1297
1127
  deliver_on_event_loop(SessionFinishedCommand.new(coordinator: self, **result))
1298
1128
  })
1299
1129
  end
@@ -1327,9 +1157,9 @@ module Phronomy
1327
1157
  # ----------------------------------------------------------------------
1328
1158
 
1329
1159
  def finish_on_event_loop(execution_id, result_task, invocation, error, fsm_session_id:)
1330
- event_loop = Phronomy::Runtime.instance.event_loop
1331
- assert_event_loop!(event_loop)
1332
- state = Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_state(execution_id)
1160
+ environment = @agent.__execution_environment
1161
+ assert_event_loop!(environment)
1162
+ state = environment.registry.agent_execution_state(execution_id)
1333
1163
  return fail_task(result_task, runtime_rejected_error(:terminal)) unless state
1334
1164
 
1335
1165
  unless state.agent.equal?(@agent) && state.coordinator.equal?(self) &&
@@ -1342,15 +1172,15 @@ module Phronomy
1342
1172
  end
1343
1173
 
1344
1174
  terminal_error = error || invocation&.error
1345
- unless Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_quiescent?(execution_id)
1175
+ unless environment.registry.agent_execution_quiescent?(execution_id)
1346
1176
  wait_state = quiescence_sensitive_terminal_error?(terminal_error) ?
1347
1177
  :cancelling : :terminalizing
1348
- Phronomy::Agent::ExecutionRegistry.for(event_loop).mark_agent_execution_admission(
1178
+ environment.registry.mark_agent_execution_admission(
1349
1179
  @agent.agent_id,
1350
1180
  execution_id: execution_id,
1351
1181
  state: wait_state
1352
1182
  )
1353
- Phronomy::Agent::ExecutionRegistry.for(event_loop).defer_agent_terminal_until_quiescent(
1183
+ environment.registry.defer_agent_terminal_until_quiescent(
1354
1184
  execution_id,
1355
1185
  DeferredTerminalCommand.new(
1356
1186
  coordinator: self,
@@ -1374,18 +1204,18 @@ module Phronomy
1374
1204
  end
1375
1205
 
1376
1206
  def resume_deferred_terminal_on_event_loop(command)
1377
- event_loop = Phronomy::Runtime.instance.event_loop
1378
- state = Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_state(command.execution_id)
1207
+ environment = @agent.__execution_environment
1208
+ state = environment.registry.agent_execution_state(command.execution_id)
1379
1209
  unless state && state.agent.equal?(@agent) &&
1380
1210
  state.fsm_session_id.to_s == command.fsm_session_id.to_s &&
1381
1211
  state.invocation.equal?(command.invocation)
1382
- Phronomy.configuration.logger&.warn(
1212
+ Phronomy::RuntimeSettings.current.logger&.warn(
1383
1213
  "[Phronomy] Dropped stale deferred terminal for #{command.execution_id}"
1384
1214
  )
1385
1215
  return
1386
1216
  end
1387
1217
 
1388
- unless Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_quiescent?(command.execution_id)
1218
+ unless environment.registry.agent_execution_quiescent?(command.execution_id)
1389
1219
  raise Phronomy::Error,
1390
1220
  "deferred terminal resumed before quiescence for #{command.execution_id}"
1391
1221
  end
@@ -1442,7 +1272,7 @@ module Phronomy
1442
1272
  end
1443
1273
 
1444
1274
  def begin_terminal_without_session_on_event_loop(request:, prepared:, error:)
1445
- return deliver_start_failure_on_event_loop(request, translated(error)) unless prepared&.execution
1275
+ return deliver_start_failure_on_event_loop(request, error) unless prepared&.execution
1446
1276
 
1447
1277
  operation = build_terminal_operation(
1448
1278
  execution: prepared.execution,
@@ -1481,7 +1311,8 @@ module Phronomy
1481
1311
  execution: execution,
1482
1312
  runtime_snapshot: invocation ? invocation.runtime_snapshot : empty_runtime_snapshot,
1483
1313
  terminal_view: terminal_view(invocation, source_error),
1484
- state_required: state_required
1314
+ state_required: state_required,
1315
+ wiring: (invocation ? invocation.config : @agent.__execution_wiring).dup.freeze
1485
1316
  )
1486
1317
  end
1487
1318
 
@@ -1490,20 +1321,19 @@ module Phronomy
1490
1321
  end
1491
1322
 
1492
1323
  def submit_terminal_operation(operation, delivery)
1493
- runtime = Phronomy::Runtime.instance
1494
- event_loop = runtime.event_loop
1324
+ environment = @agent.__execution_environment
1495
1325
  terminal_transition_started = false
1496
- Phronomy::Agent::ExecutionRegistry.for(event_loop).mark_agent_execution_admission(
1326
+ environment.registry.mark_agent_execution_admission(
1497
1327
  @agent.agent_id,
1498
1328
  execution_id: operation.execution_id,
1499
1329
  state: :terminalizing
1500
1330
  )
1501
1331
  terminal_transition_started = true
1502
- Phronomy::Agent::ExecutionRegistry.for(event_loop).register_agent_completion_waiter(
1332
+ environment.registry.register_agent_completion_waiter(
1503
1333
  operation.execution_id,
1504
1334
  delivery.result_task
1505
1335
  )
1506
- task = runtime.offload.submit(on_full: :raise) do
1336
+ task = environment.submit(on_full: :raise) do
1507
1337
  # Only the operation-specific immutable durable snapshot crosses the
1508
1338
  # worker boundary. TaskResult/listener delivery state stays outside it.
1509
1339
  @outcome_committer.commit_outcome(operation)
@@ -1517,23 +1347,23 @@ module Phronomy
1517
1347
  error: error
1518
1348
  )
1519
1349
  fail_task(delivery.result_task, runtime_rejected_error(:terminal_apply)) unless
1520
- post_control(runtime, ready)
1350
+ post_control(environment, ready)
1521
1351
  end
1522
1352
  rescue => error
1523
1353
  if terminal_transition_started
1524
- Phronomy::Agent::ExecutionRegistry.for(event_loop).mark_agent_execution_admission(
1354
+ environment.registry.mark_agent_execution_admission(
1525
1355
  @agent.agent_id,
1526
1356
  execution_id: operation.execution_id,
1527
1357
  state: :recovery_required
1528
1358
  )
1529
- Phronomy.configuration.logger&.warn(
1359
+ Phronomy::RuntimeSettings.current.logger&.warn(
1530
1360
  "[Phronomy] Agent terminal transition requires recovery for " \
1531
1361
  "#{operation.execution_id}: #{error.class}: #{error.message}"
1532
1362
  )
1533
1363
  return
1534
1364
  end
1535
1365
 
1536
- fail_task(delivery.result_task, translated(error))
1366
+ fail_task(delivery.result_task, error)
1537
1367
  raise
1538
1368
  end
1539
1369
 
@@ -1555,20 +1385,7 @@ module Phronomy
1555
1385
  )
1556
1386
  end
1557
1387
 
1558
- def handoff_terminal_view(request)
1559
- return unless request
1560
-
1561
- HandoffTerminalView.new(
1562
- target_agent_id: request.handoff.target_agent.agent_id.to_s.freeze,
1563
- responsibility: request.responsibility.to_s.freeze,
1564
- selection_intent: request.selection_intent.to_h do |category, included|
1565
- [category.to_s.freeze, !!included]
1566
- end.freeze,
1567
- llm_call_id: request.llm_call_id&.to_s&.freeze,
1568
- tool_call_id: request.tool_call_id&.to_s&.freeze,
1569
- policy: Phronomy::Values::Immutable.copy(request.handoff.policy.to_h)
1570
- )
1571
- end
1388
+ def handoff_terminal_view(request) = request
1572
1389
 
1573
1390
  def empty_runtime_snapshot
1574
1391
  {llm_results: [].freeze, runtime_events: [].freeze, active_call: nil}.freeze
@@ -1577,14 +1394,14 @@ module Phronomy
1577
1394
  def apply_terminal_commit_on_event_loop(ready)
1578
1395
  operation = ready.operation
1579
1396
  delivery = ready.delivery
1580
- event_loop = Phronomy::Runtime.instance.event_loop
1581
- state = Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_state(operation.execution_id)
1397
+ environment = @agent.__execution_environment
1398
+ state = environment.registry.agent_execution_state(operation.execution_id)
1582
1399
 
1583
1400
  if operation.state_required
1584
1401
  unless state && state.agent.equal?(@agent) &&
1585
1402
  state.execution.execution_revision == operation.expected_execution_revision &&
1586
1403
  state.fsm_session_id.to_s == operation.fsm_session_id.to_s
1587
- Phronomy.configuration.logger&.warn(
1404
+ Phronomy::RuntimeSettings.current.logger&.warn(
1588
1405
  "[Phronomy] Dropped stale Agent terminal result for #{operation.execution_id}"
1589
1406
  )
1590
1407
  return
@@ -1592,23 +1409,23 @@ module Phronomy
1592
1409
  end
1593
1410
 
1594
1411
  if ready.error
1595
- handle_terminal_commit_error_on_event_loop(ready, state, event_loop)
1412
+ handle_terminal_commit_error_on_event_loop(ready, state, environment)
1596
1413
  return
1597
1414
  end
1598
1415
 
1599
- apply_terminal_outcome_state_on_event_loop(ready, state, event_loop)
1416
+ apply_terminal_outcome_state_on_event_loop(ready, state, environment)
1600
1417
  outcome = ready.outcome
1601
1418
  case outcome.type
1602
1419
  when :coordination_wait
1603
- release_coordination_wait_on_event_loop(ready, state, event_loop)
1420
+ release_coordination_wait_on_event_loop(ready, state, environment)
1604
1421
  when :suspended
1605
- suspend_execution_on_event_loop(ready, state, event_loop)
1422
+ suspend_execution_on_event_loop(ready, state, environment)
1606
1423
  when :completed
1607
- deliver_completed_execution_on_event_loop(ready, state, event_loop)
1424
+ deliver_completed_execution_on_event_loop(ready, state, environment)
1608
1425
  when :handed_off
1609
- deliver_handoff_on_event_loop(ready, state, event_loop)
1426
+ deliver_handoff_on_event_loop(ready, state, environment)
1610
1427
  when :failed
1611
- deliver_failed_execution_on_event_loop(ready, state, event_loop)
1428
+ deliver_failed_execution_on_event_loop(ready, state, environment)
1612
1429
  else
1613
1430
  fail_task(
1614
1431
  delivery.result_task,
@@ -1617,28 +1434,28 @@ module Phronomy
1617
1434
  end
1618
1435
  end
1619
1436
 
1620
- def handle_terminal_commit_error_on_event_loop(ready, state, event_loop)
1437
+ def handle_terminal_commit_error_on_event_loop(ready, state, environment)
1621
1438
  operation = ready.operation
1622
1439
  delivery = ready.delivery
1623
- if operation.execution.metadata["coordination"] || operation.execution.metadata["multi_agent_coordination_ref"]
1624
- release_terminal_ownership(event_loop, operation.execution_id, state)
1625
- Phronomy::Agent::ExecutionRegistry.for(event_loop).take_agent_completion_waiters(operation.execution_id, fallback: delivery.result_task).each do |task|
1440
+ if operation.execution.metadata["reservation"] || operation.execution.metadata["execution_extension"]
1441
+ release_terminal_ownership(environment, operation.execution_id, state)
1442
+ environment.registry.take_agent_completion_waiters(operation.execution_id, fallback: delivery.result_task).each do |task|
1626
1443
  task.fail(ready.error)
1627
1444
  end
1628
1445
  return
1629
1446
  end
1630
- Phronomy::Agent::ExecutionRegistry.for(event_loop).mark_agent_execution_admission(
1447
+ environment.registry.mark_agent_execution_admission(
1631
1448
  @agent.agent_id,
1632
1449
  execution_id: operation.execution_id,
1633
1450
  state: :recovery_required
1634
1451
  )
1635
- Phronomy.configuration.logger&.warn(
1452
+ Phronomy::RuntimeSettings.current.logger&.warn(
1636
1453
  "[Phronomy] Agent terminal durable outcome requires recovery for " \
1637
1454
  "#{operation.execution_id}: #{ready.error.class}: #{ready.error.message}"
1638
1455
  )
1639
1456
  end
1640
1457
 
1641
- def apply_terminal_outcome_state_on_event_loop(ready, state, event_loop)
1458
+ def apply_terminal_outcome_state_on_event_loop(ready, state, environment)
1642
1459
  operation = ready.operation
1643
1460
  outcome = ready.outcome
1644
1461
  apply_agent_live_state(
@@ -1647,7 +1464,7 @@ module Phronomy
1647
1464
  )
1648
1465
  if state
1649
1466
  state.invocation&.acknowledge_runtime_snapshot(operation.runtime_snapshot)
1650
- Phronomy::Agent::ExecutionRegistry.for(event_loop).replace_agent_execution(
1467
+ environment.registry.replace_agent_execution(
1651
1468
  operation.execution_id,
1652
1469
  execution: outcome.execution,
1653
1470
  fsm_session_id: (outcome.type == :suspended) ? nil : state.fsm_session_id
@@ -1655,19 +1472,19 @@ module Phronomy
1655
1472
  end
1656
1473
  end
1657
1474
 
1658
- def release_coordination_wait_on_event_loop(ready, state, event_loop)
1475
+ def release_coordination_wait_on_event_loop(ready, state, environment)
1659
1476
  operation = ready.operation
1660
1477
  delivery = ready.delivery
1661
1478
  outcome = ready.outcome
1662
- release_terminal_ownership(event_loop, operation.execution_id, state)
1663
- Phronomy::Agent::ExecutionRegistry.for(event_loop).take_agent_completion_waiters(operation.execution_id, fallback: delivery.result_task).each { |task| task.fail(outcome.error) }
1479
+ release_terminal_ownership(environment, operation.execution_id, state)
1480
+ environment.registry.take_agent_completion_waiters(operation.execution_id, fallback: delivery.result_task).each { |task| task.fail(outcome.error) }
1664
1481
  end
1665
1482
 
1666
- def suspend_execution_on_event_loop(ready, state, event_loop)
1483
+ def suspend_execution_on_event_loop(ready, state, environment)
1667
1484
  operation = ready.operation
1668
1485
  delivery = ready.delivery
1669
1486
  outcome = ready.outcome
1670
- Phronomy::Agent::ExecutionRegistry.for(event_loop).mark_agent_execution_admission(
1487
+ environment.registry.mark_agent_execution_admission(
1671
1488
  @agent.agent_id,
1672
1489
  execution_id: operation.execution_id,
1673
1490
  state: :suspended
@@ -1688,39 +1505,39 @@ module Phronomy
1688
1505
  end
1689
1506
  end
1690
1507
 
1691
- def deliver_completed_execution_on_event_loop(ready, state, event_loop)
1508
+ def deliver_completed_execution_on_event_loop(ready, state, environment)
1692
1509
  operation = ready.operation
1693
1510
  delivery = ready.delivery
1694
1511
  outcome = ready.outcome
1695
- release_terminal_ownership(event_loop, operation.execution_id, state)
1512
+ release_terminal_ownership(environment, operation.execution_id, state)
1696
1513
  callback_error = deliver_terminal(delivery.application_listener, :done, outcome.result)
1697
1514
  settle_execution_waiters(
1698
- event_loop, operation.execution_id, delivery.result_task,
1515
+ environment, operation.execution_id, delivery.result_task,
1699
1516
  callback_error, :done, outcome.result
1700
1517
  )
1701
1518
  end
1702
1519
 
1703
- def deliver_handoff_on_event_loop(ready, state, event_loop)
1520
+ def deliver_handoff_on_event_loop(ready, state, environment)
1704
1521
  operation = ready.operation
1705
1522
  delivery = ready.delivery
1706
1523
  outcome = ready.outcome
1707
- release_terminal_ownership(event_loop, operation.execution_id, state)
1524
+ release_terminal_ownership(environment, operation.execution_id, state)
1708
1525
  result = outcome.result.merge(
1709
1526
  handoff_request: delivery.handoff_request,
1710
1527
  _phronomy_handoff_manifest: delivery.handoff_manifest
1711
1528
  ).freeze
1712
1529
  callback_error = deliver_terminal(delivery.application_listener, :handoff, result)
1713
1530
  settle_execution_waiters(
1714
- event_loop, operation.execution_id, delivery.result_task,
1531
+ environment, operation.execution_id, delivery.result_task,
1715
1532
  callback_error, :handoff, result
1716
1533
  )
1717
1534
  end
1718
1535
 
1719
- def deliver_failed_execution_on_event_loop(ready, state, event_loop)
1536
+ def deliver_failed_execution_on_event_loop(ready, state, environment)
1720
1537
  operation = ready.operation
1721
1538
  delivery = ready.delivery
1722
1539
  outcome = ready.outcome
1723
- release_terminal_ownership(event_loop, operation.execution_id, state)
1540
+ release_terminal_ownership(environment, operation.execution_id, state)
1724
1541
  type = terminal_event_type(outcome.error)
1725
1542
  callback_error = deliver_terminal(
1726
1543
  delivery.application_listener,
@@ -1728,13 +1545,13 @@ module Phronomy
1728
1545
  error: outcome.error
1729
1546
  )
1730
1547
  settle_execution_waiters(
1731
- event_loop, operation.execution_id, delivery.result_task,
1548
+ environment, operation.execution_id, delivery.result_task,
1732
1549
  callback_error, type, nil, outcome.error
1733
1550
  )
1734
1551
  end
1735
1552
 
1736
- def release_terminal_ownership(event_loop, execution_id, state)
1737
- registry = Phronomy::Agent::ExecutionRegistry.for(event_loop)
1553
+ def release_terminal_ownership(environment, execution_id, state)
1554
+ registry = environment.registry
1738
1555
  registry.release_agent_execution(execution_id) if state
1739
1556
  registry.release_agent_execution_admission(@agent.agent_id, execution_id: execution_id)
1740
1557
  end
@@ -1749,16 +1566,16 @@ module Phronomy
1749
1566
  expected_execution_revision:,
1750
1567
  expected_fsm_state:
1751
1568
  )
1752
- event_loop = Phronomy::Runtime.instance.event_loop
1753
- state = Phronomy::Agent::ExecutionRegistry.for(event_loop).agent_execution_state(execution_id)
1569
+ environment = @agent.__execution_environment
1570
+ state = environment.registry.agent_execution_state(execution_id)
1754
1571
  authoritative = state &&
1755
1572
  state.agent.equal?(@agent) &&
1756
1573
  state.execution.execution_revision == expected_execution_revision &&
1757
1574
  state.fsm_session_id.to_s == fsm_session_id.to_s &&
1758
- event_loop.fsm_session_state(fsm_session_id) == expected_fsm_state
1575
+ environment.session_phase(fsm_session_id) == expected_fsm_state
1759
1576
  return state if authoritative
1760
1577
 
1761
- Phronomy.configuration.logger&.warn(
1578
+ Phronomy::RuntimeSettings.current.logger&.warn(
1762
1579
  "[Phronomy] Dropped stale Agent operation result: " \
1763
1580
  "execution_id=#{execution_id} fsm_session_id=#{fsm_session_id}"
1764
1581
  )
@@ -1777,14 +1594,14 @@ module Phronomy
1777
1594
  end
1778
1595
 
1779
1596
  def apply_agent_live_state(root:, appended_records:)
1780
- event_loop = Phronomy::Runtime.instance.event_loop
1781
- assert_event_loop!(event_loop)
1597
+ environment = @agent.__execution_environment
1598
+ assert_event_loop!(environment)
1782
1599
  @agent.send(:_append_journal_records, appended_records)
1783
1600
  @agent.__replace_root(root)
1784
1601
  end
1785
1602
 
1786
- def assert_event_loop!(event_loop)
1787
- return if event_loop.current?
1603
+ def assert_event_loop!(environment)
1604
+ return if environment.executing?
1788
1605
 
1789
1606
  raise Phronomy::Error,
1790
1607
  "ExecutionCoordinator live-state apply must run on EventLoop"
@@ -1803,20 +1620,26 @@ module Phronomy
1803
1620
  def dispatch_approval_listener(listener, request)
1804
1621
  return unless listener
1805
1622
 
1806
- Phronomy::Runtime.instance.offload.submit(on_full: :raise) do
1623
+ Phronomy::Blocking.call_async do
1807
1624
  listener.call(request)
1625
+ end.on_complete do |_value, error|
1626
+ report_approval_dispatch_failure(error) if error
1808
1627
  end
1809
1628
  rescue => error
1810
- Phronomy.configuration.logger&.warn(
1629
+ report_approval_dispatch_failure(error)
1630
+ end
1631
+
1632
+ def report_approval_dispatch_failure(error)
1633
+ Phronomy::RuntimeSettings.current.logger&.warn(
1811
1634
  "[Phronomy] approval listener dispatch failed: #{error.class}: #{error.message}"
1812
1635
  )
1813
1636
  end
1814
1637
 
1815
1638
  def settle_execution_waiters(
1816
- event_loop, execution_id, fallback_task, callback_error, event_type,
1639
+ environment, execution_id, fallback_task, callback_error, event_type,
1817
1640
  result, execution_error = nil
1818
1641
  )
1819
- waiters = Phronomy::Agent::ExecutionRegistry.for(event_loop).take_agent_completion_waiters(
1642
+ waiters = environment.registry.take_agent_completion_waiters(
1820
1643
  execution_id,
1821
1644
  fallback: fallback_task
1822
1645
  )
@@ -1835,7 +1658,7 @@ module Phronomy
1835
1658
  callback_error,
1836
1659
  event: StreamEvent.new(type: event_type, payload: result),
1837
1660
  execution_id: result&.fetch(:execution_id, nil),
1838
- callback_error_policy: Phronomy.configuration.stream_callback_error_policy
1661
+ callback_error_policy: Phronomy::Agent::Settings.current.stream_callback_error_policy
1839
1662
  )
1840
1663
  end
1841
1664
 
@@ -1847,7 +1670,7 @@ module Phronomy
1847
1670
  execution_error = nil
1848
1671
  )
1849
1672
  if callback_error
1850
- policy = Phronomy.configuration.stream_callback_error_policy
1673
+ policy = Phronomy::Agent::Settings.current.stream_callback_error_policy
1851
1674
  @agent.send(
1852
1675
  :_report_stream_callback_error,
1853
1676
  callback_error,
@@ -1888,7 +1711,7 @@ module Phronomy
1888
1711
  :error
1889
1712
  end
1890
1713
 
1891
- def post_control(runtime, command)
1714
+ def post_control(environment, command)
1892
1715
  admission = command.is_a?(StartCommand) || command.is_a?(ResumeCommand)
1893
1716
  completion = case command
1894
1717
  when StartCommand, ResumeCommand then command.result_task
@@ -1897,7 +1720,7 @@ module Phronomy
1897
1720
  when TerminalCommitReady then command.delivery.result_task
1898
1721
  when DeferredTerminalCommand then command.result_task
1899
1722
  end
1900
- ExecutionRegistry.for(runtime.event_loop).post(command,
1723
+ environment.registry.post(command,
1901
1724
  admission: admission, completion: completion)
1902
1725
  rescue Phronomy::RuntimeShutdownError
1903
1726
  false
@@ -1909,10 +1732,6 @@ module Phronomy
1909
1732
  )
1910
1733
  end
1911
1734
 
1912
- def translated(error)
1913
- @agent.send(:_translated_error, error)
1914
- end
1915
-
1916
1735
  def complete_task(task, result)
1917
1736
  @agent.send(:_complete_result_task, task, result)
1918
1737
  end