llm.rb 11.3.0 → 11.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/README.md +77 -96
- data/lib/llm/a2a.rb +2 -2
- data/lib/llm/active_record/acts_as_agent.rb +7 -0
- data/lib/llm/active_record/acts_as_llm.rb +7 -0
- data/lib/llm/agent.rb +1 -1
- data/lib/llm/cost.rb +1 -1
- data/lib/llm/function/fiber_group.rb +2 -2
- data/lib/llm/function/task_group.rb +2 -2
- data/lib/llm/function/thread_group.rb +3 -3
- data/lib/llm/pipe.rb +1 -1
- data/lib/llm/providers/anthropic/request_adapter.rb +1 -1
- data/lib/llm/providers/bedrock/request_adapter/completion.rb +5 -5
- data/lib/llm/providers/bedrock/request_adapter.rb +3 -3
- data/lib/llm/providers/bedrock/response_adapter/completion.rb +2 -2
- data/lib/llm/providers/bedrock/response_adapter.rb +2 -2
- data/lib/llm/providers/deepseek/request_adapter.rb +1 -1
- data/lib/llm/providers/google/request_adapter.rb +1 -1
- data/lib/llm/providers/ollama/request_adapter.rb +1 -1
- data/lib/llm/providers/openai/request_adapter.rb +1 -1
- data/lib/llm/registry.rb +2 -2
- data/lib/llm/response.rb +1 -1
- data/lib/llm/schema/object.rb +1 -1
- data/lib/llm/stream.rb +1 -1
- data/lib/llm/tool.rb +2 -2
- data/lib/llm/transport/http.rb +2 -2
- data/lib/llm/transport/persistent_http.rb +1 -1
- data/lib/llm/transport/response/http.rb +1 -1
- data/lib/llm/utils.rb +1 -1
- data/lib/llm/version.rb +1 -1
- data/lib/llm.rb +11 -8
- data/llm.gemspec +10 -9
- data/resources/deepdive.md +432 -0
- metadata +14 -14
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://r.uby.dev/llm/">
|
|
3
|
+
<img
|
|
4
|
+
src="https://github.com/r-uby-dev/llm.rb/raw/main/rubydev.svg"
|
|
5
|
+
width="400"
|
|
6
|
+
height="200"
|
|
7
|
+
border="0"
|
|
8
|
+
alt="a r.uby.dev project"
|
|
9
|
+
>
|
|
10
|
+
</a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
> A [r.uby.dev](https://r.uby.dev) project.
|
|
14
|
+
|
|
15
|
+
## Intro
|
|
16
|
+
|
|
17
|
+
This guide is a practical walkthrough of [llm.rb](https://github.com/r-uby-dev/llm.rb#readme) —
|
|
18
|
+
Ruby's capable AI runtime.
|
|
19
|
+
|
|
20
|
+
llm.rb runs on Ruby's standard library by default and loads optional pieces
|
|
21
|
+
only when needed. You can start with a provider and a single context, then add
|
|
22
|
+
agents, tools, streaming, persistence, embeddings, and protocol clients
|
|
23
|
+
without changing the shape of your code.
|
|
24
|
+
|
|
25
|
+
It supports OpenAI, OpenAI-compatible endpoints, Anthropic, Google Gemini,
|
|
26
|
+
DeepSeek, xAI, Z.ai, AWS Bedrock, Ollama, and llama.cpp. ActiveRecord and
|
|
27
|
+
Sequel support are built in, along with concurrent tool execution through
|
|
28
|
+
threads, tasks, fibers, ractors, and fork.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
gem install llm.rb
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
#### Agent
|
|
39
|
+
|
|
40
|
+
[`LLM::Agent`](https://r.uby.dev/api-docs/llm.rb/LLM/Agent.html) is the
|
|
41
|
+
recommended starting point.
|
|
42
|
+
<br>
|
|
43
|
+
It manages tool execution for you and keeps conversation state across turns.
|
|
44
|
+
|
|
45
|
+
```ruby
|
|
46
|
+
require "llm"
|
|
47
|
+
|
|
48
|
+
llm = LLM.openai(key: ENV["KEY"])
|
|
49
|
+
agent = LLM::Agent.new(llm, stream: $stdout)
|
|
50
|
+
agent.talk "Hello world"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
#### REPL
|
|
54
|
+
|
|
55
|
+
A read-eval-print loop is the simplest way to interact with an agent.
|
|
56
|
+
<br>
|
|
57
|
+
The loop reads input, sends it to the model, and prints the response as it
|
|
58
|
+
arrives:
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
require "llm"
|
|
62
|
+
|
|
63
|
+
llm = LLM.openai(key: ENV["KEY"])
|
|
64
|
+
agent = LLM::Agent.new(llm, stream: $stdout)
|
|
65
|
+
|
|
66
|
+
loop do
|
|
67
|
+
print "> "
|
|
68
|
+
agent.talk(STDIN.gets || break)
|
|
69
|
+
puts
|
|
70
|
+
end
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### Context
|
|
74
|
+
|
|
75
|
+
[`LLM::Context`](https://r.uby.dev/api-docs/llm.rb/LLM/Context.html) is the
|
|
76
|
+
lower-level runtime object.
|
|
77
|
+
<br>
|
|
78
|
+
It holds the same conversation state but leaves tool execution up to you.
|
|
79
|
+
Use it when you want to decide when and how tools run.
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
require "llm"
|
|
83
|
+
|
|
84
|
+
llm = LLM.openai(key: ENV["KEY"])
|
|
85
|
+
ctx = LLM::Context.new(llm, stream: $stdout)
|
|
86
|
+
ctx.talk "Hello world"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
With tools, the manual loop is explicit:
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
ctx = LLM::Context.new(llm, tools: [ReadFile])
|
|
93
|
+
ctx.talk("Read README.md and summarize it.")
|
|
94
|
+
ctx.talk(ctx.wait(:call)) while ctx.functions?
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
For ordinary application code, prefer
|
|
98
|
+
[`LLM::Agent`](https://r.uby.dev/api-docs/llm.rb/LLM/Agent.html).
|
|
99
|
+
It does the same thing but manages the loop for you.
|
|
100
|
+
|
|
101
|
+
## Tools
|
|
102
|
+
|
|
103
|
+
#### Definition
|
|
104
|
+
|
|
105
|
+
Tools extend what the model can do.
|
|
106
|
+
<br>
|
|
107
|
+
They are plain Ruby classes with typed parameters. Define one, attach it to
|
|
108
|
+
an agent, and the model can call it when it makes sense.
|
|
109
|
+
|
|
110
|
+
```ruby
|
|
111
|
+
class ReadFile < LLM::Tool
|
|
112
|
+
name "read-file"
|
|
113
|
+
description "Read a file"
|
|
114
|
+
parameter :path, String, "The filename or path"
|
|
115
|
+
required %i[path]
|
|
116
|
+
|
|
117
|
+
def call(path:)
|
|
118
|
+
{contents: File.read(path)}
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Attach the tool to an agent:
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
agent = LLM::Agent.new(llm, stream: $stdout, tools: [ReadFile])
|
|
127
|
+
agent.talk "Read README.md and summarize the project."
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
[`LLM::Tool`](https://r.uby.dev/api-docs/llm.rb/LLM/Tool.html) handles the
|
|
131
|
+
Ruby-side definition. llm.rb adapts the tool schema to the provider at request
|
|
132
|
+
time.
|
|
133
|
+
|
|
134
|
+
#### Concurrency
|
|
135
|
+
|
|
136
|
+
When an agent calls several tools at once, you can run them in parallel.
|
|
137
|
+
<br>
|
|
138
|
+
This cuts down waiting time when tools do independent work like reading
|
|
139
|
+
files or calling APIs.
|
|
140
|
+
|
|
141
|
+
```ruby
|
|
142
|
+
class Agent < LLM::Agent
|
|
143
|
+
model "gpt-5.4-mini"
|
|
144
|
+
tools ReadFile
|
|
145
|
+
concurrency :thread
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
llm = LLM.openai(key: ENV["KEY"])
|
|
149
|
+
agent = Agent.new(llm, stream: $stdout)
|
|
150
|
+
agent.talk "Read README.md and CHANGELOG.md and compare them."
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Structured Output
|
|
154
|
+
|
|
155
|
+
#### Schema
|
|
156
|
+
|
|
157
|
+
When you need JSON with a known shape, use
|
|
158
|
+
[`LLM::Schema`](https://r.uby.dev/api-docs/llm.rb/LLM/Schema.html).
|
|
159
|
+
<br>
|
|
160
|
+
The model will return data that matches your schema instead of free text.
|
|
161
|
+
|
|
162
|
+
```ruby
|
|
163
|
+
class Report < LLM::Schema
|
|
164
|
+
property :category, Enum["performance", "security", "outage"]
|
|
165
|
+
property :summary, String, "Short summary"
|
|
166
|
+
property :services, Array[String], "Impacted services"
|
|
167
|
+
required %i[category summary services]
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
agent = LLM::Agent.new(llm, schema: Report)
|
|
171
|
+
res = agent.talk("Classify: 'API latency spiked for the billing service.'")
|
|
172
|
+
puts res.content!
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
For one-off schemas, build the shape inline:
|
|
176
|
+
|
|
177
|
+
```ruby
|
|
178
|
+
schema = LLM::Schema.new.object(
|
|
179
|
+
category: LLM::Schema.new.string.enum("bug", "feature").required,
|
|
180
|
+
summary: LLM::Schema.new.string.required
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
agent = LLM::Agent.new(llm, schema:)
|
|
184
|
+
res = agent.talk("Classify: add a dark mode toggle.")
|
|
185
|
+
puts res.content
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Streaming
|
|
189
|
+
|
|
190
|
+
#### Stream
|
|
191
|
+
|
|
192
|
+
Streaming works with any object that responds to `#<<`, like `$stdout`.
|
|
193
|
+
<br>
|
|
194
|
+
For more control, subclass
|
|
195
|
+
[`LLM::Stream`](https://r.uby.dev/api-docs/llm.rb/LLM/Stream.html) and
|
|
196
|
+
override its callbacks:
|
|
197
|
+
|
|
198
|
+
```ruby
|
|
199
|
+
class MyStream < LLM::Stream
|
|
200
|
+
def on_content(content)
|
|
201
|
+
print content
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def on_reasoning_content(content)
|
|
205
|
+
warn content
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
llm = LLM.openai(key: ENV["KEY"])
|
|
210
|
+
agent = LLM::Agent.new(llm, stream: MyStream.new)
|
|
211
|
+
agent.talk "Explain Ruby fibers."
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Skills
|
|
215
|
+
|
|
216
|
+
#### Release
|
|
217
|
+
|
|
218
|
+
Skills package repeatable instructions and scoped tool access into
|
|
219
|
+
`SKILL.md` directories.
|
|
220
|
+
<br>
|
|
221
|
+
They turn common workflows into named capabilities that agents can load
|
|
222
|
+
on demand.
|
|
223
|
+
|
|
224
|
+
```yaml
|
|
225
|
+
---
|
|
226
|
+
name: release
|
|
227
|
+
description: Prepare a release
|
|
228
|
+
tools: ["search-docs", "git"]
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Task
|
|
232
|
+
|
|
233
|
+
Review the release state, summarize what changed, and prepare the release.
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
```ruby
|
|
237
|
+
class ReleaseAgent < LLM::Agent
|
|
238
|
+
model "gpt-5.4-mini"
|
|
239
|
+
skills "./skills/release"
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
llm = LLM.openai(key: ENV["KEY"])
|
|
243
|
+
ReleaseAgent.new(llm, stream: $stdout).talk("Prepare the next release.")
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
When a skill runs, llm.rb starts a subagent with the skill's instructions,
|
|
247
|
+
its allowed tools, and recent conversation context. Skills can also use
|
|
248
|
+
`tools: inherit` to run with the parent agent's full toolset.
|
|
249
|
+
|
|
250
|
+
## MCP
|
|
251
|
+
|
|
252
|
+
#### Stdio
|
|
253
|
+
|
|
254
|
+
[`LLM::MCP`](https://r.uby.dev/api-docs/llm.rb/LLM/MCP.html) lets llm.rb use
|
|
255
|
+
tools provided by local stdio servers or remote HTTP servers.
|
|
256
|
+
<br>
|
|
257
|
+
This is how you connect your agent to GitHub, databases, or anything else
|
|
258
|
+
that speaks the Model Context Protocol.
|
|
259
|
+
|
|
260
|
+
```ruby
|
|
261
|
+
require "llm"
|
|
262
|
+
|
|
263
|
+
llm = LLM.openai(key: ENV["KEY"])
|
|
264
|
+
mcp = LLM::MCP.stdio(argv: ["ruby", "server.rb"])
|
|
265
|
+
|
|
266
|
+
mcp.session do
|
|
267
|
+
agent = LLM::Agent.new(llm, stream: $stdout, tools: mcp.tools)
|
|
268
|
+
agent.talk "Use the available tools to inspect the environment."
|
|
269
|
+
end
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
#### Remote
|
|
273
|
+
|
|
274
|
+
For HTTP MCP servers, use persistent connections when you make repeated
|
|
275
|
+
tool calls:
|
|
276
|
+
|
|
277
|
+
```ruby
|
|
278
|
+
mcp = LLM::MCP.http(
|
|
279
|
+
url: "https://remote-mcp.example.com",
|
|
280
|
+
transport: :net_http_persistent
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
agent = LLM::Agent.new(llm, stream: $stdout, tools: mcp.tools)
|
|
284
|
+
agent.talk "Use the remote tools to inspect the repository."
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Persistence
|
|
288
|
+
|
|
289
|
+
#### Overview
|
|
290
|
+
|
|
291
|
+
Agents and contexts serialize to JSON and restore later.
|
|
292
|
+
<br>
|
|
293
|
+
The same serialized state powers the ActiveRecord and Sequel integrations.
|
|
294
|
+
|
|
295
|
+
#### Filesystem
|
|
296
|
+
|
|
297
|
+
Persist agent state to a JSON file on disk.
|
|
298
|
+
|
|
299
|
+
```ruby
|
|
300
|
+
require "llm"
|
|
301
|
+
|
|
302
|
+
llm = LLM.openai(key: ENV["KEY"])
|
|
303
|
+
agent = LLM::Agent.new(llm)
|
|
304
|
+
agent.talk "Remember that my favorite language is Ruby"
|
|
305
|
+
|
|
306
|
+
# Save
|
|
307
|
+
File.write("agent.json", agent.to_json)
|
|
308
|
+
|
|
309
|
+
# Restore later
|
|
310
|
+
agent2 = LLM::Agent.new(llm, stream: $stdout)
|
|
311
|
+
agent2.restore(path: "agent.json")
|
|
312
|
+
agent2.talk "What is my favorite language?"
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### ActiveRecord
|
|
316
|
+
|
|
317
|
+
[`acts_as_agent`](https://r.uby.dev/api-docs/llm.rb/LLM/ActiveRecord/ActsAsAgent.html)
|
|
318
|
+
wraps an agent directly on an ActiveRecord model.
|
|
319
|
+
<br>
|
|
320
|
+
Serialized state lives in a single `data` column while your application
|
|
321
|
+
controls provider, model, and tool configuration.
|
|
322
|
+
|
|
323
|
+
```ruby
|
|
324
|
+
require "llm"
|
|
325
|
+
require "active_record"
|
|
326
|
+
require "llm/active_record"
|
|
327
|
+
|
|
328
|
+
class Ticket < ApplicationRecord
|
|
329
|
+
acts_as_agent provider: :set_provider, context: :set_context
|
|
330
|
+
model "gpt-5.4-mini"
|
|
331
|
+
instructions "You are a concise support assistant."
|
|
332
|
+
tools SearchDocs, Escalate
|
|
333
|
+
concurrency :thread
|
|
334
|
+
|
|
335
|
+
private
|
|
336
|
+
|
|
337
|
+
def set_provider
|
|
338
|
+
LLM.openai(key: ENV["OPENAI_SECRET"])
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def set_context
|
|
342
|
+
{mode: :responses, store: false}
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
ticket = Ticket.create!
|
|
347
|
+
puts ticket.talk("How do I rotate my API key?").content
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
If you need manual control over tool execution, use
|
|
351
|
+
[`acts_as_llm`](https://r.uby.dev/api-docs/llm.rb/LLM/ActiveRecord/ActsAsLLM.html)
|
|
352
|
+
instead. It wraps
|
|
353
|
+
[`LLM::Context`](https://r.uby.dev/api-docs/llm.rb/LLM/Context.html) with the
|
|
354
|
+
same persistence contract.
|
|
355
|
+
|
|
356
|
+
## Embeddings
|
|
357
|
+
|
|
358
|
+
#### Vector
|
|
359
|
+
|
|
360
|
+
Embeddings turn text into vectors. Call `.embed` on any provider that supports
|
|
361
|
+
it. The returned vectors can be stored in a vector-aware database (PostgreSQL
|
|
362
|
+
with pgvector, SQLite with `vec0`, or a dedicated vector database) and
|
|
363
|
+
compared by semantic similarity.
|
|
364
|
+
|
|
365
|
+
```ruby
|
|
366
|
+
llm = LLM.openai(key: ENV["KEY"])
|
|
367
|
+
res = llm.embed("llm.rb manages providers, agents, tools, and state")
|
|
368
|
+
puts res.model
|
|
369
|
+
puts res.embeddings.first.size
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Embed multiple texts at once:
|
|
373
|
+
|
|
374
|
+
```ruby
|
|
375
|
+
chunks = [
|
|
376
|
+
"LLM::Agent manages the tool loop automatically.",
|
|
377
|
+
"LLM::Context exposes the low-level tool loop.",
|
|
378
|
+
"MCP tools can be passed to agents as local tools."
|
|
379
|
+
]
|
|
380
|
+
|
|
381
|
+
res = llm.embed(chunks)
|
|
382
|
+
res.embeddings.each_with_index { |vec, i| puts "Vector #{i}: #{vec.size} dimensions" }
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
## Multimodal
|
|
386
|
+
|
|
387
|
+
#### Image
|
|
388
|
+
|
|
389
|
+
Prompts can be strings, arrays, or
|
|
390
|
+
[`LLM::Prompt`](https://r.uby.dev/api-docs/llm.rb/LLM/Prompt.html) objects.
|
|
391
|
+
<br>
|
|
392
|
+
Arrays let you mix text with images and other content.
|
|
393
|
+
|
|
394
|
+
```ruby
|
|
395
|
+
agent = LLM::Agent.new(llm)
|
|
396
|
+
agent.talk [
|
|
397
|
+
"Describe this image",
|
|
398
|
+
agent.image_url("https://example.com/image.png")
|
|
399
|
+
]
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Attach local files directly with
|
|
403
|
+
[`LLM::Agent#ask`](https://r.uby.dev/api-docs/llm.rb/LLM/Agent.html#ask-instance_method):
|
|
404
|
+
|
|
405
|
+
```ruby
|
|
406
|
+
agent = LLM::Agent.new(llm)
|
|
407
|
+
puts agent.ask("Summarize this document.", with: "README.md").content
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
## Tracing
|
|
411
|
+
|
|
412
|
+
#### Logger
|
|
413
|
+
|
|
414
|
+
Attach a tracer at the provider level to log requests and tool calls:
|
|
415
|
+
|
|
416
|
+
```ruby
|
|
417
|
+
llm.tracer = LLM::Tracer::Logger.new(llm, io: $stdout)
|
|
418
|
+
agent = LLM::Agent.new(llm)
|
|
419
|
+
agent.talk("Hello")
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
## Applications
|
|
423
|
+
|
|
424
|
+
#### SSH
|
|
425
|
+
|
|
426
|
+
The llm.rb runtime powers small terminal applications that you can try over
|
|
427
|
+
SSH right now.
|
|
428
|
+
|
|
429
|
+
| Application | Try it | Runtime |
|
|
430
|
+
|---|---|---|
|
|
431
|
+
| [matz](https://r.uby.dev/matz/) | `ssh matz@r.uby.dev` | [mruby-llm](https://r.uby.dev/mruby-llm/) |
|
|
432
|
+
| [robert](https://4.4bsd.dev/robert) | `ssh robert@4.4bsd.dev` | [mruby-llm](https://r.uby.dev/mruby-llm/) |
|
metadata
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: llm.rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 11.3.
|
|
4
|
+
version: 11.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- Robert (0x1eef)
|
|
8
8
|
- Antar Azri
|
|
9
9
|
- Rodrigo Serrano
|
|
10
|
-
- Christos Maris
|
|
11
10
|
bindir: bin
|
|
12
11
|
cert_chain: []
|
|
13
12
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
@@ -41,19 +40,19 @@ dependencies:
|
|
|
41
40
|
- !ruby/object:Gem::Version
|
|
42
41
|
version: 0.9.37
|
|
43
42
|
- !ruby/object:Gem::Dependency
|
|
44
|
-
name:
|
|
43
|
+
name: redcarpet
|
|
45
44
|
requirement: !ruby/object:Gem::Requirement
|
|
46
45
|
requirements:
|
|
47
46
|
- - "~>"
|
|
48
47
|
- !ruby/object:Gem::Version
|
|
49
|
-
version: '
|
|
48
|
+
version: '3.6'
|
|
50
49
|
type: :development
|
|
51
50
|
prerelease: false
|
|
52
51
|
version_requirements: !ruby/object:Gem::Requirement
|
|
53
52
|
requirements:
|
|
54
53
|
- - "~>"
|
|
55
54
|
- !ruby/object:Gem::Version
|
|
56
|
-
version: '
|
|
55
|
+
version: '3.6'
|
|
57
56
|
- !ruby/object:Gem::Dependency
|
|
58
57
|
name: webrick
|
|
59
58
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -279,7 +278,7 @@ dependencies:
|
|
|
279
278
|
- !ruby/object:Gem::Version
|
|
280
279
|
version: '1.18'
|
|
281
280
|
description: |
|
|
282
|
-
llm.rb is Ruby's
|
|
281
|
+
llm.rb is Ruby's capable AI runtime.
|
|
283
282
|
|
|
284
283
|
It runs on Ruby's standard library by default. loads optional pieces
|
|
285
284
|
only when needed, and offers a single runtime for providers, agents,
|
|
@@ -293,7 +292,7 @@ description: |
|
|
|
293
292
|
tool execution through threads, tasks (via async gem), fibers, ractors,
|
|
294
293
|
and fork (via xchan.rb gem).
|
|
295
294
|
email:
|
|
296
|
-
- robert@
|
|
295
|
+
- robert@r.uby.dev
|
|
297
296
|
executables: []
|
|
298
297
|
extensions: []
|
|
299
298
|
extra_rdoc_files: []
|
|
@@ -512,14 +511,15 @@ files:
|
|
|
512
511
|
- lib/sequel/plugins/agent.rb
|
|
513
512
|
- lib/sequel/plugins/llm.rb
|
|
514
513
|
- llm.gemspec
|
|
515
|
-
|
|
514
|
+
- resources/deepdive.md
|
|
515
|
+
homepage: https://r.uby.dev/llm/
|
|
516
516
|
licenses:
|
|
517
517
|
- 0BSD
|
|
518
518
|
metadata:
|
|
519
|
-
homepage_uri: https://
|
|
520
|
-
source_code_uri: https://github.com/
|
|
521
|
-
documentation_uri: https://
|
|
522
|
-
changelog_uri: https://
|
|
519
|
+
homepage_uri: https://r.uby.dev/llm/
|
|
520
|
+
source_code_uri: https://github.com/r-uby-dev/llm.rb
|
|
521
|
+
documentation_uri: https://r.uby.dev/llm/
|
|
522
|
+
changelog_uri: https://r.uby.dev/api-docs/llm.rb/file.CHANGELOG.html
|
|
523
523
|
rdoc_options: []
|
|
524
524
|
require_paths:
|
|
525
525
|
- lib
|
|
@@ -536,5 +536,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
536
536
|
requirements: []
|
|
537
537
|
rubygems_version: 4.0.6
|
|
538
538
|
specification_version: 4
|
|
539
|
-
summary: Ruby's
|
|
539
|
+
summary: Ruby's capable AI runtime
|
|
540
540
|
test_files: []
|