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 copies its declarations and referenced Assembly definitions. Later builder changes affect future executions without changing an Assembly already built. Ruby closures and the objects they reference remain live 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 the current declarations as a Tool.
-
#ask(message, **options) ⇒ Object
Executes the current declarations and returns their 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 declarations.
-
#call(input = nil, **options) ⇒ Object
Executes the current declarations to completion.
-
#definition ⇒ Object
Returns a complete definition for the builder's current declarations.
-
#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 the current declarations.
-
#stream(input = nil, **options) ⇒ Object
Streams the current declarations as StreamEvent objects.
-
#stream_ask(message, **options) ⇒ Object
Lazily streams an execution built from the current declarations.
-
#validate! ⇒ Object
Validates the builder's current declarations and returns this 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 the current declarations as a Tool.
147 |
# File 'lib/little_ghost/assembly_builder.rb', line 147 def as_tool(**) = build.as_tool(**) |
#ask(message, **options) ⇒ Object
Executes the current declarations and returns their 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 declarations.
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 the current declarations to completion.
141 142 |
# File 'lib/little_ghost/assembly_builder.rb', line 141 def call(input = nil, **) = build.call(input, **) # Streams the current declarations as StreamEvent objects. |
#definition ⇒ Object
Returns a complete definition for the builder's current declarations.
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 the current declarations.
145 146 |
# File 'lib/little_ghost/assembly_builder.rb', line 145 def start_execution(payload, &block) = build.start_execution(payload, &block) # Exposes the current declarations as a Tool. |
#stream(input = nil, **options) ⇒ Object
Streams the current declarations 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 the current declarations. |
#stream_ask(message, **options) ⇒ Object
Lazily streams an execution built from the current declarations.
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 builder's current declarations and returns this builder.
91 92 93 94 |
# File 'lib/little_ghost/assembly_builder.rb', line 91 def validate! definition self end |