Class: Riffer::ToolRuntime

Inherits:
Object
  • Object
show all
Defined in:
lib/riffer/tool_runtime.rb

Overview

Riffer::ToolRuntime handles tool call execution for an agent.

Composes with a Riffer::Runner for concurrency control and provides execute as the sole public entry point.

Subclass and override dispatch_tool_call to customize how individual tool calls are dispatched (e.g., HTTP, gRPC).

runtime = Riffer::ToolRuntime::Inline.new
results = runtime.execute(tool_calls, tools: tools, context: context)

Direct Known Subclasses

Fibers, Inline, Threaded

Defined Under Namespace

Classes: Fibers, Inline, Threaded

Instance Method Summary collapse

Constructor Details

#initialize(runner:) ⇒ ToolRuntime

runner

the concurrency runner to use for batch execution.

Subclasses must provide a runner; instantiating ToolRuntime directly raises NotImplementedError.

– : (runner: Riffer::Runner) -> void

Raises:

  • (NotImplementedError)


25
26
27
28
# File 'lib/riffer/tool_runtime.rb', line 25

def initialize(runner:)
  raise NotImplementedError, "#{self.class} is abstract — use a subclass like Riffer::ToolRuntime::Inline" if instance_of?(Riffer::ToolRuntime)
  @runner = runner
end

Instance Method Details

#around_tool_call(tool_call, context:, assistant_message: nil) ⇒ Object

Hook that wraps each tool call execution. Override in subclasses to customize. Must yield to continue execution.

The default implementation simply yields.

class InstrumentedRuntime < Riffer::ToolRuntime::Inline
  private

  def around_tool_call(tool_call, context:, assistant_message: nil)
    start = Time.now
    result = yield
    Rails.logger.info("Tool #{tool_call.name} took #{Time.now - start}s")
    result
  end
end

– : (Riffer::Messages::Assistant::ToolCall, context: Hash[Symbol, untyped]?, ?assistant_message: Riffer::Messages::Assistant?) { () -> Riffer::Tools::Response } -> Riffer::Tools::Response



69
70
71
# File 'lib/riffer/tool_runtime.rb', line 69

def around_tool_call(tool_call, context:, assistant_message: nil)
  yield
end

#execute(tool_calls, tools:, context:, assistant_message: nil) ⇒ Object

Executes a batch of tool calls, returning [tool_call, response] pairs.

tool_calls

the tool calls to execute.

tools

the resolved tool classes.

context

the context hash.

assistant_message

the assistant message that produced these tool

calls, when known. Forwarded to +around_tool_call+ and
+dispatch_tool_call+ so subclasses can access it (e.g. for
instrumentation that needs the accompanying assistant text).

– : (Array, tools: Array, context: Hash[Symbol, untyped]?, ?assistant_message: Riffer::Messages::Assistant?) -> Array[[Riffer::Messages::Assistant::ToolCall, Riffer::Tools::Response]]



42
43
44
45
46
47
48
49
# File 'lib/riffer/tool_runtime.rb', line 42

def execute(tool_calls, tools:, context:, assistant_message: nil)
  @runner.map(tool_calls, context: context) do |tool_call|
    result = around_tool_call(tool_call, context: context, assistant_message: assistant_message) do
      dispatch_tool_call(tool_call, tools: tools, context: context, assistant_message: assistant_message)
    end
    [tool_call, result]
  end
end