Class: LLM::Function

Inherits:
Object
  • Object
show all
Extended by:
Registry
Includes:
Tracing
Defined in:
lib/llm/function.rb,
lib/llm/function/task.rb,
lib/llm/function/array.rb,
lib/llm/function/ractor.rb,
lib/llm/function/tracing.rb,
lib/llm/function/registry.rb,
lib/llm/function/ractor/job.rb,
lib/llm/function/task_group.rb,
lib/llm/function/fiber_group.rb,
lib/llm/function/ractor/task.rb,
lib/llm/function/ractor_group.rb,
lib/llm/function/thread_group.rb,
lib/llm/function/ractor/mailbox.rb

Overview

The LLM::Function class represents a local function that can be called by an LLM.

Examples:

example #1

LLM.function(:system) do |fn|
  fn.name "system"
  fn.description "Runs system commands"
  fn.params do |schema|
    schema.object(command: schema.string.required)
  end
  fn.define do |command:|
    {success: Kernel.system(command)}
  end
end

example #2

class System < LLM::Tool
  name "system"
  description "Runs system commands"
  params do |schema|
    schema.object(command: schema.string.required)
  end

  def call(command:)
    {success: Kernel.system(command)}
  end
end

Defined Under Namespace

Modules: Array, Ractor, Registry, Tracing Classes: FiberGroup, Return, Task, TaskGroup, ThreadGroup

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Registry

clear_registry!, extended, find_by_name, lock, registry, registry_key, tool_name, unregister

Constructor Details

#initialize(name) {|self| ... } ⇒ Function

Returns a new instance of Function.

Parameters:

  • name (String)

    The function name

Yield Parameters:



97
98
99
100
101
102
103
# File 'lib/llm/function.rb', line 97

def initialize(name, &b)
  @name = name
  @schema = LLM::Schema.new
  @called = false
  @cancelled = false
  yield(self) if block_given?
end

Instance Attribute Details

#argumentsArray?

Returns function arguments

Returns:



82
83
84
# File 'lib/llm/function.rb', line 82

def arguments
  @arguments
end

#idString?

Returns the function ID

Returns:

  • (String, nil)


77
78
79
# File 'lib/llm/function.rb', line 77

def id
  @id
end

#modelString?

Returns a model name, or nil

Returns:

  • (String, nil)


92
93
94
# File 'lib/llm/function.rb', line 92

def model
  @model
end

#tracerLLM::Tracer?

Returns a tracer, or nil

Returns:



87
88
89
# File 'lib/llm/function.rb', line 87

def tracer
  @tracer
end

Instance Method Details

#adapt(provider) ⇒ Hash

Returns:

  • (Hash)


263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/llm/function.rb', line 263

def adapt(provider)
  case provider.class.to_s
  when "LLM::Google"
    {name: @name, description: @description, parameters: @params}.compact
  when "LLM::Anthropic"
    {
      name: @name,
      description: @description,
      input_schema: @params || {type: "object", properties: {}}
    }.compact
  else
    format_openai(provider)
  end
end

#callLLM::Function::Return

Call the function

Returns:



159
160
161
162
163
# File 'lib/llm/function.rb', line 159

def call
  call_function
ensure
  @called = true
end

#called?Boolean

Returns true when a function has been called

Returns:

  • (Boolean)


243
244
245
# File 'lib/llm/function.rb', line 243

def called?
  @called
end

#cancel(reason: "function call cancelled") ⇒ LLM::Function::Return

Returns a value that communicates that the function call was cancelled

Examples:

llm = LLM.openai(key: ENV["KEY"])
ctx = LLM::Context.new(llm, tools: [fn1, fn2])
ctx.talk "I want to run the functions"
ctx.talk ctx.functions.map(&:cancel)

Returns:



222
223
224
225
226
# File 'lib/llm/function.rb', line 222

def cancel(reason: "function call cancelled")
  Return.new(id, name, {cancelled: true, reason:})
ensure
  @cancelled = true
end

#cancelled?Boolean

Returns true when a function has been cancelled

Returns:

  • (Boolean)


250
251
252
# File 'lib/llm/function.rb', line 250

def cancelled?
  @cancelled
end

#define(klass = nil, &b) ⇒ void Also known as: register

This method returns an undefined value.

Set the function implementation

Parameters:

  • b (Proc, Class)

    The function implementation



151
152
153
# File 'lib/llm/function.rb', line 151

def define(klass = nil, &b)
  @runner = klass || b
end

#description(desc = nil) ⇒ void

This method returns an undefined value.

Set (or get) the function description

Parameters:

  • desc (String) (defaults to: nil)

    The function description



121
122
123
124
125
126
127
# File 'lib/llm/function.rb', line 121

def description(desc = nil)
  if desc
    @description = desc
  else
    @description
  end
end

#interrupt!nil Also known as: cancel!

Notifies the function runner that the call was interrupted. This is cooperative and only applies to runners that implement ‘on_interrupt`.

Returns:

  • (nil)


233
234
235
236
237
# File 'lib/llm/function.rb', line 233

def interrupt!
  hook = %i[on_cancel on_interrupt].find { @runner.respond_to?(_1) }
  @runner.public_send(hook) if hook
  nil
end

#name(name = nil) ⇒ void

This method returns an undefined value.

Set (or get) the function name

Parameters:

  • name (String) (defaults to: nil)

    The function name



109
110
111
112
113
114
115
# File 'lib/llm/function.rb', line 109

def name(name = nil)
  if name
    @name = name.to_s
  else
    @name
  end
end

#params {|schema| ... } ⇒ LLM::Schema::Leaf?

Set (or get) the function parameters

Yield Parameters:

Returns:



133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/llm/function.rb', line 133

def params
  if block_given?
    params = yield(@schema)
    params = LLM::Schema.parse(params) if Hash === params
    if @params
      @params.merge!(params)
    else
      @params = params
    end
  else
    @params
  end
end

#pending?Boolean

Returns true when a function has neither been called nor cancelled

Returns:

  • (Boolean)


257
258
259
# File 'lib/llm/function.rb', line 257

def pending?
  !@called && !@cancelled
end

#spawn(strategy) ⇒ LLM::Function::Task

Calls the function concurrently.

This is the low-level method that powers concurrent tool execution. Prefer the collection methods on Context#functions for most use cases: LLM::Function::Array#call, LLM::Function::Array#wait, or LLM::Function::Array#spawn.

Examples:

# Normal usage (via collection)
ctx.talk(ctx.functions.wait)

# Direct usage (uncommon)
task = tool.spawn(:thread)
result = task.value

Parameters:

  • strategy (Symbol)

    Controls concurrency strategy:

    • ‘:thread`: Use threads

    • ‘:task`: Use async tasks (requires async gem)

    • ‘:fiber`: Use raw fibers

    • ‘:ractor`: Use Ruby ractors (class-based tools only; MCP tools are not supported)

Returns:



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/llm/function.rb', line 190

def spawn(strategy)
  task = case strategy
  when :task
    require "async" unless defined?(::Async)
    Async { call }
  when :thread
    Thread.new { call }
  when :fiber
    Fiber.new do
      call
    ensure
      Fiber.yield
    end.tap(&:resume)
  when :ractor
    raise ArgumentError, "Ractor concurrency only supports class-based tools" unless Class === @runner
    Ractor::Task.new(@runner, id, name, arguments)
  else
    raise ArgumentError, "Unknown strategy: #{strategy.inspect}. Expected :thread, :task, :fiber, or :ractor"
  end
  Task.new(task, self)
ensure
  @called = true
end