ruby_llm 0.1.0.pre9 → 0.1.0.pre11
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/README.md +30 -26
- data/lib/ruby_llm/chat.rb +5 -4
- data/lib/ruby_llm/tool.rb +59 -70
- data/lib/ruby_llm/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed2ff977d45e5ac9a14d93b81740516f14f6c4ef33140e0163f6011efa14d697
|
4
|
+
data.tar.gz: a51b24bd4e88512d9abb3d4db33551bd391da97fa8161f8f6d1b23e415f427d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff245f6f9378b51481a096b63a4c5cb688cf80e3b5d218a9e0ff5ca74a0ac09c720a8647df8f8fe9603ee10d9b3b61e4704638d81051c1378694bff47f272e7f
|
7
|
+
data.tar.gz: 8fae7e20c68130cabc9d769a82b5b3a94d765b2cb53804a2df7833c402da37c6c781bcaaf477cb41a0b610026bfa57fee2670029793526c4375dee3731bc4bf3
|
data/README.md
CHANGED
@@ -39,7 +39,7 @@ chat.ask "What's the best way to learn Ruby?"
|
|
39
39
|
|
40
40
|
## Available Models
|
41
41
|
|
42
|
-
RubyLLM gives you access to the latest models from multiple providers
|
42
|
+
RubyLLM gives you access to the latest models from multiple providers:
|
43
43
|
|
44
44
|
```ruby
|
45
45
|
# List all available models
|
@@ -79,49 +79,53 @@ puts "Conversation used #{last_message.input_tokens} input tokens and #{last_mes
|
|
79
79
|
|
80
80
|
## Using Tools
|
81
81
|
|
82
|
-
Give
|
82
|
+
Give Claude some Ruby superpowers by letting it call your code. Simply create a tool class:
|
83
83
|
|
84
84
|
```ruby
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
param :expression,
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
85
|
+
class CalculatorTool < RubyLLM::Tool
|
86
|
+
description "Performs arithmetic calculations"
|
87
|
+
|
88
|
+
param :expression,
|
89
|
+
type: :string,
|
90
|
+
required: true,
|
91
|
+
desc: "A mathematical expression to evaluate (e.g. '2 + 2')"
|
92
|
+
|
93
|
+
def execute(expression:)
|
94
|
+
eval(expression).to_s
|
93
95
|
end
|
94
96
|
end
|
97
|
+
```
|
95
98
|
|
96
|
-
|
97
|
-
chat = RubyLLM.chat.with_tool calculator
|
99
|
+
Then use it in your conversations:
|
98
100
|
|
99
|
-
|
101
|
+
```ruby
|
102
|
+
chat = RubyLLM.chat.with_tool(CalculatorTool)
|
103
|
+
|
104
|
+
# Claude will automatically use the calculator when appropriate
|
100
105
|
chat.ask "What's 2+2?"
|
101
|
-
# => "
|
106
|
+
# => "Let me calculate that for you. The result is 4."
|
102
107
|
|
103
|
-
chat.ask "and
|
104
|
-
# => "
|
108
|
+
chat.ask "If I have 3 apples and multiply them by 5, how many do I have?"
|
109
|
+
# => "Let me help you calculate that. 3 × 5 = 15, so you would have 15 apples."
|
105
110
|
|
106
111
|
# Add multiple tools
|
107
|
-
chat.with_tools
|
112
|
+
chat.with_tools(CalculatorTool, WeatherTool, DatabaseTool)
|
108
113
|
```
|
109
114
|
|
110
|
-
Tools let you seamlessly integrate Ruby code with AI capabilities.
|
111
|
-
|
112
|
-
## Choosing the Right Model
|
115
|
+
Tools let you seamlessly integrate your Ruby code with AI capabilities. The model will automatically decide when to use your tools and handle the results appropriately.
|
113
116
|
|
114
|
-
RubyLLM
|
117
|
+
Need to debug a tool? RubyLLM automatically logs all tool calls and their results when debug logging is enabled:
|
115
118
|
|
116
119
|
```ruby
|
117
|
-
|
120
|
+
ENV['RUBY_LLM_DEBUG'] = 'true'
|
118
121
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
model.supports_json_mode # => true
|
122
|
+
chat.ask "What's 123 * 456?"
|
123
|
+
# D, -- RubyLLM: Tool calculator called with: {"expression" => "123 * 456"}
|
124
|
+
# D, -- RubyLLM: Tool calculator returned: "56088"
|
123
125
|
```
|
124
126
|
|
127
|
+
Create tools for anything - database queries, API calls, custom business logic - and let Claude use them naturally in conversation.
|
128
|
+
|
125
129
|
## Coming Soon
|
126
130
|
|
127
131
|
- Rails integration for seamless database and Active Record support
|
data/lib/ruby_llm/chat.rb
CHANGED
@@ -26,7 +26,8 @@ module RubyLLM
|
|
26
26
|
def with_tool(tool)
|
27
27
|
raise Error, "Model #{@model.id} doesn't support function calling" unless @model.supports_functions
|
28
28
|
|
29
|
-
|
29
|
+
tool_instance = tool.is_a?(Class) ? tool.to_tool : tool
|
30
|
+
@tools[tool_instance.name.to_sym] = tool_instance
|
30
31
|
self
|
31
32
|
end
|
32
33
|
|
@@ -64,7 +65,7 @@ module RubyLLM
|
|
64
65
|
end
|
65
66
|
|
66
67
|
def execute_tool(tool_call)
|
67
|
-
tool = tools[tool_call.name]
|
68
|
+
tool = tools[tool_call.name.to_sym]
|
68
69
|
args = tool_call.arguments
|
69
70
|
tool.call(args)
|
70
71
|
end
|
@@ -85,8 +86,8 @@ module RubyLLM
|
|
85
86
|
|
86
87
|
def ensure_valid_tools
|
87
88
|
tools.each_key do |name|
|
88
|
-
unless name.is_a?(
|
89
|
-
raise Error, 'Tools should be of the format {<name>: <RubyLLM::Tool>}'
|
89
|
+
unless name.is_a?(Symbol) && tools[name].is_a?(RubyLLM::Tool)
|
90
|
+
raise Error, 'Tools should be of the format {<name.to_sym>: <RubyLLM::Tool>}'
|
90
91
|
end
|
91
92
|
end
|
92
93
|
end
|
data/lib/ruby_llm/tool.rb
CHANGED
@@ -1,100 +1,89 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# lib/ruby_llm/tool.rb
|
3
4
|
module RubyLLM
|
4
5
|
class Tool
|
5
|
-
class
|
6
|
-
|
6
|
+
class << self
|
7
|
+
def description(text = nil)
|
8
|
+
return @description unless text
|
7
9
|
|
8
|
-
|
9
|
-
@name = name
|
10
|
-
@type = type
|
11
|
-
@description = description
|
12
|
-
@required = required
|
10
|
+
@description = text
|
13
11
|
end
|
14
12
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
def param(name, type:, desc: nil, required: true)
|
14
|
+
param = Parameter.new(
|
15
|
+
name,
|
16
|
+
type: type.to_s,
|
17
|
+
description: desc,
|
19
18
|
required: required
|
20
|
-
|
19
|
+
)
|
20
|
+
parameters[name] = param
|
21
21
|
end
|
22
|
-
end
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
@tool = tool
|
23
|
+
def parameters
|
24
|
+
@parameters ||= {}
|
27
25
|
end
|
28
26
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
27
|
+
def name
|
28
|
+
super
|
29
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
30
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
31
|
+
.downcase
|
32
|
+
.delete_suffix('_tool')
|
32
33
|
end
|
33
34
|
|
34
|
-
def
|
35
|
-
|
36
|
-
self
|
37
|
-
end
|
35
|
+
def to_tool
|
36
|
+
tool_instance = new
|
38
37
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
38
|
+
def tool_instance.name
|
39
|
+
self.class.name
|
40
|
+
end
|
44
41
|
|
45
|
-
|
42
|
+
def tool_instance.description
|
43
|
+
self.class.description
|
44
|
+
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
builder.instance_eval(&block)
|
51
|
-
tool
|
52
|
-
end
|
46
|
+
def tool_instance.parameters
|
47
|
+
self.class.parameters
|
48
|
+
end
|
53
49
|
|
54
|
-
|
55
|
-
|
56
|
-
@parameters = {}
|
50
|
+
tool_instance
|
51
|
+
end
|
57
52
|
end
|
58
53
|
|
59
54
|
def call(args)
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
rescue StandardError => e
|
69
|
-
RubyLLM.logger.error "Tool #{name}(#{args.inspect}) failed with error #{e.message}"
|
70
|
-
{ error: e.message }
|
71
|
-
end
|
55
|
+
RubyLLM.logger.debug "Tool #{name} called with: #{args.inspect}"
|
56
|
+
symbolized_args = args.transform_keys(&:to_sym)
|
57
|
+
result = execute(**symbolized_args)
|
58
|
+
RubyLLM.logger.debug "Tool #{name} returned: #{result.inspect}"
|
59
|
+
result
|
60
|
+
rescue StandardError => e
|
61
|
+
RubyLLM.logger.error "Tool #{name} failed with error: #{e.message}"
|
62
|
+
{ error: e.message }
|
72
63
|
end
|
73
64
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
65
|
+
def execute(args)
|
66
|
+
raise NotImplementedError, 'Subclasses must implement #execute'
|
67
|
+
end
|
68
|
+
end
|
78
69
|
|
79
|
-
|
80
|
-
|
81
|
-
|
70
|
+
# Using the existing Parameter class from Tool.rb
|
71
|
+
class Parameter
|
72
|
+
attr_reader :name, :type, :description, :required
|
82
73
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
74
|
+
def initialize(name, type: 'string', description: nil, required: true)
|
75
|
+
@name = name
|
76
|
+
@type = type
|
77
|
+
@description = description
|
78
|
+
@required = required
|
88
79
|
end
|
89
80
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
key
|
97
|
-
end
|
81
|
+
def to_h
|
82
|
+
{
|
83
|
+
type: type,
|
84
|
+
description: description,
|
85
|
+
required: required
|
86
|
+
}.compact
|
98
87
|
end
|
99
88
|
end
|
100
89
|
end
|
data/lib/ruby_llm/version.rb
CHANGED