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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '095ac1376e77f34201dceeafec7dc114340aa2cae7cd8f1bb2bb7c2552e64e87'
4
- data.tar.gz: 4d900c3bdc20e3fb0210046daffc4d78d1b990f118281c04037cc45beca2d699
3
+ metadata.gz: f097c81530a33bd631974866ff26a0d2ec8b4793286c6dfa0bb0facaac4fdd83
4
+ data.tar.gz: 80b9980737c80446f660d9a058aa1b898bdcdec452e517764261c386c32a1e78
5
5
  SHA512:
6
- metadata.gz: 3108c48424885f72ea256e6c7cd7dfa8a7230647727f288f9fce840ee9309a51b523e64748663a7d1341e88b0c05cfe5432cb91a521039b16f28b0e2c14a4714
7
- data.tar.gz: 51795e8c019cb92d8a17eadb864b726f9359ed1c963b06acfb52cb7440b99234755ad2c7e169a5afb8e5958ea45b99635d9035eea4d3c4ceb84ac4d554fdc814
6
+ metadata.gz: 2cacf04ecea168021b36835f12901723380a7a908d0173f23b564e9bb67d4f85cf46bf958949fd4257043393234ef5acc7e8d9cecdcf68beac61b0c7ce454084
7
+ data.tar.gz: c7f7b1d9cbcd54d0d0d9bb7583e5587ecadfafa987788f44e8c8abc0f9fa75241092d63a543669b55a6837fc1c2c09c102cf514578b6c266b2c85ff17d2ba2cc
data/.mutant.yml CHANGED
@@ -9,14 +9,14 @@ matcher:
9
9
  subjects:
10
10
  - Phronomy::WorkflowContext
11
11
  - Phronomy::WorkflowRunner
12
- # Phronomy::Tool::Base is a public constant alias to this same Class object.
13
- # Use the implementation canonical name returned by Class#name for Mutant.
14
- - Phronomy::Agent::Context::Capability::Base
12
+ - Phronomy::Tool::Base
13
+ - Phronomy::Tool::Schema
15
14
  - Phronomy::LlmContextWindow::TokenBudget
16
- - Phronomy::Agent::ContextAssembler
17
- - Phronomy::Agent::ContextPolicies::Default
18
- - Phronomy::Agent::ContextPolicyInputBuilder
19
- - Phronomy::Agent::ContextPlanValidator
20
- - Phronomy::Agent::HandoffPolicy
21
- - Phronomy::Agent::HandoffProjection
15
+ - Phronomy::Context::Assembly
16
+ - Phronomy::Agent::ContextPreparation
17
+ - Phronomy::Context::DefaultPolicy
18
+ - Phronomy::Context::ContextPolicyInputBuilder
19
+ - Phronomy::Context::ContextPlanValidator
20
+ - Phronomy::MultiAgent::HandoffPolicy
21
+ - Phronomy::Agent::TransferProjection
22
22
  - Phronomy::VectorStore::InMemory
data/CHANGELOG.md CHANGED
@@ -12,6 +12,58 @@ Release history for 0.14.0 and earlier is archived in
12
12
 
13
13
  ## [Unreleased]
14
14
 
15
+ ### r8 first implementation unit (breaking, unreleased)
16
+
17
+ - Move Context policy/plan/manifest/budget/prompt operations into `Phronomy::Context`.
18
+ Agent retains snapshot, journal and lifecycle ownership. Manifest and execution
19
+ references remain written within the same transaction.
20
+ - Make `Tool::Base` the actual implementation; move common definition and
21
+ authorization operations into Tool. Remove the old Agent Context namespace.
22
+ - Move chat construction and SDK failure translation into the LLM adapter.
23
+ Custom synchronous adapters must implement the expanded construction SPI.
24
+ - Unite execution contracts and services in `execution/`; move FSM values and
25
+ scheduling bindings to Engine, observation to Tracing. Keep result/control
26
+ rules independent of Engine startup. Update Ruby/RBS analysis and diagrams.
27
+ - Remove empty contract-only subdivisions and old API aliases. This unit does
28
+ not complete r8 Persistence, parent admission or all domain FSM separation.
29
+ See [the scope and migration report](docs/architecture/r8-unit1.md).
30
+
31
+ ### Changed
32
+
33
+ - Add public Beta `Storage::AsyncClient#transaction_async` and route 16 existing
34
+ durable Agent/Workflow/coordination execution units through its private submit
35
+ boundary. Preserve transaction/savepoint, result reconciliation and admission
36
+ policy; do not add cancellation or timeout to existing terminal writes.
37
+ - Move StoredContents into `content_store/backends/` without changing its
38
+ constant or behavior. Complete P4; see the
39
+ [Storage client guide](docs/migrations/storage-async-client.md).
40
+ - Preserve transparent text panels and module outlines in generated diagrams.
41
+ Hide arrows into M33/M41/M44 as a display choice; keep their measured source
42
+ dependencies, evidence and complete matrix.
43
+
44
+ - **Beta API receiver migration:** move VectorStore `add_async`, `search_async`,
45
+ `remove_async`, `clear_async` and Embeddings `embed_async` onto the public
46
+ feature-specific `AsyncClient` objects. Synchronous backend methods and
47
+ concrete class names remain unchanged. Remove the inherited async methods
48
+ and `VectorStore::AsyncBackend`; see the
49
+ [migration guide](docs/migrations/vector-async-clients.md).
50
+ - Split VectorStore/Embeddings implementations into collapsed `backends/`
51
+ directories. Synchronous RBS uses structural cancellation; separate client
52
+ signatures retain TaskResult and the full execution token. Complete P3 and
53
+ remove the remaining backend-to-Engine edges from the measured graph.
54
+
55
+ - Separate the synchronous LLMAdapter SPI, RubyLLM implementation and internal
56
+ AsyncClient. Adapter authors implement only `complete` and `stream`; default
57
+ configuration, provider behavior, admission/cancellation and Agent event
58
+ delivery remain unchanged. See
59
+ [ADR-059](docs/decisions/059-backend-contracts-and-async-clients.md).
60
+ - Separate responsibility groups from the diagram's B1-B6 display layers. Add
61
+ the source-derived SVG/matrix generator and Architecture CI boundary gate;
62
+ retain individual module boxes, stable module IDs and the earlier horizontal
63
+ layer layout with topical columns. Separated Contracts belong in B5 beside
64
+ the independent Engine group; clients, implementations and pending mixed
65
+ backends are displayed in B4. Storage/ContentStore migration remains pending.
66
+
15
67
  ---
16
68
 
17
69
  ## [0.27.0] - 2026-09-24
data/CONTRIBUTING.md CHANGED
@@ -219,14 +219,14 @@ The authoritative subject list is `.mutant.yml`. It currently includes:
219
219
 
220
220
  - `Phronomy::WorkflowContext`
221
221
  - `Phronomy::WorkflowRunner`
222
- - `Phronomy::Agent::Context::Capability::Base`
222
+ - `Phronomy::Tool::Base`
223
223
  - `Phronomy::LlmContextWindow::TokenBudget`
224
- - `Phronomy::Agent::ContextAssembler`
225
- - `Phronomy::Agent::ContextPolicies::Default`
226
- - `Phronomy::Agent::ContextPolicyInputBuilder`
227
- - `Phronomy::Agent::ContextPlanValidator`
228
- - `Phronomy::Agent::HandoffPolicy`
229
- - `Phronomy::Agent::HandoffProjection`
224
+ - `Phronomy::Agent::ContextPreparation`
225
+ - `Phronomy::Context::DefaultPolicy`
226
+ - `Phronomy::Context::ContextPolicyInputBuilder`
227
+ - `Phronomy::Context::ContextPlanValidator`
228
+ - `Phronomy::MultiAgent::HandoffPolicy`
229
+ - `Phronomy::Agent::TransferProjection`
230
230
  - `Phronomy::VectorStore::InMemory`
231
231
 
232
232
  The nightly mutation matrix mirrors this authoritative list so each subject can
@@ -235,7 +235,7 @@ configuration-consistency guard that fails if the nightly subject set diverges
235
235
  from `.mutant.yml`.
236
236
 
237
237
  The Tool mutation subject intentionally uses
238
- `Phronomy::Agent::Context::Capability::Base`, which is the implementation
238
+ `Phronomy::Tool::Base`, which is the implementation
239
239
  canonical name returned by the single Class object's runtime `Class#name`.
240
240
  `Phronomy::Tool::Base` is the public facade constant alias to that same Class
241
241
  object; it is not a second Tool base class.
data/README.md CHANGED
@@ -8,7 +8,11 @@
8
8
 
9
9
  **Phronomy** is a Ruby AI agent framework for stateful Agents, Workflows, Tools,
10
10
  context management, filtering, tracing, and multi-agent coordination. Large Language
11
- Model (LLM) access is provided through [RubyLLM](https://github.com/crmne/ruby_llm).
11
+ Model (LLM) operations use `Phronomy::LLMAdapter`; the default backend uses
12
+ [RubyLLM](https://github.com/crmne/ruby_llm). Custom backends implement the
13
+ [SDK-independent LLM contract](docs/migrations/r8-unit6.md).
14
+ Tool declarations and argument validation belong to `Phronomy::Tool`, independently
15
+ of the selected LLM backend.
12
16
 
13
17
  Phronomy is pre-1.0. Pin to a released gem version for production use rather than
14
18
  tracking `main` directly.
@@ -16,7 +20,7 @@ tracking `main` directly.
16
20
  ## Core concepts
17
21
 
18
22
  - **Agent** — stateful, persistence-backed LLM agent with canonical execution history.
19
- - **Persistence** — unified durable backend for Agent state and Workflow `workflow_states`.
23
+ - **Persistence** — shared atomic scopes with domain-owned Agent/Team stores and Workflow checkpoints.
20
24
  - **Workflow** — state-machine-driven application workflow with explicit events and wait states.
21
25
  - **Tool / Capability** — callable application capability exposed to an Agent; application-defined Tools subclass `Phronomy::Tool::Base`.
22
26
  - **Multi-Agent Handoff** — semantic Source-to-Target responsibility transfer with policy-bounded Context projection and persisted active responsibility and exact Target recovery within one Persistence domain.
@@ -88,7 +92,7 @@ puts result[:output]
88
92
  ```
89
93
 
90
94
  `Phronomy::Tool::Base` is the public authoring name for the existing Tool base
91
- class. The legacy `Phronomy::Agent::Context::Capability::Base` constant remains
95
+ class. The legacy `Phronomy::Tool::Base` constant remains
92
96
  valid for compatibility.
93
97
 
94
98
  For non-blocking top-level use, call `invoke_async` and keep the returned
@@ -155,6 +159,8 @@ contracts, timeout/cancellation semantics, metrics, and callback rules.
155
159
  - [MCP client](docs/mcp-client.md) — Model Context Protocol (MCP) integration and supported schema subset.
156
160
  - [Migration from 0.15-era APIs](docs/migrations/0.15.md).
157
161
  - [0.16 cleanup migration](docs/migrations/0.16.md).
162
+ - [r8 persistence boundary migration](docs/architecture/r8-unit3.md) — domain stores, shared scopes, and removed facade APIs.
163
+ - [Persistence failure contract migration](docs/migrations/persistence-failure-contracts.md) — domain rescue clauses and unchanged raw backend errors.
158
164
  - [0.19 unified Persistence migration](docs/migrations/0.19.md).
159
165
  - [0.22 semantic Multi-Agent Handoff migration](docs/migrations/0.22.md).
160
166
  - [Architecture Decision Records](docs/decisions/) — design rationale and superseding decisions.
@@ -19,49 +19,21 @@ require_relative "../lib/phronomy"
19
19
  # Shared stubs
20
20
  # ---------------------------------------------------------------------------
21
21
 
22
- module BenchAgentMessage
23
- def self.assistant(content = "done")
24
- RubyLLM::Message.new(
25
- role: :assistant, content: content,
26
- tokens: RubyLLM::Tokens.new(input: 5, output: 5, cache_read: 0, cache_write: 0)
27
- )
28
- end
29
- end
30
-
31
- # A minimal stub Chat that returns a pre-built response immediately.
32
- class BenchStubChat
33
- attr_reader :messages
34
-
22
+ # A stub backend that preserves the adapter's validation/cancellation template.
23
+ class BenchStubLLMAdapter < Phronomy::LLMAdapter::Base
35
24
  def initialize(response)
36
25
  @response = response
37
- @messages = []
38
- end
39
-
40
- def with_instructions(_, **_options) = self
41
- def with_tools(*) = self
42
- def with_temperature(_) = self
43
- def with_cache_instructions(_) = self
44
- def with_output_schema(_) = self
45
- def last_message = @response
46
-
47
- def after_message(&block)
48
- @after_message = block
49
- self
50
26
  end
51
27
 
52
- def ask(_)
53
- complete
54
- end
28
+ protected
55
29
 
56
- def complete
57
- @messages << @response
58
- @after_message&.call(@response)
30
+ def perform_complete(request, cancellation_token:)
59
31
  @response
60
32
  end
61
33
  end
62
34
 
63
35
  # A stub tool that does nothing but conforms to the Tool::Base interface.
64
- class BenchNullTool < Phronomy::Agent::Context::Capability::Base
36
+ class BenchNullTool < Phronomy::Tool::Base
65
37
  description "No-op benchmark tool"
66
38
  param :x, type: :string, desc: "input"
67
39
 
@@ -74,38 +46,41 @@ end
74
46
  # Agent classes
75
47
  # ---------------------------------------------------------------------------
76
48
 
77
- BENCH_RESP = BenchAgentMessage.assistant("benchmark complete")
49
+ BENCH_RESP = Phronomy::LLMAdapter::Response.new(
50
+ content: "benchmark complete",
51
+ usage: Phronomy::LLMAdapter::TokenUsage.new(input: 5, output: 5, cached: 0, cache_creation: 0)
52
+ )
78
53
 
79
54
  bench_minimal_class = Class.new(Phronomy::Agent::Base) do
80
55
  agent_definition id: "bench-minimal", version: 1
81
56
  model "stub-model"
82
-
83
- define_method(:build_chat) { |*| BenchStubChat.new(BENCH_RESP) }
84
57
  end
85
58
 
86
59
  bench_tool_class = Class.new(Phronomy::Agent::Base) do
87
60
  agent_definition id: "bench-tool", version: 1
88
61
  model "stub-model"
89
62
  tools(BenchNullTool => nil)
90
-
91
- define_method(:build_chat) { |*| BenchStubChat.new(BENCH_RESP) }
92
63
  end
93
64
 
94
65
  AGENT_INVOKE_ITERATIONS = 200
95
- BENCH_AGENTS_MINIMAL = Array.new(AGENT_INVOKE_ITERATIONS) { bench_minimal_class.new }.freeze
96
- BENCH_AGENTS_TOOLS = Array.new(AGENT_INVOKE_ITERATIONS) { bench_tool_class.new }.freeze
97
-
98
- puts "=== bench_agent_invoke ==="
99
- Benchmark.bm(50) do |x|
100
- x.report("Agent#invoke — fresh, no tools, #{AGENT_INVOKE_ITERATIONS} iters") do
101
- BENCH_AGENTS_MINIMAL.each do |agent|
102
- agent.invoke("ping")
66
+
67
+ Phronomy.with_configuration do |config|
68
+ config.llm_adapter = BenchStubLLMAdapter.new(BENCH_RESP)
69
+ bench_agents_minimal = Array.new(AGENT_INVOKE_ITERATIONS) { bench_minimal_class.new }.freeze
70
+ bench_agents_tools = Array.new(AGENT_INVOKE_ITERATIONS) { bench_tool_class.new }.freeze
71
+
72
+ puts "=== bench_agent_invoke ==="
73
+ Benchmark.bm(50) do |x|
74
+ x.report("Agent#invoke — fresh, no tools, #{AGENT_INVOKE_ITERATIONS} iters") do
75
+ bench_agents_minimal.each do |agent|
76
+ agent.invoke("ping")
77
+ end
103
78
  end
104
- end
105
79
 
106
- x.report("Agent#invoke — fresh, tool-aware, #{AGENT_INVOKE_ITERATIONS} iters") do
107
- BENCH_AGENTS_TOOLS.each do |agent|
108
- agent.invoke("ping")
80
+ x.report("Agent#invoke — fresh, tool-aware, #{AGENT_INVOKE_ITERATIONS} iters") do
81
+ bench_agents_tools.each do |agent|
82
+ agent.invoke("ping")
83
+ end
109
84
  end
110
85
  end
111
86
  end
@@ -14,7 +14,7 @@ module BenchContextAssembler
14
14
  module_function
15
15
 
16
16
  def provenance
17
- Phronomy::Agent::ContextPolicyInput::Provenance.new(origin: :journal)
17
+ Phronomy::Context::ContextPolicyInput::Provenance.new(origin: :journal)
18
18
  end
19
19
 
20
20
  def policy_input(item_count)
@@ -22,13 +22,13 @@ module BenchContextAssembler
22
22
  conversation = []
23
23
  item_count.times do |index|
24
24
  if (index % 10).zero?
25
- knowledge << Phronomy::Agent::ContextPolicyInput::KnowledgeItem.new(
25
+ knowledge << Phronomy::Context::ContextPolicyInput::KnowledgeItem.new(
26
26
  id: "knowledge-#{index}", kind: :knowledge, role: :user,
27
27
  content: "knowledge #{index}", content_format: :text,
28
28
  estimated_tokens: 8, required: false, provenance: provenance, metadata: {}
29
29
  )
30
30
  else
31
- conversation << [Phronomy::Agent::ContextPolicyInput::ConversationItem.new(
31
+ conversation << [Phronomy::Context::ContextPolicyInput::ConversationItem.new(
32
32
  id: "message-#{index}", kind: :external_message, role: :user,
33
33
  content: "message #{index}", content_format: :text,
34
34
  sequence: index, estimated_tokens: 8, required: false,
@@ -38,7 +38,7 @@ module BenchContextAssembler
38
38
  end
39
39
  end
40
40
 
41
- Phronomy::Agent::ContextPolicyInput.new(
41
+ Phronomy::Context::ContextPolicyInput.new(
42
42
  agent_id: "bench-agent", execution_id: "bench-execution",
43
43
  call_sequence: 2, call_mode: :complete,
44
44
  instruction: [], knowledge: knowledge, tools: [], conversation: conversation,
@@ -50,7 +50,7 @@ module BenchContextAssembler
50
50
  end
51
51
 
52
52
  def assembler_fixture
53
- persistence = Phronomy::Persistence.in_memory
53
+ persistence = Phronomy::PersistenceComposition.in_memory.agent
54
54
  agent_class = Class.new(Phronomy::Agent::Base) do
55
55
  agent_definition id: "bench-manifest-context-assembler", version: 1
56
56
  # Resolve capabilities from RubyLLM's bundled registry; no provider call.
@@ -86,9 +86,10 @@ module BenchContextAssembler
86
86
  )
87
87
 
88
88
  [
89
- Phronomy::Agent::ContextAssembler.new(agent: agent, persistence: persistence),
89
+ Phronomy::Agent::ContextPreparation.new(agent: agent, persistence: persistence),
90
90
  root,
91
- execution
91
+ execution,
92
+ persistence
92
93
  ]
93
94
  end
94
95
  end
@@ -97,7 +98,7 @@ puts "Typed Context Policy benchmark"
97
98
  puts "Ruby #{RUBY_VERSION} on #{RUBY_PLATFORM}"
98
99
  puts "=" * 72
99
100
 
100
- policy = Phronomy::Agent::ContextPolicies::Default.instance
101
+ policy = Phronomy::Context::DefaultPolicy.instance
101
102
  policy_inputs = [10, 100, 1_000].to_h do |count|
102
103
  [count, BenchContextAssembler.policy_input(count)]
103
104
  end
@@ -110,15 +111,17 @@ Benchmark.bm(46) do |x|
110
111
  end
111
112
  end
112
113
 
113
- assembler, root, execution = BenchContextAssembler.assembler_fixture
114
- x.report("ContextAssembler prepare/finalize x500") do
114
+ assembler, root, execution, persistence = BenchContextAssembler.assembler_fixture
115
+ x.report("Context prepare/store x500") do
115
116
  500.times do
116
117
  prepared = assembler.prepare_initial(
117
118
  input: "benchmark input",
118
119
  agent_root: root,
119
120
  execution: execution
120
121
  )
121
- assembler.finalize(prepared)
122
+ persistence.transaction do |tx|
123
+ Phronomy::Context::Assembly.new.store(prepared, contents: tx.contents)
124
+ end
122
125
  end
123
126
  end
124
127
  end
@@ -69,7 +69,7 @@ end
69
69
  # ---------------------------------------------------------------------------
70
70
  # Target 3: Tool::Base#params_schema generation (10 params)
71
71
  # ---------------------------------------------------------------------------
72
- tool_class = Class.new(Phronomy::Agent::Context::Capability::Base) do
72
+ tool_class = Class.new(Phronomy::Tool::Base) do
73
73
  description "Test tool with 10 params"
74
74
  param :p1, type: :string, desc: "param 1"
75
75
  param :p2, type: :string, desc: "param 2"
@@ -7,7 +7,7 @@
7
7
  require "benchmark"
8
8
  require_relative "../lib/phronomy"
9
9
 
10
- class BenchTool10Params < Phronomy::Agent::Context::Capability::Base
10
+ class BenchTool10Params < Phronomy::Tool::Base
11
11
  description "A tool with 10 parameters for benchmarking purposes"
12
12
  param :param1, type: :string, desc: "First parameter"
13
13
  param :param2, type: :integer, desc: "Second parameter"
@@ -1,5 +1,11 @@
1
1
  # Agent Chat and explicit state ownership (R09, second slice)
2
2
 
3
+ > Current boundary: r8 unit 6 supersedes the historical Chat/SDK ownership and
4
+ > adapter extension SPI below. Agent uses LLMAdapter values; the backend owns SDK
5
+ > construction/interception; Tool owns canonical schema validation. See
6
+ > `docs/architecture/r8-unit6.md` and `docs/migrations/r8-unit6.md`.
7
+
8
+
3
9
  ## Purpose and clients
4
10
 
5
11
  Agent::Base is the declaration and lifecycle facade used by application Agent
@@ -62,7 +68,7 @@ hook retains application/test overrides of apply_instructions and Orchestrator's
62
68
  prepare_tool_class(invocation:) cooperation. Moving it into a builder receiving
63
69
  the entire Agent would merely introduce callbacks back into Base.
64
70
 
65
- AgentInvocationSessionBuilder and InvocationRestorer keep using the same hooks.
71
+ InvocationActions and EngineSessionBuilder and InvocationRestorer keep using the same hooks.
66
72
  Saved config is authoritative during recovery; current class declarations do
67
73
  not overwrite it. A failure stops installation at that operation, propagates
68
74
  the same error and does not install later Tools/messages. No new Chat cache,
@@ -1,89 +1,13 @@
1
- # Agent invocation transition ownership
2
-
3
- ## Role and scope
4
-
5
- An Agent invocation moves between preparation, Provider calls, Tool processing,
6
- approval suspension and completion. Three collaborators need the same policy:
7
- AgentInvocation consumes external payloads; PhaseMachineBuilder creates the
8
- executable state machine; AgentInvocationSessionBuilder configures FSMSession's
9
- advance, wait and terminal boundaries. Independently maintained event lists and
10
- transition copies could disagree about what the current phase can accept.
11
-
12
- Refactor 39 gives that shared policy one private owner, InvocationTransitions in
13
- agent/execution. This is Agent data in the existing transition Hash format, not
14
- a new cross-feature DSL or Engine extension. It is not a new execution object.
15
-
16
- ## Ownership and reading order
17
-
18
- | Owner | Responsibility |
19
- |---|---|
20
- | InvocationTransitions | Initial phase, declared/automatic/approval-wait states, Tool event vocabulary and ordered external transition definitions. |
21
- | PhaseMachineBuilder | Translate those external definitions to state_machines; retain automatic state_completed transitions and synchronous entry-action validation. |
22
- | AgentInvocationSessionBuilder | Assemble the invocation, event sink, entry actions and machine; pass shared state and transition metadata to FSMSession. |
23
- | AgentInvocation | Apply payloads and expose the current guard predicates; use the shared Tool event vocabulary. |
24
- | FSMSession | Generic advancement, event delivery and wait/terminal handling. No Agent-specific decisions. |
25
-
26
- Read the policy table for legal external sources and guard priority, the machine
27
- builder for execution mechanics, and the session builder for action wiring.
28
- The EXTERNAL_EVENTS Hash, each transition array and each row are frozen so one
29
- session cannot edit another session's policy. Guard lambdas contain no captured
30
- invocation state; they inspect the context supplied at transition time.
31
- Old private constants and the external_events factory are removed without aliases.
32
-
33
- ## Preserved event and phase contract
34
-
35
- The six Tool events are authorized, approval_required, completed, failed,
36
- rejected and cancelled, each with the tool_ prefix. Each moves waiting_for_tools
37
- to evaluating_tools. LLM completion from calling_llm tries these in order:
38
-
39
- 1. callback_failed? to failed;
40
- 2. handoff_failed? to failed;
41
- 3. handoff_requested? to handed_off;
42
- 4. tool_call_pending? to starting_tools;
43
- 5. unconditional fallback to output_filtering.
44
-
45
- Guards short-circuit. A nil context skips guarded rows and takes the fallback;
46
- guard exceptions propagate unchanged. Each evaluation uses the latest context,
47
- without caching a selected destination. Session applies the event payload first.
48
-
49
- LLM failure/setup failure leads from calling_llm to failed. Tool setup failure
50
- leads from dispatching_tools to failed, while tool_dispatch_prepared returns it
51
- to evaluating_tools. Resume moves suspended to waiting_for_tools. Application
52
- callback failure is accepted from the existing nine active phases only.
53
-
54
- Automatic phases remain idle, filtering_input, building_context, starting_tools,
55
- evaluating_tools, recording_tool_results and output_filtering. calling_llm,
56
- waiting_for_tools and dispatching_tools wait for external events. suspended ends
57
- a segment with halted; resume uses a fresh Session identity. The four declared
58
- terminal phases remain handed_off, completed, blocked and failed.
59
-
60
- FSMSession reads only the from field when determining external-event admission
61
- and waiting. It does not execute metadata guards or choose their destinations;
62
- state_machines does that. Known-but-undeclared and unknown events retain their
63
- existing error behavior; context-consumed stale events retain their early exit.
64
- The internal order of event registration now follows the shared table. Transition
65
- order within each event, which determines behavior, is preserved. The generated
66
- machine's private event-enumeration order is not a supported public contract.
67
-
68
- ## Verification and limits
69
-
70
- Independent behavioral tests run on both Refactor 38 and the candidate: all 195
71
- external-event/source-state combinations, all sixteen LLM condition combinations
72
- including short-circuit order, nil context and guard exceptions, fifteen Session
73
- boundaries, context-before-guard ordering, approval suspension/resume/dispatch,
74
- and invalid source-state handling. Existing Agent, causal durability, Handoff,
75
- Workflow and Engine tests continue to cover their collaborating behavior.
76
-
77
- The candidate also runs the full core/integration suites, offline examples and
78
- real SQLite, API/SPI snapshots, RBS, style, annotations and isolated gem checks.
79
- No SQL, stored format, entry action implementation, Tool restoration, cancellation
80
- or Coordinator sequencing is changed. The new contract tests isolate entry actions
81
- and do not claim live Provider coverage. Live PostgreSQL/LLM and remote CI are
82
- not executed for this candidate. Refactor 39 was independently verified after application at core 4d57614a,
83
- tree 654241da4b2b7f32d988602d28127bc1fa155641. All 10 files and the full tree
84
- matched, and core/integration/examples/SQLite/API/type/gem checks passed.
85
- The published SVG is applied39-01.
86
-
87
- R06 is applied and complete. R07 now has a Refactor 40 candidate; R08/D08, R09
88
- and R10 remain afterward. R09's inheritance behavior and R10's action names
89
- are not altered by the transition-ownership work.
1
+ # Agent transition ownership (r8 unit 7)
2
+
3
+ InvocationTransitions owns both automatic and external transitions, including
4
+ ordered guard evaluation. InvocationActions owns Agent entry operations.
5
+ EngineSessionBuilder configures FSMSession using those definitions;
6
+ PhaseMachineBuilder adapts them to state_machines without defining progress rules.
7
+ ExecutionCoordinator and RecoveryCoordinator retain durable decisions and use
8
+ the Agent-owned ExecutionEnvironment port for execution connection.
9
+
10
+ See [r8 unit 7](r8-unit7.md) and [ADR-067](../decisions/067-agent-progress-and-engine-connection.md).
11
+ Existing event source validation, callback failure priority, short-circuiting,
12
+ Tool outcome priority, suspended/wait/terminal boundaries and session incarnation
13
+ rules are preserved. Agent's Tool child FSM is still a separate remaining task.