Class: Omakase::FakeChat

Inherits:
Object
  • Object
show all
Defined in:
lib/omakase/fake_chat.rb

Overview

Stands in for a RubyLLM::Chat so agents can be tested without a network: records how the chat was configured, then runs the script you gave it.

agent = SupportAgent.new(chat: Omakase::FakeChat.new { {"severity" => "high"} })

The script receives the chat, so it can drive the tool the way a model would:

Omakase::FakeChat.new { |chat| chat.run("finish(42)") }

Or one reply per model turn, in order; a turn past the last one raises:

Omakase::FakeChat.replies("prose, not JSON", {"result" => 42})

Defined Under Namespace

Classes: Response

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(&script) ⇒ FakeChat

Returns a new instance of FakeChat.



30
31
32
33
34
35
36
37
# File 'lib/omakase/fake_chat.rb', line 30

def initialize(&script)
  @script = script
  @instructions = []
  @tools = []
  @tasks = []
  @attachments = []
  @complete = true
end

Instance Attribute Details

#attachments ⇒ Object (readonly)

Returns the value of attribute attachments.



28
29
30
# File 'lib/omakase/fake_chat.rb', line 28

def attachments
  @attachments
end

#instructions ⇒ Object (readonly)

Returns the value of attribute instructions.



28
29
30
# File 'lib/omakase/fake_chat.rb', line 28

def instructions
  @instructions
end

#schema ⇒ Object (readonly)

Returns the value of attribute schema.



28
29
30
# File 'lib/omakase/fake_chat.rb', line 28

def schema
  @schema
end

#tasks ⇒ Object (readonly)

Returns the value of attribute tasks.



28
29
30
# File 'lib/omakase/fake_chat.rb', line 28

def tasks
  @tasks
end

#tools ⇒ Object (readonly)

Returns the value of attribute tools.



28
29
30
# File 'lib/omakase/fake_chat.rb', line 28

def tools
  @tools
end

Class Method Details

.replies(*replies) ⇒ Object



19
20
21
22
23
24
25
26
# File 'lib/omakase/fake_chat.rb', line 19

def self.replies(*replies)
  new do |chat|
    raise Error, "FakeChat: no scripted reply left for turn #{chat.tasks.size}" if replies.empty?

    reply = replies.shift
    reply.respond_to?(:call) ? reply.call(chat) : reply
  end
end

Instance Method Details

#ask(task, with: nil) ⇒ Object



46
# File 'lib/omakase/fake_chat.rb', line 46

def ask(task, with: nil) = ask_later(task, with:).step

#ask_later(task, with: nil) ⇒ Object



48
49
50
51
52
# File 'lib/omakase/fake_chat.rb', line 48

def ask_later(task, with: nil)
  @tasks << task
  @attachments << with if with
  tap { @complete = false }
end

#complete? ⇒ Boolean

Returns:

  • (Boolean)


60
# File 'lib/omakase/fake_chat.rb', line 60

def complete? = @complete

#run(code) ⇒ Object

Run code the way the model would, through the agent's one tool.



63
# File 'lib/omakase/fake_chat.rb', line 63

def run(code) = tools.fetch(0).call(code:)

#step ⇒ Object

The whole script is one step: it answers, so the chat is then complete.



55
56
57
58
# File 'lib/omakase/fake_chat.rb', line 55

def step
  @complete = true
  Response.new(@script.call(self))
end

#with_instructions(text) ⇒ Object

A log of every call — the real chat replaces unless append:.



40
# File 'lib/omakase/fake_chat.rb', line 40

def with_instructions(text, **) = tap { @instructions << text }

#with_schema(schema) ⇒ Object



42
# File 'lib/omakase/fake_chat.rb', line 42

def with_schema(schema) = tap { @schema = schema }

#with_tools(*tools) ⇒ Object



44
# File 'lib/omakase/fake_chat.rb', line 44

def with_tools(*tools) = tap { @tools.concat(tools) }