phronomy 0.22.0 → 0.23.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.
- checksums.yaml +4 -4
- data/.mutant.yml +3 -4
- data/CHANGELOG.md +200 -10
- data/CONTRIBUTING.md +81 -9
- data/README.md +15 -6
- data/VERIFY.sh +587 -0
- data/benchmark/bench_agent_invoke.rb +2 -2
- data/benchmark/bench_context_assembler.rb +39 -68
- data/benchmark/bench_regression.rb +2 -2
- data/docs/architecture/agent-context.md +174 -0
- data/docs/architecture/before-llm-input.md +78 -0
- data/docs/architecture/context-management.md +232 -0
- data/docs/architecture/knowledge-and-rag.md +130 -0
- data/docs/architecture/multi-agent-handoff.md +152 -0
- data/docs/architecture/persistence.md +175 -0
- data/docs/architecture/removed/agent-context.md +72 -0
- data/docs/architecture/security-boundaries.md +173 -0
- data/docs/architecture/tracing.md +194 -0
- data/docs/architecture.md +82 -0
- data/docs/archive/design/archived/04_api_design.md +507 -0
- data/docs/archive/design/archived/09_guardrails.md +186 -0
- data/docs/archive/design/archived/17_rails_integration.md +175 -0
- data/docs/archive/design/historical/00_design_philosophy.md +122 -0
- data/docs/archive/design/historical/01_rubyllm_evaluation.md +178 -0
- data/docs/archive/design/historical/06_design_decisions.md +143 -0
- data/docs/changelog/0.14-and-earlier.md +1 -1
- data/docs/decisions/001-rubyllm-as-provider-layer.md +6 -1
- data/docs/decisions/002-workflow-context-immutability.md +26 -1
- data/docs/decisions/006-no-built-in-guardrails.md +2 -1
- data/docs/decisions/012-canonical-execution-log-and-context-policy.md +120 -38
- data/docs/decisions/014-unified-persistence-durable-state.md +9 -2
- data/docs/decisions/016-semantic-multi-agent-handoff.md +112 -0
- data/docs/decisions/017-design-authority-and-adr-governance.md +200 -0
- data/docs/decisions/018-durability-guarantees-and-failure-model.md +488 -0
- data/docs/decisions/019-filter-contract-and-security-boundaries.md +229 -0
- data/docs/decisions/020-canonical-workflow-instance-identity.md +177 -0
- data/docs/decisions/021-generic-agent-invocation-identity-removal.md +119 -0
- data/docs/decisions/022-agent-execution-parent-identity-and-runtime-routing-boundary.md +193 -0
- data/docs/decisions/023-fsm-session-incarnation-identity-and-routing.md +139 -0
- data/docs/decisions/024-event-loop-single-writer-agent-runtime.md +188 -0
- data/docs/decisions/025-process-local-agent-ownership-and-runtime-admission.md +249 -0
- data/docs/decisions/026-workflow-runtime-admission-and-durable-terminal-barrier.md +257 -0
- data/docs/decisions/027-llm-adapter-provider-boundary.md +93 -0
- data/docs/decisions/README.md +172 -0
- data/docs/features.md +31 -11
- data/docs/getting-started.md +77 -45
- data/docs/migrations/0.19.md +14 -7
- data/docs/migrations/0.22.md +390 -0
- data/docs/persistence-backends.md +88 -38
- data/docs/runtime-and-concurrency.md +227 -33
- data/examples/README.md +13 -0
- data/lib/phronomy/agent/agent_execution.rb +19 -15
- data/lib/phronomy/agent/agent_invocation.rb +288 -93
- data/lib/phronomy/agent/agent_invocation_session_builder.rb +236 -202
- data/lib/phronomy/agent/agent_root.rb +3 -3
- data/lib/phronomy/agent/approval_evaluation_request.rb +37 -19
- data/lib/phronomy/agent/async_event_api.rb +145 -72
- data/lib/phronomy/agent/base.rb +388 -181
- data/lib/phronomy/agent/concerns/before_llm_input.rb +1 -1
- data/lib/phronomy/agent/context_assembler.rb +437 -178
- data/lib/phronomy/agent/context_candidate_resolver.rb +2 -2
- data/lib/phronomy/agent/context_plan.rb +18 -13
- data/lib/phronomy/agent/context_plan_validator.rb +246 -88
- data/lib/phronomy/agent/context_policies/default.rb +123 -34
- data/lib/phronomy/agent/context_policy.rb +109 -3
- data/lib/phronomy/agent/context_policy_input.rb +244 -0
- data/lib/phronomy/agent/context_policy_input_builder.rb +241 -0
- data/lib/phronomy/agent/execution_coordinator.rb +1975 -587
- data/lib/phronomy/agent/journal_record.rb +17 -4
- data/lib/phronomy/agent/llm_input_build_context.rb +1 -1
- data/lib/phronomy/agent/llm_input_manifest.rb +277 -2
- data/lib/phronomy/agent/llm_operation_result.rb +12 -7
- data/lib/phronomy/agent/phase_machine_builder.rb +19 -7
- data/lib/phronomy/agent/provider_call_outcome.rb +23 -7
- data/lib/phronomy/agent/recovery_coordinator/continuation.rb +271 -0
- data/lib/phronomy/agent/recovery_coordinator/installation.rb +427 -0
- data/lib/phronomy/agent/recovery_coordinator/resolution.rb +635 -0
- data/lib/phronomy/agent/recovery_coordinator.rb +211 -0
- data/lib/phronomy/agent/recovery_support.rb +512 -0
- data/lib/phronomy/agent/ruby_llm_materializer.rb +22 -13
- data/lib/phronomy/agent/selection/candidate.rb +53 -0
- data/lib/phronomy/agent/selection/constraint.rb +49 -0
- data/lib/phronomy/agent/shared_state.rb +38 -1
- data/lib/phronomy/agent/tool_approval_request.rb +33 -5
- data/lib/phronomy/agent/tool_definition_set.rb +49 -3
- data/lib/phronomy/agent/tool_invocation.rb +336 -102
- data/lib/phronomy/agent/tool_invocation_session_builder.rb +49 -45
- data/lib/phronomy/agent.rb +20 -2
- data/lib/phronomy/agent_already_exists_error.rb +5 -0
- data/lib/phronomy/agent_purged_error.rb +5 -0
- data/lib/phronomy/engine/concurrency/offload_pool.rb +17 -3
- data/lib/phronomy/engine/concurrency/physical_completion_task.rb +135 -0
- data/lib/phronomy/engine/event_loop.rb +622 -63
- data/lib/phronomy/engine/fsm_session.rb +194 -21
- data/lib/phronomy/engine/runtime/agent_ownership_registry.rb +352 -0
- data/lib/phronomy/engine/runtime.rb +77 -20
- data/lib/phronomy/generator_verifier.rb +12 -14
- data/lib/phronomy/invocation_context.rb +9 -29
- data/lib/phronomy/multi_agent/admission_registry.rb +51 -0
- data/lib/phronomy/multi_agent/coordination_state.rb +18 -0
- data/lib/phronomy/multi_agent/coordinator.rb +154 -0
- data/lib/phronomy/multi_agent/execution_coordinator.rb +116 -0
- data/lib/phronomy/multi_agent/fan_out_invocation.rb +24 -33
- data/lib/phronomy/multi_agent/fan_out_session_builder.rb +12 -19
- data/lib/phronomy/multi_agent/handoff.rb +24 -45
- data/lib/phronomy/multi_agent/handoff_capability_factory.rb +87 -0
- data/lib/phronomy/multi_agent/handoff_context.rb +95 -0
- data/lib/phronomy/multi_agent/handoff_policy.rb +137 -0
- data/lib/phronomy/multi_agent/handoff_projection.rb +191 -0
- data/lib/phronomy/multi_agent/handoff_request.rb +45 -0
- data/lib/phronomy/multi_agent/orchestrator.rb +12 -15
- data/lib/phronomy/multi_agent/runner.rb +98 -0
- data/lib/phronomy/persistence/durable_codec.rb +646 -0
- data/lib/phronomy/persistence/durable_record.rb +117 -0
- data/lib/phronomy/persistence/in_memory.rb +210 -134
- data/lib/phronomy/persistence/migration/initial_format_migration.rb +226 -0
- data/lib/phronomy/persistence/repository_facades.rb +316 -0
- data/lib/phronomy/persistence.rb +81 -41
- data/lib/phronomy/recovery.rb +186 -0
- data/lib/phronomy/testing/persistence_contract/a_journal_repository.rb +2 -2
- data/lib/phronomy/testing/persistence_contract/a_persistence_backend.rb +1 -1
- data/lib/phronomy/testing/persistence_contract/a_workflow_state_repository.rb +19 -19
- data/lib/phronomy/testing/persistence_contract/an_agent_repository.rb +3 -3
- data/lib/phronomy/testing/persistence_contract/an_execution_repository.rb +5 -5
- data/lib/phronomy/tracing/automatic.rb +176 -0
- data/lib/phronomy/tracing/base.rb +11 -2
- data/lib/phronomy/tracing/langfuse_tracer.rb +20 -12
- data/lib/phronomy/version.rb +1 -1
- data/lib/phronomy/workflow.rb +3 -6
- data/lib/phronomy/workflow_context.rb +14 -5
- data/lib/phronomy/workflow_recovery.rb +123 -0
- data/lib/phronomy/workflow_runner.rb +468 -256
- data/lib/phronomy.rb +6 -0
- data/scripts/api_snapshot.rb +12 -0
- data/sig/phronomy/agent.rbs +209 -7
- data/sig/phronomy/multi_agent.rbs +39 -0
- data/sig/phronomy/persistence.rbs +62 -4
- data/sig/phronomy/runtime.rbs +1 -4
- data/sig/phronomy/workflow.rbs +2 -2
- data/sig/phronomy.rbs +10 -0
- metadata +65 -17
- data/examples/workflows/agent_event_mapping.rb +0 -101
- data/examples/workflows/generic_task_event_mapping.rb +0 -66
- data/lib/phronomy/agent/activation_registry.rb +0 -28
- data/lib/phronomy/agent/agent_execution_activation.rb +0 -172
- data/lib/phronomy/agent/context_candidate.rb +0 -47
- data/lib/phronomy/agent/context_parts/budget/token_budget_packer.rb +0 -53
- data/lib/phronomy/agent/context_parts/requirements/required_context_resolver.rb +0 -56
- data/lib/phronomy/agent/context_parts/selectors/recent_first_selector.rb +0 -30
- data/lib/phronomy/agent/context_parts/unit_builders/dependency_aware_unit_builder.rb +0 -118
- data/lib/phronomy/agent/context_policy_descriptor.rb +0 -49
- data/lib/phronomy/agent/context_policy_registry.rb +0 -46
- data/lib/phronomy/agent/context_request.rb +0 -35
- data/lib/phronomy/agent/context_selection_unit.rb +0 -38
- data/lib/phronomy/agent/derived_content_spec.rb +0 -34
- data/lib/phronomy/agent/runner.rb +0 -97
data/lib/phronomy.rb
CHANGED
|
@@ -113,3 +113,9 @@ module Phronomy
|
|
|
113
113
|
end
|
|
114
114
|
end
|
|
115
115
|
end
|
|
116
|
+
|
|
117
|
+
# Shared Recovery primitives and Workflow Persistence F1 reconciliation.
|
|
118
|
+
# Entity-specific Agent Recovery is loaded from lib/phronomy/agent.rb when the
|
|
119
|
+
# Agent namespace is materialized.
|
|
120
|
+
require_relative "phronomy/recovery"
|
|
121
|
+
require_relative "phronomy/workflow_recovery"
|
data/scripts/api_snapshot.rb
CHANGED
|
@@ -19,12 +19,24 @@ require_relative "../lib/phronomy"
|
|
|
19
19
|
PUBLIC_API_ENTRIES = [
|
|
20
20
|
# Stable
|
|
21
21
|
Phronomy::Agent::Base,
|
|
22
|
+
Phronomy::Agent::ContextPolicy,
|
|
23
|
+
Phronomy::Agent::ContextPolicyInput,
|
|
24
|
+
Phronomy::Agent::ContextPolicyInput::Provenance,
|
|
25
|
+
Phronomy::Agent::ContextPolicyInput::InstructionItem,
|
|
26
|
+
Phronomy::Agent::ContextPolicyInput::KnowledgeItem,
|
|
27
|
+
Phronomy::Agent::ContextPolicyInput::ToolItem,
|
|
28
|
+
Phronomy::Agent::ContextPolicyInput::ConversationItem,
|
|
29
|
+
Phronomy::Agent::ContextPlan,
|
|
30
|
+
Phronomy::InvocationContext,
|
|
22
31
|
Phronomy::Agent::Context::Capability::Base,
|
|
23
32
|
Phronomy::Workflow,
|
|
24
33
|
Phronomy::WorkflowContext,
|
|
25
34
|
Phronomy::Runnable,
|
|
26
35
|
Phronomy::Agent::Context::Instruction::PromptTemplate,
|
|
27
36
|
# Beta
|
|
37
|
+
Phronomy::MultiAgent::Handoff,
|
|
38
|
+
Phronomy::MultiAgent::HandoffPolicy,
|
|
39
|
+
Phronomy::MultiAgent::Runner,
|
|
28
40
|
Phronomy::MultiAgent::Orchestrator,
|
|
29
41
|
Phronomy::MultiAgent::TeamCoordinator,
|
|
30
42
|
Phronomy::Filter::Base,
|
data/sig/phronomy/agent.rbs
CHANGED
|
@@ -1,5 +1,184 @@
|
|
|
1
1
|
module Phronomy
|
|
2
2
|
module Agent
|
|
3
|
+
interface _BeforeLLMInputHook
|
|
4
|
+
def call: (LLMInputBuildContext context) -> LLMInputPatch?
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
class LLMInputPatch
|
|
8
|
+
attr_reader model_config_patch: Hash[untyped, untyped]?
|
|
9
|
+
attr_reader segment_candidates: Array[untyped]?
|
|
10
|
+
|
|
11
|
+
def initialize: (?model_config_patch: Hash[untyped, untyped]?, ?segment_candidates: Array[untyped]?) -> void
|
|
12
|
+
def self.empty: () -> LLMInputPatch
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class LLMInputBuildContext
|
|
16
|
+
attr_reader agent_id: String
|
|
17
|
+
attr_reader agent_definition_id: String
|
|
18
|
+
attr_reader agent_definition_version: Integer
|
|
19
|
+
attr_reader config: Hash[untyped, untyped]
|
|
20
|
+
attr_reader call_sequence: Integer
|
|
21
|
+
|
|
22
|
+
def initialize: (agent_id: String, agent_definition_id: String, agent_definition_version: Integer, ?config: Hash[untyped, untyped], call_sequence: Integer) -> void
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class ToolApprovalRequest
|
|
26
|
+
class Item
|
|
27
|
+
attr_reader tool_invocation_id: String
|
|
28
|
+
attr_reader tool_call_id: String?
|
|
29
|
+
attr_reader tool_name: String
|
|
30
|
+
attr_reader arguments: Hash[untyped, untyped]
|
|
31
|
+
attr_reader facts: Hash[untyped, untyped]
|
|
32
|
+
attr_reader reason: String?
|
|
33
|
+
attr_reader origin: Symbol
|
|
34
|
+
attr_reader metadata: Hash[untyped, untyped]
|
|
35
|
+
|
|
36
|
+
def initialize: (tool_invocation_id: String, tool_call_id: String?, tool_name: String, arguments: Hash[untyped, untyped], facts: Hash[untyped, untyped], reason: String?, origin: Symbol, metadata: Hash[untyped, untyped]) -> void
|
|
37
|
+
def self.from_h: (Hash[untyped, untyped]) -> Item
|
|
38
|
+
def to_h: () -> Hash[Symbol, untyped]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
attr_reader id: String
|
|
42
|
+
attr_reader execution_id: String
|
|
43
|
+
attr_reader items: Array[Item]
|
|
44
|
+
attr_reader created_at: untyped
|
|
45
|
+
|
|
46
|
+
def initialize: (execution_id: String, items: Array[Item], ?id: String, ?created_at: untyped) -> void
|
|
47
|
+
def self.from_h: (Hash[untyped, untyped]) -> ToolApprovalRequest
|
|
48
|
+
def to_h: () -> Hash[Symbol, untyped]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
class ApprovalEvaluationRequest
|
|
52
|
+
attr_reader agent_id: String
|
|
53
|
+
attr_reader agent_definition_id: String
|
|
54
|
+
attr_reader agent_definition_version: Integer
|
|
55
|
+
attr_reader execution_id: String
|
|
56
|
+
attr_reader tool_name: String
|
|
57
|
+
attr_reader tool_schema: Hash[untyped, untyped]
|
|
58
|
+
attr_reader tool_invocation_id: String
|
|
59
|
+
attr_reader tool_call_id: String?
|
|
60
|
+
attr_reader arguments: Hash[untyped, untyped]
|
|
61
|
+
attr_reader facts: Hash[untyped, untyped]
|
|
62
|
+
attr_reader invocation_context: Hash[untyped, untyped]
|
|
63
|
+
attr_reader origin: Symbol
|
|
64
|
+
attr_reader metadata: Hash[untyped, untyped]
|
|
65
|
+
attr_reader default_decision: Symbol?
|
|
66
|
+
|
|
67
|
+
def initialize: (agent_id: String, agent_definition_id: String, agent_definition_version: Integer, execution_id: String, tool_name: String, tool_schema: Hash[untyped, untyped], tool_invocation_id: String, tool_call_id: String?, arguments: Hash[untyped, untyped], ?facts: Hash[untyped, untyped], ?invocation_context: Hash[untyped, untyped], ?origin: Symbol, ?metadata: Hash[untyped, untyped], ?default_decision: Symbol?) -> void
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
class LLMInputManifest
|
|
71
|
+
VERSION: String
|
|
72
|
+
CALL_MODES: Array[Symbol]
|
|
73
|
+
SEGMENT_DELIVERIES: Array[String]
|
|
74
|
+
|
|
75
|
+
def self.from_h: (Hash[String, untyped] hash) -> LLMInputManifest
|
|
76
|
+
def version: () -> String
|
|
77
|
+
def to_h: () -> Hash[String, untyped]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
class ContextPolicyInput
|
|
81
|
+
class Provenance
|
|
82
|
+
attr_reader origin: Symbol
|
|
83
|
+
attr_reader content_ref: String?
|
|
84
|
+
attr_reader record_id: String?
|
|
85
|
+
attr_reader agent_id: String?
|
|
86
|
+
attr_reader execution_id: String?
|
|
87
|
+
attr_reader llm_call_id: String?
|
|
88
|
+
def initialize: (origin: Symbol, ?content_ref: String?, ?record_id: String?, ?agent_id: String?, ?execution_id: String?, ?llm_call_id: String?) -> void
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
class InstructionItem
|
|
92
|
+
attr_reader id: String
|
|
93
|
+
attr_reader kind: Symbol
|
|
94
|
+
attr_reader role: Symbol?
|
|
95
|
+
attr_reader content: untyped
|
|
96
|
+
attr_reader content_format: Symbol
|
|
97
|
+
attr_reader estimated_tokens: Integer
|
|
98
|
+
attr_reader required: bool
|
|
99
|
+
attr_reader provenance: Provenance
|
|
100
|
+
attr_reader metadata: Hash[untyped, untyped]
|
|
101
|
+
def initialize: (id: String, kind: Symbol, ?role: Symbol?, content: untyped, ?content_format: Symbol?, ?estimated_tokens: Integer?, ?required: bool?, ?provenance: Provenance?, ?metadata: Hash[untyped, untyped]) -> void
|
|
102
|
+
def required?: () -> bool
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
class KnowledgeItem
|
|
106
|
+
attr_reader id: String
|
|
107
|
+
attr_reader kind: Symbol
|
|
108
|
+
attr_reader role: Symbol?
|
|
109
|
+
attr_reader content: untyped
|
|
110
|
+
attr_reader content_format: Symbol
|
|
111
|
+
attr_reader estimated_tokens: Integer
|
|
112
|
+
attr_reader required: bool
|
|
113
|
+
attr_reader provenance: Provenance
|
|
114
|
+
attr_reader metadata: Hash[untyped, untyped]
|
|
115
|
+
def initialize: (id: String, kind: Symbol, ?role: Symbol?, content: untyped, ?content_format: Symbol?, ?estimated_tokens: Integer?, ?required: bool?, ?provenance: Provenance?, ?metadata: Hash[untyped, untyped]) -> void
|
|
116
|
+
def required?: () -> bool
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
class ToolItem
|
|
120
|
+
attr_reader id: String
|
|
121
|
+
attr_reader definition: Hash[untyped, untyped]
|
|
122
|
+
attr_reader estimated_tokens: Integer
|
|
123
|
+
attr_reader required: bool
|
|
124
|
+
attr_reader provenance: Provenance
|
|
125
|
+
attr_reader metadata: Hash[untyped, untyped]
|
|
126
|
+
def initialize: (id: String, definition: Hash[untyped, untyped], ?estimated_tokens: Integer?, ?required: bool?, ?provenance: Provenance?, ?metadata: Hash[untyped, untyped]) -> void
|
|
127
|
+
def required?: () -> bool
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
class ConversationItem
|
|
131
|
+
attr_reader id: String
|
|
132
|
+
attr_reader kind: Symbol
|
|
133
|
+
attr_reader role: Symbol?
|
|
134
|
+
attr_reader content: untyped
|
|
135
|
+
attr_reader content_format: Symbol
|
|
136
|
+
attr_reader sequence: Integer?
|
|
137
|
+
attr_reader estimated_tokens: Integer
|
|
138
|
+
attr_reader required: bool
|
|
139
|
+
attr_reader provenance: Provenance
|
|
140
|
+
attr_reader tool_call_id: String?
|
|
141
|
+
attr_reader tool_call_ids: Array[String]
|
|
142
|
+
attr_reader delivery: Symbol
|
|
143
|
+
attr_reader metadata: Hash[untyped, untyped]
|
|
144
|
+
def initialize: (id: String, kind: Symbol, ?role: Symbol?, content: untyped, ?content_format: Symbol?, ?sequence: Integer?, ?estimated_tokens: Integer?, ?required: bool?, ?provenance: Provenance?, ?tool_call_id: String?, ?tool_call_ids: Array[String], ?delivery: Symbol, ?metadata: Hash[untyped, untyped]) -> void
|
|
145
|
+
def required?: () -> bool
|
|
146
|
+
def with_required: (bool required) -> ConversationItem
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
attr_reader agent_id: String
|
|
150
|
+
attr_reader execution_id: String?
|
|
151
|
+
attr_reader call_sequence: Integer
|
|
152
|
+
attr_reader call_mode: Symbol
|
|
153
|
+
attr_reader instruction: Array[InstructionItem]
|
|
154
|
+
attr_reader knowledge: Array[KnowledgeItem]
|
|
155
|
+
attr_reader tools: Array[ToolItem]
|
|
156
|
+
attr_reader conversation: Array[Array[ConversationItem]]
|
|
157
|
+
attr_reader token_budget: untyped
|
|
158
|
+
attr_reader model_config: Hash[untyped, untyped]
|
|
159
|
+
attr_reader previous_manifest: LLMInputManifest?
|
|
160
|
+
attr_reader metadata: Hash[untyped, untyped]
|
|
161
|
+
def initialize: (agent_id: String, ?execution_id: String?, call_sequence: Integer, call_mode: Symbol, ?instruction: Array[InstructionItem], ?knowledge: Array[KnowledgeItem], ?tools: Array[ToolItem], ?conversation: Array[Array[ConversationItem]], token_budget: untyped, ?model_config: Hash[untyped, untyped], previous_manifest: LLMInputManifest?, ?metadata: Hash[untyped, untyped]) -> void
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
class ContextPlan
|
|
165
|
+
attr_reader instruction: Array[ContextPolicyInput::InstructionItem]
|
|
166
|
+
attr_reader knowledge: Array[ContextPolicyInput::KnowledgeItem]
|
|
167
|
+
attr_reader tools: Array[ContextPolicyInput::ToolItem]
|
|
168
|
+
attr_reader conversation: Array[Array[ContextPolicyInput::ConversationItem]]
|
|
169
|
+
attr_reader metadata: Hash[untyped, untyped]
|
|
170
|
+
def initialize: (?instruction: Array[ContextPolicyInput::InstructionItem], ?knowledge: Array[ContextPolicyInput::KnowledgeItem], ?tools: Array[ContextPolicyInput::ToolItem], ?conversation: Array[Array[ContextPolicyInput::ConversationItem]], ?metadata: Hash[untyped, untyped]) -> void
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
class ContextPolicy
|
|
174
|
+
def call: (ContextPolicyInput input) -> ContextPlan
|
|
175
|
+
|
|
176
|
+
def instruction_item: (content: untyped, ?role: Symbol, ?kind: Symbol, ?content_format: Symbol?, ?required: bool, ?metadata: Hash[untyped, untyped]) -> ContextPolicyInput::InstructionItem
|
|
177
|
+
def knowledge_item: (content: untyped, ?role: Symbol, ?kind: Symbol, ?content_format: Symbol?, ?required: bool, ?metadata: Hash[untyped, untyped]) -> ContextPolicyInput::KnowledgeItem
|
|
178
|
+
def conversation_item: (content: untyped, role: Symbol, ?kind: Symbol, ?content_format: Symbol?, ?sequence: Integer?, ?required: bool, ?tool_call_id: String?, ?tool_call_ids: Array[String], ?delivery: Symbol, ?metadata: Hash[untyped, untyped]) -> ContextPolicyInput::ConversationItem
|
|
179
|
+
def plan: (?instruction: Array[ContextPolicyInput::InstructionItem], ?knowledge: Array[ContextPolicyInput::KnowledgeItem], ?tools: Array[ContextPolicyInput::ToolItem], ?conversation: Array[Array[ContextPolicyInput::ConversationItem]], ?metadata: Hash[untyped, untyped]) -> ContextPlan
|
|
180
|
+
end
|
|
181
|
+
|
|
3
182
|
class Base
|
|
4
183
|
def self.model: (?String name) -> String?
|
|
5
184
|
def self.instructions: (?untyped text) { (untyped) -> untyped } -> untyped
|
|
@@ -12,18 +191,41 @@ module Phronomy
|
|
|
12
191
|
def self.cache_instructions: (?bool enabled) -> bool?
|
|
13
192
|
def self.max_output_tokens: (?Integer value) -> Integer?
|
|
14
193
|
def self.context_window: (?Integer value) -> Integer?
|
|
15
|
-
def self.
|
|
16
|
-
|
|
17
|
-
def self.
|
|
194
|
+
def self.context_policy: () -> ContextPolicy
|
|
195
|
+
| (ContextPolicy policy) -> ContextPolicy
|
|
196
|
+
def self.agent_definition: () -> Hash[Symbol, untyped]
|
|
197
|
+
| (version: Integer, ?id: String?) -> Hash[Symbol, untyped]
|
|
198
|
+
def self.before_llm_input: (?_BeforeLLMInputHook callable) ?{ (LLMInputBuildContext context) -> LLMInputPatch? } -> _BeforeLLMInputHook?
|
|
199
|
+
|
|
200
|
+
# on_event is bound once to the live Agent Runtime incarnation. The block
|
|
201
|
+
# is an alternative spelling of on_event; supplying both is an error.
|
|
202
|
+
def self.create: (?agent_id: String, ?context: untyped, ?knowledge: Array[untyped], ?persistence: Persistence?, ?metadata: Hash[untyped, untyped], ?on_event: ^(untyped) -> void) ?{ (untyped event) -> void } -> instance
|
|
203
|
+
def self.load: (String agent_id, persistence: Persistence, ?on_event: ^(untyped) -> void) ?{ (untyped event) -> void } -> instance
|
|
204
|
+
def self.get: (String agent_id) -> instance?
|
|
18
205
|
def self.live_for_execution: (String execution_id) -> instance
|
|
19
206
|
|
|
207
|
+
def initialize: (?agent_id: String?, ?context: untyped, ?knowledge: Array[untyped], ?persistence: Persistence?, ?metadata: Hash[untyped, untyped], ?on_event: ^(untyped) -> void) ?{ (untyped event) -> void } -> void
|
|
208
|
+
|
|
20
209
|
attr_reader agent_id: String
|
|
21
210
|
attr_reader persistence: Persistence
|
|
211
|
+
attr_accessor before_llm_input: _BeforeLLMInputHook?
|
|
212
|
+
|
|
213
|
+
# Public operation methods no longer accept per-invocation event listeners
|
|
214
|
+
# or event-listener blocks.
|
|
215
|
+
def invoke: (untyped input, ?config: Hash[untyped, untyped], ?invocation_context: untyped) -> Hash[Symbol, untyped]
|
|
216
|
+
def invoke_async: (untyped input, ?config: Hash[untyped, untyped], ?invocation_context: untyped) -> Task[Hash[Symbol, untyped]]
|
|
217
|
+
def stream: (untyped input, ?config: Hash[untyped, untyped], ?invocation_context: untyped) -> Hash[Symbol, untyped]
|
|
218
|
+
def stream_async: (untyped input, ?config: Hash[untyped, untyped], ?invocation_context: untyped) -> Task[Hash[Symbol, untyped]]
|
|
219
|
+
|
|
220
|
+
def approve: (String execution_id, approval_request_id: String, ?approved: bool, ?config: Hash[untyped, untyped]) -> untyped
|
|
221
|
+
def approve_async: (String execution_id, approval_request_id: String, ?approved: bool, ?config: Hash[untyped, untyped]) -> Task[untyped]
|
|
222
|
+
|
|
223
|
+
# Resolves a factual Recovery ambiguity. result: is meaningful for
|
|
224
|
+
# :succeeded; error: is required for :failed; neither is used by
|
|
225
|
+
# :not_performed.
|
|
226
|
+
def resolve: (String execution_id, expected_execution_revision: Integer, subject: Hash[Symbol, untyped], outcome: Symbol, ?result: untyped, ?error: Exception) -> untyped
|
|
227
|
+
def resolve_async: (String execution_id, expected_execution_revision: Integer, subject: Hash[Symbol, untyped], outcome: Symbol, ?result: untyped, ?error: Exception) -> Task[untyped]
|
|
22
228
|
|
|
23
|
-
def invoke: (untyped input, **untyped) -> Hash[Symbol, untyped]
|
|
24
|
-
def invoke_async: (untyped input, **untyped) -> Task[Hash[Symbol, untyped]]
|
|
25
|
-
def stream: (untyped input, **untyped) { (untyped event) -> void } -> Hash[Symbol, untyped]
|
|
26
|
-
def stream_async: (untyped input, **untyped) -> Task[Hash[Symbol, untyped]]
|
|
27
229
|
def transcript: () -> Array[untyped]
|
|
28
230
|
def add_knowledge: (untyped content, ?metadata: Hash[untyped, untyped]) -> self
|
|
29
231
|
def clear_transcript!: () -> untyped
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Phronomy
|
|
2
|
+
module MultiAgent
|
|
3
|
+
class Handoff
|
|
4
|
+
attr_reader source_agent: ::Phronomy::Agent::Base
|
|
5
|
+
attr_reader target_agent: ::Phronomy::Agent::Base
|
|
6
|
+
attr_reader policy: HandoffPolicy
|
|
7
|
+
attr_reader description: String
|
|
8
|
+
|
|
9
|
+
def initialize: (source_agent: ::Phronomy::Agent::Base, target_agent: ::Phronomy::Agent::Base, ?policy: HandoffPolicy, ?description: String?) -> void
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class HandoffPolicy
|
|
13
|
+
CATEGORIES: Array[Symbol]
|
|
14
|
+
MODES: Array[Symbol]
|
|
15
|
+
DEFAULTS: Array[Symbol]
|
|
16
|
+
|
|
17
|
+
def self.define: () { () -> void } -> HandoffPolicy
|
|
18
|
+
def self.default: () -> HandoffPolicy
|
|
19
|
+
|
|
20
|
+
def rule: (Symbol | String) -> untyped
|
|
21
|
+
def required?: (Symbol | String) -> bool
|
|
22
|
+
def forbidden?: (Symbol | String) -> bool
|
|
23
|
+
def selectable?: (Symbol | String) -> bool
|
|
24
|
+
def default_include?: (Symbol | String) -> bool
|
|
25
|
+
def selectable_categories: () -> Array[Symbol]
|
|
26
|
+
def to_h: () -> Hash[String, Hash[String, String]]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class Runner
|
|
30
|
+
MAX_HANDOFFS: Integer
|
|
31
|
+
|
|
32
|
+
attr_reader main_agent: ::Phronomy::Agent::Base
|
|
33
|
+
attr_reader handoffs: Array[Handoff]
|
|
34
|
+
|
|
35
|
+
def initialize: (main_agent: ::Phronomy::Agent::Base, ?handoffs: Array[Handoff]) -> void
|
|
36
|
+
def invoke: (untyped input, ?config: Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -5,6 +5,7 @@ module Phronomy
|
|
|
5
5
|
def exist?: (String content_id) -> bool
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
+
# Runtime/domain-facing repository interfaces.
|
|
8
9
|
interface _AgentRepository
|
|
9
10
|
def create: (untyped root) -> untyped
|
|
10
11
|
def load: (String agent_id) -> untyped
|
|
@@ -30,9 +31,46 @@ module Phronomy
|
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
interface _WorkflowStateRepository
|
|
33
|
-
def load: (String
|
|
34
|
-
def save: (String
|
|
35
|
-
def delete: (String
|
|
34
|
+
def load: (String workflow_instance_id) -> Hash[untyped, untyped]?
|
|
35
|
+
def save: (String workflow_instance_id, expected_revision: Integer?, snapshot: Hash[untyped, untyped]) -> Integer
|
|
36
|
+
def delete: (String workflow_instance_id, expected_revision: Integer) -> untyped
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Backend-side record repository interfaces. DurableRecord is the opaque data
|
|
40
|
+
# carrier. Identity/revision/index metadata is passed separately so backends do
|
|
41
|
+
# not need to interpret DurableRecord#payload.
|
|
42
|
+
interface _BackendAgentRecordRepository
|
|
43
|
+
def create: (agent_id: String, agent_revision: Integer, record: Persistence::DurableRecord) -> Persistence::DurableRecord
|
|
44
|
+
def load: (String agent_id) -> Persistence::DurableRecord
|
|
45
|
+
def save: (String agent_id, expected_revision: Integer, next_revision: Integer, record: Persistence::DurableRecord) -> Persistence::DurableRecord
|
|
46
|
+
def delete: (String agent_id) -> untyped
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
interface _BackendJournalRecordRepository
|
|
50
|
+
def append: (String agent_id, expected_position: Integer, records: Array[Persistence::DurableRecord], record_ids: Array[String]) -> Array[Persistence::DurableRecord]
|
|
51
|
+
def read: (String agent_id, ?after: Integer?, ?limit: Integer?) -> Array[Persistence::DurableRecord]
|
|
52
|
+
def head: (String agent_id) -> Integer
|
|
53
|
+
def delete: (String agent_id) -> untyped
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
interface _BackendExecutionRecordRepository
|
|
57
|
+
def create_active: (execution_id: String, agent_id: String, execution_revision: Integer, record: Persistence::DurableRecord) -> Persistence::DurableRecord
|
|
58
|
+
def load: (String execution_id) -> Persistence::DurableRecord
|
|
59
|
+
def save: (String execution_id, expected_revision: Integer, next_revision: Integer, agent_id: String, active: bool, record: Persistence::DurableRecord) -> Persistence::DurableRecord
|
|
60
|
+
def list_active: (String agent_id) -> Array[Persistence::DurableRecord]
|
|
61
|
+
def delete: (String execution_id) -> untyped
|
|
62
|
+
def delete_for_agent: (String agent_id) -> untyped
|
|
63
|
+
def assert_idle!: (String agent_id) -> untyped
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
interface _BackendWorkflowStateRecordRepository
|
|
67
|
+
def load: (String workflow_instance_id) -> Persistence::DurableRecord?
|
|
68
|
+
def save: (String workflow_instance_id, expected_revision: Integer?, next_revision: Integer, record: Persistence::DurableRecord) -> Persistence::DurableRecord
|
|
69
|
+
def delete: (String workflow_instance_id, expected_revision: Integer) -> untyped
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
interface _BackendWatermark
|
|
73
|
+
def assert_agent_watermark!: (agent_id: String, agent_revision: Integer, journal_position: Integer) -> true
|
|
36
74
|
end
|
|
37
75
|
|
|
38
76
|
interface _PersistenceTransactionView
|
|
@@ -54,6 +92,25 @@ module Phronomy
|
|
|
54
92
|
class SerializationError < Phronomy::Error
|
|
55
93
|
end
|
|
56
94
|
|
|
95
|
+
class DurableRecord
|
|
96
|
+
FORMAT_VERSION_PATTERN: Regexp
|
|
97
|
+
attr_reader record_type: String
|
|
98
|
+
attr_reader format_version: String
|
|
99
|
+
attr_reader payload: Hash[String, untyped]
|
|
100
|
+
def initialize: (record_type: String, format_version: String, payload: Hash[String, untyped]) -> void
|
|
101
|
+
def copy: () -> DurableRecord
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
module Migration
|
|
105
|
+
module InitialFormatMigration
|
|
106
|
+
def self.agent_root: (Hash[untyped, untyped] hash) -> DurableRecord
|
|
107
|
+
def self.agent_execution: (Hash[untyped, untyped] hash) -> DurableRecord
|
|
108
|
+
def self.journal_record: (Hash[untyped, untyped] hash) -> DurableRecord
|
|
109
|
+
def self.workflow_state: (workflow_instance_id: String, revision: Integer, snapshot: Hash[untyped, untyped]) -> DurableRecord
|
|
110
|
+
def self.llm_input_manifest: (Hash[untyped, untyped] hash) -> Hash[String, untyped]
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
57
114
|
REQUIRED_CAPABILITIES: Hash[Symbol, bool]
|
|
58
115
|
|
|
59
116
|
attr_reader contents: _ContentRepository
|
|
@@ -62,9 +119,10 @@ module Phronomy
|
|
|
62
119
|
attr_reader executions: _ExecutionRepository
|
|
63
120
|
attr_reader workflow_states: _WorkflowStateRepository
|
|
64
121
|
|
|
65
|
-
def initialize: (contents: _ContentRepository, agents:
|
|
122
|
+
def initialize: (contents: _ContentRepository, agents: _BackendAgentRecordRepository, journals: _BackendJournalRecordRepository, executions: _BackendExecutionRecordRepository, workflow_states: _BackendWorkflowStateRecordRepository) -> void
|
|
66
123
|
def capabilities: () -> Hash[Symbol, bool]
|
|
67
124
|
def transaction: () { (_PersistenceTransactionView) -> untyped } -> untyped
|
|
125
|
+
def build_transaction_view: (contents: _ContentRepository, agents: _BackendAgentRecordRepository, journals: _BackendJournalRecordRepository, executions: _BackendExecutionRecordRepository, workflow_states: _BackendWorkflowStateRecordRepository, watermark: _BackendWatermark) -> _PersistenceTransactionView
|
|
68
126
|
def assert_agent_watermark!: (agent_id: String, agent_revision: Integer, journal_position: Integer) -> true
|
|
69
127
|
end
|
|
70
128
|
end
|
data/sig/phronomy/runtime.rbs
CHANGED
|
@@ -26,18 +26,15 @@ end
|
|
|
26
26
|
|
|
27
27
|
module Phronomy
|
|
28
28
|
class InvocationContext
|
|
29
|
-
attr_reader thread_id: String?
|
|
30
|
-
attr_reader session_id: String?
|
|
31
29
|
attr_reader user_id: String?
|
|
32
30
|
attr_reader cancellation_token: Concurrency::CancellationToken?
|
|
33
31
|
attr_reader deadline: untyped
|
|
34
|
-
attr_reader tracer_span: untyped
|
|
35
32
|
attr_reader token_budget: Integer?
|
|
36
33
|
attr_reader approval_policy: untyped
|
|
37
34
|
attr_reader redaction_policy: untyped
|
|
38
35
|
attr_reader task_id: String?
|
|
39
36
|
attr_reader parent_task_id: String?
|
|
40
37
|
|
|
41
|
-
def initialize: (?
|
|
38
|
+
def initialize: (?user_id: String?, ?cancellation_token: Concurrency::CancellationToken?, ?deadline: untyped, ?token_budget: Integer?, ?approval_policy: untyped, ?redaction_policy: untyped, ?task_id: String?, ?parent_task_id: String?) -> void
|
|
42
39
|
end
|
|
43
40
|
end
|
data/sig/phronomy/workflow.rbs
CHANGED
|
@@ -2,7 +2,7 @@ module Phronomy
|
|
|
2
2
|
module WorkflowContext
|
|
3
3
|
def phase: () -> Symbol
|
|
4
4
|
def halted?: () -> bool
|
|
5
|
-
def
|
|
5
|
+
def workflow_instance_id: () -> String?
|
|
6
6
|
def merge: (Hash[Symbol, untyped] updates) -> self
|
|
7
7
|
def to_h: () -> Hash[Symbol, untyped]
|
|
8
8
|
end
|
|
@@ -15,7 +15,7 @@ module Phronomy
|
|
|
15
15
|
def stream: (untyped input, ?config: Hash[untyped, untyped], ?invocation_context: untyped) { (untyped) -> void } -> untyped
|
|
16
16
|
def resume: (state: untyped, ?input: untyped) -> untyped
|
|
17
17
|
def send_event: (state: untyped, event: Symbol, ?input: untyped) -> untyped
|
|
18
|
-
def signal: (
|
|
18
|
+
def signal: (workflow_instance_id: String, event: Symbol, ?payload: untyped) -> bool
|
|
19
19
|
|
|
20
20
|
class Builder
|
|
21
21
|
def initial: (Symbol state_name) -> untyped
|
data/sig/phronomy.rbs
CHANGED
|
@@ -19,6 +19,9 @@ module Phronomy
|
|
|
19
19
|
class ConfigurationError < Error
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
class HandoffError < Error
|
|
23
|
+
end
|
|
24
|
+
|
|
22
25
|
class TransportError < Error
|
|
23
26
|
end
|
|
24
27
|
|
|
@@ -37,6 +40,12 @@ module Phronomy
|
|
|
37
40
|
class EventLoopReentrancyError < Error
|
|
38
41
|
end
|
|
39
42
|
|
|
43
|
+
class AgentAlreadyExistsError < Error
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class AgentPurgedError < Error
|
|
47
|
+
end
|
|
48
|
+
|
|
40
49
|
class PoolShutdownError < Error
|
|
41
50
|
end
|
|
42
51
|
|
|
@@ -45,6 +54,7 @@ module Phronomy
|
|
|
45
54
|
|
|
46
55
|
class Configuration
|
|
47
56
|
attr_accessor llm_adapter: LLMAdapter::Base
|
|
57
|
+
attr_accessor before_llm_input: Agent::_BeforeLLMInputHook?
|
|
48
58
|
end
|
|
49
59
|
|
|
50
60
|
def self.configuration: () -> Configuration
|