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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b3d80806db64371193199ae3e0731060a156fd08398628e68fdd0bae2fa459c
4
- data.tar.gz: bd70e01c89c093a85b2f32cf62b6de0826fff868378721e4203bfbc732998a63
3
+ metadata.gz: b83e9d2c4e62f4e457a1cb4cf041da04bb0af0abb324bc6138ffa528b39a9a0b
4
+ data.tar.gz: fc6ee779728aebe0507d58a576968f5f8f4c1c57da8863d95d78420fe7616ff8
5
5
  SHA512:
6
- metadata.gz: 796005900f27745768ec4cb9467937aaad3cb2dd2cad6d76e8ae3fa1a0da29a32c596de8456d491b3c7fadfc2db9324369befbf120ceddfc1224bbb53cdba05b
7
- data.tar.gz: 8d1fcf58fbaf734dab49276bec6fdd6f8aabddbe187c0a97495fe1ca767e5dfcdd09eb56069bfc3574712941fe3e7d77a1b2420ca7b294ef2a701b4d7deb1e5b
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 Rainbow("monologue: #{text}").yellow }
31
- - on_outer_voice: ->(text:) { puts Rainbow("voice: #{text}").green }
32
- - on_action_request: ->(text:) { puts Rainbow("action: #{text}").red }
33
- - on_pack_history: ->(text:) { puts Rainbow("summary: #{text}").blue }
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 Rainbow("monologue: #{text}").yellow },
115
- on_outer_voice: ->(text:) { puts Rainbow("voice: #{text}").green },
116
- on_action_request: ->(text:) { puts Rainbow("action: #{text}").red },
117
- on_pack_history: ->(text:) { puts Rainbow("summary: #{text}").blue }
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 'rainbow'
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 Rainbow("monologue: #{text}").yellow },
14
- on_outer_voice: ->(text:) { puts Rainbow("voice: #{text}").green },
15
- on_action_request: ->(text:) { puts Rainbow("action: #{text}").red },
16
- on_pack_history: ->(text:) { puts Rainbow("summary: #{text}").blue }
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 Rainbow("monologue: #{text}").yellow },
14
- on_outer_voice: ->(text:) { puts Rainbow("voice: #{text}").green },
15
- on_action_request: ->(text:) { puts Rainbow("action: #{text}").red },
16
- on_pack_history: ->(text:) { puts Rainbow("summary: #{text}").blue }
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
@@ -65,7 +65,7 @@ module OxAiWorkers
65
65
  @file_id = response['id']
66
66
  process_batch!
67
67
  rescue OpenAI::Error => e
68
- puts e.inspect
68
+ OxAiWorkers.logger.debug(e.inspect, for: self.class)
69
69
  fail_batch!
70
70
  end
71
71
  file.unlink
@@ -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: :system, content: speach.to_s }
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: :system, content: text.to_s }
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: :system, content: action.to_s }
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 !@role.nil? && @role.present?
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 !@context.nil? and @context.any?
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: :system, content: milestone) }
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.any?
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: :system, content: out.to_s } if out.present?
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 append_context(text, role: :system)
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')
@@ -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
- puts e.inspect
16
+ OxAiWorkers.logger.debug(e.inspect, for: self.class)
19
17
  end
20
18
 
21
19
  def completed?
@@ -56,10 +56,5 @@ module OxAiWorkers
56
56
  @batch_id = nil
57
57
  super()
58
58
  end
59
-
60
- def initialize
61
- puts "call: StateBatch::#{__method__}"
62
- super()
63
- end
64
59
  end
65
60
  end
@@ -3,7 +3,7 @@
3
3
  module OxAiWorkers
4
4
  module StateHelper
5
5
  def log_me(transition)
6
- # puts "`#{transition.event}` was called to transition from :#{transition.from} to :#{transition.to}"
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
- puts('Dumping schema tables and keys', for: self.class)
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
- puts("Executing \"#{input}\"", for: self.class)
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 Rainbow("Executing ruby: \"#{input}\"").red
20
+ # puts "Executing ruby: \"#{input}\"".colorize(:red)
21
21
  # eval(input)
22
22
  # end
23
23
 
24
24
  def sh(input:)
25
- puts Rainbow("Executing sh: \"#{input}\"").red
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
- puts Rainbow("Listing directory: #{directory_path}").magenta
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
- puts Rainbow("Reading file: #{file_path}").magenta
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
- puts Rainbow("Writing to file: #{file_path}").magenta
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OxAiWorkers
4
- VERSION = '0.5.1'
4
+ VERSION = '0.5.3'
5
5
  end
@@ -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"
@@ -2,21 +2,21 @@ en:
2
2
  oxaiworkers:
3
3
  iterator:
4
4
  inner_monologue:
5
- description: "Use inner monologue to plan the response and articulate main points"
6
- speech: "Text"
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: "Provide the user with necessary information without expecting a response"
9
- text: "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: "Ask a clarifying question or request an action with a response from the user"
12
- action: "Text"
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: "Save facts, nuances, and actions before clearing messages"
15
- text: "Listing important facts and nuances"
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
- - "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 ox_ai_workers_iterator__inner_monologue 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 ox_ai_workers_iterator__outer_voice and ox_ai_workers_iterator__action_request functions during the process."
21
- - "Step 3: When the solution is ready, report it using the ox_ai_workers_iterator__outer_voice function."
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.
@@ -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"
@@ -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
- - Шаг 1.1. Заключи все свои наработки для этого шага в функцию ox_ai_workers_iterator__inner_monologue.
19
- - Шаг 2. Соотнеси свое решение с задачей, улучшай его и вызывай необходимые функции шаг за шагом.
20
- - Шаг 2.1. Во время работы используй функции ox_ai_workers_iterator__outer_voice и ox_ai_workers_iterator__action_request.
21
- - Шаг 3. Когда решение готово, сообщи о нем с помощью функции ox_ai_workers_iterator__outer_voice
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. Когда решение готово, сообщи об этом и ожидай ответ пользователя.
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rainbow'
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 Rainbow("monologue: #{text}").yellow },
15
- on_outer_voice: ->(text:) { puts Rainbow("voice: #{text}").green },
16
- on_action_request: ->(text:) { puts Rainbow("action: #{text}").red },
17
- on_pack_history: ->(text:) { puts Rainbow("summary: #{text}").blue }
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
@@ -22,6 +22,8 @@ OxAiWorkers.configure do |config|
22
22
  config.model = 'gpt-4o-mini'
23
23
  end
24
24
 
25
+ # OxAiWorkers.logger.level = :debug
26
+
25
27
  # Main algorithm
26
28
  @assistant = MyAssistant.new
27
29
  @assistant.task = '2 + 2 is ?'
@@ -9,7 +9,7 @@ class MyTool
9
9
  end
10
10
 
11
11
  def sh(input:)
12
- puts "Executing sh: \"#{input}\""
12
+ OxAiWorkers.logger.info("Executing sh: \"#{input}\"", for: self.class)
13
13
  stdout_and_stderr_s, = Open3.capture2e(input)
14
14
  stdout_and_stderr_s
15
15
  end
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.1
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-30 00:00:00.000000000 Z
11
+ date: 2024-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: faraday
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-multipart
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: i18n
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: ptools
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: rainbow
70
+ name: ptools
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '3'
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: '3'
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