ox-ai-workers 0.5.1 → 0.5.3
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 +13 -4
- data/README.md +13 -44
- data/lib/ox-ai-workers.rb +12 -1
- data/lib/oxaiworkers/assistant/coder.rb +4 -4
- data/lib/oxaiworkers/assistant/localizer.rb +25 -0
- data/lib/oxaiworkers/assistant/sysop.rb +4 -4
- data/lib/oxaiworkers/contextual_logger.rb +60 -0
- data/lib/oxaiworkers/delayed_request.rb +1 -1
- data/lib/oxaiworkers/iterator.rb +10 -24
- data/lib/oxaiworkers/module_request.rb +0 -3
- data/lib/oxaiworkers/request.rb +1 -3
- data/lib/oxaiworkers/state_batch.rb +0 -5
- data/lib/oxaiworkers/state_helper.rb +1 -1
- data/lib/oxaiworkers/tool/database.rb +3 -2
- data/lib/oxaiworkers/tool/eval.rb +3 -2
- data/lib/oxaiworkers/tool/file_system.rb +3 -3
- data/lib/oxaiworkers/version.rb +1 -1
- data/locales/en.assistant.yml +5 -1
- data/locales/en.iterator.yml +14 -14
- data/locales/ru.assistant.yml +4 -0
- data/locales/ru.iterator.yml +13 -13
- data/template/my_assistant.rb +5 -5
- data/template/start +2 -0
- data/template/tools/my_tool.rb +1 -1
- metadata +13 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b83e9d2c4e62f4e457a1cb4cf041da04bb0af0abb324bc6138ffa528b39a9a0b
|
4
|
+
data.tar.gz: fc6ee779728aebe0507d58a576968f5f8f4c1c57da8863d95d78420fe7616ff8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a6395486f158fb8a8f1ed302e2fe17484a551426a050448f0112fb851457afcb0c3a11523ec1a6d70f4bf02c2b7b884744d0926b16d2ce4cd53a0b6e74f576f
|
7
|
+
data.tar.gz: cb6532ed38d70d74a5c50526324b00e33514d524ac222921015fc3695c83952b3a219603c5b27890089f71f26f33a65ed0498e2c740fb2357e6abb5701bb0ac4
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.5.3] - 2024-07-31
|
4
|
+
|
5
|
+
- Fixed summarize state
|
6
|
+
|
7
|
+
## [0.5.2] - 2024-07-31
|
8
|
+
|
9
|
+
- Added new assistant: `Localizer`
|
10
|
+
- Added logger
|
11
|
+
|
3
12
|
## [0.5.1] - 2024-07-30
|
4
13
|
|
5
14
|
- Improved FileSystem functionality
|
@@ -27,10 +36,10 @@
|
|
27
36
|
|
28
37
|
## [0.3.0] - 2024-07-30
|
29
38
|
|
30
|
-
- on_inner_monologue: ->(text:) { puts
|
31
|
-
- on_outer_voice: ->(text:) { puts
|
32
|
-
- on_action_request: ->(text:) { puts
|
33
|
-
- on_pack_history: ->(text:) { puts
|
39
|
+
- on_inner_monologue: ->(text:) { puts "monologue: #{text}" }
|
40
|
+
- on_outer_voice: ->(text:) { puts "voice: #{text}" }
|
41
|
+
- on_action_request: ->(text:) { puts "action: #{text}" }
|
42
|
+
- on_pack_history: ->(text:) { puts "summary: #{text}" }
|
34
43
|
|
35
44
|
## [0.2.5] - 2024-07-30
|
36
45
|
|
data/README.md
CHANGED
@@ -111,10 +111,10 @@ iterator = OxAiWorkers::Iterator.new(
|
|
111
111
|
worker: my_worker,
|
112
112
|
tools: [my_tool],
|
113
113
|
role: "You are a software agent inside my computer",
|
114
|
-
on_inner_monologue: ->(text:) { puts
|
115
|
-
on_outer_voice: ->(text:) { puts
|
116
|
-
on_action_request: ->(text:) { puts
|
117
|
-
on_pack_history: ->(text:) { puts
|
114
|
+
on_inner_monologue: ->(text:) { puts "monologue: #{text}".colorize(:yellow) },
|
115
|
+
on_outer_voice: ->(text:) { puts "voice: #{text}".colorize(:green) },
|
116
|
+
on_action_request: ->(text:) { puts "action: #{text}".colorize(:red) },
|
117
|
+
on_pack_history: ->(text:) { puts "summary: #{text}".colorize(:blue) }
|
118
118
|
)
|
119
119
|
|
120
120
|
iterator.add_task("Show files in current directory.")
|
@@ -158,6 +158,15 @@ After this, in the `my_assistant.rb` file, you can find an example of an assista
|
|
158
158
|
.oxaiworkers-local/start
|
159
159
|
```
|
160
160
|
|
161
|
+
## Logging
|
162
|
+
|
163
|
+
OxAiWorkers uses standard logging mechanisms and defaults to `:warn` level. Most messages are at info level, but we will add debug or warn statements as needed.
|
164
|
+
To show all log messages:
|
165
|
+
|
166
|
+
```ruby
|
167
|
+
OxAiWorkers.logger.level = :debug
|
168
|
+
```
|
169
|
+
|
161
170
|
## Features
|
162
171
|
|
163
172
|
- **Generative Intelligence**: Leverages OpenAI's capabilities to enhance task execution.
|
@@ -165,46 +174,6 @@ After this, in the `my_assistant.rb` file, you can find an example of an assista
|
|
165
174
|
- **External Tools**: Integrates with external tools and services to complete tasks.
|
166
175
|
- **Finite State Machine**: Implements a robust state machine to manage task states and transitions.
|
167
176
|
|
168
|
-
## Configuration
|
169
|
-
|
170
|
-
OxAiWorkers uses YAML files for configuration. Below is an example configuration:
|
171
|
-
|
172
|
-
```yaml
|
173
|
-
en:
|
174
|
-
oxaiworkers:
|
175
|
-
iterator:
|
176
|
-
inner_monologue:
|
177
|
-
description: "Use inner monologue to plan the response and articulate main points"
|
178
|
-
speech: "Text"
|
179
|
-
outer_voice:
|
180
|
-
description: "Provide the user with necessary information without expecting a response"
|
181
|
-
text: "Text"
|
182
|
-
action_request:
|
183
|
-
description: "Ask a clarifying question or request an action with a response from the user"
|
184
|
-
action: "Text"
|
185
|
-
pack_history:
|
186
|
-
description: "Save facts, nuances, and actions before clearing messages"
|
187
|
-
text: "Listing important facts and nuances"
|
188
|
-
monologue:
|
189
|
-
- "Step 1: Develop your own solution to the problem. Take initiative and make assumptions."
|
190
|
-
- "Step 1.1: Wrap all your work for this step in the inner_monologue function."
|
191
|
-
- "Step 2: Relate your solution to the task, improve it, and call the necessary functions step by step."
|
192
|
-
- "Step 2.1: Interact with the user using the outer_voice and action_request functions during the process."
|
193
|
-
- "Step 3: When the solution is ready, report it using the outer_voice function."
|
194
|
-
- "Step 4: Save facts, nuances, and actions using the summarize function."
|
195
|
-
tool:
|
196
|
-
eval:
|
197
|
-
ruby:
|
198
|
-
description: "Execute Ruby code and return the result of the last expression"
|
199
|
-
input: "Ruby source code"
|
200
|
-
sh:
|
201
|
-
description: "Execute a sh command and get the result (stdout + stderr)"
|
202
|
-
input: "Source command"
|
203
|
-
assistant:
|
204
|
-
sysop:
|
205
|
-
role: "You are a software agent inside my computer"
|
206
|
-
```
|
207
|
-
|
208
177
|
## Contributing
|
209
178
|
|
210
179
|
Bug reports and pull requests are welcome on GitHub at https://github.com/neonix20b/ox-ai-workers. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/neonix20b/ox-ai-workers/blob/main/CODE_OF_CONDUCT.md).
|
data/lib/ox-ai-workers.rb
CHANGED
@@ -2,12 +2,13 @@
|
|
2
2
|
|
3
3
|
require 'faraday'
|
4
4
|
require 'faraday/multipart'
|
5
|
-
require '
|
5
|
+
require 'colorize'
|
6
6
|
require 'openai'
|
7
7
|
require 'yaml'
|
8
8
|
require 'json'
|
9
9
|
|
10
10
|
require_relative 'oxaiworkers/version'
|
11
|
+
require_relative 'oxaiworkers/contextual_logger'
|
11
12
|
require_relative 'oxaiworkers/load_i18n'
|
12
13
|
require_relative 'oxaiworkers/present_compat'
|
13
14
|
require_relative 'oxaiworkers/module_request'
|
@@ -27,6 +28,7 @@ require_relative 'oxaiworkers/tool/file_system'
|
|
27
28
|
require_relative 'oxaiworkers/assistant/module_base'
|
28
29
|
require_relative 'oxaiworkers/assistant/sysop'
|
29
30
|
require_relative 'oxaiworkers/assistant/coder'
|
31
|
+
require_relative 'oxaiworkers/assistant/localizer'
|
30
32
|
|
31
33
|
module OxAiWorkers
|
32
34
|
DEFAULT_MODEL = 'gpt-4o-mini'
|
@@ -54,8 +56,17 @@ module OxAiWorkers
|
|
54
56
|
|
55
57
|
class << self
|
56
58
|
attr_writer :configuration
|
59
|
+
attr_reader :logger
|
60
|
+
|
61
|
+
# @param logger [Logger]
|
62
|
+
# @return [ContextualLogger]
|
63
|
+
def logger=(logger)
|
64
|
+
@logger = ContextualLogger.new(logger)
|
65
|
+
end
|
57
66
|
end
|
58
67
|
|
68
|
+
self.logger ||= ::Logger.new($stdout, level: :info)
|
69
|
+
|
59
70
|
def self.configuration
|
60
71
|
@configuration ||= OxAiWorkers::Configuration.new
|
61
72
|
end
|
@@ -10,10 +10,10 @@ module OxAiWorkers
|
|
10
10
|
worker: init_worker(delayed: delayed, model: model),
|
11
11
|
role: format(I18n.t('oxaiworkers.assistant.coder.role'), language),
|
12
12
|
tools: [Tool::Eval.new, Tool::FileSystem.new],
|
13
|
-
on_inner_monologue: ->(text:) { puts
|
14
|
-
on_outer_voice: ->(text:) { puts
|
15
|
-
on_action_request: ->(text:) { puts
|
16
|
-
on_pack_history: ->(text:) { puts
|
13
|
+
on_inner_monologue: ->(text:) { puts "monologue: #{text}".colorize(:yellow) },
|
14
|
+
on_outer_voice: ->(text:) { puts "voice: #{text}".colorize(:green) },
|
15
|
+
on_action_request: ->(text:) { puts "action: #{text}".colorize(:red) },
|
16
|
+
on_pack_history: ->(text:) { puts "summary: #{text}".colorize(:blue) }
|
17
17
|
)
|
18
18
|
end
|
19
19
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OxAiWorkers
|
4
|
+
module Assistant
|
5
|
+
class Localizer
|
6
|
+
include OxAiWorkers::Assistant::ModuleBase
|
7
|
+
|
8
|
+
def initialize(delayed: false, model: nil, language: 'русский', locale: :ru, source: 'english')
|
9
|
+
@iterator = Iterator.new(
|
10
|
+
worker: init_worker(delayed: delayed, model: model),
|
11
|
+
role: format(I18n.t('oxaiworkers.assistant.localizer.role'), language),
|
12
|
+
tools: [Tool::Eval.new, Tool::FileSystem.new],
|
13
|
+
on_inner_monologue: ->(text:) { puts "monologue: #{text}".colorize(:yellow) },
|
14
|
+
on_outer_voice: ->(text:) { puts "voice: #{text}".colorize(:green) },
|
15
|
+
on_action_request: ->(text:) { puts "action: #{text}".colorize(:red) },
|
16
|
+
on_pack_history: ->(text:) { puts "summary: #{text}".colorize(:blue) }
|
17
|
+
)
|
18
|
+
@iterator.add_context(format(I18n.t('oxaiworkers.assistant.localizer.source'), source))
|
19
|
+
|
20
|
+
@iterator.add_context(format(I18n.t('oxaiworkers.assistant.localizer.locale'),
|
21
|
+
language, locale))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -10,10 +10,10 @@ module OxAiWorkers
|
|
10
10
|
worker: init_worker(delayed: delayed, model: model),
|
11
11
|
role: I18n.t('oxaiworkers.assistant.sysop.role'),
|
12
12
|
tools: [Tool::Eval.new],
|
13
|
-
on_inner_monologue: ->(text:) { puts
|
14
|
-
on_outer_voice: ->(text:) { puts
|
15
|
-
on_action_request: ->(text:) { puts
|
16
|
-
on_pack_history: ->(text:) { puts
|
13
|
+
on_inner_monologue: ->(text:) { puts "monologue: #{text}".colorize(:yellow) },
|
14
|
+
on_outer_voice: ->(text:) { puts "voice: #{text}".colorize(:green) },
|
15
|
+
on_action_request: ->(text:) { puts "action: #{text}".colorize(:red) },
|
16
|
+
on_pack_history: ->(text:) { puts "summary: #{text}".colorize(:blue) }
|
17
17
|
)
|
18
18
|
end
|
19
19
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OxAiWorkers
|
4
|
+
class ContextualLogger
|
5
|
+
MESSAGE_COLOR_OPTIONS = {
|
6
|
+
debug: {
|
7
|
+
color: :white
|
8
|
+
},
|
9
|
+
error: {
|
10
|
+
color: :red
|
11
|
+
},
|
12
|
+
fatal: {
|
13
|
+
color: :red,
|
14
|
+
background: :white,
|
15
|
+
mode: :bold
|
16
|
+
},
|
17
|
+
unknown: {
|
18
|
+
color: :white
|
19
|
+
},
|
20
|
+
info: {
|
21
|
+
color: :magenta
|
22
|
+
},
|
23
|
+
warn: {
|
24
|
+
color: :yellow,
|
25
|
+
mode: :bold
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
def initialize(logger)
|
30
|
+
@logger = logger
|
31
|
+
@levels = Logger::Severity.constants.map(&:downcase)
|
32
|
+
end
|
33
|
+
|
34
|
+
def respond_to_missing?(method, include_private = false)
|
35
|
+
@logger.respond_to?(method, include_private)
|
36
|
+
end
|
37
|
+
|
38
|
+
def method_missing(method, *args, **kwargs, &block)
|
39
|
+
return @logger.send(method, *args, **kwargs, &block) unless @levels.include?(method)
|
40
|
+
|
41
|
+
for_class = kwargs.delete(:for)
|
42
|
+
for_class_name = for_class&.name
|
43
|
+
|
44
|
+
log_line_parts = []
|
45
|
+
log_line_parts << '[OxAiWorkers]' # .colorize(color: :yellow)
|
46
|
+
log_line_parts << if for_class.respond_to?(:logger_options)
|
47
|
+
"#{"[#{for_class_name}]".colorize(for_class.logger_options)}:"
|
48
|
+
elsif for_class_name
|
49
|
+
"[#{for_class_name}]:"
|
50
|
+
end
|
51
|
+
log_line_parts << args.first.colorize(MESSAGE_COLOR_OPTIONS[method])
|
52
|
+
log_line = log_line_parts.compact.join(' ')
|
53
|
+
|
54
|
+
@logger.send(
|
55
|
+
method,
|
56
|
+
log_line
|
57
|
+
)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/oxaiworkers/iterator.rb
CHANGED
@@ -26,7 +26,6 @@ module OxAiWorkers
|
|
26
26
|
|
27
27
|
def initialize(worker:, role: nil, tools: [], on_inner_monologue: nil, on_outer_voice: nil, on_action_request: nil,
|
28
28
|
on_pack_history: nil)
|
29
|
-
puts "call: #{__method__}"
|
30
29
|
@worker = worker
|
31
30
|
@tools = [self] + tools
|
32
31
|
@role = role
|
@@ -54,14 +53,14 @@ module OxAiWorkers
|
|
54
53
|
|
55
54
|
def inner_monologue(speach:)
|
56
55
|
# @queue.pop
|
57
|
-
@queue << { role: :
|
56
|
+
@queue << { role: :assistant, content: speach.to_s }
|
58
57
|
@on_inner_monologue&.call(text: speach)
|
59
58
|
nil
|
60
59
|
end
|
61
60
|
|
62
61
|
def outer_voice(text:)
|
63
62
|
# @queue.pop
|
64
|
-
@queue << { role: :
|
63
|
+
@queue << { role: :assistant, content: text.to_s }
|
65
64
|
@on_outer_voice&.call(text: text)
|
66
65
|
nil
|
67
66
|
end
|
@@ -69,7 +68,7 @@ module OxAiWorkers
|
|
69
68
|
def action_request(action:)
|
70
69
|
@result = action
|
71
70
|
# @queue.pop
|
72
|
-
@messages << { role: :
|
71
|
+
@messages << { role: :assistant, content: action.to_s }
|
73
72
|
complete! if can_complete?
|
74
73
|
@on_action_request&.call(text: action)
|
75
74
|
nil
|
@@ -78,6 +77,7 @@ module OxAiWorkers
|
|
78
77
|
def summarize(text:)
|
79
78
|
@milestones << text.to_s
|
80
79
|
@messages = []
|
80
|
+
@queue << { role: :assistant, content: I18n.t('oxaiworkers.iterator.pack_history.result') }
|
81
81
|
@worker.finish
|
82
82
|
rebuild_worker
|
83
83
|
# complete! if can_complete?
|
@@ -86,24 +86,22 @@ module OxAiWorkers
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def init
|
89
|
-
puts "call: #{__method__} state: #{state_name}"
|
90
89
|
rebuild_worker
|
91
90
|
request!
|
92
91
|
end
|
93
92
|
|
94
93
|
def rebuild_worker
|
95
94
|
@worker.messages = []
|
96
|
-
@worker.append(role: :system, content: @role) if
|
95
|
+
@worker.append(role: :system, content: @role) if @role.present?
|
97
96
|
@worker.append(role: :system, content: @monologue.join("\n"))
|
98
|
-
@worker.append(messages: @context) if
|
97
|
+
@worker.append(messages: @context) if @context.present?
|
99
98
|
@tasks.each { |task| @worker.append(role: :user, content: task) }
|
100
|
-
@milestones.each { |milestone| @worker.append(role: :
|
99
|
+
@milestones.each { |milestone| @worker.append(role: :assistant, content: milestone) }
|
101
100
|
@worker.append(messages: @messages)
|
102
|
-
@worker.tools = @tools.map { |tool| tool.class.function_schemas.to_openai_format }.flatten if @tools.
|
101
|
+
@worker.tools = @tools.map { |tool| tool.class.function_schemas.to_openai_format }.flatten if @tools.present?
|
103
102
|
end
|
104
103
|
|
105
104
|
def next_iteration
|
106
|
-
puts "call: #{__method__} state: #{state_name}"
|
107
105
|
@worker.append(messages: @queue)
|
108
106
|
@messages += @queue
|
109
107
|
@queue = []
|
@@ -111,19 +109,16 @@ module OxAiWorkers
|
|
111
109
|
end
|
112
110
|
|
113
111
|
def external_request
|
114
|
-
puts "call: #{__method__} state: #{state_name}"
|
115
112
|
@worker.request!
|
116
113
|
ticker
|
117
114
|
end
|
118
115
|
|
119
116
|
def ticker
|
120
|
-
puts "call: #{__method__} state: #{state_name}"
|
121
117
|
sleep(60) until @worker.completed?
|
122
118
|
analyze!
|
123
119
|
end
|
124
120
|
|
125
121
|
def process_result(_transition)
|
126
|
-
puts "call: #{__method__} state: #{state_name}"
|
127
122
|
@result = @worker.result || @worker.errors
|
128
123
|
if @worker.tool_calls.present?
|
129
124
|
@queue << { role: :assistant, content: @worker.tool_calls_raw.to_s }
|
@@ -133,18 +128,11 @@ module OxAiWorkers
|
|
133
128
|
end.first
|
134
129
|
unless tool.nil?
|
135
130
|
out = tool.send(external_call[:name], **external_call[:args])
|
136
|
-
@queue << { role: :
|
131
|
+
@queue << { role: :user, content: out.to_s } if out.present?
|
137
132
|
end
|
138
133
|
end
|
139
134
|
@worker.finish
|
140
135
|
iterate! if can_iterate?
|
141
|
-
|
142
|
-
# tool = @tools.select{|t| t.class.tool_name == @worker.external_call[:class] && t.respond_to?(@worker.external_call[:name]) }.first
|
143
|
-
# out = tool.send(@worker.external_call[:name], **@worker.external_call[:args])
|
144
|
-
# if can_iterate?
|
145
|
-
# @queue << {role: :system, content: out.to_s} if out.present?
|
146
|
-
# iterate!
|
147
|
-
# end
|
148
136
|
elsif @worker.result.present?
|
149
137
|
action_request action: @worker.result
|
150
138
|
end
|
@@ -161,17 +149,15 @@ module OxAiWorkers
|
|
161
149
|
execute if auto_execute
|
162
150
|
end
|
163
151
|
|
164
|
-
def
|
152
|
+
def add_context(text, role: :system)
|
165
153
|
@context << { role: role, content: text }
|
166
154
|
end
|
167
155
|
|
168
156
|
def execute
|
169
|
-
puts "call: #{__method__} state: #{state_name}"
|
170
157
|
prepare! if valid?
|
171
158
|
end
|
172
159
|
|
173
160
|
def cancel
|
174
|
-
puts "call: #{__method__} state: #{state_name}"
|
175
161
|
@worker.cancel if @worker.respond_to?(:cancel)
|
176
162
|
end
|
177
163
|
|
@@ -6,7 +6,6 @@ module OxAiWorkers
|
|
6
6
|
:tool_calls_raw, :tool_calls
|
7
7
|
|
8
8
|
def initialize_requests(model: nil, max_tokens: nil, temperature: nil)
|
9
|
-
# puts "call: ModuleRequest::#{__method__}"
|
10
9
|
@max_tokens = max_tokens || OxAiWorkers.configuration.max_tokens
|
11
10
|
@custom_id = SecureRandom.uuid
|
12
11
|
@model = model || OxAiWorkers.configuration.model
|
@@ -23,7 +22,6 @@ module OxAiWorkers
|
|
23
22
|
end
|
24
23
|
|
25
24
|
def cleanup
|
26
|
-
# puts "call: ModuleRequest::#{__method__}"
|
27
25
|
@client ||= OpenAI::Client.new(
|
28
26
|
access_token: OxAiWorkers.configuration.access_token,
|
29
27
|
log_errors: true # Highly recommended in development, so you can see what errors OpenAI is returning. Not recommended in production because it could leak private data to your logs.
|
@@ -61,7 +59,6 @@ module OxAiWorkers
|
|
61
59
|
end
|
62
60
|
|
63
61
|
def parse_choices(response)
|
64
|
-
# puts response.inspect
|
65
62
|
@tool_calls = []
|
66
63
|
@result = response.dig('choices', 0, 'message', 'content')
|
67
64
|
@tool_calls_raw = response.dig('choices', 0, 'message', 'tool_calls')
|
data/lib/oxaiworkers/request.rb
CHANGED
@@ -12,10 +12,8 @@ module OxAiWorkers
|
|
12
12
|
def request!
|
13
13
|
response = @client.chat(parameters: params)
|
14
14
|
parse_choices(response)
|
15
|
-
# @result = response.dig("choices", 0, "message", "content")
|
16
|
-
# puts response.inspect
|
17
15
|
rescue OpenAI::Error => e
|
18
|
-
|
16
|
+
OxAiWorkers.logger.debug(e.inspect, for: self.class)
|
19
17
|
end
|
20
18
|
|
21
19
|
def completed?
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module OxAiWorkers
|
4
4
|
module StateHelper
|
5
5
|
def log_me(transition)
|
6
|
-
#
|
6
|
+
# OxAiWorkers.logger.debug("`#{transition.event}` was called to transition from :#{transition.from} to :#{transition.to}")
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
@@ -72,7 +72,7 @@ module OxAiWorkers
|
|
72
72
|
#
|
73
73
|
# @return [String] Database schema
|
74
74
|
def dump_schema
|
75
|
-
|
75
|
+
OxAiWorkers.logger.debug('Dumping schema tables and keys', for: self.class)
|
76
76
|
schema = ''
|
77
77
|
db.tables.each do |table|
|
78
78
|
describe_table(table, schema)
|
@@ -108,10 +108,11 @@ module OxAiWorkers
|
|
108
108
|
# @param input [String] SQL query to be executed
|
109
109
|
# @return [Array] Results from the SQL query
|
110
110
|
def execute(input:)
|
111
|
-
|
111
|
+
OxAiWorkers.logger.info("Executing \"#{input}\"", for: self.class)
|
112
112
|
|
113
113
|
db[input].to_a
|
114
114
|
rescue Sequel::DatabaseError => e
|
115
|
+
OxAiWorkers.logger.info(e.message, for: self.class)
|
115
116
|
e.message
|
116
117
|
end
|
117
118
|
end
|
@@ -17,18 +17,19 @@ module OxAiWorkers
|
|
17
17
|
end
|
18
18
|
|
19
19
|
# def ruby(input:)
|
20
|
-
# puts
|
20
|
+
# puts "Executing ruby: \"#{input}\"".colorize(:red)
|
21
21
|
# eval(input)
|
22
22
|
# end
|
23
23
|
|
24
24
|
def sh(input:)
|
25
|
-
|
25
|
+
OxAiWorkers.logger.info("Executing sh: \"#{input}\"", for: self.class)
|
26
26
|
begin
|
27
27
|
stdout_and_stderr_s, status = Open3.capture2e(input)
|
28
28
|
return stdout_and_stderr_s if stdout_and_stderr_s.present?
|
29
29
|
|
30
30
|
status.to_s
|
31
31
|
rescue StandardError => e
|
32
|
+
OxAiWorkers.logger.debug(e.message, for: self.class)
|
32
33
|
e.message
|
33
34
|
end
|
34
35
|
end
|
@@ -38,7 +38,7 @@ module OxAiWorkers
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def list_directory(directory_path:)
|
41
|
-
|
41
|
+
OxAiWorkers.logger.info("Listing directory: #{directory_path}", for: self.class)
|
42
42
|
list = Dir.entries(directory_path)
|
43
43
|
list.delete_if { |f| f.start_with?('.') }
|
44
44
|
if list.present?
|
@@ -51,7 +51,7 @@ module OxAiWorkers
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def read_file(file_path:)
|
54
|
-
|
54
|
+
OxAiWorkers.logger.info("Reading file: #{file_path}", for: self.class)
|
55
55
|
if File.binary?(file_path)
|
56
56
|
"File is binary: #{file_path}"
|
57
57
|
else
|
@@ -62,7 +62,7 @@ module OxAiWorkers
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def write_to_file(file_path:, content:)
|
65
|
-
|
65
|
+
OxAiWorkers.logger.info("Writing to file: #{file_path}", for: self.class)
|
66
66
|
File.write(file_path, content)
|
67
67
|
"Content was successfully written to the file: #{file_path}"
|
68
68
|
rescue Errno::EACCES
|
data/lib/oxaiworkers/version.rb
CHANGED
data/locales/en.assistant.yml
CHANGED
@@ -4,4 +4,8 @@ en:
|
|
4
4
|
sysop:
|
5
5
|
role: "You are a software agent inside my computer"
|
6
6
|
coder:
|
7
|
-
role: "You are a professional %s programmer inside my computer"
|
7
|
+
role: "You are a professional %s programmer inside my computer"
|
8
|
+
localizer:
|
9
|
+
role: "You are a professional localizer (translator) to the %s language inside my computer. Your task is to correctly localize files (create new ones in the required language based on the original) provided by the user."
|
10
|
+
source: "Use the %s language as a basis"
|
11
|
+
locale: "For the %s language, the correct locale is :%s"
|
data/locales/en.iterator.yml
CHANGED
@@ -2,21 +2,21 @@ en:
|
|
2
2
|
oxaiworkers:
|
3
3
|
iterator:
|
4
4
|
inner_monologue:
|
5
|
-
description:
|
6
|
-
|
5
|
+
description: A function for internal monologue, allowing the AI to ponder and formulate its thoughts without user involvement. Used for intermediate reflections and recording data that do not require immediate response or action from the user.
|
6
|
+
speach: Text of reflections or conclusions
|
7
7
|
outer_voice:
|
8
|
-
description:
|
9
|
-
text:
|
8
|
+
description: Inform the user of the necessary information without expecting a response.
|
9
|
+
text: Content of the message
|
10
10
|
action_request:
|
11
|
-
description:
|
12
|
-
action:
|
11
|
+
description: A function for interactive interaction with the user. Allows you to ask a clarifying question, request actions, or complete the current step. The function waits for the user's response and returns it.
|
12
|
+
action: Text of the request or action
|
13
13
|
pack_history:
|
14
|
-
description:
|
15
|
-
text:
|
14
|
+
description: The function saves key facts, nuances, and actions from previous messages, including the provided response. After calling this function, all previous messages will be deleted. Use it only after all intermediate steps are completed and when the exact content of previous messages is no longer relevant.
|
15
|
+
text: Enumeration of important facts and nuances
|
16
|
+
result: Messages deleted
|
16
17
|
monologue:
|
17
|
-
-
|
18
|
-
-
|
19
|
-
-
|
20
|
-
-
|
21
|
-
-
|
22
|
-
- "Step 4: Save facts, nuances, and actions using the ox_ai_workers_iterator__summarize function."
|
18
|
+
- Step 1. Develop your own solution to the problem, taking initiative and making assumptions.
|
19
|
+
- Step 2. Enclose all your developments from the previous step in the ox_ai_workers_iterator__inner_monologue function.
|
20
|
+
- Step 3. Call the necessary functions one after another until the desired result is achieved.
|
21
|
+
- Step 4. When all intermediate steps are completed and the exact content of previous messages is no longer relevant, use the ox_ai_workers_iterator__pack_history function.
|
22
|
+
- Step 5. When the solution is ready, notify about it and wait for the user's response.
|
data/locales/ru.assistant.yml
CHANGED
@@ -5,3 +5,7 @@ ru:
|
|
5
5
|
role: Ты программный агент внутри моего компьютера
|
6
6
|
coder:
|
7
7
|
role: "Ты профессиональный программист на %s внутри моего компьютера"
|
8
|
+
localizer:
|
9
|
+
role: "Ты профессиональный локализатор (переводчик) на %s язык внутри моего компьютера. Твоя задача корректно локализовать файлы (создать по аналогии новые на нужном языке), которые предоставит пользователь."
|
10
|
+
source: "Возьми за основу %s язык"
|
11
|
+
locale: "%s язык имеет локаль :%s"
|
data/locales/ru.iterator.yml
CHANGED
@@ -2,21 +2,21 @@ ru:
|
|
2
2
|
oxaiworkers:
|
3
3
|
iterator:
|
4
4
|
inner_monologue:
|
5
|
-
description:
|
6
|
-
speach: Текст
|
5
|
+
description: Функция для внутреннего монолога, позволяющая ИИ обдумывать и формулировать свои мысли без участия пользователя. Используется для промежуточных размышлений и фиксации данных, которые не требуют немедленного ответа или действия от пользователя.
|
6
|
+
speach: Текст размышлений или выводов
|
7
7
|
outer_voice:
|
8
|
-
description: Сообщить пользователю необходимую информацию без ожидания
|
9
|
-
text:
|
8
|
+
description: Сообщить пользователю необходимую информацию без ожидания ответа.
|
9
|
+
text: Содержимое сообщения
|
10
10
|
action_request:
|
11
|
-
description:
|
12
|
-
action: Текст
|
11
|
+
description: Функция для интерактивного взаимодействия с пользователем. Позволяет задать уточняющий вопрос, запросить выполнение действий или завершить текущий шаг. Функция ожидает ответ пользователя и возвращает его.
|
12
|
+
action: Текст запроса или действия
|
13
13
|
pack_history:
|
14
|
-
description:
|
14
|
+
description: Функция сохраняет ключевые факты, нюансы и действия из предыдущих сообщений, включая предоставленный ответ. После вызова этой функции все предыдущие сообщения будут удалены. Используйте её только после завершения всех промежуточных шагов и когда точное содержание предыдущих сообщений больше не имеет значения.
|
15
15
|
text: Перечисление важных фактов и нюансов
|
16
|
+
result: Сообщения удалены
|
16
17
|
monologue:
|
17
|
-
- Шаг 1. Разработай собственное решение
|
18
|
-
- Шаг
|
19
|
-
- Шаг
|
20
|
-
- Шаг
|
21
|
-
- Шаг
|
22
|
-
- Шаг 4. Сохрани факты, нюансы и действия с помощью функции ox_ai_workers_iterator__summarize и предложи дальнейшие действия с помощью функции ox_ai_workers_iterator__action_request.
|
18
|
+
- Шаг 1. Разработай собственное решение проблемы, проявляя инициативу и делая предположения.
|
19
|
+
- Шаг 2. Заключи все свои наработки из предыдущего шага в функцию ox_ai_workers_iterator__inner_monologue.
|
20
|
+
- Шаг 3. Вызывай необходимые функции друг за другом, пока желаемый результат не будет достигнут.
|
21
|
+
- Шаг 4. Когда все промежуточные шаги завершены и точное содержание предыдущих сообщений больше не имеет значения, используй функцию ox_ai_workers_iterator__pack_history.
|
22
|
+
- Шаг 5. Когда решение готово, сообщи об этом и ожидай ответ пользователя.
|
data/template/my_assistant.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'colorize'
|
4
4
|
require_relative 'tools/my_tool'
|
5
5
|
|
6
6
|
class MyAssistant
|
@@ -11,10 +11,10 @@ class MyAssistant
|
|
11
11
|
worker: init_worker(delayed: delayed, model: model),
|
12
12
|
role: 'You are a software agent inside my computer',
|
13
13
|
tools: [MyTool.new],
|
14
|
-
on_inner_monologue: ->(text:) { puts
|
15
|
-
on_outer_voice: ->(text:) { puts
|
16
|
-
on_action_request: ->(text:) { puts
|
17
|
-
on_pack_history: ->(text:) { puts
|
14
|
+
on_inner_monologue: ->(text:) { puts "monologue: #{text}".colorize(:yellow) },
|
15
|
+
on_outer_voice: ->(text:) { puts "voice: #{text}".colorize(:green) },
|
16
|
+
on_action_request: ->(text:) { puts "action: #{text}".colorize(:red) },
|
17
|
+
on_pack_history: ->(text:) { puts "summary: #{text}".colorize(:blue) }
|
18
18
|
)
|
19
19
|
end
|
20
20
|
end
|
data/template/start
CHANGED
data/template/tools/my_tool.rb
CHANGED
metadata
CHANGED
@@ -1,31 +1,31 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ox-ai-workers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Smolev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-07-
|
11
|
+
date: 2024-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: colorize
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: faraday
|
28
|
+
name: faraday
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: faraday-multipart
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: i18n
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,19 +67,19 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: ptools
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '1'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '1'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: ruby-openai
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -135,9 +135,11 @@ files:
|
|
135
135
|
- exe/start
|
136
136
|
- lib/ox-ai-workers.rb
|
137
137
|
- lib/oxaiworkers/assistant/coder.rb
|
138
|
+
- lib/oxaiworkers/assistant/localizer.rb
|
138
139
|
- lib/oxaiworkers/assistant/module_base.rb
|
139
140
|
- lib/oxaiworkers/assistant/sysop.rb
|
140
141
|
- lib/oxaiworkers/compatibility.rb
|
142
|
+
- lib/oxaiworkers/contextual_logger.rb
|
141
143
|
- lib/oxaiworkers/delayed_request.rb
|
142
144
|
- lib/oxaiworkers/dependency_helper.rb
|
143
145
|
- lib/oxaiworkers/iterator.rb
|