Class: Silas::Eval::DSL

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

Overview

Define-time recorder for the scenario DSL.

Instance Method Summary collapse

Constructor Details

#initialize(name, tags) ⇒ DSL

Returns a new instance of DSL.



5
6
7
8
9
10
11
12
13
14
# File 'lib/silas/eval/dsl.rb', line 5

def initialize(name, tags)
  @name = name
  @tags = tags
  @mode = :fake
  @steps = {}
  @stubs = {}
  @approvals = []
  @metadata = {}
  @max_steps = nil
end

Instance Method Details

#approve(tool:) ⇒ Object



20
# File 'lib/silas/eval/dsl.rb', line 20

def approve(tool:) = (@approvals << tool.to_s)

#expect(&block) ⇒ Object



43
# File 'lib/silas/eval/dsl.rb', line 43

def expect(&block) = (@assertions = block)

#input(text) ⇒ Object



16
# File 'lib/silas/eval/dsl.rb', line 16

def input(text)  = (@input = text)

#max_steps(n) ⇒ Object



19
# File 'lib/silas/eval/dsl.rb', line 19

def max_steps(n) = (@max_steps = n)

#metadata(h) ⇒ Object



17
# File 'lib/silas/eval/dsl.rb', line 17

def (h)  = (@metadata = h)

#mode(m) ⇒ Object



18
# File 'lib/silas/eval/dsl.rb', line 18

def mode(m)      = (@mode = m)

#on_step(index, text: nil, call: nil, calls: []) ⇒ Object

on_step(0, text:, call: arguments:, calls: [ …, … ])



23
24
25
26
27
28
29
30
31
# File 'lib/silas/eval/dsl.rb', line 23

def on_step(index, text: nil, call: nil, calls: [])
  tcs = (calls + [ call ].compact).each_with_index.map do |c, n|
    Silas::Engines::ToolCall.new(id: "eval_s#{index}_#{n}", name: c[:name].to_s,
                                 arguments: (c[:arguments] || {}).stringify_keys)
  end
  blocks = []
  blocks << { "type" => "text", "text" => text } if text
  @steps[index] = { blocks: blocks, tool_calls: tcs }
end

#stub_tool(name, effect_mode: :at_most_once, approval: :never, &body) ⇒ Object

Override a real tool with a stub for a side-effect-free eval.



34
35
36
37
38
39
40
41
# File 'lib/silas/eval/dsl.rb', line 34

def stub_tool(name, effect_mode: :at_most_once, approval: :never, &body)
  obj = Object.new
  obj.define_singleton_method(:effect_mode) { effect_mode }
  obj.define_singleton_method(:approval_policy) { approval }
  obj.singleton_class.attr_accessor :session
  obj.define_singleton_method(:call, &body)
  @stubs[name.to_s] = obj
end

#to_scenarioObject

Raises:



45
46
47
48
49
50
51
52
# File 'lib/silas/eval/dsl.rb', line 45

def to_scenario
  raise Silas::Error, "eval #{@name.inspect} needs an input" unless @input
  raise Silas::Error, "eval #{@name.inspect} needs an expect block" unless @assertions

  Scenario.new(name: @name, input: @input, mode: @mode, steps: @steps,
               stubs: @stubs, approvals: @approvals, metadata: @metadata,
               max_steps: @max_steps, tags: @tags, assertions: @assertions)
end