llm.rb 13.0.0 → 14.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 +505 -14
- data/README.md +484 -50
- data/bin/llm.rb +148 -0
- data/data/anthropic.json +206 -263
- data/data/bedrock.json +2138 -1860
- data/data/deepinfra.json +1003 -624
- data/data/deepseek.json +38 -34
- data/data/google.json +1079 -371
- data/data/mistral.json +448 -368
- data/data/moonshot.json +384 -0
- data/data/openai.json +974 -1343
- data/data/xai.json +154 -126
- data/data/zai.json +191 -191
- data/lib/llm/agent.rb +123 -20
- data/lib/llm/context.rb +71 -88
- data/lib/llm/cost.rb +23 -17
- data/lib/llm/error.rb +0 -8
- data/lib/llm/function/array.rb +3 -3
- data/lib/llm/function/async/task.rb +2 -0
- data/lib/llm/function/fiber/task.rb +2 -0
- data/lib/llm/function/fork/task.rb +2 -0
- data/lib/llm/function/ractor/task.rb +2 -0
- data/lib/llm/function/sequential/group.rb +4 -1
- data/lib/llm/function/sequential/task.rb +1 -1
- data/lib/llm/function/task.rb +4 -0
- data/lib/llm/function/thread/task.rb +2 -0
- data/lib/llm/function.rb +33 -6
- data/lib/llm/guard/loop.rb +89 -0
- data/lib/llm/guard/null.rb +19 -0
- data/lib/llm/guard.rb +61 -0
- data/lib/llm/provider.rb +36 -0
- data/lib/llm/providers/anthropic/stream_parser.rb +1 -0
- data/lib/llm/providers/anthropic.rb +2 -9
- data/lib/llm/providers/bedrock/request_adapter.rb +1 -1
- data/lib/llm/providers/bedrock/stream_parser.rb +1 -0
- data/lib/llm/providers/bedrock.rb +1 -8
- data/lib/llm/providers/google/stream_parser.rb +1 -0
- data/lib/llm/providers/google.rb +1 -8
- data/lib/llm/providers/mistral.rb +1 -1
- data/lib/llm/providers/moonshot.rb +76 -0
- data/lib/llm/providers/ollama.rb +2 -9
- data/lib/llm/providers/openai/responses/stream_parser.rb +1 -0
- data/lib/llm/providers/openai/responses.rb +7 -9
- data/lib/llm/providers/openai/stream_parser.rb +1 -0
- data/lib/llm/providers/openai.rb +4 -11
- data/lib/llm/repl/bar.rb +4 -3
- data/lib/llm/repl/{transcript.rb → buffer.rb} +69 -29
- data/lib/llm/repl/color.rb +78 -0
- data/lib/llm/repl/command.rb +12 -5
- data/lib/llm/repl/commands/compact.rb +2 -2
- data/lib/llm/repl/commands/help.rb +3 -5
- data/lib/llm/repl/input/char.rb +46 -0
- data/lib/llm/repl/input/row.rb +39 -0
- data/lib/llm/repl/input.rb +251 -66
- data/lib/llm/repl/markdown/table.rb +11 -3
- data/lib/llm/repl/markdown.rb +34 -8
- data/lib/llm/repl/node.rb +37 -0
- data/lib/llm/repl/status.rb +42 -7
- data/lib/llm/repl/stream.rb +18 -6
- data/lib/llm/repl/walker.rb +3 -2
- data/lib/llm/repl/window.rb +54 -35
- data/lib/llm/repl.rb +74 -32
- data/lib/llm/skill.rb +20 -4
- data/lib/llm/stream.rb +8 -7
- data/lib/llm/tool.rb +29 -0
- data/lib/llm/tools/{swap_text.rb → edit-file.rb} +3 -3
- data/lib/llm/tools/git.rb +3 -0
- data/lib/llm/tools/mkdir.rb +3 -0
- data/lib/llm/tools/rg.rb +3 -0
- data/lib/llm/tools/ruby.rb +46 -0
- data/lib/llm/tools/shell.rb +3 -0
- data/lib/llm/tracer/pretty_logger.rb +127 -0
- data/lib/llm/tracer.rb +1 -0
- data/lib/llm/transformer/null.rb +21 -0
- data/lib/llm/transformer.rb +55 -0
- data/lib/llm/version.rb +1 -1
- data/lib/llm.rb +12 -2
- data/llm.gemspec +9 -2
- data/resources/deepdive/advanced/cancellation.md +74 -0
- data/resources/deepdive/advanced/compaction.md +83 -0
- data/resources/deepdive/advanced/context.md +267 -0
- data/resources/deepdive/advanced/guard.md +371 -0
- data/resources/deepdive/advanced/tracer.md +180 -0
- data/resources/deepdive/advanced/transformer.md +67 -0
- data/resources/deepdive/advanced/transports.md +45 -0
- data/resources/deepdive/everything_else/audio.md +122 -0
- data/resources/deepdive/everything_else/cost.md +99 -0
- data/resources/deepdive/everything_else/images.md +89 -0
- data/resources/deepdive/everything_else/object.md +108 -0
- data/resources/deepdive/everything_else/ocr.md +48 -0
- data/resources/deepdive/fundamentals/agents.md +202 -0
- data/resources/deepdive/fundamentals/builtin_tools.md +191 -0
- data/resources/deepdive/fundamentals/concurrency.md +104 -0
- data/resources/deepdive/fundamentals/database.md +449 -0
- data/resources/deepdive/fundamentals/embeddings.md +157 -0
- data/resources/deepdive/fundamentals/repl.md +87 -0
- data/resources/deepdive/fundamentals/schema.md +61 -0
- data/resources/deepdive/fundamentals/skills.md +106 -0
- data/resources/deepdive/fundamentals/stream.md +110 -0
- data/resources/deepdive/fundamentals/tools.md +265 -0
- data/resources/deepdive/protocols/a2a.md +106 -0
- data/resources/deepdive/protocols/mcp.md +111 -0
- data/resources/deepdive.md +58 -1792
- metadata +51 -7
- data/lib/llm/loop_guard.rb +0 -107
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
|
|
2
|
+
## MCP
|
|
3
|
+
|
|
4
|
+
### Introduction
|
|
5
|
+
|
|
6
|
+
#### Overview
|
|
7
|
+
|
|
8
|
+
The Model Context Protocol (MCP) connects agents to external tools
|
|
9
|
+
and data sources through a standardized interface. Instead of
|
|
10
|
+
wiring each service directly into your agent, you run an MCP
|
|
11
|
+
server that exposes its capabilities. The runtime translates the
|
|
12
|
+
server's tool list into
|
|
13
|
+
[`LLM::Tool`](https://r.uby.dev/api-docs/llm.rb/LLM/Tool.html)
|
|
14
|
+
subclasses the model can call.
|
|
15
|
+
|
|
16
|
+
#### How it works
|
|
17
|
+
|
|
18
|
+
The stdio transport runs the server as a child process and
|
|
19
|
+
communicates over stdin/stdout. Use
|
|
20
|
+
[`LLM::MCP#session`](https://r.uby.dev/api-docs/llm.rb/LLM/MCP.html#session)
|
|
21
|
+
to avoid launching the same process multiple times.
|
|
22
|
+
|
|
23
|
+
```ruby
|
|
24
|
+
require "llm"
|
|
25
|
+
|
|
26
|
+
llm = LLM.deepseek(key: ENV["KEY"])
|
|
27
|
+
mcp = LLM::MCP.stdio(argv: ["npx", "-y", "@forgejo/mcp-server"])
|
|
28
|
+
agent = LLM::Agent.new(llm)
|
|
29
|
+
|
|
30
|
+
mcp.session do
|
|
31
|
+
agent.talk "What's happening on forgejo?", tools: mcp.tools
|
|
32
|
+
end
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
#### Why would I use it?
|
|
36
|
+
|
|
37
|
+
MCP decouples tool implementation from the agent. Add tools by
|
|
38
|
+
launching a new MCP server. Update them by restarting an existing
|
|
39
|
+
one. Remove them without touching the agent's code.
|
|
40
|
+
|
|
41
|
+
#### Notes
|
|
42
|
+
|
|
43
|
+
For stdio, use
|
|
44
|
+
[`LLM::MCP#session`](https://r.uby.dev/api-docs/llm.rb/LLM/MCP.html#session)
|
|
45
|
+
to avoid launching the same process multiple times. For HTTP,
|
|
46
|
+
[`LLM::MCP#session`](https://r.uby.dev/api-docs/llm.rb/LLM/MCP.html#session)
|
|
47
|
+
carries little benefit.
|
|
48
|
+
|
|
49
|
+
### HTTP
|
|
50
|
+
|
|
51
|
+
#### Overview
|
|
52
|
+
|
|
53
|
+
The HTTP transport connects to a remote MCP server over HTTP.
|
|
54
|
+
It is the right choice for cloud-hosted servers like GitHub's
|
|
55
|
+
MCP endpoint. Tools exposed by the server become
|
|
56
|
+
[`LLM::Tool`](https://r.uby.dev/api-docs/llm.rb/LLM/Tool.html)
|
|
57
|
+
subclasses the model can call. The server does not need to run
|
|
58
|
+
locally or even on the same machine. Configure headers for
|
|
59
|
+
authentication and pick a transport backend for connection
|
|
60
|
+
management.
|
|
61
|
+
|
|
62
|
+
#### How it works
|
|
63
|
+
|
|
64
|
+
When you want to connect to a remote MCP server, provide a URL and
|
|
65
|
+
optional headers. The server's tool list is fetched and translated
|
|
66
|
+
into
|
|
67
|
+
[`LLM::Tool`](https://r.uby.dev/api-docs/llm.rb/LLM/Tool.html) subclasses the model can call.
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
require "llm"
|
|
71
|
+
|
|
72
|
+
llm = LLM.deepseek(key: ENV["KEY"])
|
|
73
|
+
mcp = LLM::MCP.http(
|
|
74
|
+
url: "https://api.githubcopilot.com/mcp/",
|
|
75
|
+
headers: {
|
|
76
|
+
"Authorization" => "Bearer #{ENV.fetch('GITHUB_PAT')}"
|
|
77
|
+
},
|
|
78
|
+
transport: :net_http_persistent
|
|
79
|
+
)
|
|
80
|
+
agent = LLM::Agent.new(llm)
|
|
81
|
+
agent.talk "What's happening on GitHub?", tools: mcp.tools
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### Why would I use it?
|
|
85
|
+
|
|
86
|
+
The HTTP transport connects to remote MCP servers. This matters
|
|
87
|
+
when the server is not running locally or when tools are maintained
|
|
88
|
+
by a different team and exposed as a service.
|
|
89
|
+
|
|
90
|
+
#### Notes
|
|
91
|
+
|
|
92
|
+
For HTTP,
|
|
93
|
+
[`LLM::MCP#session`](https://r.uby.dev/api-docs/llm.rb/LLM/MCP.html#session)
|
|
94
|
+
carries little benefit.
|
|
95
|
+
|
|
96
|
+
##### Persistent connections
|
|
97
|
+
|
|
98
|
+
Set `persistent: true` to reuse HTTP connections across requests
|
|
99
|
+
to the same MCP server. This uses
|
|
100
|
+
[`Net::HTTP::Persistent`](https://github.com/drbrain/net-http-persistent)
|
|
101
|
+
under the hood and avoids the overhead of opening a new TCP
|
|
102
|
+
connection for every request.
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
mcp = LLM::MCP.http(
|
|
106
|
+
url: "https://api.githubcopilot.com/mcp/",
|
|
107
|
+
headers: {"Authorization" => "Bearer #{ENV.fetch('GITHUB_PAT')}"},
|
|
108
|
+
persistent: true
|
|
109
|
+
)
|
|
110
|
+
```
|
|
111
|
+
|