Class: LittleGhost::AssemblyBuilder
- Inherits:
-
Object
- Object
- LittleGhost::AssemblyBuilder
- Defined in:
- lib/little_ghost/assembly_builder.rb
Overview
Builds an Assembly when its participants or routes are discovered at runtime.
Class definitions are the usual, easier-to-find way to declare behavior.
Builders expose the underlying dynamic form while preserving the same
ask, stream_ask, call, and stream interface:
graph = LittleGhost::GraphBuilder.new(id: "support_flow")
graph.node :triage, TriageAgent
graph.node :respond, CustomerSupportAgent
graph.start :triage
graph.edge :triage, :respond
graph.finish :respond
graph.validate!
run = graph.ask("Can I get a refund?")
A builder remains mutable. Each build or invocation snapshots declaration containers and referenced Assembly definitions, so later builder changes affect only future executions. Executable Ruby closures and the external objects they reference remain live trusted application code.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#runtime ⇒ Object
readonly
Optional Runtime reused by standalone executions from this builder.
Instance Method Summary collapse
-
#as_tool(**options) ⇒ Object
Exposes a snapshot as a Tool.
-
#ask(message, **options) ⇒ Object
Executes a standalone snapshot and returns its Run.
-
#assembly_id(value = nil) ⇒ Object
Reads or assigns the stable Assembly identifier.
-
#assembly_kind ⇒ Object
Returns
:agent,:workflow,:swarm, or:graph. -
#build(runtime: self.runtime, run: nil) ⇒ Object
Builds one execution instance from the current definition snapshot.
-
#call(input = nil, **options) ⇒ Object
Executes a snapshot to completion.
-
#definition ⇒ Object
Returns an immutable, recursively snapshotted definition.
-
#description(value = nil) ⇒ Object
Reads or assigns the human-readable description.
-
#initialize(id: nil, description: nil, runtime: nil, base: nil) ⇒ AssemblyBuilder
constructor
Creates a mutable builder with optional identity, runtime, and base class.
-
#start_execution(payload, &block) ⇒ Object
Starts a supervised execution from a snapshot.
-
#stream(input = nil, **options) ⇒ Object
Streams a snapshot as StreamEvent objects.
-
#stream_ask(message, **options) ⇒ Object
Lazily streams a standalone snapshot.
-
#validate! ⇒ Object
Validates the current snapshot and returns this mutable builder.
Constructor Details
#initialize(id: nil, description: nil, runtime: nil, base: nil) ⇒ AssemblyBuilder
Creates a mutable builder with optional identity, runtime, and base class.
63 64 65 66 67 68 69 |
# File 'lib/little_ghost/assembly_builder.rb', line 63 def initialize(id: nil, description: nil, runtime: nil, base: nil) @mutex = Mutex.new @assembly_id = id&.to_s&.dup&.freeze @description = description&.to_s&.dup&.freeze @runtime = runtime @base = base end |
Instance Attribute Details
#runtime ⇒ Object (readonly)
Optional Runtime reused by standalone executions from this builder.
60 61 62 |
# File 'lib/little_ghost/assembly_builder.rb', line 60 def runtime @runtime end |
Instance Method Details
#as_tool(**options) ⇒ Object
Exposes a snapshot as a Tool.
147 |
# File 'lib/little_ghost/assembly_builder.rb', line 147 def as_tool(**) = build.as_tool(**) |
#ask(message, **options) ⇒ Object
Executes a standalone snapshot and returns its Run.
130 |
# File 'lib/little_ghost/assembly_builder.rb', line 130 def ask(, **) = build.ask(, **) |
#assembly_id(value = nil) ⇒ Object
Reads or assigns the stable Assembly identifier.
72 73 74 75 76 77 |
# File 'lib/little_ghost/assembly_builder.rb', line 72 def assembly_id(value = nil) return @mutex.synchronize { @assembly_id || default_assembly_id } if value.nil? @mutex.synchronize { @assembly_id = String(value).dup.freeze } self end |
#assembly_kind ⇒ Object
Returns :agent, :workflow, :swarm, or :graph.
88 |
# File 'lib/little_ghost/assembly_builder.rb', line 88 def assembly_kind = self.class.assembly_kind |
#build(runtime: self.runtime, run: nil) ⇒ Object
Builds one execution instance from the current definition snapshot.
122 123 124 125 126 127 |
# File 'lib/little_ghost/assembly_builder.rb', line 122 def build(runtime: self.runtime, run: nil) snapshot = definition return (runtime || run.runtime).build_assembly(snapshot, run:) if run snapshot.implementation.new(runtime:) end |
#call(input = nil, **options) ⇒ Object
Executes a snapshot to completion.
141 142 |
# File 'lib/little_ghost/assembly_builder.rb', line 141 def call(input = nil, **) = build.call(input, **) # Streams a snapshot as StreamEvent objects. |
#definition ⇒ Object
Returns an immutable, recursively snapshotted definition.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/little_ghost/assembly_builder.rb', line 97 def definition stack = Thread.current[:little_ghost_assembly_definition_stack] ||= [] identity = base || self if stack.include?(identity) raise ConfigurationError, "assembly definitions cannot contain themselves recursively" end stack << identity state = @mutex.synchronize { snapshot_state } implementation = build_implementation(state) prepare_implementation!(implementation) validate_implementation!(implementation) seal_implementation!(implementation) implementation.freeze AssemblyDefinition.new( kind: assembly_kind, assembly_id: implementation.assembly_id, description: implementation.description, implementation: ) ensure stack&.pop if stack&.last.equal?(identity) Thread.current[:little_ghost_assembly_definition_stack] = nil if stack && stack.empty? end |
#description(value = nil) ⇒ Object
Reads or assigns the human-readable description.
80 81 82 83 84 85 |
# File 'lib/little_ghost/assembly_builder.rb', line 80 def description(value = nil) return @mutex.synchronize { @description || base_description } if value.nil? @mutex.synchronize { @description = String(value).dup.freeze } self end |
#start_execution(payload, &block) ⇒ Object
Starts a supervised execution from a snapshot.
145 146 |
# File 'lib/little_ghost/assembly_builder.rb', line 145 def start_execution(payload, &block) = build.start_execution(payload, &block) # Exposes a snapshot as a Tool. |
#stream(input = nil, **options) ⇒ Object
Streams a snapshot as StreamEvent objects.
143 144 |
# File 'lib/little_ghost/assembly_builder.rb', line 143 def stream(input = nil, **) = build.stream(input, **) # Starts a supervised execution from a snapshot. |
#stream_ask(message, **options) ⇒ Object
Lazily streams a standalone snapshot.
133 134 135 136 137 138 |
# File 'lib/little_ghost/assembly_builder.rb', line 133 def stream_ask(, **) snapshot = definition Enumerator.new do |events| snapshot.implementation.new(runtime:).stream_ask(, **).each { |event| events << event } end end |
#validate! ⇒ Object
Validates the current snapshot and returns this mutable builder.
91 92 93 94 |
# File 'lib/little_ghost/assembly_builder.rb', line 91 def validate! definition self end |