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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c86e9ccde2cc0844b5172935bc222c1adf3cda8b0f49e84730179bcc635b2d2b
4
- data.tar.gz: 60c740c3dc2c20d8b1d86de55ae5ef25eb7bbe5b5b567f3766c059b37520efcc
3
+ metadata.gz: b2700592b8b9fbb85694c24a0a7379a84494b0e4f2157d6302fad1552df9d684
4
+ data.tar.gz: 43864e55f008478a40860511f9ca138f86010695225f91f0b2a07fbcff1ed448
5
5
  SHA512:
6
- metadata.gz: fd1901c5bebd659b242db55ed91ea4f538832c24b4ab119b80f46ae987fc5166823fa70174d9f545c079addd90487eb379b1dfd6eeea2365d045a831b861134e
7
- data.tar.gz: 5949efbaa7381fb0cab7328e64c08af4022a8b976a24b8b24901c167c67cd060f912a7054956a7942cd7cf67b3f0aa226ad5aec608bcd273bfa1aa25d3ffb5d0
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, it supports
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
- Once you learn the fundamentals, everything else falls into place
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. If
31
- you want to know more then simply [ask the chatbot](https://r.uby.dev) and
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. <br> See the [deepdive.md](https://r.uby.dev/llm/deepdive/fundamentals/tools) to learn more.
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 models is a one-line
680
- change. See the [deepdive](https://r.uby.dev/llm/deepdive/fundamentals/providers)
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
- If you like what you read so far, check out the [deepdive.md](https://r.uby.dev/llm/deepdive/)
932
- to learn more. Unfortunately it
933
- wasn't possible to cover every feature without the README becoming a small book.
934
- The [r.uby.dev](https://r.uby.dev) homepage also includes more learning material
935
- and resources.
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
 
@@ -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.to_h
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LLM
4
- VERSION = "15.0.2"
4
+ VERSION = "15.0.3"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: llm.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 15.0.2
4
+ version: 15.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Gleeson