phronomy 0.15.1 → 0.16.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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +105 -28
  3. data/README.md +300 -75
  4. data/benchmark/bench_agent_invoke.rb +3 -0
  5. data/benchmark/bench_regression.rb +2 -18
  6. data/benchmark/bench_tool_schema.rb +1 -0
  7. data/docs/decisions/011-build-context-as-single-llm-input-authority.md +40 -1
  8. data/docs/decisions/012-canonical-execution-log-and-context-policy.md +69 -0
  9. data/lib/phronomy/agent/activation_registry.rb +28 -0
  10. data/lib/phronomy/agent/agent_execution.rb +97 -0
  11. data/lib/phronomy/agent/agent_execution_activation.rb +172 -0
  12. data/lib/phronomy/agent/agent_invocation.rb +42 -10
  13. data/lib/phronomy/agent/agent_invocation_session_builder.rb +50 -11
  14. data/lib/phronomy/agent/agent_root.rb +67 -0
  15. data/lib/phronomy/agent/async_event_api.rb +55 -475
  16. data/lib/phronomy/agent/base.rb +301 -285
  17. data/lib/phronomy/agent/concerns/before_llm_input.rb +66 -0
  18. data/lib/phronomy/agent/context_assembler.rb +321 -0
  19. data/lib/phronomy/agent/context_candidate.rb +47 -0
  20. data/lib/phronomy/agent/context_candidate_resolver.rb +65 -0
  21. data/lib/phronomy/agent/context_importer.rb +217 -0
  22. data/lib/phronomy/agent/context_parts/budget/token_budget_packer.rb +53 -0
  23. data/lib/phronomy/agent/context_parts/requirements/required_context_resolver.rb +56 -0
  24. data/lib/phronomy/agent/context_parts/selectors/recent_first_selector.rb +30 -0
  25. data/lib/phronomy/agent/context_parts/unit_builders/dependency_aware_unit_builder.rb +188 -0
  26. data/lib/phronomy/agent/context_parts/validators/final_budget_validator.rb +37 -0
  27. data/lib/phronomy/agent/context_plan.rb +25 -0
  28. data/lib/phronomy/agent/context_plan_validator.rb +167 -0
  29. data/lib/phronomy/agent/context_policies/default.rb +53 -0
  30. data/lib/phronomy/agent/context_policy.rb +15 -0
  31. data/lib/phronomy/agent/context_policy_descriptor.rb +49 -0
  32. data/lib/phronomy/agent/context_policy_registry.rb +46 -0
  33. data/lib/phronomy/agent/context_request.rb +35 -0
  34. data/lib/phronomy/agent/context_selection_unit.rb +38 -0
  35. data/lib/phronomy/agent/derived_content_spec.rb +34 -0
  36. data/lib/phronomy/agent/execution_coordinator.rb +1123 -0
  37. data/lib/phronomy/agent/fsm_runtime_adapter.rb +210 -0
  38. data/lib/phronomy/agent/immutable.rb +31 -0
  39. data/lib/phronomy/agent/journal_projection.rb +34 -0
  40. data/lib/phronomy/agent/journal_record.rb +67 -0
  41. data/lib/phronomy/agent/llm_call_record.rb +51 -0
  42. data/lib/phronomy/agent/llm_input_build_context.rb +17 -0
  43. data/lib/phronomy/agent/llm_input_manifest.rb +103 -0
  44. data/lib/phronomy/agent/llm_input_patch.rb +21 -0
  45. data/lib/phronomy/agent/phase_machine_builder.rb +12 -0
  46. data/lib/phronomy/agent/provider_call_outcome.rb +90 -0
  47. data/lib/phronomy/agent/ruby_llm_materializer.rb +298 -0
  48. data/lib/phronomy/agent/token_budget_resolver.rb +69 -0
  49. data/lib/phronomy/agent/tool_call_intercepted.rb +11 -4
  50. data/lib/phronomy/agent/tool_definition_set.rb +55 -0
  51. data/lib/phronomy/agent.rb +14 -16
  52. data/lib/phronomy/agent_busy_error.rb +5 -0
  53. data/lib/phronomy/canonical_json.rb +136 -0
  54. data/lib/phronomy/configuration.rb +9 -4
  55. data/lib/phronomy/content_store/base.rb +51 -0
  56. data/lib/phronomy/context_budget_exceeded_error.rb +8 -0
  57. data/lib/phronomy/engine/event_loop.rb +3 -0
  58. data/lib/phronomy/execution_rehydration_required_error.rb +5 -0
  59. data/lib/phronomy/invalid_context_budget_configuration_error.rb +8 -0
  60. data/lib/phronomy/llm_context_window/assembler.rb +8 -8
  61. data/lib/phronomy/multi_agent/orchestrator.rb +1 -0
  62. data/lib/phronomy/multi_agent/parallel_tool_chat.rb +7 -5
  63. data/lib/phronomy/multi_agent/team_coordinator.rb +6 -2
  64. data/lib/phronomy/persistence/in_memory.rb +247 -0
  65. data/lib/phronomy/persistence.rb +39 -0
  66. data/lib/phronomy/tools/agent.rb +14 -36
  67. data/lib/phronomy/version.rb +1 -1
  68. data/lib/phronomy.rb +11 -0
  69. data/scripts/add_to_h_to_token_doubles.rb +33 -0
  70. data/scripts/add_to_h_unnamed_doubles.rb +27 -0
  71. data/scripts/migrate_spec_agent_definition.rb +108 -0
  72. data/scripts/migrate_spec_agent_definition_pass2.rb +53 -0
  73. data/scripts/migrate_spec_inline_pass3.rb +24 -0
  74. metadata +54 -7
  75. data/lib/phronomy/agent/agent_invocation_registry.rb +0 -75
  76. data/lib/phronomy/agent/before_completion_context.rb +0 -47
  77. data/lib/phronomy/agent/concerns/before_completion.rb +0 -111
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98b90b892fcd752aa84d1a00d033bb627df70d143145502f044e5288c7b124a4
4
- data.tar.gz: c1e37fa68d782d5f506a83e019594e2f77efeb7d37e8f46c8b57286d8b8c9eaa
3
+ metadata.gz: 633f62428045fed9447fd95414687cf8f2d0df11163afd767a73cc1c9b0ea97e
4
+ data.tar.gz: 68d352c78047e7b87dade2f8659cf44d4ecd16acf506090329d3e276f8a35f0c
5
5
  SHA512:
6
- metadata.gz: e8a62f9eb2d0971a0faa91d822a9ecff39b495242514dd5144f442c8bcfba85edd84a3e22738df17447604f8c6201169df1f0b308035ad8a5e50603ad379da5b
7
- data.tar.gz: bcb09d22cf850b447e49e13d022cf760c6b4628fe3df6ea744f91738e1085fea6218bee4ce96c4caf0b6f8a8c07f2900bc7f243ed374cc71c940869f64856ea1
6
+ metadata.gz: 67cd757c8efacd34360a3b876bae0ebbac0e37080f77472a9b69eaf774f14b5f2c070288d4e5d66bbfcc31a6be60353ca043e4f95ee6b1a14da09e8fe5792b00
7
+ data.tar.gz: '0382e7bbf708605dea900725e7ab4c093baf653ef0e88c11ba79c6ab227b1584624aa73b9b16cacd8644d4d1aafe0ffade1b6b1d6361a1f33d7395e730b4e1df'
data/CHANGELOG.md CHANGED
@@ -9,20 +9,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
- ### Changed
12
+ ---
13
13
 
14
- - Refactor: `Agent::AsyncEventApi` is now the single implementation of
15
- `invoke`, `invoke_async`, `stream`, `stream_async`, and their session
16
- lifecycle helpers (`_start_invocation`, `_handle_agent_completion`,
17
- `_register_tool_invocation_session`, `_start_approval_resume`). The
18
- duplicate definitions in `Agent::Base` have been removed. No public
19
- behavior change is intended.
20
- - Remove `faraday` and `event_stream_parser` from gemspec declared
21
- dependencies; both are transitive dependencies of `ruby_llm` and are
22
- not used directly by phronomy.
14
+ ## [0.16.0] - 2026-08-08
23
15
 
24
16
  ### Added
25
17
 
18
+ - Stateful Agent identity and persistence:
19
+ - Every concrete Agent definition declares a stable `agent_definition id:, version:`.
20
+ - Every Agent instance has a stable `agent_id`.
21
+ - `Agent::Base.create` creates a persistent Agent instance.
22
+ - `Agent::Base.load` restores an Agent from a shared Persistence backend.
23
+ - `Agent#agent_root`, `#transcript`, `#clear_transcript!`, `#clear_memory!`,
24
+ `#reset_context!`, `#close!`, and `#purge!` provide explicit state lifecycle operations.
25
+
26
+ - Persistence-backed Agent execution state:
27
+ - Agent executions have stable `execution_id` values and are persisted separately from the owning Agent.
28
+ - Suspended approval executions remain represented in Persistence.
29
+ - Resuming after process loss still requires future durable activation rehydration support.
30
+
31
+ - Canonical Complete Execution Log:
32
+ - Phronomy records observed logical execution facts in an append-only Agent Journal.
33
+ - Provider assistant responses preserve assistant content and all Tool Calls as one logical assistant message.
34
+ - Raw Tool return values and the Tool-role messages sent back to the LLM are represented as separate execution facts.
35
+
36
+ - Per-LLM-call canonical Manifests:
37
+ - Each LLM Call is assembled from a canonical Manifest.
38
+ - The Manifest records the logical input selected for that specific LLM Call.
39
+ - Runtime RubyLLM messages are materialized from the Manifest rather than treated as the source of truth.
40
+
41
+ - Context Policy domain:
42
+ - Context candidates are selected from canonical history without deleting the underlying Journal.
43
+ - Tool Call / Tool message protocol dependencies are selected atomically.
44
+ - Required context is validated independently from optional historical context.
45
+ - `ContextBudgetExceededError` is raised when required context cannot fit in the available model budget.
46
+
47
+ - Context import for stateful Agents:
48
+ - Existing user / assistant / Tool history can be supplied through Agent creation context.
49
+ - Imported assistant messages retain their original logical message boundary and Tool Calls.
50
+ - Invalid Tool protocol histories are rejected instead of being guessed or repaired.
51
+
26
52
  - `Workflow#signal(thread_id:, event:, payload:)` for FIFO delivery to a live
27
53
  Workflow FSMSession.
28
54
  - Workflow transition `action:` callbacks, executed after source exit callbacks
@@ -42,27 +68,49 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
42
68
  - EventLoop emits a rate-limited warning when its shared event queue reaches
43
69
  1,000 pending entries. Events are observed only; they are not dropped.
44
70
 
45
- ### Removed
71
+ ### Changed
46
72
 
47
- - Implicit awaiting of Task-returning Workflow/Agent/Tool entry actions and the
48
- Workflow `action_timeout:` DSL. Entry actions are synchronous RTC callbacks.
49
- - The duplicate caller-thread `WorkflowRunner#run_workflow` execution path.
50
- - Agent-wide automatic replay: `Agent::Base.retry_policy` and the `Retryable`
51
- concern. A failed AgentInvocation is no longer started again by Phronomy.
52
- - Agent-class `invoke_timeout`. Callers that need a root deadline should pass an
53
- `InvocationContext` with `deadline:` or `cancellation_token:`.
54
- - Phronomy LLM operation timeout `config[:llm_timeout]`; configure RubyLLM's
55
- `request_timeout` instead.
56
- - Generic Tool retry DSL (`retry_on`, `retry_policies`) and
57
- `config[:tool_timeout]`; Tool/client implementations own their transport policy.
58
- - `max_parallel_tools` from Agent, AgentInvocation, ParallelToolChat, and
59
- InvocationContext.
60
- - Unused `InvocationContext#provider_limits`.
61
- - `Configuration#stream_queue_max_size`, which no longer affected the
62
- Runtime-owned EventLoop streaming path.
73
+ - Agent instances are now always stateful and Persistence-backed.
63
74
 
64
- ### Changed
75
+ - Conversation history ownership has moved from the caller to the Agent:
76
+ callers no longer need to pass the previous `messages` array back on every invocation.
77
+ Completed invocation results may still expose `result[:messages]` as a materialized
78
+ transcript projection.
79
+
80
+ - `agent_definition id:, version:` is required for concrete Agent definitions.
81
+ Loading persisted Agent state validates the stored definition identity and version
82
+ against the runtime Agent class.
83
+
84
+ - Context-window management is now Manifest-first:
85
+ canonical Agent history is retained in the Journal while each LLM Call receives
86
+ only the context selected for its Manifest.
87
+
88
+ - Context pruning no longer means deleting or mutating historical Agent messages.
89
+ Context Policy omission affects only the current LLM Call input.
90
+
91
+ - Tool execution results and Tool protocol messages are no longer treated as the
92
+ same value. The raw Tool return value is retained as an execution fact while the
93
+ exact Tool-role message remains independently available for LLM context assembly.
65
94
 
95
+ - `thread_id` is an execution/correlation identifier rather than the owner of
96
+ conversation state. Persistent Agent identity is defined by `agent_id`.
97
+
98
+ - `context_overhead` is retained only for the legacy `build_context` path.
99
+ Manifest-first context assembly accounts for actual mandatory context instead of
100
+ reserving this value as Tool/system-prompt overhead.
101
+
102
+ - Phronomy now requires `ruby_llm >= 1.15, < 2` so Provider assistant messages can
103
+ be captured before Agent-owned Tool execution begins.
104
+
105
+ - Refactor: `Agent::AsyncEventApi` is now the single implementation of
106
+ `invoke`, `invoke_async`, `stream`, `stream_async`, and their session
107
+ lifecycle helpers (`_start_invocation`, `_handle_agent_completion`,
108
+ `_register_tool_invocation_session`, `_start_approval_resume`). The
109
+ duplicate definitions in `Agent::Base` have been removed. No public
110
+ behavior change is intended.
111
+ - Remove `faraday` and `event_stream_parser` from gemspec declared
112
+ dependencies; both are transitive dependencies of `ruby_llm` and are
113
+ not used directly by phronomy.
66
114
  - `Workflow#invoke`, `#invoke_async`, and `#stream` now share context
67
115
  preparation, StateStore load/save, EventLoop registration, and FSMSession
68
116
  execution.
@@ -81,6 +129,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
81
129
  bounded workers and queues remain the coarse process-protection boundary.
82
130
  - Caller-provided deadline and cancellation-token propagation is unchanged.
83
131
 
132
+ ### Removed
133
+
134
+ - Caller-managed `messages:` continuation from the Agent invocation API.
135
+ Stateful Agent history is now obtained from the Agent's persisted Journal.
136
+
137
+ - `Agent::Base#trim_messages` and the legacy Agent-level message-trimming model.
138
+ Context selection is performed by the Context Policy / Manifest assembly path.
139
+
140
+ - The assumption that `build_context` and the legacy `LlmContextWindow::Assembler`
141
+ are the long-term single authority for LLM input. ADR-012 defines the replacement
142
+ Journal / Context Policy / Manifest architecture.
143
+
144
+ - Implicit awaiting of Task-returning Workflow/Agent/Tool entry actions and the
145
+ Workflow `action_timeout:` DSL. Entry actions are synchronous RTC callbacks.
146
+ - The duplicate caller-thread `WorkflowRunner#run_workflow` execution path.
147
+ - Agent-wide automatic replay: `Agent::Base.retry_policy` and the `Retryable`
148
+ concern. A failed AgentInvocation is no longer started again by Phronomy.
149
+ - Agent-class `invoke_timeout`. Callers that need a root deadline should pass an
150
+ `InvocationContext` with `deadline:` or `cancellation_token:`.
151
+ - Phronomy LLM operation timeout `config[:llm_timeout]`; configure RubyLLM's
152
+ `request_timeout` instead.
153
+ - Generic Tool retry DSL (`retry_on`, `retry_policies`) and
154
+ `config[:tool_timeout]`; Tool/client implementations own their transport policy.
155
+ - `max_parallel_tools` from Agent, AgentInvocation, ParallelToolChat, and
156
+ InvocationContext.
157
+ - Unused `InvocationContext#provider_limits`.
158
+ - `Configuration#stream_queue_max_size`, which no longer affected the
159
+ Runtime-owned EventLoop streaming path.
160
+
84
161
  ### Fixed
85
162
 
86
163
  - `Agent#approve` now rejects EventLoop re-entry instead of synchronously waiting