llm.rb 15.0.2 → 15.0.3
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 +15 -0
- data/README.md +13 -56
- data/lib/llm/active_record.rb +1 -1
- data/lib/llm/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b2700592b8b9fbb85694c24a0a7379a84494b0e4f2157d6302fad1552df9d684
|
|
4
|
+
data.tar.gz: 43864e55f008478a40860511f9ca138f86010695225f91f0b2a07fbcff1ed448
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 464e203f6e4dc1fb2ea2aaa5bd4a2f95753d569190e63e4cd590b014aed4e369fa2f2835a4d6d95394b6988210c880e976abd5d8e8c69f015b057bb1f193609d
|
|
7
|
+
data.tar.gz: 9303d2475e2bd32dc53b65b7b9d54fa28611616a0714015bd1c0d74e8ca7cd66e6d88889b73231ed19dda38b2f2888ded08569694f23bd834a8e7c1f3fd6db35
|
data/CHANGELOG.md
CHANGED
|
@@ -15,6 +15,21 @@
|
|
|
15
15
|
|
|
16
16
|
## What's next
|
|
17
17
|
|
|
18
|
+
## v15.0.3
|
|
19
|
+
|
|
20
|
+
Changes since `v15.0.2`.
|
|
21
|
+
|
|
22
|
+
This release fixes ActiveRecord `:json`/`:jsonb` serialization so tool
|
|
23
|
+
call arguments round-trip as JSON objects instead of arrays of pairs.
|
|
24
|
+
|
|
25
|
+
### Fix
|
|
26
|
+
|
|
27
|
+
* **activerecord: serialize tool call arguments properly** <br>
|
|
28
|
+
Fix a bug where the ActiveRecord `:json`/`:jsonb` layer serialized tool
|
|
29
|
+
call arguments as an array of pairs instead of a Hash. The context is
|
|
30
|
+
now serialized through its JSON form, so tool call arguments round-trip
|
|
31
|
+
as JSON objects that providers accept.
|
|
32
|
+
|
|
18
33
|
## v15.0.2
|
|
19
34
|
|
|
20
35
|
Changes since `v15.0.1`.
|
data/README.md
CHANGED
|
@@ -15,22 +15,16 @@
|
|
|
15
15
|
Welcome to the canonical llm.rb repository.
|
|
16
16
|
|
|
17
17
|
llm.rb is an advanced runtime for building agentic AI applications
|
|
18
|
-
on CRuby. It has zero runtime dependencies by default,
|
|
18
|
+
on CRuby. It has zero runtime dependencies by default, supports
|
|
19
19
|
concurrent and parallel tool execution and has a single coherent API
|
|
20
20
|
that spans 13+ providers. Streaming, tools, guards, compaction, the
|
|
21
21
|
REPL, builtin MCP/A2A support and the database integrations all build
|
|
22
22
|
on the same three concepts: providers, contexts, and agents.
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
naturally. Some features, such as ActiveRecord support, require
|
|
26
|
-
optional dependencies that are opt-in.
|
|
27
|
-
|
|
28
|
-
The best way to learn about llm.rb is to ask [the official chatbot](https://r.uby.dev)
|
|
24
|
+
The most effective way to learn about llm.rb is to ask [the r.uby.dev chatbot](https://r.uby.dev)
|
|
29
25
|
a question. It is connected to the llm.rb GitHub repository, backed by
|
|
30
|
-
ActiveRecord and uses the builtin MCP feature to connect to GitHub.
|
|
31
|
-
|
|
32
|
-
you should get an answer that is grounded in the source code. It is 100%
|
|
33
|
-
free to use and powered by DeepSeek under the hood.
|
|
26
|
+
ActiveRecord and uses the builtin MCP feature to connect to GitHub. All
|
|
27
|
+
answers are grounded in the llm.rb source code.
|
|
34
28
|
|
|
35
29
|
## Install
|
|
36
30
|
|
|
@@ -46,8 +40,7 @@ The
|
|
|
46
40
|
[`LLM::Agent`](https://r.uby.dev/api-docs/llm.rb/LLM/Agent.html)
|
|
47
41
|
class is the default high-level interface,
|
|
48
42
|
and it is recommended for most use-cases. It manages tool execution
|
|
49
|
-
automatically and
|
|
50
|
-
[guards against infinite loops](https://r.uby.dev/llm/deepdive/advanced/guard),
|
|
43
|
+
automatically and guards against infinite loops,
|
|
51
44
|
manages conversation state, and much more.
|
|
52
45
|
|
|
53
46
|
```ruby
|
|
@@ -68,9 +61,6 @@ reasoning, tool calls, tool returns, and compaction.
|
|
|
68
61
|
Streams can also observe message transformers, which rewrite
|
|
69
62
|
outgoing messages before they reach the provider.
|
|
70
63
|
|
|
71
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/fundamentals/stream/)
|
|
72
|
-
to learn more.
|
|
73
|
-
|
|
74
64
|
```ruby
|
|
75
65
|
class MyStream < LLM::Stream
|
|
76
66
|
# Visible assistant output.
|
|
@@ -140,7 +130,7 @@ call them on your behalf, and they're one of the most powerful features
|
|
|
140
130
|
for extending the feature set or abilities of a model.
|
|
141
131
|
|
|
142
132
|
The runtime also ships with a catalog of built-in tools for
|
|
143
|
-
filesystem, search, and shell operations.
|
|
133
|
+
filesystem, search, and shell operations.
|
|
144
134
|
|
|
145
135
|
```ruby
|
|
146
136
|
class ReadFile < LLM::Tool
|
|
@@ -175,8 +165,6 @@ callback hands back the subagent that ran the skill, so you can inspect
|
|
|
175
165
|
its conversation, measure its usage, track costs or add a verification
|
|
176
166
|
step (eg `subagent.talk("verify your work")`).
|
|
177
167
|
|
|
178
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/fundamentals/skills) to learn more.
|
|
179
|
-
|
|
180
168
|
##### summary.md
|
|
181
169
|
|
|
182
170
|
```markdown
|
|
@@ -216,8 +204,6 @@ with the `:fork` and `:ractor` strategies. The
|
|
|
216
204
|
The `:fork` strategy also provides a separate process that offers
|
|
217
205
|
isolation from its parent.
|
|
218
206
|
|
|
219
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/features/concurrency) to learn more.
|
|
220
|
-
|
|
221
207
|
```ruby
|
|
222
208
|
require "llm"
|
|
223
209
|
require "llm/tools"
|
|
@@ -242,8 +228,6 @@ the control channel, a ractor via message passing, and pending tools
|
|
|
242
228
|
are stopped before they run. The in-flight HTTP request is closed
|
|
243
229
|
too, so a turn you no longer want stops without burning tokens.
|
|
244
230
|
|
|
245
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/advanced/cancellation) to learn more.
|
|
246
|
-
|
|
247
231
|
```ruby
|
|
248
232
|
llm = LLM.deepseek(key: ENV["KEY"])
|
|
249
233
|
agent = LLM::Agent.new(llm)
|
|
@@ -268,8 +252,6 @@ The REPL stands out because it connects to the surrounding
|
|
|
268
252
|
runtime and it can be extended by your code. Think of it as
|
|
269
253
|
`binding.pry` but for agents.
|
|
270
254
|
|
|
271
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/features/repl) to learn more.
|
|
272
|
-
|
|
273
255
|
##### Demo
|
|
274
256
|
|
|
275
257
|
[Watch in high quality on asciinema](https://asciinema.org/a/OsS8wwaasKasoDDz)
|
|
@@ -327,8 +309,6 @@ code. For database-backed persistence, ActiveRecord and Sequel
|
|
|
327
309
|
integrations are also available. All persistence options use the same
|
|
328
310
|
underlying serialization.
|
|
329
311
|
|
|
330
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/features/database) to learn more.
|
|
331
|
-
|
|
332
312
|
```ruby
|
|
333
313
|
require "llm"
|
|
334
314
|
|
|
@@ -355,8 +335,6 @@ for both Rack-based / Rails-based applications. On databases
|
|
|
355
335
|
where it is supported, such as PostgreSQL, the column can be optimized by using
|
|
356
336
|
the `jsonb` type.
|
|
357
337
|
|
|
358
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/features/database) to learn more.
|
|
359
|
-
|
|
360
338
|
```ruby
|
|
361
339
|
require "active_record"
|
|
362
340
|
require "llm"
|
|
@@ -418,9 +396,6 @@ used with
|
|
|
418
396
|
[`LLM::Context`](https://r.uby.dev/api-docs/llm.rb/LLM/Context.html) or
|
|
419
397
|
[`LLM::Agent`](https://r.uby.dev/api-docs/llm.rb/LLM/Agent.html).
|
|
420
398
|
|
|
421
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/protocols/mcp/), and the
|
|
422
|
-
[deepdive.md on persistent connections](https://r.uby.dev/llm/deepdive/features/transports) to learn more.
|
|
423
|
-
|
|
424
399
|
```ruby
|
|
425
400
|
require "llm"
|
|
426
401
|
|
|
@@ -441,9 +416,6 @@ used with
|
|
|
441
416
|
[`LLM::Context`](https://r.uby.dev/api-docs/llm.rb/LLM/Context.html) or
|
|
442
417
|
[`LLM::Agent`](https://r.uby.dev/api-docs/llm.rb/LLM/Agent.html).
|
|
443
418
|
|
|
444
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/protocols/a2a/), and the
|
|
445
|
-
[deepdive.md on persistent connections](https://r.uby.dev/llm/deepdive/features/transports) to learn more.
|
|
446
|
-
|
|
447
419
|
```ruby
|
|
448
420
|
require "llm"
|
|
449
421
|
|
|
@@ -516,8 +488,6 @@ and implement
|
|
|
516
488
|
The pending call arrives as `function:`. Return a value to close
|
|
517
489
|
the call, or `nil` to let it run:
|
|
518
490
|
|
|
519
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/advanced/guard) to learn more.
|
|
520
|
-
|
|
521
491
|
```ruby
|
|
522
492
|
class PolicyGuard < LLM::Guard
|
|
523
493
|
def call(function:)
|
|
@@ -543,8 +513,6 @@ Create a subclass and implement `call(message:)` to scrub sensitive data,
|
|
|
543
513
|
inject context, or normalize content. The transform runs automatically
|
|
544
514
|
on every turn, so you never have to change your prompt code.
|
|
545
515
|
|
|
546
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/advanced/transformer) to learn more.
|
|
547
|
-
|
|
548
516
|
```ruby
|
|
549
517
|
class RedactEmails < LLM::Transformer
|
|
550
518
|
def call(message:)
|
|
@@ -581,8 +549,6 @@ and
|
|
|
581
549
|
[`LLM::Stream#on_compaction_finish`](https://r.uby.dev/api-docs/llm.rb/LLM/Stream.html#on_compaction_finish)
|
|
582
550
|
callbacks.
|
|
583
551
|
|
|
584
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/advanced/compaction) to learn more.
|
|
585
|
-
|
|
586
552
|
```ruby
|
|
587
553
|
llm = LLM.deepseek(key: ENV["KEY"])
|
|
588
554
|
agent = LLM::Agent.new(
|
|
@@ -631,8 +597,6 @@ exports spans via OTLP for OpenTelemetry in production.
|
|
|
631
597
|
* [`LLM::Tracer::Logger`](https://r.uby.dev/api-docs/llm.rb/LLM/Tracer/Logger.html):
|
|
632
598
|
structured JSON to stdout or a file.
|
|
633
599
|
|
|
634
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/reference/tracer) to learn more.
|
|
635
|
-
|
|
636
600
|
```ruby
|
|
637
601
|
llm = LLM.deepseek(key: ENV["KEY"])
|
|
638
602
|
agent = LLM::Agent.new(llm, tracer: LLM::Tracer::PrettyLogger.new(llm))
|
|
@@ -676,9 +640,8 @@ Each provider is constructed with a class-level factory method on
|
|
|
676
640
|
[`LLM::Context`](https://r.uby.dev/api-docs/llm.rb/LLM/Context.html)
|
|
677
641
|
or
|
|
678
642
|
[`LLM::Agent`](https://r.uby.dev/api-docs/llm.rb/LLM/Agent.html). The
|
|
679
|
-
same API drives every one of them, so switching
|
|
680
|
-
change.
|
|
681
|
-
for a full provider reference.
|
|
643
|
+
same API drives every one of them, so switching providers is a one-line
|
|
644
|
+
change.
|
|
682
645
|
|
|
683
646
|
#### What providers does llm.rb support?
|
|
684
647
|
|
|
@@ -741,8 +704,6 @@ modalities with the gem, sourced from [models.dev](https://models.dev).
|
|
|
741
704
|
Reach it from any provider, context, or agent, enumerate models, or
|
|
742
705
|
sort them by price.
|
|
743
706
|
|
|
744
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/reference/model_registry) to learn more.
|
|
745
|
-
|
|
746
707
|
```ruby
|
|
747
708
|
require "llm"
|
|
748
709
|
|
|
@@ -765,8 +726,6 @@ is always available and the default, `net/http/persistent` pools
|
|
|
765
726
|
connections for many requests to the same host, and `curb` wraps
|
|
766
727
|
libcurl. They share one interface, so switching is a one-word change.
|
|
767
728
|
|
|
768
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/advanced/transports) to learn more.
|
|
769
|
-
|
|
770
729
|
```ruby
|
|
771
730
|
llm = LLM.deepseek(
|
|
772
731
|
key: ENV["KEY"],
|
|
@@ -788,8 +747,6 @@ llm.rb also includes support for OpenAI's vector store API. It
|
|
|
788
747
|
provides a vector database as a HTTP service but we won't cover
|
|
789
748
|
that here.
|
|
790
749
|
|
|
791
|
-
See the [deepdive.md](https://r.uby.dev/llm/deepdive/features/embeddings) to learn more.
|
|
792
|
-
|
|
793
750
|
```ruby
|
|
794
751
|
require "llm"
|
|
795
752
|
|
|
@@ -928,11 +885,11 @@ it as my primary driver for development.
|
|
|
928
885
|
|
|
929
886
|
## Resources
|
|
930
887
|
|
|
931
|
-
|
|
932
|
-
to
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
888
|
+
The [r.uby.dev chatbot](https://r.uby.dev) is connected
|
|
889
|
+
to this very GitHub repository. It can read documentation,
|
|
890
|
+
source code, issues, and pull requests. The [docs/](docs/)
|
|
891
|
+
directory contains the full documentation and the chatbot
|
|
892
|
+
can find the answers to your questions there.
|
|
936
893
|
|
|
937
894
|
## License
|
|
938
895
|
|
data/lib/llm/active_record.rb
CHANGED
|
@@ -39,7 +39,7 @@ module LLM::ActiveRecord
|
|
|
39
39
|
def self.serialize_context(ctx, format)
|
|
40
40
|
case format
|
|
41
41
|
when :string then ctx.to_json
|
|
42
|
-
when :json, :jsonb then ctx.
|
|
42
|
+
when :json, :jsonb then LLM.json.load(ctx.to_json)
|
|
43
43
|
else raise ArgumentError, "Unknown format: #{format.inspect}"
|
|
44
44
|
end
|
|
45
45
|
end
|
data/lib/llm/version.rb
CHANGED