ox-ai-workers 0.1.0 → 0.1.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 +6 -0
- data/README.md +46 -9
- data/lib/ox-ai-workers.rb +9 -0
- data/lib/oxaiworkers/assistant/sysop.rb +2 -2
- data/lib/oxaiworkers/delayed_request.rb +5 -3
- data/lib/oxaiworkers/iterator.rb +24 -6
- data/lib/oxaiworkers/module_request.rb +6 -7
- data/lib/oxaiworkers/request.rb +1 -1
- data/lib/oxaiworkers/version.rb +1 -1
- data/locales/en.system.yml +6 -8
- data/locales/ru.system.yml +1 -2
- 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: cdc74e4ff15dab4e67681666575aacb9a57d05183caaaa18982cbff7bdeea280
|
4
|
+
data.tar.gz: 3e7e8f0c6cec85b1b6b6857d395f5ee05a48904e157d99a72d82bd60429d0970
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af5d143c8a8ad34c6f65f5b576076785848b16736025177358bcf2cc87c062b8ded0f2dec8f9b4d44635c3ed8ade86085daed0b075e1f7c59b152149d5f41397
|
7
|
+
data.tar.gz: d6754f9a006e04829d02ff7b32844b4179c0318371cbc8b573de37fc4552a3c3d9533d8665d847682e5e2af937a1c133ee14d7c28883bce0fdbd426ab1e5812e
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -32,12 +32,51 @@ I18n.default_locale = :en # for pure Ruby
|
|
32
32
|
require 'ox-ai-workers'
|
33
33
|
|
34
34
|
# Initialize the assistant
|
35
|
-
sysop = OxAiWorkers::Assistant::Sysop.new()
|
35
|
+
sysop = OxAiWorkers::Assistant::Sysop.new(delayed: false, model: "gpt-4o")
|
36
36
|
|
37
37
|
# Add a task
|
38
38
|
sysop.addTask("Add a cron job to synchronize files daily.")
|
39
39
|
```
|
40
40
|
|
41
|
+
```ruby
|
42
|
+
worker = OxAiWorkers::DelayedRequest.new(batch_id: "xxx-xxx-xxx", model: "gpt-4o-mini", max_tokens: 4096, temperature: 0.7)
|
43
|
+
# or
|
44
|
+
# worker = OxAiWorkers::Request.new(model: "gpt-4o-mini", max_tokens: 4096, temperature: 0.7)
|
45
|
+
my_tool = OxAiWorkers::Tool::Eval.new()
|
46
|
+
iterator = OxAiWorkers::Iterator.new(worker: worker, tools: [my_tool])
|
47
|
+
iterator.role = "You are a software agent inside my computer"
|
48
|
+
iterator.addTask("Show files in current dir")
|
49
|
+
```
|
50
|
+
|
51
|
+
### With Config
|
52
|
+
|
53
|
+
For a more robust setup, you can configure the gem with your API keys, for example in an oxaiworkers.rb initializer file. Never hardcode secrets into your codebase - instead use something like [dotenv](https://github.com/motdotla/dotenv) to pass the keys safely into your environments.
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
OxAiWorkers.configure do |config|
|
57
|
+
config.access_token = ENV.fetch("OPENAI")
|
58
|
+
config.model = "gpt-4o"
|
59
|
+
config.max_tokens = 4096
|
60
|
+
config.temperature = 0.7
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
Then you can create an assistant like this:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
assistant = OxAiWorkers::Assistant::Sysop.new()
|
68
|
+
```
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
iterator = OxAiWorkers::Iterator.new(
|
72
|
+
worker: OxAiWorkers::Request.new,
|
73
|
+
tools: [OxAiWorkers::Tool::Eval.new],
|
74
|
+
role: "You are a software agent inside my computer"
|
75
|
+
)
|
76
|
+
|
77
|
+
iterator.addTask("Show files in current dir")
|
78
|
+
```
|
79
|
+
|
41
80
|
## Features
|
42
81
|
|
43
82
|
- **Generative Intelligence**: Leverages OpenAI's capabilities to enhance task execution.
|
@@ -66,14 +105,12 @@ en:
|
|
66
105
|
description: "Save facts, nuances, and actions before clearing messages"
|
67
106
|
text: "Listing important facts and nuances"
|
68
107
|
monologue:
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
- "Step 3.1: Save facts, nuances, and actions using the packHistory function."
|
76
|
-
- "Step 4: Conclude the work with the actionRequest function, without repeating the response if it was already given with outerVoice."
|
108
|
+
- "Step 1: Develop your own solution to the problem. Take initiative and make assumptions."
|
109
|
+
- "Step 1.1: Wrap all your work for this step in the innerMonologue function."
|
110
|
+
- "Step 2: Relate your solution to the task, improve it, and call the necessary functions step by step."
|
111
|
+
- "Step 2.1: Interact with the user using the outerVoice and actionRequest functions during the process."
|
112
|
+
- "Step 3: When the solution is ready, report it using the outerVoice function."
|
113
|
+
- "Step 4: Save facts, nuances, and actions using the packHistory function."
|
77
114
|
tool:
|
78
115
|
eval:
|
79
116
|
ruby:
|
data/lib/ox-ai-workers.rb
CHANGED
@@ -23,14 +23,23 @@ require_relative "oxaiworkers/version.rb"
|
|
23
23
|
require_relative "oxaiworkers/assistant/sysop.rb"
|
24
24
|
|
25
25
|
module OxAiWorkers
|
26
|
+
DEFAULT_MODEL = "gpt-4o-mini"
|
27
|
+
DEFAULT_MAX_TOKEN = 4096
|
28
|
+
DEFAULT_TEMPERATURE = 0.7
|
29
|
+
|
26
30
|
class Error < StandardError; end
|
27
31
|
class ConfigurationError < Error; end
|
28
32
|
|
29
33
|
class Configuration
|
30
34
|
attr_writer :access_token
|
35
|
+
attr_accessor :model, :max_tokens, :temperature
|
31
36
|
|
32
37
|
def initialize
|
33
38
|
@access_token = nil
|
39
|
+
@model = DEFAULT_MODEL
|
40
|
+
@max_tokens = DEFAULT_MAX_TOKEN
|
41
|
+
@temperature = DEFAULT_TEMPERATURE
|
42
|
+
|
34
43
|
[Array, NilClass, String, Symbol, Hash].each{|c|
|
35
44
|
c.send(:include, OxAiWorkers::PresentCompat) unless c.method_defined?(:present?)
|
36
45
|
}
|
@@ -2,9 +2,9 @@ module OxAiWorkers
|
|
2
2
|
module Assistant
|
3
3
|
class Sysop
|
4
4
|
attr_accessor :iterator
|
5
|
-
def initialize delayed: false, model:
|
5
|
+
def initialize delayed: false, model: nil
|
6
6
|
worker = delayed ? OxAiWorkers::DelayedRequest.new : OxAiWorkers::Request.new
|
7
|
-
worker.model = model
|
7
|
+
worker.model = model || OxAiWorkers.configuration.model
|
8
8
|
@iterator = OxAiWorkers::Iterator.new(worker: worker, tools: [OxAiWorkers::Tool::Eval.new])
|
9
9
|
@iterator.role = I18n.t("oxaiworkers.assistant.sysop.role")
|
10
10
|
# @iterator.addTask("покажи мне файлы на диске")
|
@@ -1,11 +1,12 @@
|
|
1
1
|
class OxAiWorkers::DelayedRequest < OxAiWorkers::StateBatch
|
2
|
-
def initialize(batch_id: nil, model:
|
2
|
+
def initialize(batch_id: nil, model: nil, max_tokens: nil, temperature: nil)
|
3
3
|
initializeRequests(model: model, max_tokens: max_tokens, temperature: temperature)
|
4
4
|
@custom_id = nil if batch_id.present?
|
5
5
|
@batch_id = batch_id
|
6
6
|
@file_id = nil
|
7
7
|
super()
|
8
8
|
end
|
9
|
+
|
9
10
|
def postBatch
|
10
11
|
response = @client.batches.create(
|
11
12
|
parameters: {
|
@@ -38,7 +39,7 @@ class OxAiWorkers::DelayedRequest < OxAiWorkers::StateBatch
|
|
38
39
|
|
39
40
|
def finish
|
40
41
|
@custom_id = SecureRandom.uuid
|
41
|
-
end_batch!
|
42
|
+
end_batch! unless batch_idle?
|
42
43
|
end
|
43
44
|
|
44
45
|
def uploadToStorage
|
@@ -86,7 +87,8 @@ class OxAiWorkers::DelayedRequest < OxAiWorkers::StateBatch
|
|
86
87
|
output = @client.files.content(id: batch["output_file_id"])
|
87
88
|
output.each do |line|
|
88
89
|
@custom_id = line["custom_id"]
|
89
|
-
@result = line.dig("response", "body", "choices", 0, "message", "content")
|
90
|
+
# @result = line.dig("response", "body", "choices", 0, "message", "content")
|
91
|
+
parseChoices(line.dig("response", "body"))
|
90
92
|
complete_batch!
|
91
93
|
end
|
92
94
|
elsif !batch["error_file_id"].nil?
|
data/lib/oxaiworkers/iterator.rb
CHANGED
@@ -31,7 +31,6 @@ class OxAiWorkers::Iterator < OxAiWorkers::StateTools
|
|
31
31
|
@tasks = []
|
32
32
|
@milestones = []
|
33
33
|
|
34
|
-
# @tools = OxAiWorkers::Tool.constants.map(&OxAiWorkers::Tool.method(:const_get)).select { |c| c.is_a? Class }.map{|c|c.new}
|
35
34
|
super()
|
36
35
|
end
|
37
36
|
|
@@ -60,7 +59,7 @@ class OxAiWorkers::Iterator < OxAiWorkers::StateTools
|
|
60
59
|
|
61
60
|
def packHistory text:
|
62
61
|
puts Rainbow("summarize: #{text}").blue
|
63
|
-
@milestones << "#{
|
62
|
+
@milestones << "#{__method__}: #{text}"
|
64
63
|
@messages = []
|
65
64
|
@worker.finish()
|
66
65
|
rebuildWorker()
|
@@ -110,7 +109,7 @@ class OxAiWorkers::Iterator < OxAiWorkers::StateTools
|
|
110
109
|
def processResult(transition)
|
111
110
|
puts "call: #{__method__} state: #{state_name}"
|
112
111
|
@result = @worker.result || @worker.errors
|
113
|
-
if @worker.
|
112
|
+
if @worker.tool_calls.present?
|
114
113
|
@queue << {role: :system, content: @worker.tool_calls_raw.to_s}
|
115
114
|
@worker.tool_calls.each do |external_call|
|
116
115
|
tool = @tools.select{|t| t.class.tool_name == external_call[:class] && t.respond_to?(external_call[:name]) }.first
|
@@ -119,6 +118,7 @@ class OxAiWorkers::Iterator < OxAiWorkers::StateTools
|
|
119
118
|
@queue << {role: :system, content: out.to_s} if out.present?
|
120
119
|
end
|
121
120
|
end
|
121
|
+
@worker.finish()
|
122
122
|
iterate! if can_iterate?
|
123
123
|
|
124
124
|
# tool = @tools.select{|t| t.class.tool_name == @worker.external_call[:class] && t.respond_to?(@worker.external_call[:name]) }.first
|
@@ -127,19 +127,19 @@ class OxAiWorkers::Iterator < OxAiWorkers::StateTools
|
|
127
127
|
# @queue << {role: :system, content: out.to_s} if out.present?
|
128
128
|
# iterate!
|
129
129
|
# end
|
130
|
-
elsif @result.present?
|
131
|
-
actionRequest action: @result
|
130
|
+
elsif @worker.result.present?
|
131
|
+
actionRequest action: @worker.result
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
135
|
def completeIteration
|
136
|
+
@queue = []
|
136
137
|
@worker.finish()
|
137
138
|
end
|
138
139
|
|
139
140
|
def addTask task, auto_execute: true
|
140
141
|
@tasks << task
|
141
142
|
@messages << {role: :user, content: task}
|
142
|
-
task
|
143
143
|
execute() if auto_execute
|
144
144
|
end
|
145
145
|
|
@@ -162,3 +162,21 @@ class OxAiWorkers::Iterator < OxAiWorkers::StateTools
|
|
162
162
|
end
|
163
163
|
|
164
164
|
end
|
165
|
+
|
166
|
+
# r = OxAiWorkers::Iterator.new(worker: OxAiWorkers::Request.new)
|
167
|
+
# r.addTask("сколько будет 2+2?")
|
168
|
+
# r.execute
|
169
|
+
# r.result
|
170
|
+
|
171
|
+
|
172
|
+
# @worker.append(role: "user", content: "сколько будет 2+2?")
|
173
|
+
# @worker.request!
|
174
|
+
# @worker.completed?
|
175
|
+
# @worker.result
|
176
|
+
# @worker.finish
|
177
|
+
#
|
178
|
+
# r = OxAiWorkers::Iterator.new(worker: OxAiWorkers::Request.new)
|
179
|
+
# r.role = "ты программный агент внутри моего компьютера"
|
180
|
+
# r.tools = [OxAiWorkers::Tool::Eval.new]
|
181
|
+
# r.addTask("покажи мне файлы на диске, используй код на ruby")
|
182
|
+
# r.execute
|
@@ -1,16 +1,13 @@
|
|
1
1
|
class OxAiWorkers::ModuleRequest
|
2
2
|
attr_accessor :result, :client, :messages, :model, :max_tokens, :custom_id, :temperature, :tools, :errors
|
3
3
|
attr_accessor :tool_calls_raw, :tool_calls
|
4
|
-
DEFAULT_MODEL = "gpt-4o-mini"
|
5
|
-
DEFAULT_MAX_TOKEN = 4096
|
6
|
-
DEFAULT_TEMPERATURE = 0.7
|
7
4
|
|
8
|
-
def initializeRequests(model:
|
5
|
+
def initializeRequests(model: nil, max_tokens: nil, temperature: nil)
|
9
6
|
puts "call: ModuleRequest::#{__method__}"
|
10
|
-
@max_tokens = max_tokens
|
7
|
+
@max_tokens = max_tokens || OxAiWorkers.configuration.max_tokens
|
11
8
|
@custom_id = SecureRandom.uuid
|
12
|
-
@model = model
|
13
|
-
@temperature = temperature
|
9
|
+
@model = model || OxAiWorkers.configuration.model
|
10
|
+
@temperature = temperature || OxAiWorkers.configuration.temperature
|
14
11
|
@client = nil
|
15
12
|
|
16
13
|
OxAiWorkers.configuration.access_token ||= ENV["OPENAI"]
|
@@ -31,6 +28,8 @@ class OxAiWorkers::ModuleRequest
|
|
31
28
|
@result = nil
|
32
29
|
@errors = nil
|
33
30
|
@messages = []
|
31
|
+
@tool_calls = nil
|
32
|
+
@tool_calls_raw = nil
|
34
33
|
end
|
35
34
|
|
36
35
|
def append role: nil, content: nil, messages: nil
|
data/lib/oxaiworkers/request.rb
CHANGED
data/lib/oxaiworkers/version.rb
CHANGED
data/locales/en.system.yml
CHANGED
@@ -14,14 +14,12 @@ en:
|
|
14
14
|
description: "Save facts, nuances, and actions before clearing messages"
|
15
15
|
text: "Listing important facts and nuances"
|
16
16
|
monologue:
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
- "Step 3.1: Save facts, nuances, and actions using the packHistory function."
|
24
|
-
- "Step 4: Conclude the work with the actionRequest function, without repeating the response if it was already given with outerVoice."
|
17
|
+
- "Step 1: Develop your own solution to the problem. Take initiative and make assumptions."
|
18
|
+
- "Step 1.1: Wrap all your work for this step in the innerMonologue function."
|
19
|
+
- "Step 2: Relate your solution to the task, improve it, and call the necessary functions step by step."
|
20
|
+
- "Step 2.1: Interact with the user using the outerVoice and actionRequest functions during the process."
|
21
|
+
- "Step 3: When the solution is ready, report it using the outerVoice function."
|
22
|
+
- "Step 4: Save facts, nuances, and actions using the packHistory function."
|
25
23
|
tool:
|
26
24
|
eval:
|
27
25
|
ruby:
|
data/locales/ru.system.yml
CHANGED
@@ -19,8 +19,7 @@ ru:
|
|
19
19
|
- Шаг 2. Соотнеси свое решение с задачей, улучшай его и вызывай необходимые функции шаг за шагом.
|
20
20
|
- Шаг 2.1. Во время работы используй функции outerVoice и actionRequest.
|
21
21
|
- Шаг 3. Когда решение готово, сообщи о нем с помощью функции outerVoice.
|
22
|
-
- Шаг
|
23
|
-
- Шаг 4. Заверши работу с помощью функции actionRequest, не повторяя ответ, если он уже был дан.
|
22
|
+
- Шаг 4. Сохрани факты, нюансы и действия с помощью функции packHistory.
|
24
23
|
tool:
|
25
24
|
eval:
|
26
25
|
ruby:
|