ox-ai-workers 0.8.7 → 0.9.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/.cursorrules +88 -2
- data/CHANGELOG.md +20 -13
- data/README.md +135 -38
- data/config/locales/en.oxaiworkers.assistant.yml +39 -5
- data/config/locales/en.oxaiworkers.iterator.yml +1 -9
- data/config/locales/en.oxaiworkers.tool.yml +16 -1
- data/config/locales/ru.oxaiworkers.assistant.yml +39 -5
- data/config/locales/ru.oxaiworkers.iterator.yml +2 -11
- data/config/locales/ru.oxaiworkers.tool.yml +16 -1
- data/lib/ox-ai-workers.rb +16 -6
- data/lib/oxaiworkers/assistant/coder.rb +16 -8
- data/lib/oxaiworkers/assistant/localizer.rb +16 -9
- data/lib/oxaiworkers/assistant/module_base.rb +14 -5
- data/lib/oxaiworkers/assistant/orchestrator.rb +44 -0
- data/lib/oxaiworkers/assistant/painter.rb +37 -0
- data/lib/oxaiworkers/assistant/sysop.rb +15 -7
- data/lib/oxaiworkers/delayed_request.rb +2 -2
- data/lib/oxaiworkers/image_iterator.rb +41 -0
- data/lib/oxaiworkers/iterator.rb +34 -54
- data/lib/oxaiworkers/models/deepseek_max.rb +16 -0
- data/lib/oxaiworkers/models/module_base.rb +17 -0
- data/lib/oxaiworkers/models/openai_max.rb +15 -0
- data/lib/oxaiworkers/models/openai_mini.rb +12 -0
- data/lib/oxaiworkers/models/openai_nano.rb +12 -0
- data/lib/oxaiworkers/module_request.rb +11 -15
- data/lib/oxaiworkers/tool/eval.rb +19 -8
- data/lib/oxaiworkers/tool/file_system.rb +30 -15
- data/lib/oxaiworkers/tool/pipeline.rb +106 -0
- data/lib/oxaiworkers/tool/pixels.rb +76 -0
- data/lib/oxaiworkers/version.rb +1 -1
- data/template/start +4 -6
- metadata +11 -1
@@ -29,4 +29,19 @@ ru:
|
|
29
29
|
description: 'Инструмент базы данных: Возвращает схему базы данных'
|
30
30
|
execute:
|
31
31
|
description: 'Инструмент базы данных: Выполняет SQL-запрос и возвращает результаты'
|
32
|
-
input: 'SQL-запрос для выполнения'
|
32
|
+
input: 'SQL-запрос для выполнения'
|
33
|
+
pipeline:
|
34
|
+
send_message:
|
35
|
+
description: 'Отправить сообщение другому ассистенту'
|
36
|
+
message: 'Сообщение или задача для отправки'
|
37
|
+
result: 'Описание ожидаемого результата, что должно быть получено на выходе'
|
38
|
+
example: 'Пример хорошего результата'
|
39
|
+
to_id: 'ID ассистента получателя'
|
40
|
+
assistant_info: "ID: **%{id}**, Название: %{title}\nРоль: %{role}\nОписание: %{description}\nВозможности: %{capabilities}"
|
41
|
+
pixels:
|
42
|
+
generate_image:
|
43
|
+
description: 'Инструмент генерации изображений: Создает изображение на основе предоставленного текстового запроса. Если указать имя файла, изображение будет сохранено в формате png. В любом случае будет возвращен url изображения.'
|
44
|
+
prompt: 'Текстовое описание изображения для генерации'
|
45
|
+
size: 'Размер генерируемого изображения (1024x1792, 1792x1024, 1024x1024)'
|
46
|
+
quality: 'Качество генерируемого изображения (standard, hd)'
|
47
|
+
file_name: 'Имя файла для сохранения изображения в формате png. Например: image.png'
|
data/lib/ox-ai-workers.rb
CHANGED
@@ -20,21 +20,31 @@ require_relative 'oxaiworkers/state_batch'
|
|
20
20
|
require_relative 'oxaiworkers/state_tools'
|
21
21
|
require_relative 'oxaiworkers/delayed_request'
|
22
22
|
require_relative 'oxaiworkers/iterator'
|
23
|
+
require_relative 'oxaiworkers/image_iterator'
|
23
24
|
require_relative 'oxaiworkers/request'
|
24
25
|
|
25
26
|
require_relative 'oxaiworkers/tool/eval'
|
26
27
|
require_relative 'oxaiworkers/tool/database'
|
27
28
|
require_relative 'oxaiworkers/tool/file_system'
|
29
|
+
require_relative 'oxaiworkers/tool/pipeline'
|
30
|
+
require_relative 'oxaiworkers/tool/pixels'
|
28
31
|
|
29
32
|
require_relative 'oxaiworkers/assistant/module_base'
|
30
33
|
require_relative 'oxaiworkers/assistant/sysop'
|
31
34
|
require_relative 'oxaiworkers/assistant/coder'
|
32
35
|
require_relative 'oxaiworkers/assistant/localizer'
|
36
|
+
require_relative 'oxaiworkers/assistant/orchestrator'
|
37
|
+
require_relative 'oxaiworkers/assistant/painter'
|
38
|
+
|
39
|
+
require_relative 'oxaiworkers/models/module_base'
|
40
|
+
require_relative 'oxaiworkers/models/openai_max'
|
41
|
+
require_relative 'oxaiworkers/models/openai_mini'
|
42
|
+
require_relative 'oxaiworkers/models/openai_nano'
|
43
|
+
require_relative 'oxaiworkers/models/deepseek_max'
|
33
44
|
|
34
45
|
require_relative 'oxaiworkers/engine' if defined?(Rails)
|
35
46
|
|
36
47
|
module OxAiWorkers
|
37
|
-
DEFAULT_MODEL = 'gpt-4o-mini'
|
38
48
|
DEFAULT_MAX_TOKEN = 4096
|
39
49
|
DEFAULT_TEMPERATURE = 0.7
|
40
50
|
|
@@ -42,16 +52,15 @@ module OxAiWorkers
|
|
42
52
|
class ConfigurationError < Error; end
|
43
53
|
|
44
54
|
class Configuration
|
45
|
-
attr_accessor :
|
55
|
+
attr_accessor :max_tokens, :temperature, :wait_for_complete, :access_token_deepseek, :access_token_openai
|
46
56
|
|
47
57
|
def initialize
|
48
|
-
@access_token = nil
|
49
|
-
@model = DEFAULT_MODEL
|
50
58
|
@max_tokens = DEFAULT_MAX_TOKEN
|
51
59
|
@temperature = DEFAULT_TEMPERATURE
|
52
|
-
@auto_execute = true
|
53
60
|
@wait_for_complete = true
|
54
|
-
|
61
|
+
|
62
|
+
@access_token_deepseek = nil
|
63
|
+
@access_token_openai = nil
|
55
64
|
|
56
65
|
[Array, NilClass, String, Symbol, Hash].each do |c|
|
57
66
|
c.send(:include, OxAiWorkers::PresentCompat) unless c.method_defined?(:present?)
|
@@ -63,6 +72,7 @@ module OxAiWorkers
|
|
63
72
|
class << self
|
64
73
|
attr_writer :configuration
|
65
74
|
attr_reader :logger
|
75
|
+
attr_accessor :default_model
|
66
76
|
|
67
77
|
# @param logger [Logger]
|
68
78
|
# @return [ContextualLogger]
|
@@ -5,23 +5,31 @@ module OxAiWorkers
|
|
5
5
|
class Coder
|
6
6
|
include OxAiWorkers::Assistant::ModuleBase
|
7
7
|
|
8
|
-
def initialize(delayed: false, model: nil, language: 'ruby')
|
8
|
+
def initialize(current_dir: nil, delayed: false, model: nil, language: 'ruby')
|
9
9
|
store_locale
|
10
|
+
|
11
|
+
with_locale do
|
12
|
+
@id = 'coder'
|
13
|
+
@role = format(I18n.t('oxaiworkers.assistant.coder.role'), language)
|
14
|
+
@description = I18n.t('oxaiworkers.assistant.coder.description')
|
15
|
+
@capabilities = I18n.t('oxaiworkers.assistant.coder.capabilities').split(',').map(&:strip)
|
16
|
+
@title = I18n.t('oxaiworkers.assistant.coder.title')
|
17
|
+
end
|
18
|
+
|
10
19
|
@iterator = Iterator.new(
|
11
|
-
worker: init_worker(delayed
|
12
|
-
role:
|
13
|
-
tools: [Tool::Eval.new, Tool::FileSystem.new],
|
20
|
+
worker: init_worker(delayed:, model:),
|
21
|
+
role: @role,
|
22
|
+
tools: [Tool::Eval.new(current_dir:), Tool::FileSystem.new(current_dir:)],
|
14
23
|
locale: @locale,
|
15
24
|
on_inner_monologue: ->(text:) { puts "monologue: #{text}".colorize(:yellow) },
|
16
|
-
on_outer_voice: ->(text:) { puts "voice: #{text}".colorize(:green) }
|
17
|
-
on_action_request: ->(text:) { puts "action: #{text}".colorize(:red) },
|
18
|
-
on_summarize: ->(text:) { puts "summary: #{text}".colorize(:blue) }
|
25
|
+
on_outer_voice: ->(text:) { puts "voice: #{text}".colorize(:green) }
|
19
26
|
)
|
20
27
|
end
|
21
28
|
|
22
29
|
def language=(language)
|
23
30
|
with_locale do
|
24
|
-
@
|
31
|
+
@role = format(I18n.t('oxaiworkers.assistant.coder.role'), language)
|
32
|
+
@iterator.role = @role
|
25
33
|
end
|
26
34
|
end
|
27
35
|
end
|
@@ -5,22 +5,29 @@ module OxAiWorkers
|
|
5
5
|
class Localizer
|
6
6
|
include OxAiWorkers::Assistant::ModuleBase
|
7
7
|
|
8
|
-
def initialize(delayed: false, model: nil, language: 'русский', locale: :ru, source: 'english')
|
8
|
+
def initialize(delayed: false, model: nil, language: 'русский', locale: :ru, source: 'english', current_dir: nil)
|
9
9
|
store_locale
|
10
|
+
|
11
|
+
with_locale do
|
12
|
+
@id = 'localizer'
|
13
|
+
@role = format(I18n.t('oxaiworkers.assistant.localizer.role'), source_lang: source)
|
14
|
+
@description = I18n.t('oxaiworkers.assistant.localizer.description')
|
15
|
+
@capabilities = I18n.t('oxaiworkers.assistant.localizer.capabilities').split(',').map(&:strip)
|
16
|
+
@title = I18n.t('oxaiworkers.assistant.localizer.title')
|
17
|
+
end
|
18
|
+
|
10
19
|
@iterator = Iterator.new(
|
11
|
-
worker: init_worker(delayed
|
12
|
-
role:
|
13
|
-
tools: [Tool::Eval.new, Tool::FileSystem.new],
|
20
|
+
worker: init_worker(delayed:, model:),
|
21
|
+
role: @role,
|
22
|
+
tools: [Tool::Eval.new(current_dir:), Tool::FileSystem.new(current_dir:)],
|
14
23
|
locale: @locale,
|
15
24
|
on_inner_monologue: ->(text:) { puts "monologue: #{text}".colorize(:yellow) },
|
16
|
-
on_outer_voice: ->(text:) { puts "voice: #{text}".colorize(:green) }
|
17
|
-
on_action_request: ->(text:) { puts "action: #{text}".colorize(:red) },
|
18
|
-
on_summarize: ->(text:) { puts "summary: #{text}".colorize(:blue) }
|
25
|
+
on_outer_voice: ->(text:) { puts "voice: #{text}".colorize(:green) }
|
19
26
|
)
|
20
|
-
@iterator.add_context(format(I18n.t('oxaiworkers.assistant.localizer.source'), source))
|
27
|
+
@iterator.add_context(format(I18n.t('oxaiworkers.assistant.localizer.source'), source_lang: source))
|
21
28
|
|
22
29
|
@iterator.add_context(format(I18n.t('oxaiworkers.assistant.localizer.locale'),
|
23
|
-
language, locale))
|
30
|
+
target_lang: language, locale:))
|
24
31
|
end
|
25
32
|
end
|
26
33
|
end
|
@@ -5,14 +5,14 @@ module OxAiWorkers
|
|
5
5
|
module ModuleBase
|
6
6
|
include OxAiWorkers::LoadI18n
|
7
7
|
|
8
|
-
attr_accessor :iterator
|
8
|
+
attr_accessor :iterator, :role, :description, :capabilities, :id, :title
|
9
9
|
|
10
10
|
def task=(task)
|
11
11
|
@iterator.cleanup
|
12
12
|
@iterator.add_task task
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
15
|
+
def add_task(text)
|
16
16
|
@iterator.add_task text
|
17
17
|
end
|
18
18
|
|
@@ -20,10 +20,19 @@ module OxAiWorkers
|
|
20
20
|
@iterator.execute
|
21
21
|
end
|
22
22
|
|
23
|
+
def run_task(text)
|
24
|
+
self.task = text
|
25
|
+
execute
|
26
|
+
end
|
27
|
+
|
23
28
|
def init_worker(delayed: false, model: nil, on_stream: nil)
|
24
|
-
|
25
|
-
|
26
|
-
|
29
|
+
model ||= OxAiWorkers.default_model
|
30
|
+
delayed ? DelayedRequest.new(model:) : Request.new(model:, on_stream:)
|
31
|
+
end
|
32
|
+
|
33
|
+
def replace_context(context)
|
34
|
+
@iterator.clear_context
|
35
|
+
@iterator.add_context context
|
27
36
|
end
|
28
37
|
end
|
29
38
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OxAiWorkers
|
4
|
+
module Assistant
|
5
|
+
class Orchestrator
|
6
|
+
include OxAiWorkers::Assistant::ModuleBase
|
7
|
+
|
8
|
+
attr_accessor :workflow
|
9
|
+
|
10
|
+
def initialize(delayed: false, model: nil, role: nil, workflow: nil)
|
11
|
+
store_locale
|
12
|
+
|
13
|
+
@pipeline = Tool::Pipeline.new(
|
14
|
+
on_message: ->(text:) { @iterator.add_queue text, role: :system }
|
15
|
+
)
|
16
|
+
|
17
|
+
with_locale do
|
18
|
+
@id = 'orchestrator'
|
19
|
+
@role = role || I18n.t('oxaiworkers.assistant.orchestrator.role')
|
20
|
+
@description = I18n.t('oxaiworkers.assistant.orchestrator.description')
|
21
|
+
@capabilities = I18n.t('oxaiworkers.assistant.orchestrator.capabilities').split(',').map(&:strip)
|
22
|
+
@title = I18n.t('oxaiworkers.assistant.orchestrator.title')
|
23
|
+
@workflow = I18n.t('oxaiworkers.assistant.orchestrator.workflow_task',
|
24
|
+
workflow_description: workflow)
|
25
|
+
end
|
26
|
+
|
27
|
+
@iterator = Iterator.new(
|
28
|
+
worker: init_worker(delayed:, model:),
|
29
|
+
role: @role,
|
30
|
+
tools: [@pipeline],
|
31
|
+
locale: @locale,
|
32
|
+
on_inner_monologue: ->(text:) { @pipeline.recive_monologue(from_id: @id, message: text) },
|
33
|
+
on_outer_voice: ->(text:) { @pipeline.recive_voice(from_id: @id, message: text) }
|
34
|
+
)
|
35
|
+
|
36
|
+
@iterator.add_task @workflow
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_assistant(assistant)
|
40
|
+
@pipeline.add_assistant(assistant)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OxAiWorkers
|
4
|
+
module Assistant
|
5
|
+
class Painter
|
6
|
+
include OxAiWorkers::Assistant::ModuleBase
|
7
|
+
|
8
|
+
def initialize(current_dir: nil, delayed: false, model: nil)
|
9
|
+
store_locale
|
10
|
+
@current_dir = current_dir
|
11
|
+
|
12
|
+
with_locale do
|
13
|
+
@id = 'painter'
|
14
|
+
@role = I18n.t('oxaiworkers.assistant.painter.role')
|
15
|
+
@description = I18n.t('oxaiworkers.assistant.painter.description')
|
16
|
+
@capabilities = I18n.t('oxaiworkers.assistant.painter.capabilities').split(',').map(&:strip)
|
17
|
+
@title = I18n.t('oxaiworkers.assistant.painter.title')
|
18
|
+
end
|
19
|
+
|
20
|
+
@iterator = Iterator.new(
|
21
|
+
worker: init_worker(delayed:, model:),
|
22
|
+
role: @role,
|
23
|
+
tools: [Tool::Pixels.new(worker: init_worker(delayed: false, model:), current_dir:)],
|
24
|
+
locale: @locale,
|
25
|
+
on_inner_monologue: ->(text:) { puts "monologue: #{text}".colorize(:yellow) },
|
26
|
+
on_outer_voice: ->(text:) { puts "voice: #{text}".colorize(:green) }
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def cleanup
|
31
|
+
Dir.glob(File.join(@current_dir, '*.png')).each do |file|
|
32
|
+
File.delete(file) if File.exist?(file)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -5,17 +5,25 @@ module OxAiWorkers
|
|
5
5
|
class Sysop
|
6
6
|
include OxAiWorkers::Assistant::ModuleBase
|
7
7
|
|
8
|
-
def initialize(delayed: false, model: nil)
|
8
|
+
def initialize(current_dir: nil, delayed: false, model: nil)
|
9
9
|
store_locale
|
10
|
+
|
11
|
+
with_locale do
|
12
|
+
@id = 'sysop'
|
13
|
+
@role = I18n.t('oxaiworkers.assistant.sysop.role')
|
14
|
+
@description = I18n.t('oxaiworkers.assistant.sysop.description')
|
15
|
+
@capabilities = I18n.t('oxaiworkers.assistant.sysop.capabilities').split(',').map(&:strip)
|
16
|
+
@title = I18n.t('oxaiworkers.assistant.sysop.title')
|
17
|
+
end
|
18
|
+
|
10
19
|
@iterator = Iterator.new(
|
11
|
-
worker: init_worker(delayed
|
12
|
-
role:
|
13
|
-
tools: [Tool::Eval.new(only: :sh
|
20
|
+
worker: init_worker(delayed:, model:),
|
21
|
+
role: @role,
|
22
|
+
tools: [Tool::Eval.new(only: :sh, current_dir:),
|
23
|
+
Tool::FileSystem.new(only: %i[read_file write_to_file], current_dir:)],
|
14
24
|
locale: @locale,
|
15
25
|
on_inner_monologue: ->(text:) { puts "monologue: #{text}".colorize(:yellow) },
|
16
|
-
on_outer_voice: ->(text:) { puts "voice: #{text}".colorize(:green) }
|
17
|
-
on_action_request: ->(text:) { puts "action: #{text}".colorize(:red) },
|
18
|
-
on_summarize: ->(text:) { puts "summary: #{text}".colorize(:blue) }
|
26
|
+
on_outer_voice: ->(text:) { puts "voice: #{text}".colorize(:green) }
|
19
27
|
)
|
20
28
|
end
|
21
29
|
end
|
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module OxAiWorkers
|
4
4
|
class DelayedRequest < OxAiWorkers::StateBatch
|
5
|
-
def initialize(
|
6
|
-
initialize_requests(model
|
5
|
+
def initialize(model:, batch_id: nil)
|
6
|
+
initialize_requests(model:)
|
7
7
|
@custom_id = nil if batch_id.present?
|
8
8
|
@batch_id = batch_id
|
9
9
|
@file_id = nil
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OxAiWorkers
|
4
|
+
class ImageIterator
|
5
|
+
attr_accessor :worker, :on_inner_monologue, :on_outer_voice, :on_finish, :task
|
6
|
+
|
7
|
+
def initialize(worker:, on_inner_monologue: nil, on_outer_voice: nil, on_finish: nil)
|
8
|
+
@worker = worker
|
9
|
+
@on_inner_monologue = on_inner_monologue
|
10
|
+
@on_outer_voice = on_outer_voice
|
11
|
+
@on_finish = on_finish
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute
|
15
|
+
response = @worker.client.images.generate(
|
16
|
+
parameters: {
|
17
|
+
prompt: @task,
|
18
|
+
model: 'dall-e-3',
|
19
|
+
size: '1024x1792',
|
20
|
+
quality: 'standard'
|
21
|
+
}
|
22
|
+
)
|
23
|
+
|
24
|
+
url = response.dig('data', 0, 'url')
|
25
|
+
puts url
|
26
|
+
puts response.inspect
|
27
|
+
@on_inner_monologue&.call(text: I18n.t('oxaiworkers.iterator.image_iterator.url', url:))
|
28
|
+
@on_outer_voice&.call(text: url)
|
29
|
+
@on_finish&.call(result: url)
|
30
|
+
response
|
31
|
+
end
|
32
|
+
|
33
|
+
def cleanup
|
34
|
+
@worker.cleanup
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_task(task)
|
38
|
+
@task = task
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/oxaiworkers/iterator.rb
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
|
3
3
|
module OxAiWorkers
|
4
4
|
class Iterator < OxAiWorkers::StateTools
|
5
|
-
ITERATOR_FUNCTIONS = %i[inner_monologue outer_voice
|
5
|
+
ITERATOR_FUNCTIONS = %i[inner_monologue outer_voice finish_it].freeze
|
6
6
|
|
7
7
|
include OxAiWorkers::ToolDefinition
|
8
8
|
include OxAiWorkers::LoadI18n
|
9
9
|
|
10
|
-
attr_accessor :worker, :role, :messages, :context, :
|
11
|
-
:on_inner_monologue, :on_outer_voice, :
|
10
|
+
attr_accessor :worker, :role, :messages, :context, :tools, :queue, :monologue, :tasks,
|
11
|
+
:on_inner_monologue, :on_outer_voice, :on_finish, :def_except, :def_only
|
12
12
|
|
13
|
-
def initialize(worker:, role: nil, tools: [], on_inner_monologue: nil, on_outer_voice: nil,
|
14
|
-
|
13
|
+
def initialize(worker:, role: nil, tools: [], on_inner_monologue: nil, on_outer_voice: nil,
|
14
|
+
on_finish: nil, steps: nil, def_except: [], def_only: nil, locale: nil)
|
15
15
|
|
16
16
|
@locale = locale || I18n.locale
|
17
17
|
|
@@ -25,15 +25,6 @@ module OxAiWorkers
|
|
25
25
|
property :text, type: 'string', description: I18n.t('oxaiworkers.iterator.outer_voice.text'), required: true
|
26
26
|
end
|
27
27
|
|
28
|
-
define_function :action_request, description: I18n.t('oxaiworkers.iterator.action_request.description') do
|
29
|
-
property :action, type: 'string', description: I18n.t('oxaiworkers.iterator.action_request.action'),
|
30
|
-
required: true
|
31
|
-
end
|
32
|
-
|
33
|
-
define_function :summarize, description: I18n.t('oxaiworkers.iterator.summarize.description') do
|
34
|
-
property :text, type: 'string', description: I18n.t('oxaiworkers.iterator.summarize.text'), required: true
|
35
|
-
end
|
36
|
-
|
37
28
|
define_function :finish_it, description: I18n.t('oxaiworkers.iterator.finish_it.description')
|
38
29
|
|
39
30
|
@monologue = steps || I18n.t('oxaiworkers.iterator.monologue')
|
@@ -48,8 +39,6 @@ module OxAiWorkers
|
|
48
39
|
|
49
40
|
@on_inner_monologue = on_inner_monologue
|
50
41
|
@on_outer_voice = on_outer_voice
|
51
|
-
@on_action_request = on_action_request
|
52
|
-
@on_summarize = on_summarize
|
53
42
|
@on_finish = on_finish
|
54
43
|
|
55
44
|
cleanup
|
@@ -65,10 +54,8 @@ module OxAiWorkers
|
|
65
54
|
# Returns nothing.
|
66
55
|
#
|
67
56
|
def cleanup
|
68
|
-
@result = nil
|
69
57
|
@queue = []
|
70
58
|
@tasks = []
|
71
|
-
@milestones = []
|
72
59
|
@messages = []
|
73
60
|
complete_iteration
|
74
61
|
end
|
@@ -79,26 +66,24 @@ module OxAiWorkers
|
|
79
66
|
#
|
80
67
|
# @return [nil] This method does not return a value.
|
81
68
|
def inner_monologue(speach:)
|
82
|
-
|
83
|
-
|
84
|
-
|
69
|
+
if available_defs.include?(:inner_monologue)
|
70
|
+
@queue << { role: :assistant, content: speach.to_s }
|
71
|
+
@on_inner_monologue&.call(text: speach)
|
72
|
+
else
|
73
|
+
OxAiWorkers.logger.warn "Iterator::inner_monologue is not available: #{speach}"
|
74
|
+
end
|
85
75
|
nil
|
86
76
|
end
|
87
77
|
|
88
78
|
def outer_voice(text:)
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
79
|
+
if available_defs.include?(:outer_voice)
|
80
|
+
@queue << { role: :assistant, content: text.to_s }
|
81
|
+
@on_outer_voice&.call(text:)
|
82
|
+
else
|
83
|
+
OxAiWorkers.logger.warn "Iterator::outer_voice is not available: #{text}"
|
84
|
+
inner_monologue(speach: text)
|
85
|
+
end
|
95
86
|
|
96
|
-
def action_request(action:)
|
97
|
-
@result = action
|
98
|
-
# @queue.pop
|
99
|
-
@messages << { role: :assistant, content: action.to_s }
|
100
|
-
complete! if can_complete?
|
101
|
-
@on_action_request&.call(text: action)
|
102
87
|
nil
|
103
88
|
end
|
104
89
|
|
@@ -108,19 +93,6 @@ module OxAiWorkers
|
|
108
93
|
nil
|
109
94
|
end
|
110
95
|
|
111
|
-
def summarize(text:)
|
112
|
-
@milestones << text.to_s
|
113
|
-
@messages = []
|
114
|
-
with_locale do
|
115
|
-
@queue << { role: :assistant, content: I18n.t('oxaiworkers.iterator.summarize.result') }
|
116
|
-
end
|
117
|
-
@worker.finish
|
118
|
-
rebuild_worker
|
119
|
-
complete! if can_complete?
|
120
|
-
@on_summarize&.call(text:)
|
121
|
-
nil
|
122
|
-
end
|
123
|
-
|
124
96
|
def init
|
125
97
|
rebuild_worker
|
126
98
|
request!
|
@@ -129,12 +101,15 @@ module OxAiWorkers
|
|
129
101
|
def rebuild_worker
|
130
102
|
@worker.messages = []
|
131
103
|
@worker.append(role: :system, content: @role) if @role.present?
|
104
|
+
|
132
105
|
@tasks.each { |task| @worker.append(role: :user, content: task) }
|
133
106
|
@worker.append(role: :system, content: valid_monologue.join("\n"))
|
134
107
|
@worker.append(messages: @context) if @context.present?
|
135
|
-
@
|
136
|
-
|
108
|
+
@tools.each do |tool|
|
109
|
+
@worker.append(role: :user, content: tool.context) if tool.respond_to?(:context) && tool.context.present?
|
110
|
+
end
|
137
111
|
@worker.append(messages: @messages)
|
112
|
+
@tasks.each { |task| @worker.append(role: :user, content: task) }
|
138
113
|
@worker.tools = function_schemas.to_openai_format(only: available_defs)
|
139
114
|
return unless @tools.present?
|
140
115
|
|
@@ -222,7 +197,6 @@ module OxAiWorkers
|
|
222
197
|
return
|
223
198
|
end
|
224
199
|
|
225
|
-
@result = @worker.result || @worker.errors
|
226
200
|
if @worker.tool_calls.present?
|
227
201
|
@queue << { role: :assistant, content: @worker.tool_calls_raw.to_s }
|
228
202
|
@worker.tool_calls.each do |external_call|
|
@@ -239,9 +213,9 @@ module OxAiWorkers
|
|
239
213
|
end
|
240
214
|
@worker.finish
|
241
215
|
iterate! if can_iterate?
|
242
|
-
elsif @worker.result.present?
|
243
|
-
action_request action: @worker.result
|
244
216
|
end
|
217
|
+
result = @worker.result || @worker.errors
|
218
|
+
outer_voice text: result if result.present?
|
245
219
|
end
|
246
220
|
|
247
221
|
def complete_iteration
|
@@ -251,8 +225,10 @@ module OxAiWorkers
|
|
251
225
|
|
252
226
|
def add_task(task)
|
253
227
|
@tasks << task
|
254
|
-
|
255
|
-
|
228
|
+
end
|
229
|
+
|
230
|
+
def add_queue(text, role: :assistant)
|
231
|
+
@queue << { role:, content: text }
|
256
232
|
end
|
257
233
|
|
258
234
|
def add_context(text, role: :system)
|
@@ -263,6 +239,10 @@ module OxAiWorkers
|
|
263
239
|
@context << c
|
264
240
|
end
|
265
241
|
|
242
|
+
def clear_context
|
243
|
+
@context = []
|
244
|
+
end
|
245
|
+
|
266
246
|
def execute
|
267
247
|
prepare! if valid?
|
268
248
|
end
|
@@ -272,7 +252,7 @@ module OxAiWorkers
|
|
272
252
|
end
|
273
253
|
|
274
254
|
def valid?
|
275
|
-
@messages.present? || @
|
255
|
+
@messages.present? || @tasks.present?
|
276
256
|
end
|
277
257
|
end
|
278
258
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OxAiWorkers
|
4
|
+
module Models
|
5
|
+
class DeepseekMax
|
6
|
+
include OxAiWorkers::Models::ModuleBase
|
7
|
+
|
8
|
+
def initialize(uri_base: nil, api_key: nil, model: nil, max_tokens: nil, temperature: nil)
|
9
|
+
@model = model || 'deepseek-chat'
|
10
|
+
@uri_base = uri_base || 'https://api.deepseek.com/'
|
11
|
+
@api_key = api_key || OxAiWorkers.configuration.access_token_deepseek
|
12
|
+
super(uri_base: @uri_base, api_key: @api_key, model: @model, max_tokens:, temperature:)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OxAiWorkers
|
4
|
+
module Models
|
5
|
+
module ModuleBase
|
6
|
+
attr_accessor :uri_base, :api_key, :model, :max_tokens, :temperature
|
7
|
+
|
8
|
+
def initialize(uri_base:, api_key:, model:, max_tokens: nil, temperature: nil)
|
9
|
+
@max_tokens = max_tokens || OxAiWorkers.configuration.max_tokens
|
10
|
+
@temperature = temperature || OxAiWorkers.configuration.temperature
|
11
|
+
@api_key = api_key
|
12
|
+
@uri_base = uri_base
|
13
|
+
@model = model
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OxAiWorkers
|
4
|
+
module Models
|
5
|
+
class OpenaiMax
|
6
|
+
include OxAiWorkers::Models::ModuleBase
|
7
|
+
|
8
|
+
def initialize(uri_base: nil, api_key: nil, model: nil, max_tokens: nil, temperature: nil)
|
9
|
+
@model = model || 'gpt-4.1'
|
10
|
+
@api_key = api_key || OxAiWorkers.configuration.access_token_openai
|
11
|
+
super(uri_base:, api_key: @api_key, model: @model, max_tokens:, temperature:)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OxAiWorkers
|
4
|
+
module Models
|
5
|
+
class OpenaiMini < OpenaiMax
|
6
|
+
def initialize(uri_base: nil, api_key: nil, model: nil, max_tokens: nil, temperature: nil)
|
7
|
+
@model = model || 'gpt-4.1-mini'
|
8
|
+
super(uri_base:, api_key:, model: @model, max_tokens:, temperature:)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OxAiWorkers
|
4
|
+
module Models
|
5
|
+
class OpenaiNano < OpenaiMax
|
6
|
+
def initialize(uri_base: nil, api_key: nil, model: nil, max_tokens: nil, temperature: nil)
|
7
|
+
@model = model || 'gpt-4.1-nano'
|
8
|
+
super(uri_base:, api_key:, model: @model, max_tokens:, temperature:)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|