llm.rb 11.2.0 → 11.3.1
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 +85 -11
- data/README.md +137 -144
- data/lib/llm/a2a.rb +2 -2
- data/lib/llm/active_record/acts_as_agent.rb +7 -0
- data/lib/llm/active_record/acts_as_llm.rb +7 -0
- data/lib/llm/agent.rb +26 -5
- data/lib/llm/cost.rb +1 -1
- data/lib/llm/error.rb +4 -0
- data/lib/llm/function/fiber_group.rb +2 -2
- data/lib/llm/function/task_group.rb +2 -2
- data/lib/llm/function/thread_group.rb +3 -3
- data/lib/llm/pipe.rb +1 -1
- data/lib/llm/providers/anthropic/error_handler.rb +2 -0
- data/lib/llm/providers/anthropic/request_adapter.rb +1 -1
- data/lib/llm/providers/bedrock/error_handler.rb +1 -1
- data/lib/llm/providers/bedrock/request_adapter/completion.rb +5 -5
- data/lib/llm/providers/bedrock/request_adapter.rb +3 -3
- data/lib/llm/providers/bedrock/response_adapter/completion.rb +2 -2
- data/lib/llm/providers/bedrock/response_adapter.rb +2 -2
- data/lib/llm/providers/deepseek/request_adapter.rb +1 -1
- data/lib/llm/providers/google/error_handler.rb +2 -0
- data/lib/llm/providers/google/request_adapter.rb +1 -1
- data/lib/llm/providers/ollama/error_handler.rb +2 -0
- data/lib/llm/providers/ollama/request_adapter.rb +1 -1
- data/lib/llm/providers/openai/error_handler.rb +2 -0
- data/lib/llm/providers/openai/request_adapter.rb +1 -1
- data/lib/llm/registry.rb +2 -2
- data/lib/llm/response.rb +1 -1
- data/lib/llm/schema/object.rb +1 -1
- data/lib/llm/stream.rb +1 -1
- data/lib/llm/tool.rb +2 -2
- data/lib/llm/transport/http.rb +2 -2
- data/lib/llm/transport/persistent_http.rb +1 -1
- data/lib/llm/transport/response/http.rb +1 -1
- data/lib/llm/utils.rb +1 -1
- data/lib/llm/version.rb +1 -1
- data/lib/llm.rb +11 -8
- data/llm.gemspec +11 -9
- data/resources/deepdive.md +432 -0
- metadata +28 -15
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# @!parse
|
|
4
|
+
# module ::ActiveRecord
|
|
5
|
+
# class Base
|
|
6
|
+
# end
|
|
7
|
+
# end
|
|
8
|
+
|
|
3
9
|
module LLM::ActiveRecord
|
|
4
10
|
##
|
|
5
11
|
# ActiveRecord integration for persisting {LLM::Agent LLM::Agent} state.
|
|
@@ -134,4 +140,5 @@ module LLM::ActiveRecord
|
|
|
134
140
|
end
|
|
135
141
|
end
|
|
136
142
|
|
|
143
|
+
# @!parse ::ActiveRecord::Base.extend(LLM::ActiveRecord::ActsAsAgent)
|
|
137
144
|
::ActiveRecord::Base.extend(LLM::ActiveRecord::ActsAsAgent)
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# @!parse
|
|
4
|
+
# module ::ActiveRecord
|
|
5
|
+
# class Base
|
|
6
|
+
# end
|
|
7
|
+
# end
|
|
8
|
+
|
|
3
9
|
module LLM::ActiveRecord
|
|
4
10
|
##
|
|
5
11
|
# ActiveRecord integration for persisting {LLM::Context LLM::Context} state.
|
|
@@ -222,4 +228,5 @@ module LLM::ActiveRecord
|
|
|
222
228
|
end
|
|
223
229
|
end
|
|
224
230
|
|
|
231
|
+
# @!parse ::ActiveRecord::Base.extend(LLM::ActiveRecord::ActsAsLLM)
|
|
225
232
|
::ActiveRecord::Base.extend(LLM::ActiveRecord::ActsAsLLM)
|
data/lib/llm/agent.rb
CHANGED
|
@@ -72,7 +72,11 @@ module LLM
|
|
|
72
72
|
# Returns the current skills when no argument is provided
|
|
73
73
|
def self.skills(*skills, &block)
|
|
74
74
|
return @skills if skills.empty? && !block
|
|
75
|
-
|
|
75
|
+
if skills.size == 1 and skills.grep(Symbol).any?
|
|
76
|
+
@skills = skills.first
|
|
77
|
+
else
|
|
78
|
+
@skills = block || skills.flatten
|
|
79
|
+
end
|
|
76
80
|
end
|
|
77
81
|
|
|
78
82
|
##
|
|
@@ -160,18 +164,35 @@ module LLM
|
|
|
160
164
|
##
|
|
161
165
|
# Set or get the tool names that require confirmation before they can run.
|
|
162
166
|
#
|
|
167
|
+
# When a single Symbol is given, it is stored as-is and resolved at
|
|
168
|
+
# initialization time by calling the method with that name on the agent
|
|
169
|
+
# instance. This allows dynamic tool confirmation lists.
|
|
170
|
+
#
|
|
171
|
+
# @example
|
|
172
|
+
# class MyAgent < LLM::Agent
|
|
173
|
+
# confirm :tools_that_need_confirmation
|
|
174
|
+
#
|
|
175
|
+
# def tools_that_need_confirmation
|
|
176
|
+
# some_condition ? %w[delete destroy] : %w[delete]
|
|
177
|
+
# end
|
|
178
|
+
# end
|
|
179
|
+
#
|
|
163
180
|
# @param [String, Symbol, Array<String, Symbol>, Proc] tool_names
|
|
164
181
|
# One or more tool names.
|
|
165
182
|
# @param [Proc] block
|
|
166
183
|
# An optional, lazy-evaluated Proc
|
|
167
|
-
# @return [Array<String>, Proc, nil]
|
|
184
|
+
# @return [Array<String>, Proc, Symbol, nil]
|
|
168
185
|
def self.confirm(*tool_names, &block)
|
|
169
186
|
return @confirm if tool_names.empty? && !block
|
|
170
|
-
|
|
187
|
+
if tool_names.size == 1 && tool_names.grep(Symbol).any?
|
|
188
|
+
@confirm = tool_names.first
|
|
189
|
+
else
|
|
190
|
+
@confirm = block || tool_names.flatten.map(&:to_s)
|
|
191
|
+
end
|
|
171
192
|
end
|
|
172
193
|
|
|
173
194
|
##
|
|
174
|
-
# @param [LLM::Provider]
|
|
195
|
+
# @param [LLM::Provider] llm
|
|
175
196
|
# A provider
|
|
176
197
|
# @param [Hash] params
|
|
177
198
|
# The parameters to maintain throughout the conversation.
|
|
@@ -190,7 +211,7 @@ module LLM
|
|
|
190
211
|
fields_ivar = %i[tracer concurrency instructions confirm]
|
|
191
212
|
fields.each do |field|
|
|
192
213
|
resolvable = params.key?(field) ? params.delete(field) : self.class.public_send(field)
|
|
193
|
-
resolve_symbol = !%i[concurrency
|
|
214
|
+
resolve_symbol = !%i[concurrency].include?(field)
|
|
194
215
|
resolved = resolvable != nil ? resolve_option(self, resolvable, resolve_symbol:) : resolvable
|
|
195
216
|
resolved = [*resolved].map(&:to_s) if field == :confirm && resolved
|
|
196
217
|
if field == :model
|
data/lib/llm/cost.rb
CHANGED
|
@@ -37,7 +37,7 @@ class LLM::Cost < Struct.new(
|
|
|
37
37
|
)
|
|
38
38
|
##
|
|
39
39
|
# Build a cost breakdown from token usage and model pricing.
|
|
40
|
-
# @param [LLM::Context]
|
|
40
|
+
# @param [LLM::Context] ctx
|
|
41
41
|
# Context used to resolve provider, model, and token usage
|
|
42
42
|
# @return [LLM::Cost]
|
|
43
43
|
def self.from(ctx)
|
data/lib/llm/error.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
class LLM::Function
|
|
4
4
|
##
|
|
5
5
|
# The {LLM::Function::FiberGroup} class wraps an array of
|
|
6
|
-
#
|
|
6
|
+
# `Fiber` objects that are running {LLM::Function} calls
|
|
7
7
|
# concurrently using scheduler-backed fibers.
|
|
8
8
|
#
|
|
9
9
|
# This class provides the same interface as {LLM::Function::ThreadGroup}
|
|
@@ -26,7 +26,7 @@ class LLM::Function
|
|
|
26
26
|
# of fiber objects.
|
|
27
27
|
#
|
|
28
28
|
# @param [Array<Fiber>] fibers
|
|
29
|
-
# An array of fibers, each running an
|
|
29
|
+
# An array of fibers, each running an `LLM::Function#spawn_fiber` call.
|
|
30
30
|
#
|
|
31
31
|
# @return [LLM::Function::FiberGroup]
|
|
32
32
|
# Returns a new fiber group.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
class LLM::Function
|
|
4
4
|
##
|
|
5
5
|
# The {LLM::Function::TaskGroup} class wraps an array of
|
|
6
|
-
#
|
|
6
|
+
# `Async::Task` objects that are running {LLM::Function} calls
|
|
7
7
|
# concurrently using the async gem.
|
|
8
8
|
#
|
|
9
9
|
# This class provides the same interface as {LLM::Function::ThreadGroup}
|
|
@@ -27,7 +27,7 @@ class LLM::Function
|
|
|
27
27
|
# of async task objects.
|
|
28
28
|
#
|
|
29
29
|
# @param [Array<Async::Task>] tasks
|
|
30
|
-
# An array of async tasks, each running an
|
|
30
|
+
# An array of async tasks, each running an `LLM::Function#spawn_async` call.
|
|
31
31
|
#
|
|
32
32
|
# @return [LLM::Function::TaskGroup]
|
|
33
33
|
# Returns a new task group.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
class LLM::Function
|
|
4
4
|
##
|
|
5
5
|
# The {LLM::Function::ThreadGroup} class wraps an array of
|
|
6
|
-
#
|
|
6
|
+
# `Thread` objects that are running {LLM::Function} calls
|
|
7
7
|
# concurrently. It provides a single {#wait} method that
|
|
8
8
|
# collects the {LLM::Function::Return} values from those
|
|
9
9
|
# threads.
|
|
@@ -27,11 +27,11 @@ class LLM::Function
|
|
|
27
27
|
class ThreadGroup
|
|
28
28
|
##
|
|
29
29
|
# Creates a new {LLM::Function::ThreadGroup} from an array
|
|
30
|
-
# of
|
|
30
|
+
# of `Thread` objects.
|
|
31
31
|
#
|
|
32
32
|
# @param [Array<Thread>] threads
|
|
33
33
|
# An array of threads, each running an {LLM::Function#spawn}
|
|
34
|
-
# call. The thread's
|
|
34
|
+
# call. The thread's `Thread#value` will be an
|
|
35
35
|
# {LLM::Function::Return}.
|
|
36
36
|
#
|
|
37
37
|
# @return [LLM::Function::ThreadGroup]
|
data/lib/llm/pipe.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module LLM
|
|
4
4
|
##
|
|
5
5
|
# The {LLM::Pipe LLM::Pipe} class wraps a pair of IO objects created by
|
|
6
|
-
#
|
|
6
|
+
# `IO.pipe`. It is used by llm.rb internals to manage process and stream
|
|
7
7
|
# communication through one small interface.
|
|
8
8
|
class Pipe
|
|
9
9
|
##
|
|
@@ -49,6 +49,8 @@ class LLM::Anthropic
|
|
|
49
49
|
LLM::UnauthorizedError.new("Authentication error").tap { _1.response = res }
|
|
50
50
|
elsif res.rate_limited?
|
|
51
51
|
LLM::RateLimitError.new("Too many requests").tap { _1.response = res }
|
|
52
|
+
elsif res.not_found?
|
|
53
|
+
LLM::NotFoundError.new("Server response: not found (404)").tap { _1.response = res }
|
|
52
54
|
else
|
|
53
55
|
LLM::Error.new("Unexpected response").tap { _1.response = res }
|
|
54
56
|
end
|
|
@@ -53,7 +53,7 @@ class LLM::Bedrock
|
|
|
53
53
|
elsif res.rate_limited?
|
|
54
54
|
LLM::RateLimitError.new(message).tap { _1.response = res }
|
|
55
55
|
elsif res.not_found?
|
|
56
|
-
LLM::
|
|
56
|
+
LLM::NotFoundError.new("Server response: not found (404)").tap { _1.response = res }
|
|
57
57
|
else
|
|
58
58
|
LLM::Error.new(message).tap { _1.response = res }
|
|
59
59
|
end
|
|
@@ -5,11 +5,11 @@ module LLM::Bedrock::RequestAdapter
|
|
|
5
5
|
# Adapts a single message to Bedrock Converse content blocks.
|
|
6
6
|
#
|
|
7
7
|
# Bedrock Converse content blocks include:
|
|
8
|
-
# - {text: "..."}
|
|
9
|
-
# - {image: {format: "png", source: {bytes: "..."}}}
|
|
10
|
-
# - {document: {format: "pdf", name: "...", source: {bytes: "..."}}}
|
|
11
|
-
# - {toolUse: {toolUseId: "...", name: "...", input:
|
|
12
|
-
# - {toolResult: {toolUseId: "...", content: [{text: "..."}]}}
|
|
8
|
+
# - { text: "..." }
|
|
9
|
+
# - { image: { format: "png", source: { bytes: "..." } } }
|
|
10
|
+
# - { document: { format: "pdf", name: "...", source: { bytes: "..." } } }
|
|
11
|
+
# - { toolUse: { toolUseId: "...", name: "...", input: ... } }
|
|
12
|
+
# - {toolResult: {toolUseId: "...", content: [{ text: "..." }]}}
|
|
13
13
|
#
|
|
14
14
|
# @api private
|
|
15
15
|
class Completion
|
|
@@ -5,10 +5,10 @@ class LLM::Bedrock
|
|
|
5
5
|
# Adapts llm.rb internal message format to Bedrock Converse API format.
|
|
6
6
|
#
|
|
7
7
|
# Bedrock Converse uses:
|
|
8
|
-
# - system: [{text: "..."}] (top-level, separate from messages)
|
|
9
|
-
# - messages: [{role: "user"|"assistant", content: [
|
|
8
|
+
# - system: `[ { text: "..." } ]` (top-level, separate from messages)
|
|
9
|
+
# - messages: `[ { role: "user"|"assistant", content: [ ... ] } ]`
|
|
10
10
|
# - Content blocks: text, image, document, toolUse, toolResult
|
|
11
|
-
# - toolConfig: {tools: [{toolSpec: {name:, description:, inputSchema: {json: ...}}}]}
|
|
11
|
+
# - toolConfig: `{ tools: [ { toolSpec: { name:, description:, inputSchema: { json: ... } } } ] }`
|
|
12
12
|
#
|
|
13
13
|
# @api private
|
|
14
14
|
module RequestAdapter
|
|
@@ -8,9 +8,9 @@ module LLM::Bedrock::ResponseAdapter
|
|
|
8
8
|
# {
|
|
9
9
|
# "output" => {"message" => {
|
|
10
10
|
# "role" => "assistant",
|
|
11
|
-
# "content" => [{"text" => "..."}, {"toolUse" =>
|
|
11
|
+
# "content" => `[ { "text" => "..." }, { "toolUse" => ... } ]`
|
|
12
12
|
# }},
|
|
13
|
-
# "usage" => {"inputTokens" => N, "outputTokens" => N}
|
|
13
|
+
# "usage" => `{ "inputTokens" => N, "outputTokens" => N }`,
|
|
14
14
|
# "modelId" => "anthropic.claude-sonnet-4-20250514-v1:0",
|
|
15
15
|
# "stopReason" => "end_turn"
|
|
16
16
|
# }
|
|
@@ -6,8 +6,8 @@ class LLM::Bedrock
|
|
|
6
6
|
#
|
|
7
7
|
# Bedrock Converse returns:
|
|
8
8
|
# {
|
|
9
|
-
# output: {message: {role: "assistant", content: [
|
|
10
|
-
# usage: {inputTokens: N, outputTokens: N}
|
|
9
|
+
# output: `{ message: { role: "assistant", content: [ ... ] } }`,
|
|
10
|
+
# usage: `{ inputTokens: N, outputTokens: N }`,
|
|
11
11
|
# modelId: "anthropic.claude-...",
|
|
12
12
|
# stopReason: "end_turn" | "tool_use" | "max_tokens" | ...
|
|
13
13
|
# }
|
|
@@ -60,6 +60,8 @@ class LLM::Google
|
|
|
60
60
|
end
|
|
61
61
|
elsif res.rate_limited?
|
|
62
62
|
LLM::RateLimitError.new("Too many requests").tap { _1.response = res }
|
|
63
|
+
elsif res.not_found?
|
|
64
|
+
LLM::NotFoundError.new("Server response: not found (404)").tap { _1.response = res }
|
|
63
65
|
else
|
|
64
66
|
LLM::Error.new("Unexpected response").tap { _1.response = res }
|
|
65
67
|
end
|
|
@@ -49,6 +49,8 @@ class LLM::Ollama
|
|
|
49
49
|
LLM::UnauthorizedError.new("Authentication error").tap { _1.response = res }
|
|
50
50
|
elsif res.rate_limited?
|
|
51
51
|
LLM::RateLimitError.new("Too many requests").tap { _1.response = res }
|
|
52
|
+
elsif res.not_found?
|
|
53
|
+
LLM::NotFoundError.new("Server response: not found (404)").tap { _1.response = res }
|
|
52
54
|
else
|
|
53
55
|
LLM::Error.new("Unexpected response").tap { _1.response = res }
|
|
54
56
|
end
|
|
@@ -55,6 +55,8 @@ class LLM::OpenAI
|
|
|
55
55
|
LLM::UnauthorizedError.new("Authentication error").tap { _1.response = res }
|
|
56
56
|
elsif res.rate_limited?
|
|
57
57
|
LLM::RateLimitError.new("Too many requests").tap { _1.response = res }
|
|
58
|
+
elsif res.not_found?
|
|
59
|
+
LLM::NotFoundError.new("Server response: not found (404)").tap { _1.response = res }
|
|
58
60
|
else
|
|
59
61
|
error = body["error"] || {}
|
|
60
62
|
case error["type"]
|
data/lib/llm/registry.rb
CHANGED
|
@@ -12,7 +12,7 @@ class LLM::Registry
|
|
|
12
12
|
##
|
|
13
13
|
# @raise [LLM::Error]
|
|
14
14
|
# Might raise an error
|
|
15
|
-
# @param [Symbol]
|
|
15
|
+
# @param [Symbol] name
|
|
16
16
|
# A provider name
|
|
17
17
|
# @return [LLM::Registry]
|
|
18
18
|
def self.for(name)
|
|
@@ -71,7 +71,7 @@ class LLM::Registry
|
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
##
|
|
74
|
-
# Similar to
|
|
74
|
+
# Similar to `#find` but returns the block's return value
|
|
75
75
|
# @return [Object, nil]
|
|
76
76
|
def find_map(pair)
|
|
77
77
|
result = nil
|
data/lib/llm/response.rb
CHANGED
|
@@ -14,7 +14,7 @@ module LLM
|
|
|
14
14
|
# through {#res}. When the default net/http transport is in use,
|
|
15
15
|
# {LLM::Transport::Response::HTTP
|
|
16
16
|
# LLM::Transport::Response::HTTP} keeps the
|
|
17
|
-
# original
|
|
17
|
+
# original `Net::HTTPResponse` available through
|
|
18
18
|
# its own {LLM::Transport::Response::HTTP#res #res}.
|
|
19
19
|
class Response
|
|
20
20
|
require "json"
|
data/lib/llm/schema/object.rb
CHANGED
data/lib/llm/stream.rb
CHANGED
|
@@ -15,7 +15,7 @@ module LLM
|
|
|
15
15
|
# therefore block streaming progress and should generally return as
|
|
16
16
|
# quickly as possible.
|
|
17
17
|
#
|
|
18
|
-
# The most common callback is {#on_content}, which also maps to
|
|
18
|
+
# The most common callback is {#on_content}, which also maps to `#<<`.
|
|
19
19
|
# Providers may also call {#on_reasoning_content} and {#on_tool_call} when
|
|
20
20
|
# that data is available. Runtime features such as context compaction may
|
|
21
21
|
# also emit lifecycle callbacks like {#on_transform} or {#on_compaction}.
|
data/lib/llm/tool.rb
CHANGED
|
@@ -63,7 +63,7 @@ class LLM::Tool
|
|
|
63
63
|
##
|
|
64
64
|
# @param [LLM::A2A] a2a
|
|
65
65
|
# The A2A client that will execute the tool call
|
|
66
|
-
# @param [LLM::A2A::Card::Skill]
|
|
66
|
+
# @param [LLM::A2A::Card::Skill] skill
|
|
67
67
|
# An A2A tool
|
|
68
68
|
# @return [Class<LLM::Tool>]
|
|
69
69
|
# Returns a subclass of LLM::Tool
|
|
@@ -124,7 +124,7 @@ class LLM::Tool
|
|
|
124
124
|
|
|
125
125
|
##
|
|
126
126
|
# Registers the tool as a function when inherited
|
|
127
|
-
# @param [Class]
|
|
127
|
+
# @param [Class] tool The subclass
|
|
128
128
|
# @return [void]
|
|
129
129
|
def self.inherited(tool)
|
|
130
130
|
LLM.lock(:inherited) do
|
data/lib/llm/transport/http.rb
CHANGED
|
@@ -5,7 +5,7 @@ require "net/http"
|
|
|
5
5
|
class LLM::Transport
|
|
6
6
|
##
|
|
7
7
|
# The {LLM::Transport::HTTP LLM::Transport::HTTP} transport is the
|
|
8
|
-
# built-in adapter for Ruby's
|
|
8
|
+
# built-in adapter for Ruby's `Net::HTTP`. It manages
|
|
9
9
|
# transient HTTP connections, tracks active requests by owner, and
|
|
10
10
|
# interrupts in-flight requests when needed.
|
|
11
11
|
#
|
|
@@ -69,7 +69,7 @@ class LLM::Transport
|
|
|
69
69
|
|
|
70
70
|
##
|
|
71
71
|
# Performs a request on the current HTTP transport.
|
|
72
|
-
# Accepts both
|
|
72
|
+
# Accepts both `Net::HTTPRequest` and {LLM::Transport::Request}.
|
|
73
73
|
#
|
|
74
74
|
# @param [Net::HTTPRequest, LLM::Transport::Request] request
|
|
75
75
|
# @param [Fiber] owner
|
|
@@ -81,7 +81,7 @@ class LLM::Transport
|
|
|
81
81
|
|
|
82
82
|
##
|
|
83
83
|
# Performs a request on the current HTTP transport.
|
|
84
|
-
# Accepts both
|
|
84
|
+
# Accepts both `Net::HTTPRequest` and {LLM::Transport::Request}.
|
|
85
85
|
#
|
|
86
86
|
# @param [Net::HTTPRequest, LLM::Transport::Request] request
|
|
87
87
|
# @param [Fiber] owner
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
class LLM::Transport::Response
|
|
4
4
|
##
|
|
5
5
|
# {LLM::Transport::Response::HTTP LLM::Transport::Response::HTTP}
|
|
6
|
-
# adapts a
|
|
6
|
+
# adapts a `Net::HTTPResponse` to the
|
|
7
7
|
# {LLM::Transport::Response LLM::Transport::Response} interface.
|
|
8
8
|
#
|
|
9
9
|
# This is the default wrapper for responses produced by the built-in
|
data/lib/llm/utils.rb
CHANGED
data/lib/llm/version.rb
CHANGED
data/lib/llm.rb
CHANGED
|
@@ -181,16 +181,19 @@ module LLM
|
|
|
181
181
|
end
|
|
182
182
|
|
|
183
183
|
##
|
|
184
|
-
# @param [Hash
|
|
185
|
-
#
|
|
184
|
+
# @param [Hash] opts
|
|
185
|
+
# MCP client options
|
|
186
|
+
# @option opts [Hash, nil] :stdio
|
|
187
|
+
# Standard I/O transport options
|
|
188
|
+
# @option opts [Array<String>] :stdio/:argv
|
|
186
189
|
# The command to run for the MCP process
|
|
187
|
-
# @option
|
|
190
|
+
# @option opts [Hash] :stdio/:env
|
|
188
191
|
# The environment variables to set for the MCP process
|
|
189
|
-
# @option
|
|
192
|
+
# @option opts [String, nil] :stdio/:cwd
|
|
190
193
|
# The working directory for the MCP process
|
|
191
194
|
# @return [LLM::MCP]
|
|
192
|
-
def mcp(**)
|
|
193
|
-
LLM::MCP.new(**)
|
|
195
|
+
def mcp(**opts)
|
|
196
|
+
LLM::MCP.new(**opts)
|
|
194
197
|
end
|
|
195
198
|
|
|
196
199
|
##
|
|
@@ -234,7 +237,7 @@ module LLM
|
|
|
234
237
|
##
|
|
235
238
|
# Provides a thread-safe lock
|
|
236
239
|
# @param [Symbol] name The name of the lock
|
|
237
|
-
# @param [Proc]
|
|
240
|
+
# @param [Proc] block The block to execute within the lock
|
|
238
241
|
# @return [void]
|
|
239
|
-
def lock(name, &) = @monitors[name].synchronize(&)
|
|
242
|
+
def lock(name, &block) = @monitors[name].synchronize(&block)
|
|
240
243
|
end
|
data/llm.gemspec
CHANGED
|
@@ -5,12 +5,12 @@ require_relative "lib/llm/version"
|
|
|
5
5
|
Gem::Specification.new do |spec|
|
|
6
6
|
spec.name = "llm.rb"
|
|
7
7
|
spec.version = LLM::VERSION
|
|
8
|
-
spec.authors = ["
|
|
9
|
-
spec.email = ["
|
|
8
|
+
spec.authors = ["Robert (0x1eef)", "Antar Azri", "Rodrigo Serrano"]
|
|
9
|
+
spec.email = ["robert@r.uby.dev"]
|
|
10
10
|
|
|
11
|
-
spec.summary = "Ruby's
|
|
11
|
+
spec.summary = "Ruby's capable AI runtime"
|
|
12
12
|
spec.description = <<~DESC
|
|
13
|
-
llm.rb is Ruby's
|
|
13
|
+
llm.rb is Ruby's capable AI runtime.
|
|
14
14
|
|
|
15
15
|
It runs on Ruby's standard library by default. loads optional pieces
|
|
16
16
|
only when needed, and offers a single runtime for providers, agents,
|
|
@@ -28,23 +28,24 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
spec.license = "0BSD"
|
|
29
29
|
spec.required_ruby_version = ">= 3.3.0"
|
|
30
30
|
|
|
31
|
-
spec.homepage = "https://
|
|
31
|
+
spec.homepage = "https://r.uby.dev/llm/"
|
|
32
32
|
spec.metadata["homepage_uri"] = spec.homepage
|
|
33
|
-
spec.metadata["source_code_uri"] = "https://github.com/
|
|
34
|
-
spec.metadata["documentation_uri"] =
|
|
35
|
-
spec.metadata["changelog_uri"] = "https://
|
|
33
|
+
spec.metadata["source_code_uri"] = "https://github.com/r-uby-dev/llm.rb"
|
|
34
|
+
spec.metadata["documentation_uri"] = spec.homepage
|
|
35
|
+
spec.metadata["changelog_uri"] = "https://r.uby.dev/api-docs/llm.rb/file.CHANGELOG.html"
|
|
36
36
|
|
|
37
37
|
spec.files = Dir[
|
|
38
38
|
"README.md", "LICENSE",
|
|
39
39
|
"lib/*.rb", "lib/**/*.rb",
|
|
40
40
|
"data/*.json", "CHANGELOG.md",
|
|
41
|
+
"resources/deepdive.md",
|
|
41
42
|
"llm.gemspec"
|
|
42
43
|
]
|
|
43
44
|
spec.require_paths = ["lib"]
|
|
44
45
|
|
|
45
46
|
spec.add_development_dependency "webmock", "~> 3.24.0"
|
|
46
47
|
spec.add_development_dependency "yard", "~> 0.9.37"
|
|
47
|
-
spec.add_development_dependency "
|
|
48
|
+
spec.add_development_dependency "redcarpet", "~> 3.6"
|
|
48
49
|
spec.add_development_dependency "webrick", "~> 1.8"
|
|
49
50
|
spec.add_development_dependency "test-cmd.rb", "~> 0.12.0"
|
|
50
51
|
spec.add_development_dependency "rake", "~> 13.0"
|
|
@@ -60,4 +61,5 @@ Gem::Specification.new do |spec|
|
|
|
60
61
|
spec.add_development_dependency "sqlite3", "~> 2.0"
|
|
61
62
|
spec.add_development_dependency "xchan.rb", "~> 0.20"
|
|
62
63
|
spec.add_development_dependency "pg", "~> 1.5"
|
|
64
|
+
spec.add_development_dependency "irb", "~> 1.18"
|
|
63
65
|
end
|