Module: LLM
- Extended by:
- LLM
- Included in:
- LLM
- Defined in:
- lib/llm.rb,
lib/llm/pipe.rb,
lib/llm/repl.rb,
lib/llm/agent.rb,
lib/llm/error.rb,
lib/llm/guard.rb,
lib/llm/skill.rb,
lib/llm/utils.rb,
lib/llm/buffer.rb,
lib/llm/stream.rb,
lib/llm/tracer.rb,
lib/llm/context.rb,
lib/llm/message.rb,
lib/llm/session.rb,
lib/llm/uridata.rb,
lib/llm/version.rb,
lib/llm/contract.rb,
lib/llm/response.rb,
lib/llm/compactor.rb,
lib/llm/transport.rb,
lib/llm/tracer/null.rb,
lib/llm/transformer.rb,
lib/llm/eventhandler.rb,
lib/llm/json_adapter.rb,
lib/llm/providers/xai.rb,
lib/llm/providers/zai.rb,
lib/llm/tracer/logger.rb,
lib/llm/providers/google.rb,
lib/llm/providers/ollama.rb,
lib/llm/providers/openai.rb,
lib/llm/tracer/telemetry.rb,
lib/llm/providers/alibaba.rb,
lib/llm/providers/bedrock.rb,
lib/llm/providers/mistral.rb,
lib/llm/providers/deepseek.rb,
lib/llm/providers/llamacpp.rb,
lib/llm/providers/moonshot.rb,
lib/llm/providers/anthropic.rb,
lib/llm/providers/deepinfra.rb,
lib/llm/providers/openrouter.rb,
lib/llm/tracer/pretty_logger.rb
Overview
llm.rb is a zero-dependency AI runtime for Ruby. Thirteen providers, six concurrency strategies, MCP and A2A, streaming tool calls with cancellation, context compaction, and ORM persistence.
Defined Under Namespace
Modules: ActiveRecord, Contract, EventStream, Sequel, Utils Classes: A2A, Agent, Alibaba, Anthropic, Bedrock, Buffer, Compactor, Context, Cost, DeepInfra, DeepSeek, Error, EventHandler, File, Function, Google, Guard, JSONAdapter, LlamaCpp, MCP, Message, Mime, Mistral, Model, Moonshot, Multipart, Object, Ollama, OpenAI, OpenRouter, Pipe, Prompt, Provider, Registry, Repl, Response, Schema, ServerTool, Skill, Stream, Tool, Tracer, Transformer, Transport, URIData, Usage, XAI, ZAI
Constant Summary collapse
- UNDEFINED =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Object.new
Class.new(Error)
- RateLimitError =
HTTPTooManyRequests
Class.new(Error)
- InsufficientQuotaError =
A tokens-per-minute (TPM) rate limit. Alibaba reports this as
Throttling.AllocationQuota/insufficient_quota. It is a rate limit (retriable), distinct from a request-rate limit only for classification. Class.new(RateLimitError)
- ServerError =
HTTPServerError
Class.new(Error)
- NotFoundError =
HTTPNotFound
Class.new(Error)
- FormatError =
When an given an input object that is not understood
Class.new(Error)
- PromptError =
When given a prompt object that is not understood
Class.new(FormatError)
- InvalidRequestError =
When given an invalid request
Class.new(Error)
- ContextWindowError =
When the context window is exceeded
Class.new(InvalidRequestError)
- Interrupt =
When a request is interrupted
Class.new(Error)
- RactorError =
When a concurrency strategy cannot execute a given tool
Class.new(Error)
- NoSuchToolError =
When a tool call cannot be mapped to a local tool
Class.new(Error)
- NoSuchModelError =
When Registry can't map a model
Class.new(Error)
- NoSuchRegistryError =
When Registry can't map a registry
Class.new(Error)
- LoadError =
When an optional runtime dependency cannot be required
Class.new(Error)
- Session =
Deprecated.
Use Context instead. Scheduled for removal in v6.0.
Backward-compatible alias for LLM::Context
Context- VERSION =
"15.1.0"- Command =
Convenience constant
LLM::Repl::Command
Class Method Summary collapse
- .File(obj) ⇒ LLM::File
- .registry_for(llm) ⇒ LLM::Object
-
.require(name, version = nil) ⇒ Object
Requires an optional runtime dependency.
Instance Method Summary collapse
-
#a2a(http:, binding: :rest) ⇒ LLM::A2A
Creates a new A2A client connected to a remote agent.
- #alibaba(key: UNDEFINED) ⇒ Object (also: #aliyun)
- #anthropic(key: UNDEFINED) ⇒ Object
- #bedrock(access_key_id: UNDEFINED, secret_access_key: UNDEFINED, region: UNDEFINED) ⇒ Object
- #deepinfra(key: UNDEFINED) ⇒ Object
- #deepseek(key: UNDEFINED) ⇒ Object
-
#function(key, &b) ⇒ LLM::Function
Define a function.
- #google(key: UNDEFINED) ⇒ Object
-
#json ⇒ Class
Returns the JSON adapter used by the library.
-
#json=(adapter) ⇒ void
Sets the JSON adapter used by the library.
- #llamacpp(key: nil) ⇒ Object
-
#lock(name, &block) ⇒ void
Provides a thread-safe lock.
- #logger(llm, **params) ⇒ LLM::Tracer::Logger
- #mcp(**opts) ⇒ LLM::MCP
- #mistral(key: UNDEFINED) ⇒ Object
- #moonshot(key: UNDEFINED) ⇒ Object
- #ollama(key: nil) ⇒ Object
- #openai(key: UNDEFINED) ⇒ Object
- #openrouter(key: UNDEFINED) ⇒ Object
- #xai(key: UNDEFINED) ⇒ Object
- #zai(key: UNDEFINED) ⇒ Object
Class Method Details
.File(obj) ⇒ LLM::File
89 90 91 92 93 94 95 96 97 98 |
# File 'lib/llm/file.rb', line 89 def LLM.File(obj) case obj when File obj.close unless obj.closed? LLM.File(obj.path) when LLM::File, LLM::Response then obj when String then LLM::File.new(obj) else raise TypeError, "don't know how to handle #{obj.class} objects" end end |
.registry_for(llm) ⇒ LLM::Object
98 99 100 101 102 103 |
# File 'lib/llm.rb', line 98 def self.registry_for(llm) lock(:registry) do name = Symbol === llm ? llm : llm.name @registry[name] ||= Registry.for(name) end end |
.require(name, version = nil) ⇒ Object
Requires an optional runtime dependency
79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/llm.rb', line 79 def self.require(name, version = nil) names = { "xchan" => "xchan.rb", "net/http/persistent" => "net-http-persistent", "unicode/display_width" => "unicode-display_width" } gem(names[name] || name, version) if version super(name) rescue ::LoadError name = names[name] || name raise LLM::LoadError, "#{name}#{version ? " #{version}" : ""} is an optional " \ "runtime dependency but it does not appear to be installed. " \ "Consider 'gem install #{name}', adding '#{name}' to your Gemfile or " \ "opting out of the functionality provided by '#{name}'" end |
Instance Method Details
#a2a(http:, binding: :rest) ⇒ LLM::A2A
Creates a new A2A client connected to a remote agent.
341 342 343 |
# File 'lib/llm.rb', line 341 def a2a(http:, binding: :rest) LLM::A2A.http(**http, binding:) end |
#alibaba(key: UNDEFINED) ⇒ Object Also known as: aliyun
282 283 284 285 286 287 288 289 |
# File 'lib/llm.rb', line 282 def alibaba(key: UNDEFINED, **) lock(:require) { require_relative "llm/providers/alibaba" unless defined?(LLM::Alibaba) } if key == UNDEFINED LLM::Alibaba.new(key: key(name: :alibaba), **) else LLM::Alibaba.new(key:, **) end end |
#anthropic(key: UNDEFINED) ⇒ Object
140 141 142 143 144 145 146 147 |
# File 'lib/llm.rb', line 140 def anthropic(key: UNDEFINED, **) lock(:require) { require_relative "llm/providers/anthropic" unless defined?(LLM::Anthropic) } if key == UNDEFINED LLM::Anthropic.new(key: key(name: __method__), **) else LLM::Anthropic.new(key:, **) end end |
#bedrock(access_key_id: UNDEFINED, secret_access_key: UNDEFINED, region: UNDEFINED) ⇒ Object
295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
# File 'lib/llm.rb', line 295 def bedrock(access_key_id: UNDEFINED, secret_access_key: UNDEFINED, region: UNDEFINED, **) lock(:require) { require_relative "llm/providers/bedrock" unless defined?(LLM::Bedrock) } if [access_key_id, secret_access_key, region].any? { _1 == UNDEFINED } access_key_id = ENV["AWS_ACCESS_KEY_ID"] if access_key_id == UNDEFINED secret_access_key = ENV["AWS_SECRET_ACCESS_KEY"] if secret_access_key == UNDEFINED region = ENV["AWS_REGION"] if region == UNDEFINED if access_key_id.to_s.strip.empty? || secret_access_key.to_s.strip.empty? raise ArgumentError, "you must provide an API key" end LLM::Bedrock.new(access_key_id:, secret_access_key:, region:, **) else LLM::Bedrock.new(access_key_id:, secret_access_key:, region:, **) end end |
#deepinfra(key: UNDEFINED) ⇒ Object
204 205 206 207 208 209 210 211 |
# File 'lib/llm.rb', line 204 def deepinfra(key: UNDEFINED, **) lock(:require) { require_relative "llm/providers/deepinfra" unless defined?(LLM::DeepInfra) } if key == UNDEFINED LLM::DeepInfra.new(key: key(name: __method__), **) else LLM::DeepInfra.new(key:, **) end end |
#deepseek(key: UNDEFINED) ⇒ Object
180 181 182 183 184 185 186 187 |
# File 'lib/llm.rb', line 180 def deepseek(key: UNDEFINED, **) lock(:require) { require_relative "llm/providers/deepseek" unless defined?(LLM::DeepSeek) } if key == UNDEFINED LLM::DeepSeek.new(key: key(name: __method__), **) else LLM::DeepSeek.new(key:, **) end end |
#function(key, &b) ⇒ LLM::Function
Define a function
360 361 362 |
# File 'lib/llm.rb', line 360 def function(key, &b) LLM::Function.new(key, &b) end |
#google(key: UNDEFINED) ⇒ Object
152 153 154 155 156 157 158 159 |
# File 'lib/llm.rb', line 152 def google(key: UNDEFINED, **) lock(:require) { require_relative "llm/providers/google" unless defined?(LLM::Google) } if key == UNDEFINED LLM::Google.new(key: key(name: __method__), **) else LLM::Google.new(key:, **) end end |
#json ⇒ Class
Returns the JSON adapter used by the library
109 110 111 |
# File 'lib/llm.rb', line 109 def json @json ||= JSONAdapter::JSON end |
#json=(adapter) ⇒ void
This should be set once from the main thread when your program starts. Defaults to LLM::JSONAdapter::JSON.
This method returns an undefined value.
Sets the JSON adapter used by the library
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/llm.rb', line 121 def json=(adapter) @json = case adapter.to_s when "JSON", "json" then JSONAdapter::JSON when "Oj", "oj" then JSONAdapter::Oj when "Yajl", "yajl" then JSONAdapter::Yajl else is_class = Class === adapter is_subclass = is_class && adapter.ancestors.include?(LLM::JSONAdapter) if is_subclass adapter else raise TypeError, "Adapter must be a subclass of LLM::JSONAdapter" end end end |
#llamacpp(key: nil) ⇒ Object
172 173 174 175 |
# File 'lib/llm.rb', line 172 def llamacpp(key: nil, **) lock(:require) { require_relative "llm/providers/llamacpp" unless defined?(LLM::LlamaCpp) } LLM::LlamaCpp.new(key:, **) end |
#lock(name, &block) ⇒ void
This method returns an undefined value.
Provides a thread-safe lock
379 |
# File 'lib/llm.rb', line 379 def lock(name, &block) = @monitors[name].synchronize(&block) |
#logger(llm, **params) ⇒ LLM::Tracer::Logger
370 371 372 |
# File 'lib/llm.rb', line 370 def logger(llm, **params) LLM::Tracer::Logger.new(llm, params) end |
#mcp(**opts) ⇒ LLM::MCP
322 323 324 |
# File 'lib/llm.rb', line 322 def mcp(**opts) LLM::MCP.new(**opts) end |
#mistral(key: UNDEFINED) ⇒ Object
230 231 232 233 234 235 236 237 |
# File 'lib/llm.rb', line 230 def mistral(key: UNDEFINED, **) lock(:require) { require_relative "llm/providers/mistral" unless defined?(LLM::Mistral) } if key == UNDEFINED LLM::Mistral.new(key: key(name: __method__), **) else LLM::Mistral.new(key:, **) end end |
#moonshot(key: UNDEFINED) ⇒ Object
256 257 258 259 260 261 262 263 |
# File 'lib/llm.rb', line 256 def moonshot(key: UNDEFINED, **) lock(:require) { require_relative "llm/providers/moonshot" unless defined?(LLM::Moonshot) } if key == UNDEFINED LLM::Moonshot.new(key: key(name: __method__), **) else LLM::Moonshot.new(key:, **) end end |
#ollama(key: nil) ⇒ Object
164 165 166 167 |
# File 'lib/llm.rb', line 164 def ollama(key: nil, **) lock(:require) { require_relative "llm/providers/ollama" unless defined?(LLM::Ollama) } LLM::Ollama.new(key:, **) end |
#openai(key: UNDEFINED) ⇒ Object
192 193 194 195 196 197 198 199 |
# File 'lib/llm.rb', line 192 def openai(key: UNDEFINED, **) lock(:require) { require_relative "llm/providers/openai" unless defined?(LLM::OpenAI) } if key == UNDEFINED LLM::OpenAI.new(key: key(name: __method__), **) else LLM::OpenAI.new(key:, **) end end |
#openrouter(key: UNDEFINED) ⇒ Object
269 270 271 272 273 274 275 276 |
# File 'lib/llm.rb', line 269 def openrouter(key: UNDEFINED, **) lock(:require) { require_relative "llm/providers/openrouter" unless defined?(LLM::OpenRouter) } if key == UNDEFINED LLM::OpenRouter.new(key: key(name: __method__), **) else LLM::OpenRouter.new(key:, **) end end |
#xai(key: UNDEFINED) ⇒ Object
217 218 219 220 221 222 223 224 |
# File 'lib/llm.rb', line 217 def xai(key: UNDEFINED, **) lock(:require) { require_relative "llm/providers/xai" unless defined?(LLM::XAI) } if key == UNDEFINED LLM::XAI.new(key: key(name: __method__), **) else LLM::XAI.new(key:, **) end end |
#zai(key: UNDEFINED) ⇒ Object
243 244 245 246 247 248 249 250 |
# File 'lib/llm.rb', line 243 def zai(key: UNDEFINED, **) lock(:require) { require_relative "llm/providers/zai" unless defined?(LLM::ZAI) } if key == UNDEFINED LLM::ZAI.new(key: key(name: __method__), **) else LLM::ZAI.new(key:, **) end end |