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/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, 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.0.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
- #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
96 97 98 99 100 101 |
# File 'lib/llm.rb', line 96 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 |
# File 'lib/llm.rb', line 79 def self.require(name, version = nil) names = {"xchan" => "xchan.rb", "net/http/persistent" => "net-http-persistent"} 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.
326 327 328 |
# File 'lib/llm.rb', line 326 def a2a(http:, binding: :rest) LLM::A2A.http(**http, binding:) end |
#alibaba(key: UNDEFINED) ⇒ Object Also known as: aliyun
267 268 269 270 271 272 273 274 |
# File 'lib/llm.rb', line 267 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
138 139 140 141 142 143 144 145 |
# File 'lib/llm.rb', line 138 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
280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/llm.rb', line 280 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
202 203 204 205 206 207 208 209 |
# File 'lib/llm.rb', line 202 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
178 179 180 181 182 183 184 185 |
# File 'lib/llm.rb', line 178 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
345 346 347 |
# File 'lib/llm.rb', line 345 def function(key, &b) LLM::Function.new(key, &b) end |
#google(key: UNDEFINED) ⇒ Object
150 151 152 153 154 155 156 157 |
# File 'lib/llm.rb', line 150 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
107 108 109 |
# File 'lib/llm.rb', line 107 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
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/llm.rb', line 119 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
170 171 172 173 |
# File 'lib/llm.rb', line 170 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
364 |
# File 'lib/llm.rb', line 364 def lock(name, &block) = @monitors[name].synchronize(&block) |
#logger(llm, **params) ⇒ LLM::Tracer::Logger
355 356 357 |
# File 'lib/llm.rb', line 355 def logger(llm, **params) LLM::Tracer::Logger.new(llm, params) end |
#mcp(**opts) ⇒ LLM::MCP
307 308 309 |
# File 'lib/llm.rb', line 307 def mcp(**opts) LLM::MCP.new(**opts) end |
#mistral(key: UNDEFINED) ⇒ Object
228 229 230 231 232 233 234 235 |
# File 'lib/llm.rb', line 228 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
254 255 256 257 258 259 260 261 |
# File 'lib/llm.rb', line 254 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
162 163 164 165 |
# File 'lib/llm.rb', line 162 def ollama(key: nil, **) lock(:require) { require_relative "llm/providers/ollama" unless defined?(LLM::Ollama) } LLM::Ollama.new(key:, **) end |
#openai(key: UNDEFINED) ⇒ Object
190 191 192 193 194 195 196 197 |
# File 'lib/llm.rb', line 190 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 |
#xai(key: UNDEFINED) ⇒ Object
215 216 217 218 219 220 221 222 |
# File 'lib/llm.rb', line 215 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
241 242 243 244 245 246 247 248 |
# File 'lib/llm.rb', line 241 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 |