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.
41 42 43 44 45 46 47 |
# File 'lib/little_ghost/assembly_builder.rb', line 41 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.
38 39 40 |
# File 'lib/little_ghost/assembly_builder.rb', line 38 def runtime @runtime end |
Instance Method Details
#as_tool(**options) ⇒ Object
Exposes a snapshot as a Tool.
125 |
# File 'lib/little_ghost/assembly_builder.rb', line 125 def as_tool(**) = build.as_tool(**) |
#ask(message, **options) ⇒ Object
Executes a standalone snapshot and returns its Run.
108 |
# File 'lib/little_ghost/assembly_builder.rb', line 108 def ask(, **) = build.ask(, **) |
#assembly_id(value = nil) ⇒ Object
Reads or assigns the stable Assembly identifier.
50 51 52 53 54 55 |
# File 'lib/little_ghost/assembly_builder.rb', line 50 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.
66 |
# File 'lib/little_ghost/assembly_builder.rb', line 66 def assembly_kind = self.class.assembly_kind |
#build(runtime: self.runtime, run: nil) ⇒ Object
Builds one execution instance from the current definition snapshot.
100 101 102 103 104 105 |
# File 'lib/little_ghost/assembly_builder.rb', line 100 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.
119 120 |
# File 'lib/little_ghost/assembly_builder.rb', line 119 def call(input = nil, **) = build.call(input, **) # Streams a snapshot as StreamEvent objects. |
#definition ⇒ Object
Returns an immutable, recursively snapshotted definition.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/little_ghost/assembly_builder.rb', line 75 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.
58 59 60 61 62 63 |
# File 'lib/little_ghost/assembly_builder.rb', line 58 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.
123 124 |
# File 'lib/little_ghost/assembly_builder.rb', line 123 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.
121 122 |
# File 'lib/little_ghost/assembly_builder.rb', line 121 def stream(input = nil, **) = build.stream(input, **) # Starts a supervised execution from a snapshot. |
#stream_ask(message, **options) ⇒ Object
Lazily streams a standalone snapshot.
111 112 113 114 115 116 |
# File 'lib/little_ghost/assembly_builder.rb', line 111 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.
69 70 71 72 |
# File 'lib/little_ghost/assembly_builder.rb', line 69 def validate! definition self end |