rach 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +118 -4
- data/lib/rach/client.rb +2 -1
- data/lib/rach/conversation.rb +4 -1
- data/lib/rach/function.rb +6 -0
- data/lib/rach/response.rb +17 -0
- data/lib/rach/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54430271658860452dad9e146c8aed72752de64c546a888b5784724bc47fb1c8
|
4
|
+
data.tar.gz: 34ea312840fa1b5aa08104f3f3696cacad5a2488039bd1d99e87c48c7949650b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b7ced2382782e8f422d1c959f5ca6a7348110f542fd9d50cd9a350c3177575583a26641599ff5b584fba4f8fe6219b27bf2a610966a6bb941404026f97919516
|
7
|
+
data.tar.gz: 718302171ac286fe03df1030f745bcdac07e3b319bb09f15abb034d6258bf2f32a7c46ac2dfb6063d7ff385d4935968eb94ffd4a00a3f4b03708e57318f07d60
|
data/README.md
CHANGED
@@ -2,11 +2,125 @@
|
|
2
2
|
|
3
3
|
A lightweight Ruby framework for OpenAI interactions, focusing on simplicity and clean design.
|
4
4
|
|
5
|
+
## Installation
|
5
6
|
|
6
|
-
|
7
|
+
Add this line to your application's Gemfile:
|
7
8
|
|
8
|
-
|
9
|
+
```ruby
|
10
|
+
gem 'rach'
|
9
11
|
```
|
10
|
-
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
```bash
|
15
|
+
$ bundle install
|
16
|
+
```
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
```bash
|
20
|
+
$ gem install rach
|
21
|
+
```
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
### Basic Chat
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require 'rach'
|
29
|
+
client = Rach::Client.new(access_token: YOUR_OPENAI_API_KEY)
|
30
|
+
response = client.chat("Hello, how are you?")
|
31
|
+
puts response.content
|
32
|
+
```
|
33
|
+
|
34
|
+
### Conversations
|
35
|
+
|
36
|
+
Rach supports stateful conversations with memory:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
require 'rach'
|
40
|
+
|
41
|
+
client = Rach::Client.new(access_token: YOUR_OPENAI_API_KEY)
|
42
|
+
convo = Rach::Conversation.new
|
43
|
+
convo.system "You teach the German language."
|
44
|
+
convo.user "Translate: There are two birds singing outside my window."
|
45
|
+
|
46
|
+
response = client.chat(convo)
|
47
|
+
response.content
|
48
|
+
# => "Es gibt zwei Vögel, die draußen vor meinem Fenster singen."
|
49
|
+
|
50
|
+
convo.add_response(response)
|
51
|
+
|
52
|
+
# Continue the conversation...
|
53
|
+
convo.user "What are the verbs in your translation?"
|
54
|
+
client.chat(convo)
|
55
|
+
|
56
|
+
|
57
|
+
# Remove the last message from the conversation history and continue
|
58
|
+
convo.pop
|
59
|
+
convo.user "Explain the structure of your translation."
|
60
|
+
client.chat(convo)
|
11
61
|
```
|
12
|
-
|
62
|
+
|
63
|
+
### Response Formatting
|
64
|
+
|
65
|
+
Define structured response schemas for type-safe AI responses:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
class GermanTranslatorSchema
|
69
|
+
include Rach::ResponseFormat
|
70
|
+
|
71
|
+
def explain_structure
|
72
|
+
object do
|
73
|
+
array :structure_explanation do
|
74
|
+
items type: :string
|
75
|
+
description "A step by step explanation of the structure of the translation."
|
76
|
+
end
|
77
|
+
string :final_translation
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
response = client.chat(convo, response_format: GermanTranslatorSchema.render(:explain_structure))
|
83
|
+
JSON.load(response.content)
|
84
|
+
# => {"structure_explanation"=> ["The phrase starts with 'Es gibt' which translates to 'There are'. 'Es' is a pronoun that means 'it', and 'gibt' is the third person singular form of the verb 'geben' (to give), meaning 'there are' in this context.", "'zwei Vögel' means 'two birds'. 'zwei' is the number 'two' and 'Vögel' is the plural form of 'Vogel' (bird).", "The relative clause 'die draußen vor meinem Fenster singen' describes the birds. 'die' is a relative pronoun meaning 'that' or 'which',' 'draußen' means 'outside', and 'vor meinem Fenster' means 'in front of my window'.", "'singen' is the infinitive form of the verb 'sing' (to sing). It tells us what the birds are doing."], "final_translation"=>"Es gibt zwei Vögel, die draußen vor meinem Fenster singen."}
|
85
|
+
```
|
86
|
+
|
87
|
+
### Function Calling / Tools
|
88
|
+
|
89
|
+
Rach supports OpenAI's function calling feature:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
class GetWeather
|
93
|
+
include Rach::Function
|
94
|
+
|
95
|
+
def function_name
|
96
|
+
"get_current_weather"
|
97
|
+
end
|
98
|
+
|
99
|
+
def function_description
|
100
|
+
"Get the current weather in a given location"
|
101
|
+
end
|
102
|
+
|
103
|
+
def schema
|
104
|
+
object do
|
105
|
+
string :location, description: "The city and state, e.g. San Francisco, CA"
|
106
|
+
string :unit, enum: %w[celsius fahrenheit]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def execute(location:, unit: "fahrenheit")
|
111
|
+
# Implementation of weather fetching logic
|
112
|
+
"The weather in #{location} is nice 🌞 #{unit}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
response = client.chat("What is the weather in San Francisco?", tools: [GetWeather.function_schema])
|
117
|
+
response.tool_calls
|
118
|
+
# => [{"id"=>"call_8v3MuUICwn0AjPRy1wZMCXtf",
|
119
|
+
# "type"=>"function",
|
120
|
+
# "function"=>{"name"=>"get_current_weather", "arguments"=>"{\"location\":\"San Francisco, CA\",\"unit\":\"celsius\"}"}}]
|
121
|
+
```
|
122
|
+
|
123
|
+
|
124
|
+
## License
|
125
|
+
|
126
|
+
Rach is available as open source under the terms of the MIT License.
|
data/lib/rach/client.rb
CHANGED
@@ -10,6 +10,7 @@ module Rach
|
|
10
10
|
|
11
11
|
def chat(prompt, response_format: nil, tools: nil)
|
12
12
|
messages = format_messages(prompt)
|
13
|
+
formatted_tools = tools&.map(&:function_schema)
|
13
14
|
|
14
15
|
response = Response.new(
|
15
16
|
@client.chat(
|
@@ -17,7 +18,7 @@ module Rach
|
|
17
18
|
model: @model,
|
18
19
|
messages:,
|
19
20
|
response_format:,
|
20
|
-
tools
|
21
|
+
tools: formatted_tools,
|
21
22
|
}.compact
|
22
23
|
)
|
23
24
|
)
|
data/lib/rach/conversation.rb
CHANGED
data/lib/rach/function.rb
CHANGED
@@ -80,5 +80,11 @@ module Rach
|
|
80
80
|
def function_description
|
81
81
|
raise NotImplementedError, "#{self.class} must implement #function_description"
|
82
82
|
end
|
83
|
+
|
84
|
+
def validate_arguments!(arguments)
|
85
|
+
unless schema.validate(arguments)
|
86
|
+
raise ArgumentError, "Invalid arguments for function #{function_name}"
|
87
|
+
end
|
88
|
+
end
|
83
89
|
end
|
84
90
|
end
|
data/lib/rach/response.rb
CHANGED
@@ -46,6 +46,23 @@ module Rach
|
|
46
46
|
usage&.fetch("total_tokens", 0)
|
47
47
|
end
|
48
48
|
|
49
|
+
def on_function(function_class = nil, &block)
|
50
|
+
return self unless function_call?
|
51
|
+
|
52
|
+
function = function_class.new
|
53
|
+
return self unless function.function_name == function_name
|
54
|
+
|
55
|
+
args = function_arguments.transform_keys(&:to_sym)
|
56
|
+
function.validate_arguments!(args)
|
57
|
+
block.call(function, args)
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def on_content(&block)
|
62
|
+
block.call(content) if content
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
49
66
|
private
|
50
67
|
|
51
68
|
def message
|
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.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roger Garcia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -103,14 +103,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
103
103
|
requirements:
|
104
104
|
- - ">="
|
105
105
|
- !ruby/object:Gem::Version
|
106
|
-
version: '0'
|
106
|
+
version: '3.0'
|
107
107
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
109
|
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '0'
|
112
112
|
requirements: []
|
113
|
-
rubygems_version: 3.5.
|
113
|
+
rubygems_version: 3.5.22
|
114
114
|
signing_key:
|
115
115
|
specification_version: 4
|
116
116
|
summary: Orchestrate AI agents like a virtuoso
|