ox-ai-workers 0.3.1 → 0.4.0

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: 22ef23635cb8c4a085d92a6891d5a7b42ea4a2421c31566b2e0a0c64019ffde4
4
- data.tar.gz: d3ee3406e6408da1f4abf1327e0b327cfdc9d70cab53368167a0074e995c0ac7
3
+ metadata.gz: fdbdf2dc16b6418e99209c8ff4710fedb25f01eec2b5980b8cc5562e3523d680
4
+ data.tar.gz: 33f8d2543e2167be860002296cb45736c4be5fac651be37244be5a0b5ba47ab2
5
5
  SHA512:
6
- metadata.gz: 4ce35c11d98add4706ac5202f0ba93017f4563cc0c1340b159fa5218a6fa98e2fd1f2c4523a70963656e8ace51509c5a994aac6974e682f04984ab7836ddb4e0
7
- data.tar.gz: ad68072b8c05b903c84f225d0978014a9f8d4f2bf36404b5ef2d6a9956405035f1c4e61287c58fd0e25b6500426eb2a2dcf758741a3437088cf03e15caa253e6
6
+ metadata.gz: 2f341be677a58fe8959bb86c8c6944769b77ae2d58a1cdae6800caf1ed5981d9c6532ad89549a6b5cb9189305049b123163754b5315a5e30369380a954c3c175
7
+ data.tar.gz: 616972852f978d9b6c8c014dd0295d1f338cdda7737db09358a3a5ab11b1e8d120cdc54c91a88618c068b81ff5ec7e16ffc26db11a6ce1bbd176698986f4d1d5
data/CHANGELOG.md CHANGED
@@ -1,6 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [0.3.1] - 2024-07-30
3
+ ## [0.4.0] - 2024-07-30
4
+
5
+ - Added tools: `file_system`, `database`
6
+ - Added assistant: `coder`
7
+
8
+ ## [0.3.2] - 2024-07-30
4
9
 
5
10
  - Friendly I18n
6
11
 
data/exe/oxaiworkers CHANGED
@@ -14,7 +14,6 @@ if ARGV.first == 'init'
14
14
  puts "Error: The #{dir} directory already exists."
15
15
  else
16
16
  FileUtils.mkdir_p "#{dir}/locales"
17
- # FileUtils.copy_entry "#{source}/locales", "#{dest}/locales"
18
17
  if ARGV.last == 'full'
19
18
  FileUtils.copy_entry "#{source}/template", dest.to_s
20
19
  else
data/lib/ox-ai-workers.rb CHANGED
@@ -19,10 +19,14 @@ require_relative 'oxaiworkers/delayed_request'
19
19
  require_relative 'oxaiworkers/dependency_helper'
20
20
  require_relative 'oxaiworkers/iterator'
21
21
  require_relative 'oxaiworkers/request'
22
+
22
23
  require_relative 'oxaiworkers/tool/eval'
24
+ require_relative 'oxaiworkers/tool/database'
25
+ require_relative 'oxaiworkers/tool/file_system'
23
26
 
24
27
  require_relative 'oxaiworkers/assistant/module_base'
25
28
  require_relative 'oxaiworkers/assistant/sysop'
29
+ require_relative 'oxaiworkers/assistant/coder'
26
30
 
27
31
  module OxAiWorkers
28
32
  DEFAULT_MODEL = 'gpt-4o-mini'
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OxAiWorkers
4
+ module Assistant
5
+ class Coder
6
+ include OxAiWorkers::Assistant::ModuleBase
7
+
8
+ def initialize(delayed: false, model: nil, language: 'ruby')
9
+ @iterator = Iterator.new(
10
+ worker: initWorker(delayed: delayed, model: model),
11
+ role: format(I18n.t('oxaiworkers.assistant.coder.role'), language),
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 }
17
+ )
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,22 +1,22 @@
1
1
  module OxAiWorkers
2
2
  module Assistant
3
3
  module ModuleBase
4
- attr_accessor :iterator
5
-
6
- def setTask task
7
- @iterator.cleanup()
8
- @iterator.addTask task
9
- end
4
+ attr_accessor :iterator
10
5
 
11
- def addResponse text
12
- @iterator.addTask text
13
- end
6
+ def setTask(task)
7
+ @iterator.cleanup
8
+ @iterator.addTask task
9
+ end
14
10
 
15
- def initWorker delayed:, model:
16
- worker = delayed ? OxAiWorkers::DelayedRequest.new : OxAiWorkers::Request.new
17
- worker.model = model || OxAiWorkers.configuration.model
18
- worker
19
- end
11
+ def addResponse(text)
12
+ @iterator.addTask text
13
+ end
14
+
15
+ def initWorker(delayed:, model:)
16
+ worker = delayed ? DelayedRequest.new : Request.new
17
+ worker.model = model || OxAiWorkers.configuration.model
18
+ worker
19
+ end
20
20
  end
21
21
  end
22
- end
22
+ end
@@ -6,10 +6,10 @@ module OxAiWorkers
6
6
  include OxAiWorkers::Assistant::ModuleBase
7
7
 
8
8
  def initialize(delayed: false, model: nil)
9
- @iterator = OxAiWorkers::Iterator.new(
9
+ @iterator = Iterator.new(
10
10
  worker: initWorker(delayed: delayed, model: model),
11
11
  role: I18n.t('oxaiworkers.assistant.sysop.role'),
12
- tools: [OxAiWorkers::Tool::Eval.new],
12
+ tools: [Tool::Eval.new],
13
13
  on_inner_monologue: ->(text:) { puts Rainbow("monologue: #{text}").yellow },
14
14
  on_outer_voice: ->(text:) { puts Rainbow("voice: #{text}").green },
15
15
  on_action_request: ->(text:) { puts Rainbow("action: #{text}").red },
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'i18n'
4
- I18n.load_path += Dir["#{File.expand_path('locales')}/*.yml"]
4
+ I18n.load_path += Dir["#{File.expand_path('../../locales', __dir__)}/*.yml"]
@@ -6,7 +6,7 @@ module OxAiWorkers
6
6
  :tool_calls_raw, :tool_calls
7
7
 
8
8
  def initializeRequests(model: nil, max_tokens: nil, temperature: nil)
9
- puts "call: ModuleRequest::#{__method__}"
9
+ # puts "call: ModuleRequest::#{__method__}"
10
10
  @max_tokens = max_tokens || OxAiWorkers.configuration.max_tokens
11
11
  @custom_id = SecureRandom.uuid
12
12
  @model = model || OxAiWorkers.configuration.model
@@ -23,7 +23,7 @@ module OxAiWorkers
23
23
  end
24
24
 
25
25
  def cleanup
26
- puts "call: ModuleRequest::#{__method__}"
26
+ # puts "call: ModuleRequest::#{__method__}"
27
27
  @client ||= OpenAI::Client.new(
28
28
  access_token: OxAiWorkers.configuration.access_token,
29
29
  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.
@@ -0,0 +1,119 @@
1
+ module OxAiWorkers
2
+ module Tool
3
+ #
4
+ # Connects to a database, executes SQL queries, and outputs DB schema for Agents to use
5
+ #
6
+ # Gem requirements:
7
+ # gem "sequel", "~> 5.68.0"
8
+ #
9
+ # Usage:
10
+ # database = OxAiWorkers::Tool::Database.new(connection_string: "postgres://user:password@localhost:5432/db_name")
11
+ #
12
+ class Database
13
+ extend OxAiWorkers::ToolDefinition
14
+ include OxAiWorkers::DependencyHelper
15
+
16
+ define_function :list_tables,
17
+ description: I18n.t('oxaiworkers.tool.database_tool.list_tables.description')
18
+
19
+ define_function :describe_tables,
20
+ description: I18n.t('oxaiworkers.tool.database_tool.describe_tables.description') do
21
+ property :tables, type: 'string',
22
+ description: I18n.t('oxaiworkers.tool.database_tool.describe_tables.tables'),
23
+ required: true
24
+ end
25
+
26
+ define_function :dump_schema,
27
+ description: I18n.t('oxaiworkers.tool.database_tool.dump_schema.description')
28
+
29
+ define_function :execute,
30
+ description: I18n.t('oxaiworkers.tool.database_tool.execute.description') do
31
+ property :input, type: 'string',
32
+ description: I18n.t('oxaiworkers.tool.database_tool.execute.input'),
33
+ required: true
34
+ end
35
+
36
+ attr_reader :db, :requested_tables, :excluded_tables
37
+
38
+ # Establish a database connection
39
+ #
40
+ # @param connection_string [String] Database connection info, e.g. 'postgres://user:password@localhost:5432/db_name'
41
+ # @param tables [Array<Symbol>] The tables to use. Will use all if empty.
42
+ # @param except_tables [Array<Symbol>] The tables to exclude. Will exclude none if empty.
43
+ # @return [Database] Database object
44
+ def initialize(connection_string:, tables: [], exclude_tables: [])
45
+ depends_on 'sequel'
46
+
47
+ raise StandardError, 'connection_string parameter cannot be blank' if connection_string.empty?
48
+
49
+ @db = Sequel.connect(connection_string)
50
+ @requested_tables = tables
51
+ @excluded_tables = exclude_tables
52
+ end
53
+
54
+ # Database Tool: Returns a list of tables in the database
55
+ def list_tables
56
+ db.tables
57
+ end
58
+
59
+ # Database Tool: Returns the schema for a list of tables
60
+ #
61
+ # @param tables [String] The tables to describe.
62
+ # @return [String] Database schema for the tables
63
+ def describe_tables(tables:)
64
+ schema = ''
65
+ tables.split(',').each do |table|
66
+ describe_table(table, schema)
67
+ end
68
+ schema
69
+ end
70
+
71
+ # Database Tool: Returns the database schema
72
+ #
73
+ # @return [String] Database schema
74
+ def dump_schema
75
+ puts('Dumping schema tables and keys', for: self.class)
76
+ schema = ''
77
+ db.tables.each do |table|
78
+ describe_table(table, schema)
79
+ end
80
+ schema
81
+ end
82
+
83
+ def describe_table(table, schema)
84
+ primary_key_columns = []
85
+ primary_key_column_count = db.schema(table).count { |column| column[1][:primary_key] == true }
86
+
87
+ schema << "CREATE TABLE #{table}(\n"
88
+ db.schema(table).each do |column|
89
+ schema << "#{column[0]} #{column[1][:type]}"
90
+ if column[1][:primary_key] == true
91
+ schema << ' PRIMARY KEY' if primary_key_column_count == 1
92
+ else
93
+ primary_key_columns << column[0]
94
+ end
95
+ schema << ",\n" unless column == db.schema(table).last && primary_key_column_count == 1
96
+ end
97
+ schema << "PRIMARY KEY (#{primary_key_columns.join(',')})" if primary_key_column_count > 1
98
+ db.foreign_key_list(table).each do |fk|
99
+ schema << ",\n" if fk == db.foreign_key_list(table).first
100
+ schema << "FOREIGN KEY (#{fk[:columns][0]}) REFERENCES #{fk[:table]}(#{fk[:key][0]})"
101
+ schema << ",\n" unless fk == db.foreign_key_list(table).last
102
+ end
103
+ schema << ");\n"
104
+ end
105
+
106
+ # Database Tool: Executes a SQL query and returns the results
107
+ #
108
+ # @param input [String] SQL query to be executed
109
+ # @return [Array] Results from the SQL query
110
+ def execute(input:)
111
+ puts("Executing \"#{input}\"", for: self.class)
112
+
113
+ db[input].to_a
114
+ rescue Sequel::DatabaseError => e
115
+ e.message
116
+ end
117
+ end
118
+ end
119
+ end
@@ -8,18 +8,18 @@ module OxAiWorkers
8
8
  extend OxAiWorkers::ToolDefinition
9
9
  include OxAiWorkers::DependencyHelper
10
10
 
11
- define_function :ruby, description: I18n.t('oxaiworkers.tool.eval.ruby.description') do
12
- property :input, type: 'string', description: I18n.t('oxaiworkers.tool.eval.ruby.input'), required: true
13
- end
11
+ # define_function :ruby, description: I18n.t('oxaiworkers.tool.eval.ruby.description') do
12
+ # property :input, type: 'string', description: I18n.t('oxaiworkers.tool.eval.ruby.input'), required: true
13
+ # end
14
14
 
15
15
  define_function :sh, description: I18n.t('oxaiworkers.tool.eval.sh.description') do
16
16
  property :input, type: 'string', description: I18n.t('oxaiworkers.tool.eval.sh.input'), required: true
17
17
  end
18
18
 
19
- def ruby(input:)
20
- puts Rainbow("Executing ruby: \"#{input}\"").red
21
- eval(input)
22
- end
19
+ # def ruby(input:)
20
+ # puts Rainbow("Executing ruby: \"#{input}\"").red
21
+ # eval(input)
22
+ # end
23
23
 
24
24
  def sh(input:)
25
25
  puts Rainbow("Executing sh: \"#{input}\"").red
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OxAiWorkers
4
+ module Tool
5
+ #
6
+ # A tool that wraps the Ruby file system classes.
7
+ #
8
+ # Usage:
9
+ # file_system = OxAiWorkers::Tool::FileSystem.new
10
+ #
11
+ class FileSystem
12
+ extend OxAiWorkers::ToolDefinition
13
+
14
+ define_function :list_directory,
15
+ description: I18n.t('oxaiworkers.tool.file_system.list_directory.description') do
16
+ property :directory_path, type: 'string',
17
+ description: I18n.t('oxaiworkers.tool.file_system.list_directory.directory_path'),
18
+ required: true
19
+ end
20
+
21
+ define_function :read_file, description: I18n.t('oxaiworkers.tool.file_system.read_file.description') do
22
+ property :file_path, type: 'string', description: I18n.t('oxaiworkers.tool.file_system.read_file.file_path'),
23
+ required: true
24
+ end
25
+
26
+ define_function :write_to_file, description: I18n.t('oxaiworkers.tool.file_system.write_to_file.description') do
27
+ property :file_path, type: 'string',
28
+ description: I18n.t('oxaiworkers.tool.file_system.write_to_file.file_path'), required: true
29
+ property :content, type: 'string', description: I18n.t('oxaiworkers.tool.file_system.write_to_file.content'),
30
+ required: true
31
+ end
32
+
33
+ def list_directory(directory_path:)
34
+ puts "Listing directory: #{directory_path}"
35
+ Dir.entries(directory_path)
36
+ rescue Errno::ENOENT
37
+ "No such directory: #{directory_path}"
38
+ end
39
+
40
+ def read_file(file_path:)
41
+ puts "Reading file: #{file_path}"
42
+ File.read(file_path).to_s
43
+ rescue Errno::ENOENT
44
+ "No such file: #{file_path}"
45
+ end
46
+
47
+ def write_to_file(file_path:, content:)
48
+ puts "Writing to file: #{file_path}"
49
+ File.write(file_path, content)
50
+ "Content was successfully written to the file: #{file_path}"
51
+ rescue Errno::EACCES
52
+ "Permission denied: #{file_path}"
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OxAiWorkers
4
- VERSION = '0.3.1'
4
+ VERSION = '0.4.0'
5
5
  end
@@ -2,4 +2,6 @@ en:
2
2
  oxaiworkers:
3
3
  assistant:
4
4
  sysop:
5
- role: "You are a software agent inside my computer"
5
+ role: "You are a software agent inside my computer"
6
+ coder:
7
+ role: "You are a professional %s programmer inside my computer"
data/locales/en.tool.yml CHANGED
@@ -7,4 +7,26 @@ en:
7
7
  input: "Ruby source code"
8
8
  sh:
9
9
  description: "Execute a sh command and get the result (stdout + stderr)"
10
- input: "Source command"
10
+ input: "Source command"
11
+ file_system:
12
+ list_directory:
13
+ description: 'File System Tool: Lists out the content of a specified directory'
14
+ directory_path: 'Directory path to list'
15
+ read_file:
16
+ description: 'File System Tool: Reads the contents of a file'
17
+ file_path: 'Path to the file to read from'
18
+ write_to_file:
19
+ description: 'File System Tool: Write content to a file'
20
+ file_path: 'Path to the file to write'
21
+ content: 'Content to write to the file'
22
+ database_tool:
23
+ list_tables:
24
+ description: 'Database Tool: Returns a list of tables in the database'
25
+ describe_tables:
26
+ description: 'Database Tool: Returns the schema for a list of tables'
27
+ tables: 'The tables to describe'
28
+ dump_schema:
29
+ description: 'Database Tool: Returns the database schema'
30
+ execute:
31
+ description: 'Database Tool: Executes a SQL query and returns the results'
32
+ input: 'SQL query to be executed'
@@ -3,3 +3,5 @@ ru:
3
3
  assistant:
4
4
  sysop:
5
5
  role: Ты программный агент внутри моего компьютера
6
+ coder:
7
+ role: "Ты профессиональный программист на %s внутри моего компьютера"
data/locales/ru.tool.yml CHANGED
@@ -8,3 +8,25 @@ ru:
8
8
  sh:
9
9
  description: Выполнить sh-команду и получить результат (stdout + stderr)
10
10
  input: Исходная команда
11
+ file_system:
12
+ list_directory:
13
+ description: 'Инструмент файловой системы: Выводит содержимое указанного каталога'
14
+ directory_path: 'Путь к каталогу для вывода содержимого'
15
+ read_file:
16
+ description: 'Инструмент файловой системы: Считывает содержимое файла'
17
+ file_path: 'Путь к файлу для считывания'
18
+ write_to_file:
19
+ description: 'Инструмент файловой системы: Записывает содержимое в файл'
20
+ file_path: 'Путь к файлу для записи'
21
+ content: 'Содержимое для записи в файл'
22
+ database_tool:
23
+ list_tables:
24
+ description: 'Инструмент базы данных: Возвращает список таблиц в базе данных'
25
+ describe_tables:
26
+ description: 'Инструмент базы данных: Возвращает схему для списка таблиц'
27
+ tables: 'Таблицы для описания'
28
+ dump_schema:
29
+ description: 'Инструмент базы данных: Возвращает схему базы данных'
30
+ execute:
31
+ description: 'Инструмент базы данных: Выполняет SQL-запрос и возвращает результаты'
32
+ input: 'SQL-запрос для выполнения'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ox-ai-workers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Smolev
@@ -120,6 +120,7 @@ files:
120
120
  - exe/oxaiworkers
121
121
  - exe/start
122
122
  - lib/ox-ai-workers.rb
123
+ - lib/oxaiworkers/assistant/coder.rb
123
124
  - lib/oxaiworkers/assistant/module_base.rb
124
125
  - lib/oxaiworkers/assistant/sysop.rb
125
126
  - lib/oxaiworkers/compatibility.rb
@@ -133,7 +134,9 @@ files:
133
134
  - lib/oxaiworkers/state_batch.rb
134
135
  - lib/oxaiworkers/state_helper.rb
135
136
  - lib/oxaiworkers/state_tools.rb
137
+ - lib/oxaiworkers/tool/database.rb
136
138
  - lib/oxaiworkers/tool/eval.rb
139
+ - lib/oxaiworkers/tool/file_system.rb
137
140
  - lib/oxaiworkers/tool_definition.rb
138
141
  - lib/oxaiworkers/version.rb
139
142
  - lib/ruby/ox-ai-workers.rb