llm.rb 9.0.0 → 10.0.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 +76 -4
- data/README.md +80 -12
- data/data/anthropic.json +278 -258
- data/data/bedrock.json +1288 -1561
- data/data/deepseek.json +38 -38
- data/data/google.json +656 -579
- data/data/openai.json +860 -818
- data/data/xai.json +243 -552
- data/data/zai.json +168 -168
- data/lib/llm/active_record/acts_as_agent.rb +5 -0
- data/lib/llm/active_record.rb +1 -6
- data/lib/llm/agent.rb +90 -71
- data/lib/llm/context.rb +49 -48
- data/lib/llm/function/call_task.rb +46 -0
- data/lib/llm/function.rb +27 -1
- data/lib/llm/provider.rb +7 -0
- data/lib/llm/providers/anthropic/stream_parser.rb +2 -2
- data/lib/llm/providers/bedrock/stream_parser.rb +2 -2
- data/lib/llm/providers/google/stream_parser.rb +2 -2
- data/lib/llm/providers/openai/responses/stream_parser.rb +2 -2
- data/lib/llm/providers/openai/stream_parser.rb +2 -2
- data/lib/llm/schema.rb +11 -0
- data/lib/llm/sequel/agent.rb +5 -0
- data/lib/llm/sequel/plugin.rb +1 -6
- data/lib/llm/stream.rb +11 -36
- data/lib/llm/tool/param.rb +1 -8
- data/lib/llm/utils.rb +29 -0
- data/lib/llm/version.rb +1 -1
- data/lib/llm.rb +1 -0
- metadata +4 -3
- data/lib/llm/bot.rb +0 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6ba756238fa72e58ba774567a0c8e2a6d7351cb6313f9c8c08cbdeec8ec9cfa4
|
|
4
|
+
data.tar.gz: cba8295670dab2843cec902ae97b7ae14e775359380ba401ca5a0066eb60ad0e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b8347b2adfe05a4700ec42e0ed5992a1332355bd20330590d8b3de214d980476a490855ff7e69b5b36c75f3684304c4ee61bdff9ecbcf8001f0b477b8010d064
|
|
7
|
+
data.tar.gz: a41512ffbc52b3665118161251441152389ca9daba1a6f4e010303490938dc33393da62f5e821521b2a9f4b45d85fd219b558fa7d2e185c24f43777d26e36a14
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,78 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## v10.0.0
|
|
6
|
+
|
|
7
|
+
Changes since `v9.0.0`.
|
|
8
|
+
|
|
9
|
+
This release unifies context turns under `#talk`, removes the
|
|
10
|
+
deprecated `LLM::Bot` alias, and adds shared option resolution
|
|
11
|
+
through `LLM::Utils`.
|
|
12
|
+
|
|
13
|
+
Class-level agent tunables can now be resolved lazily via Proc,
|
|
14
|
+
`Array[...]` schema/tool param types are supported, and a `key?`
|
|
15
|
+
method has been added on providers.
|
|
16
|
+
|
|
17
|
+
Agent tool confirmation hooks let selected tools be approved or
|
|
18
|
+
cancelled before execution. Keep reading to learn more.
|
|
19
|
+
|
|
20
|
+
### Breaking
|
|
21
|
+
|
|
22
|
+
* **Unify context turns under `#talk`** <br>
|
|
23
|
+
Remove `LLM::Context#respond` and route responses-mode turns through
|
|
24
|
+
`LLM::Context#talk` with `mode: :responses` instead.
|
|
25
|
+
|
|
26
|
+
* **Remove the `LLM::Bot` alias** <br>
|
|
27
|
+
Remove the backward-compatible `LLM::Bot` alias for `LLM::Context`.
|
|
28
|
+
Use `LLM::Context` directly instead.
|
|
29
|
+
|
|
30
|
+
### Add
|
|
31
|
+
|
|
32
|
+
* **Add shared option resolution through `LLM::Utils`** <br>
|
|
33
|
+
Add `LLM::Utils.resolve_option` for resolving configured values as
|
|
34
|
+
literals, procs, symbol-named methods, or duplicated hashes, and use
|
|
35
|
+
it in agent and ORM option resolution paths.
|
|
36
|
+
|
|
37
|
+
* **Resolve all class-level agent tunables via Proc** <br>
|
|
38
|
+
Let `model`, `tools`, `skills`, `schema`, `stream`, and `tracer`
|
|
39
|
+
declared with a block be lazily evaluated against the agent instance
|
|
40
|
+
at initialization time, matching how `stream` and `tracer` already
|
|
41
|
+
worked.
|
|
42
|
+
|
|
43
|
+
Add `LLM::Agent#params` for direct access to the underlying context
|
|
44
|
+
parameters.
|
|
45
|
+
|
|
46
|
+
Ported from mruby-llm.
|
|
47
|
+
|
|
48
|
+
* **Support `Array[...]` schema and tool param types** <br>
|
|
49
|
+
Let `LLM::Schema` properties and `LLM::Tool` params accept
|
|
50
|
+
`Array[...]` type declarations, including mixed item unions that are
|
|
51
|
+
serialized as `anyOf` array items.
|
|
52
|
+
|
|
53
|
+
* **Add `LLM::Provider#key?`** <br>
|
|
54
|
+
Add `key?` to providers so callers can check whether a non-blank API
|
|
55
|
+
key has been configured.
|
|
56
|
+
|
|
57
|
+
* **Add agent tool confirmation hooks** <br>
|
|
58
|
+
Add `LLM::Agent.confirm` and `LLM::Agent#on_tool_confirmation` so
|
|
59
|
+
selected tools can be approved or cancelled before execution. Pending
|
|
60
|
+
tool resolution now relies on `LLM::Context#functions` so confirmed
|
|
61
|
+
tools are not executed twice when mixed with unconfirmed tool calls.
|
|
62
|
+
|
|
63
|
+
* **Add `LLM::Function#spawn(:call).wait`** <br>
|
|
64
|
+
Add task-shaped sequential execution support for direct
|
|
65
|
+
`LLM::Function#spawn(:call).wait`.
|
|
66
|
+
|
|
67
|
+
### Fix
|
|
68
|
+
|
|
69
|
+
* **Reduce private internal methods on `LLM::Stream`** <br>
|
|
70
|
+
Remove `tool_not_found` and `__tools__` from `LLM::Stream`. The
|
|
71
|
+
`__tools__` logic is inlined directly into `__find__` since that
|
|
72
|
+
was its only caller. The `tool_not_found` utility method was unused
|
|
73
|
+
externally and added unnecessary surface to LLM::Stream.
|
|
74
|
+
|
|
75
|
+
Ported from mruby-llm.
|
|
76
|
+
|
|
5
77
|
## v9.0.0
|
|
6
78
|
|
|
7
79
|
Changes since `v8.1.0`.
|
|
@@ -162,7 +234,7 @@ DSML tool-marker filtering in streamed text.
|
|
|
162
234
|
blocks that Bedrock rejects.
|
|
163
235
|
|
|
164
236
|
* **Suppress Bedrock DSML tool markers in streamed text** <br>
|
|
165
|
-
Filter
|
|
237
|
+
Filter `\"<|DSML|function_calls\"` markers out of streamed Bedrock
|
|
166
238
|
assistant text so tool-call sentinels do not leak into user-visible
|
|
167
239
|
output.
|
|
168
240
|
|
|
@@ -313,7 +385,7 @@ provider usage has been recorded yet.
|
|
|
313
385
|
buffer API.
|
|
314
386
|
|
|
315
387
|
* **Support percentage compaction token thresholds** <br>
|
|
316
|
-
Let `LLM::Compactor` accept `token_threshold:` values like
|
|
388
|
+
Let `LLM::Compactor` accept `token_threshold:` values like `\"90%\"` so
|
|
317
389
|
compaction can trigger at a percentage of the active model context
|
|
318
390
|
window.
|
|
319
391
|
|
|
@@ -1096,7 +1168,7 @@ Changes since `v4.9.0`.
|
|
|
1096
1168
|
|
|
1097
1169
|
- Add HTTP transport for MCP with `LLM::MCP::Transport::HTTP` for remote servers
|
|
1098
1170
|
- Add JSON Schema union types (`any_of`, `all_of`, `one_of`) with parser integration
|
|
1099
|
-
- Add JSON Schema type array union support (e.g.,
|
|
1171
|
+
- Add JSON Schema type array union support (e.g., `\"type\": [\"object\", \"null\"]`)
|
|
1100
1172
|
- Add JSON Schema type inference from `const`, `enum`, or `default` fields
|
|
1101
1173
|
|
|
1102
1174
|
### Change
|
|
@@ -1197,7 +1269,7 @@ Notable merged work in this range includes:
|
|
|
1197
1269
|
- `Add rack + websocket example (#130)`
|
|
1198
1270
|
- `feat(gemspec): add changelog URI (#136)`
|
|
1199
1271
|
- `feat(function): alias ThreadGroup#wait as ThreadGroup#value (#62)`
|
|
1200
|
-
- README and screencast refresh across `#66`, `#
|
|
1272
|
+
- README and screencast refresh across `#66`, `#68`, `#71`, and
|
|
1201
1273
|
`#72`
|
|
1202
1274
|
- `chore(bot): update deprecation warning from v5.0 to v6.0`
|
|
1203
1275
|
- `fix(deepseek): tolerate malformed tool arguments`
|
data/README.md
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<a href="llm.rb"
|
|
2
|
+
<a href="llm.rb">
|
|
3
|
+
<img src="https://github.com/llmrb/llm.rb/raw/main/llm.png" width="200" height="200" border="0" alt="llm.rb">
|
|
4
|
+
</a>
|
|
3
5
|
</p>
|
|
4
6
|
<p align="center">
|
|
5
|
-
<a href="https://0x1eef.github.io/x/llm.rb?rebuild=1"
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
<a href="https://0x1eef.github.io/x/llm.rb?rebuild=1">
|
|
8
|
+
<img src="https://img.shields.io/badge/docs-0x1eef.github.io-blue.svg" alt="RubyDoc">
|
|
9
|
+
</a>
|
|
10
|
+
<a href="https://opensource.org/license/0bsd">
|
|
11
|
+
<img src="https://img.shields.io/badge/License-0BSD-orange.svg?" alt="License">
|
|
12
|
+
</a>
|
|
13
|
+
<a href="https://github.com/llmrb/llm.rb/tags">
|
|
14
|
+
<img src="https://img.shields.io/badge/version-10.0.0-green.svg?" alt="Version">
|
|
15
|
+
</a>
|
|
8
16
|
</p>
|
|
9
17
|
|
|
10
18
|
## About
|
|
@@ -64,6 +72,36 @@ agent = LLM::Agent.new(llm, stream: $stdout)
|
|
|
64
72
|
agent.talk "Hello world"
|
|
65
73
|
```
|
|
66
74
|
|
|
75
|
+
#### Agents (Advanced)
|
|
76
|
+
|
|
77
|
+
An agent can be configured to require confirmation before a tool is
|
|
78
|
+
executed. When a matching tool is called, llm.rb runs
|
|
79
|
+
`on_tool_confirmation`. That callback must decide whether to cancel the
|
|
80
|
+
tool call or approve it and execute it by calling
|
|
81
|
+
`fn.spawn(strategy).wait`, and it must always return an instance of
|
|
82
|
+
[`LLM::Function::Return`](https://0x1eef.github.io/x/llm.rb/LLM/Function/Return.html):
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
require "llm"
|
|
86
|
+
|
|
87
|
+
class Agent < LLM::Agent
|
|
88
|
+
tools DeleteFile
|
|
89
|
+
confirm "delete-file"
|
|
90
|
+
|
|
91
|
+
def on_tool_confirmation(fn, strategy)
|
|
92
|
+
path = fn.arguments["path"] || fn.arguments[:path]
|
|
93
|
+
if path.start_with?("/tmp/")
|
|
94
|
+
fn.spawn(strategy).wait
|
|
95
|
+
else
|
|
96
|
+
fn.cancel(reason: "Deletion requires approval")
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
llm = LLM.openai(key: ENV["KEY"])
|
|
102
|
+
Agent.new(llm, stream: $stdout).talk("Delete /tmp/example.txt.")
|
|
103
|
+
```
|
|
104
|
+
|
|
67
105
|
#### Tools
|
|
68
106
|
|
|
69
107
|
The
|
|
@@ -249,7 +287,10 @@ gem install llm.rb
|
|
|
249
287
|
|
|
250
288
|
#### REPL
|
|
251
289
|
|
|
252
|
-
This example uses [`LLM::Context`](https://0x1eef.github.io/x/llm.rb/LLM/Context.html)
|
|
290
|
+
This example uses [`LLM::Context`](https://0x1eef.github.io/x/llm.rb/LLM/Context.html)
|
|
291
|
+
directly for an interactive REPL. <br> See the
|
|
292
|
+
[deepdive (web)](https://0x1eef.github.io/x/llm.rb/file.deepdive.html) or
|
|
293
|
+
[deepdive (markdown)](resources/deepdive.md) for more examples.
|
|
253
294
|
|
|
254
295
|
```ruby
|
|
255
296
|
require "llm"
|
|
@@ -299,7 +340,9 @@ compactor can also use its own `model:` if you want summarization to run on a
|
|
|
299
340
|
different model from the main context. `token_threshold:` accepts either a
|
|
300
341
|
fixed token count or a percentage string like `"90%"`, which resolves
|
|
301
342
|
against the active model context window and triggers compaction once total
|
|
302
|
-
token usage goes over that percentage. See the
|
|
343
|
+
token usage goes over that percentage. See the
|
|
344
|
+
[deepdive (web)](https://0x1eef.github.io/x/llm.rb/file.deepdive.html) or
|
|
345
|
+
[deepdive (markdown)](resources/deepdive.md) for more examples.
|
|
303
346
|
|
|
304
347
|
```ruby
|
|
305
348
|
require "llm"
|
|
@@ -328,7 +371,15 @@ ctx = LLM::Context.new(
|
|
|
328
371
|
|
|
329
372
|
#### Reasoning
|
|
330
373
|
|
|
331
|
-
This example uses [`LLM::Stream`](https://0x1eef.github.io/x/llm.rb/LLM/Stream.html)
|
|
374
|
+
This example uses [`LLM::Stream`](https://0x1eef.github.io/x/llm.rb/LLM/Stream.html)
|
|
375
|
+
with the OpenAI Responses API so reasoning output is streamed separately from
|
|
376
|
+
visible assistant output. See the
|
|
377
|
+
[deepdive (web)](https://0x1eef.github.io/x/llm.rb/file.deepdive.html) or
|
|
378
|
+
[deepdive (markdown)](resources/deepdive.md) for more examples.
|
|
379
|
+
|
|
380
|
+
To use the Responses API (OpenAI-specific), initialize a
|
|
381
|
+
context or agent with `mode: :responses` and keep using
|
|
382
|
+
`talk` for turns.
|
|
332
383
|
|
|
333
384
|
```ruby
|
|
334
385
|
require "llm"
|
|
@@ -356,7 +407,10 @@ ctx.talk("Solve 17 * 19 and show your work.")
|
|
|
356
407
|
|
|
357
408
|
#### Request Cancellation
|
|
358
409
|
|
|
359
|
-
Need to cancel a stream? llm.rb has you covered through
|
|
410
|
+
Need to cancel a stream? llm.rb has you covered through
|
|
411
|
+
[`LLM::Context#interrupt!`](https://0x1eef.github.io/x/llm.rb/LLM/Context.html#interrupt-21-instance_method).
|
|
412
|
+
<br> See the [deepdive (web)](https://0x1eef.github.io/x/llm.rb/file.deepdive.html)
|
|
413
|
+
or [deepdive (markdown)](resources/deepdive.md) for more examples.
|
|
360
414
|
|
|
361
415
|
```ruby
|
|
362
416
|
require "llm"
|
|
@@ -377,7 +431,14 @@ worker.join
|
|
|
377
431
|
|
|
378
432
|
#### Sequel (ORM)
|
|
379
433
|
|
|
380
|
-
The `plugin :llm` integration wraps
|
|
434
|
+
The `plugin :llm` integration wraps
|
|
435
|
+
[`LLM::Context`](https://0x1eef.github.io/x/llm.rb/LLM/Context.html) on a
|
|
436
|
+
`Sequel::Model` and keeps tool execution explicit. Like the ActiveRecord
|
|
437
|
+
wrappers, its built-in persistence contract is the serialized `data` column,
|
|
438
|
+
while `provider:` resolves a real `LLM::Provider` instance and `context:`
|
|
439
|
+
injects defaults such as `model:`. <br> See the
|
|
440
|
+
[deepdive (web)](https://0x1eef.github.io/x/llm.rb/file.deepdive.html) or
|
|
441
|
+
[deepdive (markdown)](resources/deepdive.md) for more examples.
|
|
381
442
|
|
|
382
443
|
```ruby
|
|
383
444
|
require "llm"
|
|
@@ -412,7 +473,8 @@ one serialized `data` column. If your app has provider, model, or usage
|
|
|
412
473
|
columns, provide them to llm.rb through `provider:` and `context:` instead of
|
|
413
474
|
relying on reserved wrapper columns.
|
|
414
475
|
|
|
415
|
-
See the [deepdive (web)](https://0x1eef.github.io/x/llm.rb/file.deepdive.html)
|
|
476
|
+
See the [deepdive (web)](https://0x1eef.github.io/x/llm.rb/file.deepdive.html)
|
|
477
|
+
or [deepdive (markdown)](resources/deepdive.md) for more examples.
|
|
416
478
|
|
|
417
479
|
```ruby
|
|
418
480
|
require "llm"
|
|
@@ -468,7 +530,8 @@ manages tool execution for you. Like `acts_as_llm`, its built-in persistence
|
|
|
468
530
|
contract is one serialized `data` column. If your app has provider or model
|
|
469
531
|
columns, provide them to llm.rb through your hooks and agent DSL.
|
|
470
532
|
|
|
471
|
-
See the [deepdive (web)](https://0x1eef.github.io/x/llm.rb/file.deepdive.html)
|
|
533
|
+
See the [deepdive (web)](https://0x1eef.github.io/x/llm.rb/file.deepdive.html)
|
|
534
|
+
or [deepdive (markdown)](resources/deepdive.md) for more examples.
|
|
472
535
|
|
|
473
536
|
```ruby
|
|
474
537
|
require "llm"
|
|
@@ -521,7 +584,12 @@ end
|
|
|
521
584
|
|
|
522
585
|
#### MCP
|
|
523
586
|
|
|
524
|
-
This example uses [`LLM::MCP`](https://0x1eef.github.io/x/llm.rb/LLM/MCP.html)
|
|
587
|
+
This example uses [`LLM::MCP`](https://0x1eef.github.io/x/llm.rb/LLM/MCP.html)
|
|
588
|
+
over HTTP so remote GitHub MCP tools run through the same
|
|
589
|
+
`LLM::Context` tool path as local tools. It expects a GitHub token in
|
|
590
|
+
`ENV["GITHUB_PAT"]`. See the
|
|
591
|
+
[deepdive (web)](https://0x1eef.github.io/x/llm.rb/file.deepdive.html) or
|
|
592
|
+
[deepdive (markdown)](resources/deepdive.md) for more examples.
|
|
525
593
|
|
|
526
594
|
```ruby
|
|
527
595
|
require "llm"
|