Class: Insika::DSL::SystemBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/insika/dsl.rb

Overview

Collects several agents into ONE runtime. A single agent is a Definition; more than one needs a container, because delegation (subagents) and any multi-agent pattern only mean something when the children live in the same graph. It adds no new engine path: each agent is still its own Pack, imported through the standard PackImporter.

Instance Method Summary collapse

Constructor Details

#initializeSystemBuilder

Returns a new instance of SystemBuilder.



47
48
49
50
51
# File 'lib/insika/dsl.rb', line 47

def initialize
  @definitions = []
  @workflows = []
  @runtime = {}
end

Instance Method Details

#agent(id, &block) ⇒ Object

Declares one agent — the SAME block the standalone Insika.agent takes. Returns its Definition, so a script can keep a handle if it wants one.



62
63
64
65
66
67
68
69
70
# File 'lib/insika/dsl.rb', line 62

def agent(id, &block)
  definition = Builder.new(id).build(&block)
  if @definitions.any? { |d| d.id == definition.id }
    raise ArgumentError, "duplicate agent id in system: #{definition.id}"
  end

  @definitions << definition
  definition
end

#api_base(value) ⇒ Object



103
# File 'lib/insika/dsl.rb', line 103

def api_base(value) = @runtime[:api_base] = value.to_s

#api_key(value) ⇒ Object



102
# File 'lib/insika/dsl.rb', line 102

def api_key(value) = @runtime[:api_key] = value.to_s

#build(backend: nil, &block) ⇒ Object

Raises:

  • (ArgumentError)


53
54
55
56
57
58
# File 'lib/insika/dsl.rb', line 53

def build(backend: nil, &block)
  instance_eval(&block) if block
  raise ArgumentError, "Insika.system needs at least one agent" if @definitions.empty?

  System.new(definitions: @definitions, workflows: @workflows, runtime: @runtime, backend: backend)
end

#provider(name) ⇒ Object

System-wide runtime knobs (NOT part of any pack): they configure the LLM clients for every agent. A per-agent provider still wins for that agent; this is the default and the place to put a shared key.



101
# File 'lib/insika/dsl.rb', line 101

def provider(name) = @runtime[:provider] = name.to_s

#workflow(name, description: nil, input: nil, output: nil, &block) ⇒ Object

Declares a WORKFLOW: deterministic Ruby orchestrating agent turns, for the shapes a single tool-loop should not decide on its own — chaining, routing, evaluate-and-retry. It is registered in the same WorkflowRegistry a deployment uses, so it gets a durable run (the run id IS a Task), :workflow_started/:workflow_completed on the event stream, and — when served — GET /v1/workflows + POST /v1/workflows/:name.

workflow "draft", input: { type: "object", required: ["topic"], … } do |input, ctx|
draft = ctx.ask("writer", "Write about #{input['topic']}")
ctx.ask("editor", "Tighten this:\n#{draft}")
end

input:/output: take a JSON Schema Hash (validated by the engine's zero-dep validator) or any dry-schema-compatible #call-able. A bad input is refused synchronously, with NO run created.

Raises:

  • (ArgumentError)


87
88
89
90
91
92
93
94
95
96
# File 'lib/insika/dsl.rb', line 87

def workflow(name, description: nil, input: nil, output: nil, &block)
  raise ArgumentError, "workflow '#{name}' needs a block" if block.nil?

  name = name.to_s
  raise ArgumentError, "duplicate workflow in system: #{name}" if @workflows.any? { |w| w[:name] == name }

  @workflows << { name: name, description: description,
                  input_schema: input, output_schema: output, block: block }
  name
end