rach 0.2.7 → 0.2.8
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 +41 -12
- data/lib/rach/provider/anthropic.rb +7 -5
- data/lib/rach/provider/base.rb +6 -3
- data/lib/rach/provider/openai.rb +7 -5
- data/lib/rach/response.rb +18 -10
- data/lib/rach/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aae006344d427b9f6b585ec28419beca527ee1659faeb6188e24b73a0c0d4eaf
|
4
|
+
data.tar.gz: a7348260087b8829c8465d1a3a6a6129be0a7c467e2f93fdb4dcb753ee87ae24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac363b216035937755af0e712aaa2b40d871321a791f5bb2d8be7ca3f407a3fee7e36c5746cc982f3b361c52c9b044ea89624994809547155a0c5b62241a75d7
|
7
|
+
data.tar.gz: 61238f0299ff7f149e49cfe2b4ab660aae899337e59783e0d54f91216e0a3cc990bec0aa0b1b81abf008e2c9c2468a463395250372d5f098b1bb29bfeb70882e
|
data/README.md
CHANGED
@@ -41,26 +41,32 @@ require 'rach'
|
|
41
41
|
|
42
42
|
client = Rach::Client.new(access_token: YOUR_OPENAI_API_KEY, model: "gpt-4o")
|
43
43
|
convo = Rach::Conversation.new
|
44
|
-
convo.system "You teach the German language."
|
45
|
-
convo.user "Translate: There are two birds singing outside my window."
|
46
44
|
|
45
|
+
convo.system "You are a helpful historian."
|
46
|
+
|
47
|
+
# 1. First user question
|
48
|
+
convo.user "When was the Statue of Liberty dedicated? Provide only the year."
|
47
49
|
response = client.chat(convo)
|
48
|
-
response.content
|
49
|
-
# => "
|
50
|
+
puts response.content
|
51
|
+
# => "1886"
|
50
52
|
|
51
|
-
#
|
53
|
+
# 2. Add the response to the conversation
|
52
54
|
convo.add_response(response)
|
53
|
-
|
55
|
+
|
56
|
+
# 3. Continue the conversation (the answer references the original fact: 1886)
|
57
|
+
convo.user "Name a major city that was incorporated in that year"
|
54
58
|
response = client.chat(convo)
|
55
|
-
response.content
|
56
|
-
# => "
|
59
|
+
puts response.content
|
60
|
+
# => "Vancouver"
|
57
61
|
|
58
|
-
# Remove the
|
62
|
+
# 4. Remove the most recent user message ("Name a major city...")
|
59
63
|
convo.pop
|
60
|
-
|
64
|
+
|
65
|
+
# 5. Ask a new question that references the Statue of Liberty, not Vancouver
|
66
|
+
convo.user "Why was it built?"
|
61
67
|
response = client.chat(convo)
|
62
|
-
response.content
|
63
|
-
# => "
|
68
|
+
puts response.content
|
69
|
+
# => "The Statue of Liberty was built to commemorate the 100th anniversary of the signing of the Declaration of Independence."
|
64
70
|
```
|
65
71
|
|
66
72
|
### Response Formatting
|
@@ -148,6 +154,29 @@ response = client.chat("Hi there!", model: "claude-3-5-sonnet-20241022")
|
|
148
154
|
puts response.content
|
149
155
|
```
|
150
156
|
|
157
|
+
Rach uses the gems `ruby-openai` and `anthropic` to make API calls to each provider. You can configure the providers separately in the `providers` hash, and they will be used in the respective clients:
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
client = Rach::Client.new(
|
161
|
+
providers: {
|
162
|
+
openai: {
|
163
|
+
access_token: YOUR_OPENAI_API_KEY,
|
164
|
+
uri_base: "https://oai.hconeai.com/",
|
165
|
+
extra_headers: {
|
166
|
+
"X-Proxy-TTL" => "43200",
|
167
|
+
"X-Proxy-Refresh": "true",
|
168
|
+
"Helicone-Auth": "Bearer HELICONE_API_KEY",
|
169
|
+
"helicone-stream-force-format" => "true",
|
170
|
+
}
|
171
|
+
},
|
172
|
+
anthropic: {
|
173
|
+
access_token: YOUR_ANTHROPIC_API_KEY,
|
174
|
+
request_timeout: 240
|
175
|
+
}
|
176
|
+
}
|
177
|
+
)
|
178
|
+
```
|
179
|
+
|
151
180
|
### Logging
|
152
181
|
|
153
182
|
Rach supports logging of API calls and their parameters. You can provide any logger that responds to the `info` method:
|
@@ -83,11 +83,13 @@ module Rach
|
|
83
83
|
|
84
84
|
private
|
85
85
|
|
86
|
-
def create_client(access_token, **
|
87
|
-
|
88
|
-
access_token: access_token
|
89
|
-
|
90
|
-
)
|
86
|
+
def create_client(access_token, **config)
|
87
|
+
client_config = {
|
88
|
+
access_token: access_token
|
89
|
+
}
|
90
|
+
client_config.merge!(config)
|
91
|
+
|
92
|
+
::Anthropic::Client.new(**client_config)
|
91
93
|
end
|
92
94
|
|
93
95
|
def convert_tools(functions)
|
data/lib/rach/provider/base.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
module Rach
|
2
2
|
module Provider
|
3
3
|
class Base
|
4
|
-
|
5
|
-
|
4
|
+
attr_reader :client, :logger
|
5
|
+
|
6
|
+
def initialize(access_token: nil, logger: nil, **config)
|
7
|
+
@logger = logger
|
8
|
+
@client = create_client(access_token, **config)
|
6
9
|
end
|
7
10
|
|
8
11
|
def self.key
|
@@ -19,7 +22,7 @@ module Rach
|
|
19
22
|
|
20
23
|
private
|
21
24
|
|
22
|
-
def create_client(access_token, **
|
25
|
+
def create_client(access_token, **config)
|
23
26
|
raise NotImplementedError
|
24
27
|
end
|
25
28
|
end
|
data/lib/rach/provider/openai.rb
CHANGED
@@ -34,12 +34,14 @@ module Rach
|
|
34
34
|
|
35
35
|
private
|
36
36
|
|
37
|
-
def create_client(access_token, **
|
38
|
-
|
37
|
+
def create_client(access_token, **config)
|
38
|
+
client_config = {
|
39
39
|
access_token: access_token,
|
40
|
-
log_errors: true
|
41
|
-
|
42
|
-
)
|
40
|
+
log_errors: true
|
41
|
+
}
|
42
|
+
client_config.merge!(config)
|
43
|
+
|
44
|
+
::OpenAI::Client.new(**client_config)
|
43
45
|
end
|
44
46
|
|
45
47
|
def convert_params(parameters)
|
data/lib/rach/response.rb
CHANGED
@@ -19,14 +19,19 @@ module Rach
|
|
19
19
|
!tool_calls.nil? && !tool_calls.empty?
|
20
20
|
end
|
21
21
|
|
22
|
-
def function_name
|
23
|
-
|
24
|
-
tool_calls.first.dig("function", "name")
|
22
|
+
def function_name(tool_call)
|
23
|
+
tool_call.dig("function", "name")
|
25
24
|
end
|
26
25
|
|
27
|
-
def
|
26
|
+
def each_tool_call
|
28
27
|
return nil unless function_call?
|
29
|
-
|
28
|
+
tool_calls.each do |tool_call|
|
29
|
+
yield tool_call
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def function_arguments(tool_call)
|
34
|
+
JSON.parse(tool_call.dig("function", "arguments"))
|
30
35
|
rescue JSON::ParserError
|
31
36
|
raise ParseError, "Function arguments are not valid JSON"
|
32
37
|
end
|
@@ -46,12 +51,15 @@ module Rach
|
|
46
51
|
def on_function(function_class = nil, &block)
|
47
52
|
return self unless function_call?
|
48
53
|
|
49
|
-
|
50
|
-
|
54
|
+
each_tool_call do |tool_call|
|
55
|
+
function = function_class.new
|
56
|
+
next unless function.function_name == function_name(tool_call)
|
57
|
+
|
58
|
+
args = function_arguments(tool_call).transform_keys(&:to_sym)
|
59
|
+
function.validate_arguments!(args)
|
60
|
+
block.call(function, args)
|
61
|
+
end
|
51
62
|
|
52
|
-
args = function_arguments.transform_keys(&:to_sym)
|
53
|
-
function.validate_arguments!(args)
|
54
|
-
block.call(function, args)
|
55
63
|
self
|
56
64
|
end
|
57
65
|
|
data/lib/rach/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rach
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roger Garcia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-01-
|
11
|
+
date: 2025-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -143,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
143
|
- !ruby/object:Gem::Version
|
144
144
|
version: '0'
|
145
145
|
requirements: []
|
146
|
-
rubygems_version: 3.5.
|
146
|
+
rubygems_version: 3.5.3
|
147
147
|
signing_key:
|
148
148
|
specification_version: 4
|
149
149
|
summary: Orchestrate AI agents like a virtuoso
|