Class: Phronomy::Agent::AgentExecution
- Inherits:
-
Object
- Object
- Phronomy::Agent::AgentExecution
- Defined in:
- lib/phronomy/agent/agent_execution.rb
Constant Summary collapse
- ACTIVE_STATUSES =
%i[preparing active suspended].freeze
- TERMINAL_STATUSES =
%i[completed failed cancelled rejected blocked].freeze
- TRANSITIONS =
{ preparing: %i[preparing active failed cancelled blocked], active: %i[active suspended completed failed cancelled rejected blocked], suspended: %i[suspended active failed cancelled], completed: %i[completed], failed: %i[failed], cancelled: %i[cancelled], rejected: %i[rejected], blocked: %i[blocked] }.freeze
- ATTRIBUTES =
%i[ execution_id agent_id execution_revision status phase base_agent_revision base_context_revision base_journal_position working_records llm_calls approval_request result_ref error_ref created_at updated_at terminal_reason metadata ].freeze
Class Method Summary collapse
-
.from_h(hash) ⇒ AgentExecution
Restores an execution from its canonical durable representation.
- .start(agent_root:, input_record:, metadata: {}) ⇒ Object
Instance Method Summary collapse
- #active? ⇒ Boolean
-
#initialize(**attributes) ⇒ AgentExecution
constructor
A new instance of AgentExecution.
- #terminal? ⇒ Boolean
-
#to_h ⇒ Hash{String => Object}
Returns the canonical durable representation of this execution.
- #with(**changes) ⇒ Object
Constructor Details
#initialize(**attributes) ⇒ AgentExecution
Returns a new instance of AgentExecution.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/phronomy/agent/agent_execution.rb', line 53 def initialize(**attributes) ATTRIBUTES.each do |name| value = attributes.fetch(name) value = value.to_sym if %i[status phase].include?(name) instance_variable_set("@#{name}", Immutable.copy(value)) end raise ArgumentError, "unknown execution status: #{status.inspect}" unless TRANSITIONS.key?(status) raise ArgumentError, "execution_revision must be non-negative" if execution_revision.negative? Immutable.validate_canonical_json!(, label: "Execution metadata") if approval_request Immutable.validate_canonical_json!(approval_request, label: "Approval request") end freeze end |
Class Method Details
.from_h(hash) ⇒ AgentExecution
Restores an execution from its canonical durable representation. String and Symbol top-level keys are accepted. Nested working Journal records and LLM Call records are restored through their public codecs so storage backends do not need to know their constructor details.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/phronomy/agent/agent_execution.rb', line 109 def self.from_h(hash) attributes = ATTRIBUTES.to_h do |name| key = hash.key?(name.to_s) ? name.to_s : name [name, hash.fetch(key)] end attributes[:working_records] = attributes.fetch(:working_records).map do |record| record.is_a?(JournalRecord) ? record : JournalRecord.from_h(record) end attributes[:llm_calls] = attributes.fetch(:llm_calls).map do |call| call.is_a?(LLMCallRecord) ? call : LLMCallRecord.from_h(call) end new(**attributes) end |
.start(agent_root:, input_record:, metadata: {}) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/phronomy/agent/agent_execution.rb', line 30 def self.start(agent_root:, input_record:, metadata: {}) now = Time.now.utc.iso8601(6) new( execution_id: SecureRandom.uuid, agent_id: agent_root.agent_id, execution_revision: 0, status: :preparing, phase: :preparing, base_agent_revision: agent_root.agent_revision, base_context_revision: agent_root.context_revision, base_journal_position: agent_root.journal_position, working_records: [input_record], llm_calls: [], approval_request: nil, result_ref: nil, error_ref: nil, created_at: now, updated_at: now, terminal_reason: nil, metadata: ) end |
Instance Method Details
#active? ⇒ Boolean
68 69 70 |
# File 'lib/phronomy/agent/agent_execution.rb', line 68 def active? ACTIVE_STATUSES.include?(status) end |
#terminal? ⇒ Boolean
72 73 74 |
# File 'lib/phronomy/agent/agent_execution.rb', line 72 def terminal? TERMINAL_STATUSES.include?(status) end |
#to_h ⇒ Hash{String => Object}
Returns the canonical durable representation of this execution. Nested JournalRecord and LLMCallRecord values are recursively encoded.
92 93 94 95 96 97 98 99 |
# File 'lib/phronomy/agent/agent_execution.rb', line 92 def to_h ATTRIBUTES.to_h do |name| value = public_send(name) value = value.map(&:to_h) if name == :working_records value = value.map(&:to_h) if name == :llm_calls [name.to_s, value] end end |
#with(**changes) ⇒ Object
76 77 78 79 80 81 82 83 84 85 |
# File 'lib/phronomy/agent/agent_execution.rb', line 76 def with(**changes) next_status = changes.fetch(:status, status).to_sym unless TRANSITIONS.fetch(status).include?(next_status) raise ArgumentError, "illegal AgentExecution transition: #{status} -> #{next_status}" end values = ATTRIBUTES.to_h { |name| [name, public_send(name)] }.merge(changes) values[:execution_revision] = execution_revision + 1 unless changes.key?(:execution_revision) values[:updated_at] = Time.now.utc.iso8601(6) unless changes.key?(:updated_at) self.class.new(**values) end |