llm.rb 12.4.0 → 12.5.0
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 +240 -0
- data/README.md +38 -8
- data/data/anthropic.json +249 -249
- data/data/bedrock.json +1964 -1964
- data/data/deepinfra.json +589 -589
- data/data/deepseek.json +31 -31
- data/data/google.json +332 -329
- data/data/mistral.json +381 -381
- data/data/openai.json +1133 -1133
- data/data/xai.json +138 -138
- data/data/zai.json +165 -165
- data/lib/llm/agent.rb +3 -1
- data/lib/llm/buffer.rb +15 -0
- data/lib/llm/context.rb +4 -5
- data/lib/llm/function.rb +2 -35
- data/lib/llm/message.rb +12 -2
- data/lib/llm/provider.rb +11 -1
- data/lib/llm/providers/anthropic/stream_parser.rb +3 -12
- data/lib/llm/providers/anthropic.rb +11 -0
- data/lib/llm/providers/bedrock/stream_parser.rb +4 -13
- data/lib/llm/providers/google/stream_parser.rb +3 -12
- data/lib/llm/providers/google.rb +7 -0
- data/lib/llm/providers/mistral.rb +11 -0
- data/lib/llm/providers/ollama/stream_parser.rb +4 -4
- data/lib/llm/providers/ollama.rb +11 -0
- data/lib/llm/providers/openai/responses/stream_parser.rb +4 -14
- data/lib/llm/providers/openai/responses.rb +10 -0
- data/lib/llm/providers/openai/stream_parser.rb +5 -15
- data/lib/llm/providers/openai.rb +11 -0
- data/lib/llm/repl/command.rb +121 -5
- data/lib/llm/repl/commands/exit.rb +4 -0
- data/lib/llm/repl/commands/help.rb +24 -0
- data/lib/llm/repl/input.rb +4 -1
- data/lib/llm/repl/stream.rb +3 -8
- data/lib/llm/repl.rb +58 -12
- data/lib/llm/stream.rb +2 -7
- data/lib/llm/version.rb +1 -1
- data/resources/deepdive.md +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 665281b1c81541ff2f9621138cee510e473dfbda2c7dcff7d1a324e5fe558c89
|
|
4
|
+
data.tar.gz: c3ee596e41885038dc831ef6459da330d1984fea0125a9dbc5aa7d0ff8e21061
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cecf7fa0a2b1c6aff010c537b6741c74e537104eb9a67e3c2cd2840d06963040834c87263f71f6a1f815a4be831efa7740b2c03eb3f5fde9bbb274be4ee69c5c
|
|
7
|
+
data.tar.gz: 8b695e7c1656bf427bb095a257e954437b5b2dfc46e4d22349eb91dab9981eac1c5fc6b46bca89ecfec14986d386a0fba6303ef4dcf39a82345d3a136e944092
|
data/CHANGELOG.md
CHANGED
|
@@ -15,8 +15,248 @@
|
|
|
15
15
|
|
|
16
16
|
## What's next
|
|
17
17
|
|
|
18
|
+
Changes since `v12.5.0`.
|
|
19
|
+
|
|
20
|
+
## v12.5.0
|
|
21
|
+
|
|
18
22
|
Changes since `v12.4.0`.
|
|
19
23
|
|
|
24
|
+
This release extends the REPL command system with typed parameters, a
|
|
25
|
+
built-in `/help` command, command aliases (`/quit`), and cancellation
|
|
26
|
+
via the 'Esc' key.
|
|
27
|
+
|
|
28
|
+
The default HTTP timeout is increased to 15 minutes (900s) to better
|
|
29
|
+
accommodate reasoning models and large structured outputs.
|
|
30
|
+
`LLM::Agent#deserialize` and `LLM::Agent#restore` now return `self` for
|
|
31
|
+
method chaining, and `LLM::Buffer#pop` is added for tail-end message
|
|
32
|
+
removal.
|
|
33
|
+
|
|
34
|
+
Tool resolution gains a fallback to the global `LLM::Function` registry
|
|
35
|
+
before raising `LLM::NoSuchToolError`, and `pending_functions` aliases
|
|
36
|
+
are added on both contexts and agents for a consistent interface.
|
|
37
|
+
|
|
38
|
+
Several REPL bugs are fixed including parameter state leakage across
|
|
39
|
+
turns and invalid tool-call error routing.
|
|
40
|
+
|
|
41
|
+
Model metadata is refreshed across all providers with new Anthropic,
|
|
42
|
+
OpenAI, Google, DeepInfra, DeepSeek, and xAI model entries.
|
|
43
|
+
|
|
44
|
+
### Add
|
|
45
|
+
|
|
46
|
+
#### Buffer & function internals
|
|
47
|
+
|
|
48
|
+
* **buffer: add `LLM::Buffer#pop`** <br>
|
|
49
|
+
Add `LLM::Buffer#pop` for removing the last message from the tail
|
|
50
|
+
of the buffer, complementing the existing `#<<` and array-style
|
|
51
|
+
message management.
|
|
52
|
+
|
|
53
|
+
* **function: add registry fallback for tool resolution** <br>
|
|
54
|
+
When resolving tool calls from a message, if the tool is not found
|
|
55
|
+
in the available tools list, it now also looks up the global
|
|
56
|
+
`LLM::Function` registry via `LLM::Function.find_by_name` before
|
|
57
|
+
creating a placeholder function. This improves tool resolution for
|
|
58
|
+
tools that are registered globally but not passed directly through
|
|
59
|
+
the request tool set.
|
|
60
|
+
|
|
61
|
+
#### Consistent `pending_functions` aliases
|
|
62
|
+
|
|
63
|
+
* **context: alias `LLM::Context#functions` as `LLM::Context#pending_functions`** <br>
|
|
64
|
+
Add `LLM::Context#pending_functions` as an alias for `LLM::Context#functions`,
|
|
65
|
+
so callers that prefer the more descriptive `pending_functions` name can use
|
|
66
|
+
it instead of `functions` when checking for unresolved tool work.
|
|
67
|
+
|
|
68
|
+
* **agent: alias `LLM::Agent#functions` as `LLM::Agent#pending_functions`** <br>
|
|
69
|
+
Add `LLM::Agent#pending_functions` as an alias for `LLM::Agent#functions`,
|
|
70
|
+
matching the same alias on `LLM::Context`, so callers have a consistent
|
|
71
|
+
`pending_functions` interface across both contexts and agents.
|
|
72
|
+
|
|
73
|
+
#### REPL command system
|
|
74
|
+
|
|
75
|
+
* **repl: extend command system with parameter support** <br>
|
|
76
|
+
Commands can now declare typed parameters using the `parameter`
|
|
77
|
+
DSL, modelled after `LLM::Tool` and `LLM::Schema` conventions.
|
|
78
|
+
Parameters can be marked as required with `required %i[...]`,
|
|
79
|
+
and values are type-checked before being passed to `call`.
|
|
80
|
+
Argument parsing is handled by the repl: arguments are split
|
|
81
|
+
from the input string and assigned to parameters by position.
|
|
82
|
+
|
|
83
|
+
```ruby
|
|
84
|
+
class Greeter < LLM::Command
|
|
85
|
+
name "greet"
|
|
86
|
+
description "Greets the given name"
|
|
87
|
+
parameter :name, String, "The person's name"
|
|
88
|
+
required %i[name]
|
|
89
|
+
|
|
90
|
+
def call(name:)
|
|
91
|
+
write("Welcome #{name}!\n")
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
* **repl: add `help` command** <br>
|
|
97
|
+
Add `LLM::Repl::Help` as a new built-in command, registered
|
|
98
|
+
automatically via the command registry. Typing `/help` shows
|
|
99
|
+
the `help` command's own name, description, and parameters,
|
|
100
|
+
while `/help <name>` shows details for a specific command,
|
|
101
|
+
including its parameters and whether each is required or
|
|
102
|
+
optional. Unknown command names produce an error message.
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
class Help < Command
|
|
106
|
+
name "help"
|
|
107
|
+
description "show help for a given command"
|
|
108
|
+
parameter :name, String, "The name of a command"
|
|
109
|
+
|
|
110
|
+
def call(name: nil)
|
|
111
|
+
if name.nil?
|
|
112
|
+
write("\n#{self.class.help}\n\n")
|
|
113
|
+
elsif command = LLM::Command.find_by(name:)
|
|
114
|
+
write("\n#{command.help}\n\n")
|
|
115
|
+
else
|
|
116
|
+
write "\nNo help for #{name} was found" \
|
|
117
|
+
"\nThat command doesn't exist.\n\n"
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
* **repl: add support for command aliases** <br>
|
|
124
|
+
Commands can now be aliased by creating a subclass of another
|
|
125
|
+
command (with `LLM::Command` as an indirect ancestor). The
|
|
126
|
+
first alias introduced is `/quit` as an alias of `/exit`.
|
|
127
|
+
|
|
128
|
+
```ruby
|
|
129
|
+
class Quit < Command::Exit
|
|
130
|
+
name "quit"
|
|
131
|
+
end
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
* **repl: add `Command::Parameter#optional?`** <br>
|
|
135
|
+
Parameters now expose an `#optional?` method that returns `true`
|
|
136
|
+
when a parameter has not been marked as required, making it
|
|
137
|
+
possible to query parameter optionality programmatically.
|
|
138
|
+
|
|
139
|
+
* **repl: add `LLM::Repl::Command#write`** <br>
|
|
140
|
+
Commands can now write output to the transcript via the `write`
|
|
141
|
+
method. Commands also receive a reference to the active repl
|
|
142
|
+
through their `#initialize` method, making it possible to
|
|
143
|
+
interact with the repl window from within a command.
|
|
144
|
+
|
|
145
|
+
* **repl: display command errors in the curses UI** <br>
|
|
146
|
+
Commands invoked with too few arguments now display an error
|
|
147
|
+
message — `command(<name>): too few arguments` — directly in
|
|
148
|
+
the curses transcript area, giving immediate feedback instead
|
|
149
|
+
of silently failing.
|
|
150
|
+
|
|
151
|
+
* **repl: add `LLM::Command` convenience constant** <br>
|
|
152
|
+
Add `LLM::Command = LLM::Repl::Command` as a shorter alias,
|
|
153
|
+
available once `"llm/repl"` is required.
|
|
154
|
+
|
|
155
|
+
#### Misc
|
|
156
|
+
|
|
157
|
+
* **repl: implement cancellation with the 'Esc' key** <br>
|
|
158
|
+
The curses-based REPL now supports cancelling an active model
|
|
159
|
+
request by pressing the 'Esc' key. When a request is in progress,
|
|
160
|
+
the status line shows `thinking • Esc to cancel`, and pressing
|
|
161
|
+
Esc calls `LLM::Agent#cancel!` to interrupt the request. The
|
|
162
|
+
transcript displays `request cancelled!` to confirm the
|
|
163
|
+
cancellation.
|
|
164
|
+
|
|
165
|
+
### Change
|
|
166
|
+
|
|
167
|
+
#### Misc
|
|
168
|
+
|
|
169
|
+
* **provider: increase default timeout to 900s** <br>
|
|
170
|
+
The default HTTP timeout for all providers has been increased from
|
|
171
|
+
180 to 900 seconds (15 minutes) to better accommodate long-running
|
|
172
|
+
requests such as reasoning models and large structured outputs.
|
|
173
|
+
|
|
174
|
+
* **agent: `deserialize` and `restore` return `self`** <br>
|
|
175
|
+
`LLM::Agent#deserialize` and `LLM::Agent#restore` now return `self`
|
|
176
|
+
(the agent instance) instead of forwarding the context's return
|
|
177
|
+
value, enabling method chaining after restoring agent state.
|
|
178
|
+
|
|
179
|
+
* **context: discard all messages from a cancelled turn** <br>
|
|
180
|
+
When `LLM::Context#cancel!` is called, all messages added during
|
|
181
|
+
that turn are now discarded via `Buffer#slice!`, preventing edge
|
|
182
|
+
cases where dangling tool calls between turns caused repeated
|
|
183
|
+
cancellation loops. The `#repair!` method now handles tool call
|
|
184
|
+
cancellations on the next turn instead of mutating the conversation
|
|
185
|
+
buffer directly at cancellation time.
|
|
186
|
+
|
|
187
|
+
* **stream: drop the `error` argument from `on_tool_call`** <br>
|
|
188
|
+
The `on_tool_call` callback no longer accepts an `error` argument.
|
|
189
|
+
Previously, stream parsers passed both a tool and an optional error,
|
|
190
|
+
requiring boilerplate like `if error; queue << error; end` in every
|
|
191
|
+
callback. Error handling is now pushed directly onto the stream queue
|
|
192
|
+
inside each provider's stream parser, so `on_tool_call(tool)` is the
|
|
193
|
+
only signature. The REPL stream and base `LLM::Stream` class have
|
|
194
|
+
been updated accordingly.
|
|
195
|
+
|
|
196
|
+
#### REPL internals
|
|
197
|
+
|
|
198
|
+
* **repl: pass the repl instance to command constructors** <br>
|
|
199
|
+
`LLM::Repl::Command` subclasses now receive the active repl
|
|
200
|
+
instance via `initialize(repl)`, enabling commands to write
|
|
201
|
+
to the transcript and interact with the repl window.
|
|
202
|
+
|
|
203
|
+
* **repl: `Command#write` prefixes messages with the command name** <br>
|
|
204
|
+
The `#write` method now prefixes output with `command(<name>): `
|
|
205
|
+
so command messages are consistent with the `user:` and `agent:`
|
|
206
|
+
labels in the transcript. The prefix can be customised with the
|
|
207
|
+
`who:` keyword argument, or set to `who: nil` to disable it
|
|
208
|
+
entirely.
|
|
209
|
+
|
|
210
|
+
### Fix
|
|
211
|
+
|
|
212
|
+
#### Misc
|
|
213
|
+
|
|
214
|
+
* **function: avoid silent skip of tools not found in available tools** <br>
|
|
215
|
+
When a model calls a tool that is not present in the available tools
|
|
216
|
+
list, instead of silently skipping the tool call (via `next`), a
|
|
217
|
+
`LLM::NoSuchToolError` is now raised so the model receives feedback
|
|
218
|
+
about the invalid tool call and can correct course.
|
|
219
|
+
<br><br>
|
|
220
|
+
An additional fallback to the global `LLM::Function` registry is
|
|
221
|
+
tried before raising, so globally registered tools are still
|
|
222
|
+
resolved even when not in the per-request tool set.
|
|
223
|
+
|
|
224
|
+
#### REPL bugs
|
|
225
|
+
|
|
226
|
+
* **repl: don't persist parameter state between turns** <br>
|
|
227
|
+
Parameter state (such as `Parameter#value`) was leaking across
|
|
228
|
+
turns because the same parameter objects were being mutated
|
|
229
|
+
in place. A duplicate set of parameters is now created for each
|
|
230
|
+
turn, keeping the original parameter definitions intact and
|
|
231
|
+
preventing stale state from carrying over.
|
|
232
|
+
|
|
233
|
+
* **repl: reply with error when given an invalid tool** <br>
|
|
234
|
+
When the model tries to call a tool that does not exist, the
|
|
235
|
+
error is now pushed onto the stream queue so the model can
|
|
236
|
+
see the error and correct course, instead of silently dropping
|
|
237
|
+
the invalid tool call and leaving it to `Context#repair` to
|
|
238
|
+
remove it from history.
|
|
239
|
+
|
|
240
|
+
* **repl: fix save of initial runtime state** <br>
|
|
241
|
+
Fix a bug in `LLM::Repl#configure` where a non-existent path
|
|
242
|
+
argument was treated as no path at all, preventing the initial
|
|
243
|
+
runtime state from being saved after the first turn. The correct
|
|
244
|
+
behavior is to create the file so it can be written to after
|
|
245
|
+
the first turn completes.
|
|
246
|
+
|
|
247
|
+
### Refresh
|
|
248
|
+
|
|
249
|
+
* **Refresh model metadata across all providers** <br>
|
|
250
|
+
Update model listings, pricing, capabilities, reasoning options,
|
|
251
|
+
modality support, context limits, and release dates across all
|
|
252
|
+
provider registries (Anthropic, AWS Bedrock, DeepInfra, DeepSeek,
|
|
253
|
+
Google, Mistral, OpenAI, xAI, and ZAI). Notable changes include
|
|
254
|
+
Anthropic claude-opus-4-8 and claude-sonnet-4-6 additions with
|
|
255
|
+
effort-based reasoning, OpenAI gpt-5.6-sol/terra/luna and
|
|
256
|
+
gpt-5-codex additions, Google gemini-3-pro-preview and
|
|
257
|
+
gemini-3-flash-preview additions, DeepInfra Qwen3.5 and DeepSeek
|
|
258
|
+
V4 model additions, and updated xAI Grok model entries.
|
|
259
|
+
|
|
20
260
|
## v12.4.0
|
|
21
261
|
|
|
22
262
|
Changes since `v12.3.1`.
|
data/README.md
CHANGED
|
@@ -141,6 +141,8 @@ instance. The session inherits the agent's model, tools,
|
|
|
141
141
|
skills, and instructions.
|
|
142
142
|
|
|
143
143
|
```ruby
|
|
144
|
+
require "llm"
|
|
145
|
+
|
|
144
146
|
llm = LLM.deepseek(key: ENV["KEY"])
|
|
145
147
|
agent = LLM::Agent.new(llm)
|
|
146
148
|
agent.repl
|
|
@@ -153,6 +155,8 @@ is read from and written to. This lets you resume a
|
|
|
153
155
|
conversation across REPL sessions.
|
|
154
156
|
|
|
155
157
|
```ruby
|
|
158
|
+
require "llm"
|
|
159
|
+
|
|
156
160
|
llm = LLM.deepseek(key: ENV["KEY"])
|
|
157
161
|
agent = LLM::Agent.new(llm)
|
|
158
162
|
agent.repl(path: "session.json")
|
|
@@ -169,6 +173,8 @@ llm.rb. They power the agents that can be found in the
|
|
|
169
173
|
[agents/](agents/) directory.
|
|
170
174
|
|
|
171
175
|
```ruby
|
|
176
|
+
require "llm"
|
|
177
|
+
|
|
172
178
|
llm = LLM.deepseek(key: ENV["KEY"])
|
|
173
179
|
agent = LLM::Agent.new(llm)
|
|
174
180
|
agent.repl(tools: [Debugger])
|
|
@@ -192,6 +198,8 @@ The `skills` option lets you load extra skill directories
|
|
|
192
198
|
without attaching them to an agent permanently.
|
|
193
199
|
|
|
194
200
|
```ruby
|
|
201
|
+
require "llm"
|
|
202
|
+
|
|
195
203
|
llm = LLM.deepseek(key: ENV["KEY"])
|
|
196
204
|
agent = LLM::Agent.new(llm)
|
|
197
205
|
agent.repl(skills: [__dir__])
|
|
@@ -205,11 +213,39 @@ the tracer associated with an instance of
|
|
|
205
213
|
[`LLM::Agent`](https://r.uby.dev/api-docs/llm.rb/LLM/Agent.html).
|
|
206
214
|
|
|
207
215
|
```ruby
|
|
208
|
-
|
|
209
|
-
|
|
216
|
+
require "llm"
|
|
217
|
+
|
|
218
|
+
llm = LLM.deepseek(key: ENV["KEY"])
|
|
219
|
+
tracer = LLM.logger(llm, path: "agent.log")
|
|
220
|
+
agent = LLM::Agent.new(llm, tracer:)
|
|
210
221
|
agent.repl(tracer: true, tools: [Debugger])
|
|
211
222
|
```
|
|
212
223
|
|
|
224
|
+
##### REPL: Commands
|
|
225
|
+
|
|
226
|
+
Commands are recognized by a `/` prefix and are backed by the
|
|
227
|
+
[`LLM::Repl::Command`](https://r.uby.dev/api-docs/llm.rb/LLM/Repl/Command.html)
|
|
228
|
+
class, which can be subclassed to add custom commands. Once you
|
|
229
|
+
create a subclass, it is automatically added to the repl. A command
|
|
230
|
+
can have zero or more parameters, and all parameters are presumed
|
|
231
|
+
to be a String (at least for now).
|
|
232
|
+
|
|
233
|
+
```ruby
|
|
234
|
+
require "llm"
|
|
235
|
+
require "llm/repl"
|
|
236
|
+
|
|
237
|
+
class Greeter < LLM::Command
|
|
238
|
+
name "greet"
|
|
239
|
+
description "Greets the given name"
|
|
240
|
+
parameter :name, String, "The person's name"
|
|
241
|
+
required %i[name]
|
|
242
|
+
|
|
243
|
+
def call(name:)
|
|
244
|
+
write("Welcome #{name}!\n")
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
```
|
|
248
|
+
|
|
213
249
|
##### REPL: Input
|
|
214
250
|
|
|
215
251
|
The input area supports several keyboard shortcuts:
|
|
@@ -227,12 +263,6 @@ The input area supports several keyboard shortcuts:
|
|
|
227
263
|
| `Up / Down` | Scroll the transcript |
|
|
228
264
|
| `/exit` | Leave the REPL |
|
|
229
265
|
|
|
230
|
-
##### REPL: Commands
|
|
231
|
-
|
|
232
|
-
Commands are recognized by a `/` prefix and are backed by the
|
|
233
|
-
[`LLM::Repl::Command`](https://r.uby.dev/api-docs/llm.rb/LLM/Repl/Command.html)
|
|
234
|
-
class, which can be subclassed to add custom commands.
|
|
235
|
-
|
|
236
266
|
#### LLM::MCP
|
|
237
267
|
|
|
238
268
|
The Model Context Protocol (MCP) has first-class support
|