llm.rb 15.5.0 → 16.0.0.pre.2
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 +88 -1
- data/README.md +21 -30
- data/data/alibaba.json +1123 -949
- data/data/anthropic.json +296 -242
- data/data/bedrock.json +4178 -3807
- data/data/deepinfra.json +1529 -1358
- data/data/deepseek.json +15 -11
- data/data/google.json +787 -763
- data/data/mistral.json +476 -496
- data/data/moonshot.json +53 -50
- data/data/openai.json +1294 -1165
- data/data/openrouter.json +8722 -8546
- data/data/xai.json +207 -202
- data/data/zai.json +271 -264
- data/docs/deepdive/features/builtin_tools.md +3 -1
- data/docs/deepdive/features/console.md +7 -0
- data/docs/deepdive/fundamentals/schema.md +46 -0
- data/docs/deepdive/fundamentals/tools.md +68 -0
- data/docs/deepdive/protocols/a2a.md +91 -0
- data/docs/deepdive/protocols/mcp.md +50 -0
- data/docs/deepdive/reference/model_registry.md +1 -1
- data/lib/llm/console/input.rb +15 -5
- data/lib/llm/function/async/reactor.rb +10 -0
- data/lib/llm/function/async/task.rb +63 -11
- data/lib/llm/function/fork/job.rb +31 -8
- data/lib/llm/function/ractor/job.rb +59 -20
- data/lib/llm/function/ractor/mailbox.rb +39 -3
- data/lib/llm/function/ractor/task.rb +26 -9
- data/lib/llm/function/window.rb +77 -0
- data/lib/llm/function.rb +2 -1
- data/lib/llm/providers/deepseek/request_adapter/completion.rb +43 -2
- data/lib/llm/tool/param.rb +8 -8
- data/lib/llm/tools/exec.rb +2 -0
- data/lib/llm/version.rb +1 -1
- data/llm.gemspec +4 -4
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 61578ce1082ecd25f86574ef19e1ffd4cc2b68c6689b705f0544f4aa3e391ede
|
|
4
|
+
data.tar.gz: 742b8d66f49113389c5ff08772e79498334eb6d5afe9821f05c2b8d1851cf4e8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d0024edabc9ac7360a71a485362aed854644187c116777623b340e5fbd391ae257139aefe07ba29ce7fe9bf04573e66ff09c0f48024153833cbb28b385e13280
|
|
7
|
+
data.tar.gz: ec0b4f0b2ba6a66b38cd324c5c3ea6daccd4ff76cde43a1fa8c272c20da89bec735ff7b7bae3afb516d4b5a3131b4e383abe70f48365d6ba9c8a61028e233c48
|
data/CHANGELOG.md
CHANGED
|
@@ -15,7 +15,94 @@
|
|
|
15
15
|
|
|
16
16
|
## What's next
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
### Breaking
|
|
19
|
+
|
|
20
|
+
#### Migration
|
|
21
|
+
|
|
22
|
+
| Old | New |
|
|
23
|
+
|-----|-----|
|
|
24
|
+
| Ruby 3.3 or later | Ruby 3.4 or later |
|
|
25
|
+
|
|
26
|
+
* **drop Ruby 3.3 support** <br>
|
|
27
|
+
The gem now requires Ruby 3.4 or later: `required_ruby_version` is
|
|
28
|
+
`>= 3.4.0`, the CI matrix runs 3.4 and 4.0, and RuboCop targets 3.4.
|
|
29
|
+
Ruby 3.3 cannot hold an interrupt for a ractor-backed tool call, so a
|
|
30
|
+
cancel that arrives before the tool starts is not delivered there, while
|
|
31
|
+
Ruby 3.4 and 4.0 both deliver it.
|
|
32
|
+
|
|
33
|
+
### Console
|
|
34
|
+
|
|
35
|
+
* **console: erase with the backspace key on OpenBSD** <br>
|
|
36
|
+
The console now erases a character for every code a backspace key sends. A
|
|
37
|
+
terminal that follows the Linux convention sends DEL (127), the OpenBSD
|
|
38
|
+
console sends ^H (8), and curses sends its own `KEY_BACKSPACE` when the
|
|
39
|
+
terminal's terminfo describes the key. All three erase. Before this only 127
|
|
40
|
+
did, so the backspace key did nothing on the OpenBSD console.
|
|
41
|
+
|
|
42
|
+
### Function
|
|
43
|
+
|
|
44
|
+
* **function: deliver an interrupt to the tool, not to whatever is running** <br>
|
|
45
|
+
[`LLM::Function::Window`](https://r.uby.dev/api-docs/llm.rb/LLM/Function/Window.html)
|
|
46
|
+
is the stretch of a call that an interrupt belongs to. The `:fork` and `:ractor`
|
|
47
|
+
strategies now raise
|
|
48
|
+
[`LLM::Interrupt`](https://r.uby.dev/api-docs/llm.rb/LLM/Interrupt.html) on the
|
|
49
|
+
thread that runs the tool, and only while the tool runs: a cancel that arrives
|
|
50
|
+
before the tool starts is held until it does, so the tool's own `rescue` can
|
|
51
|
+
handle it, and one that arrives after the tool has returned is a no-op, which
|
|
52
|
+
no longer throws the result away. Before this, the interrupt was raised on the
|
|
53
|
+
child process's or the ractor's main thread wherever that thread had got to.
|
|
54
|
+
|
|
55
|
+
* **function: answer a ractor-backed task once its ractor has gone** <br>
|
|
56
|
+
A `:ractor` tool's result is handed to a ractor the task holds it in,
|
|
57
|
+
rather than asked of the ractor that ran the tool, which answers `alive?`
|
|
58
|
+
while the tool runs and goes once the result is in. So a wait that arrives
|
|
59
|
+
after the tool has run is answered, a second wait is answered from memory,
|
|
60
|
+
the way
|
|
61
|
+
[`LLM::Function::Thread::Task#wait`](https://r.uby.dev/api-docs/llm.rb/LLM/Function/Thread/Task.html#wait-instance_method)
|
|
62
|
+
answers from the thread's value, and `alive?` answers `false` once the task
|
|
63
|
+
has been waited on. A cancel returns `nil` rather than raising, which is what
|
|
64
|
+
lets
|
|
65
|
+
[`LLM::Function::Ractor::Group#interrupt!`](https://r.uby.dev/api-docs/llm.rb/LLM/Function/Ractor/Group.html#interrupt!-instance_method)
|
|
66
|
+
reach every task it holds. Before this, a wait that arrived once the tool had
|
|
67
|
+
run raised `Ractor::ClosedError` or never came back, a cancel raised the same
|
|
68
|
+
error, and a group's cancel stopped at the first task that had already
|
|
69
|
+
returned, leaving the calls after it uncancelled.
|
|
70
|
+
|
|
71
|
+
* **function: tell an `:async` tool it was cancelled** <br>
|
|
72
|
+
A cancel now raises `LLM::Interrupt` on the fiber the tool runs in, through the
|
|
73
|
+
reactor's scheduler, so the tool is told and can answer with its own value. A
|
|
74
|
+
cancel that arrives before the tool started stops it from running, and the
|
|
75
|
+
reactor is stopped by whoever waits. Before this, the cancel pushed an
|
|
76
|
+
interrupt sentinel to the task's result queue and left the tool running, its
|
|
77
|
+
side effects happening and its result written to a queue nobody read, and the
|
|
78
|
+
reactor thread stayed alive until a group's `wait` stopped it.
|
|
79
|
+
|
|
80
|
+
### Provider
|
|
81
|
+
|
|
82
|
+
* **deepseek: support image attachments in chat completions** <br>
|
|
83
|
+
DeepSeek's vision models now take an image through the chat completions
|
|
84
|
+
adapter. A tagged prompt object of kind `:image_url` is sent as an `image_url`
|
|
85
|
+
content item, and a local image file is sent as a base64 encoded data URI.
|
|
86
|
+
Anything else is rejected with a reason of its own: a remote file or an
|
|
87
|
+
`LLM::Response` raises
|
|
88
|
+
[`LLM::PromptError`](https://r.uby.dev/api-docs/llm.rb/LLM/PromptError.html)
|
|
89
|
+
because DeepSeek has no Files API, so a file id cannot be resolved, and a
|
|
90
|
+
local file that is not an image raises because DeepSeek's models read images
|
|
91
|
+
only.
|
|
92
|
+
|
|
93
|
+
### Registry
|
|
94
|
+
|
|
95
|
+
* **refresh model metadata** <br>
|
|
96
|
+
Update `data/` with current model listings, limits, and pricing. Alibaba adds
|
|
97
|
+
`qwen3.5-flash`, `qwen3.7-flash`, and `qwen3.8-omni-flash`, and gives
|
|
98
|
+
`qwen3.7-plus` attachments, structured output, and a lower price; OpenAI adds
|
|
99
|
+
`gpt-daybreak-blue-latest` and `gpt-daybreak-red-latest`; Bedrock adds
|
|
100
|
+
`openai.gpt-6-sol` and `openai.gpt-6-luna`; and DeepInfra adds
|
|
101
|
+
`tencent/Hy4-preview` and the Xiaomi MiMo V2.6 Pro and V2.6 Flash models.
|
|
102
|
+
Bedrock also corrects the context and output limits of fifteen models, Google
|
|
103
|
+
lowers the limits of `gemini-2.5-computer-use-preview-10-2025` and
|
|
104
|
+
`gemini-3-pro-image`, and OpenRouter adds four models, drops six, and reprices
|
|
105
|
+
many of the DeepSeek, Z.ai, and Qwen entries.
|
|
19
106
|
|
|
20
107
|
## v15.5.0
|
|
21
108
|
|
data/README.md
CHANGED
|
@@ -14,21 +14,25 @@
|
|
|
14
14
|
|
|
15
15
|
Welcome to the canonical llm.rb repository.
|
|
16
16
|
|
|
17
|
-
llm.rb is
|
|
17
|
+
llm.rb is a runtime for building agentic AI applications
|
|
18
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 14+ providers.
|
|
21
|
+
The README covers the common cases. For everything else there is the
|
|
22
|
+
[deepdive](docs/deepdive.md), a reference with a chapter for each
|
|
23
|
+
topic, and for what changes between releases there is the
|
|
24
|
+
[changelog](CHANGELOG.md).
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
different services (eg GitHub, etc). Check it out if
|
|
28
|
-
curious. Still in early development.
|
|
26
|
+
[The r.uby.dev website](https://r.uby.dev) hosts
|
|
27
|
+
an agentic platform that provides users with
|
|
28
|
+
personalized agents who can access GitHub, and
|
|
29
|
+
other services. It is built with llm.rb. Check it
|
|
30
|
+
out if curious. **Still in early development.**
|
|
29
31
|
|
|
30
32
|
## Install
|
|
31
33
|
|
|
34
|
+
llm.rb requires Ruby 3.4 or later.
|
|
35
|
+
|
|
32
36
|
```bash
|
|
33
37
|
gem install llm.rb
|
|
34
38
|
```
|
|
@@ -53,9 +57,12 @@ model as an in-band error that allows the model to correct course.
|
|
|
53
57
|
A lot of care also goes into keeping the tool loop from entering
|
|
54
58
|
an invalid state that would lead to API-level errors. For example,
|
|
55
59
|
when a tool call is interrupted it could leave an unanswered tool
|
|
56
|
-
call that a model will reject on the next turn. The runtime
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
call that a model will reject on the next turn. The runtime closes
|
|
61
|
+
every tool call that has no return before the next request is sent,
|
|
62
|
+
and each one is answered with an in-band return of its own. The
|
|
63
|
+
conversation a provider sees is therefore always valid, and a
|
|
64
|
+
cancelled call is something the model is told about rather than
|
|
65
|
+
something that quietly disappears.
|
|
59
66
|
|
|
60
67
|
```ruby
|
|
61
68
|
require "llm"
|
|
@@ -666,8 +673,7 @@ agent = LLM::Agent.new(llm, tools: [LLM::Tool::Exec, ReadFile], guard: PolicyGua
|
|
|
666
673
|
<br>
|
|
667
674
|
|
|
668
675
|
It is possible to rewrite outgoing messages before they reach the provider with
|
|
669
|
-
[`LLM::Transformer`](https://r.uby.dev/api-docs/llm.rb/LLM/Transformer.html).
|
|
670
|
-
Create a subclass and implement `call(message:)` to scrub sensitive data,
|
|
676
|
+
[`LLM::Transformer`](https://r.uby.dev/api-docs/llm.rb/LLM/Transformer.html). Create a subclass and implement `call(message:)` to scrub sensitive data,
|
|
671
677
|
inject context, or normalize content. The transform runs automatically
|
|
672
678
|
on every turn, so you never have to change your prompt code.
|
|
673
679
|
|
|
@@ -1109,9 +1115,8 @@ It is battle tested daily.
|
|
|
1109
1115
|
The console that is distributed with llm.rb is used
|
|
1110
1116
|
to build llm.rb so there is a healthy, active feedback
|
|
1111
1117
|
loop. It also powers the [r.uby.dev](https://r.uby.dev)
|
|
1112
|
-
website where multiple llm.rb agents are deployed
|
|
1113
|
-
|
|
1114
|
-
I'm also aware of at least one production Rails deployment
|
|
1118
|
+
website where multiple llm.rb agents are deployed. I'm
|
|
1119
|
+
aware of at least one production Rails deployment
|
|
1115
1120
|
at a large-ish company.
|
|
1116
1121
|
|
|
1117
1122
|
And this git repository includes llm.rb agents that help me
|
|
@@ -1121,20 +1126,6 @@ there is a large test suite that covers live requests (recorded
|
|
|
1121
1126
|
by VCR) and database interactions.
|
|
1122
1127
|
</details>
|
|
1123
1128
|
|
|
1124
|
-
## See also
|
|
1125
|
-
|
|
1126
|
-
The [roda-llm](https://github.com/r-uby-dev/roda-llm#readme) project
|
|
1127
|
-
is how I deploy multiple ActiveRecord-backed llm.rb agents over HTTP.
|
|
1128
|
-
Each agent has an identical interface at a unique path that provide
|
|
1129
|
-
CRUD operations and stream support (via SSE - Server Side Events).
|
|
1130
|
-
It lets you focus on implementing agents rather than the glue that
|
|
1131
|
-
brings them together. It is implemented as a Roda plugin that could
|
|
1132
|
-
be hosted within a Rails application or other Rack-based applications.
|
|
1133
|
-
|
|
1134
|
-
The [docs/](docs/) directory contains the full documentation and
|
|
1135
|
-
the chatbot can find the answers to your questions there. Or you
|
|
1136
|
-
can read them yourself. :)
|
|
1137
|
-
|
|
1138
1129
|
## License
|
|
1139
1130
|
|
|
1140
1131
|
This software is released under the terms of the MIT license. <br>
|