omniai-tools 0.5.0 → 0.6.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 +4 -4
- data/Gemfile +2 -0
- data/README.md +72 -16
- data/lib/omniai/tools/browser/base_driver.rb +78 -0
- data/lib/omniai/tools/browser/base_tool.rb +31 -4
- data/lib/omniai/tools/browser/button_click_tool.rb +1 -14
- data/lib/omniai/tools/browser/element_click_tool.rb +30 -0
- data/lib/omniai/tools/browser/elements/element_grouper.rb +73 -0
- data/lib/omniai/tools/browser/elements/nearby_element_detector.rb +108 -0
- data/lib/omniai/tools/browser/formatters/action_formatter.rb +37 -0
- data/lib/omniai/tools/browser/formatters/data_entry_formatter.rb +135 -0
- data/lib/omniai/tools/browser/formatters/element_formatter.rb +52 -0
- data/lib/omniai/tools/browser/formatters/input_formatter.rb +59 -0
- data/lib/omniai/tools/browser/inspect_tool.rb +46 -13
- data/lib/omniai/tools/browser/inspect_utils.rb +51 -0
- data/lib/omniai/tools/browser/link_click_tool.rb +2 -14
- data/lib/omniai/tools/browser/page_inspect/button_summarizer.rb +140 -0
- data/lib/omniai/tools/browser/page_inspect/form_summarizer.rb +98 -0
- data/lib/omniai/tools/browser/page_inspect/html_summarizer.rb +37 -0
- data/lib/omniai/tools/browser/page_inspect/link_summarizer.rb +103 -0
- data/lib/omniai/tools/browser/page_inspect_tool.rb +30 -0
- data/lib/omniai/tools/browser/page_screenshot_tool.rb +22 -0
- data/lib/omniai/tools/browser/selector_generator/base_selectors.rb +28 -0
- data/lib/omniai/tools/browser/selector_generator/contextual_selectors.rb +140 -0
- data/lib/omniai/tools/browser/selector_generator.rb +73 -0
- data/lib/omniai/tools/browser/selector_inspect_tool.rb +44 -0
- data/lib/omniai/tools/browser/text_field_area_set_tool.rb +2 -31
- data/lib/omniai/tools/browser/visit_tool.rb +1 -1
- data/lib/omniai/tools/browser/watir_driver.rb +222 -0
- data/lib/omniai/tools/browser_tool.rb +262 -0
- data/lib/omniai/tools/computer/base_driver.rb +179 -0
- data/lib/omniai/tools/computer/mac_driver.rb +103 -0
- data/lib/omniai/tools/computer_tool.rb +189 -0
- data/lib/omniai/tools/database/base_driver.rb +17 -0
- data/lib/omniai/tools/database/postgres_driver.rb +30 -0
- data/lib/omniai/tools/database/sqlite_driver.rb +29 -0
- data/lib/omniai/tools/database_tool.rb +100 -0
- data/lib/omniai/tools/version.rb +1 -1
- metadata +31 -5
- data/lib/omniai/tools/database/base_tool.rb +0 -37
- data/lib/omniai/tools/database/sqlite_tool.rb +0 -110
@@ -0,0 +1,189 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OmniAI
|
4
|
+
module Tools
|
5
|
+
# A tool for interacting with a computer. Be careful with using as it can perform actions on your computer!
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# computer = OmniAI::Tools::Computer::MacTool.new
|
9
|
+
# computer.display # { "width": 2560, "height": 1440, "scale": 1 }
|
10
|
+
# computer.screenshot
|
11
|
+
class ComputerTool < OmniAI::Tool
|
12
|
+
description "A tool for interacting with a computer."
|
13
|
+
|
14
|
+
module Action
|
15
|
+
KEY = "key" # press a key
|
16
|
+
HOLD_KEY = "hold_key" # hold a key
|
17
|
+
MOUSE_POSITION = "mouse_position" # get the current (x, y) pixel coordinate of the cursor on the screen
|
18
|
+
MOUSE_MOVE = "mouse_move" # move the cursor to a specific (x, y) pixel coordinate on the screen
|
19
|
+
MOUSE_CLICK = "mouse_click" # click at a specific x / y coordinate
|
20
|
+
MOUSE_DOWN = "mouse_down" # press the mouse button down
|
21
|
+
MOUSE_DRAG = "mouse_drag" # drag the mouse to a specific x / y coordinate
|
22
|
+
MOUSE_UP = "mouse_up" # release the mouse button
|
23
|
+
MOUSE_DOUBLE_CLICK = "mouse_double_click" # double click at a specific x / y coordinate
|
24
|
+
MOUSE_TRIPLE_CLICK = "mouse_triple_click" # triple click at a specific x / y coordinate
|
25
|
+
TYPE = "type" # type a string
|
26
|
+
SCROLL = "scroll"
|
27
|
+
WAIT = "wait"
|
28
|
+
end
|
29
|
+
|
30
|
+
module MouseButton
|
31
|
+
LEFT = "left"
|
32
|
+
MIDDLE = "middle"
|
33
|
+
RIGHT = "right"
|
34
|
+
end
|
35
|
+
|
36
|
+
module ScrollDirection
|
37
|
+
UP = "up"
|
38
|
+
DOWN = "down"
|
39
|
+
LEFT = "left"
|
40
|
+
RIGHT = "right"
|
41
|
+
end
|
42
|
+
|
43
|
+
ACTIONS = [
|
44
|
+
Action::KEY,
|
45
|
+
Action::HOLD_KEY,
|
46
|
+
Action::MOUSE_POSITION,
|
47
|
+
Action::MOUSE_MOVE,
|
48
|
+
Action::MOUSE_CLICK,
|
49
|
+
Action::MOUSE_DOWN,
|
50
|
+
Action::MOUSE_DRAG,
|
51
|
+
Action::MOUSE_UP,
|
52
|
+
Action::TYPE,
|
53
|
+
Action::SCROLL,
|
54
|
+
Action::WAIT,
|
55
|
+
].freeze
|
56
|
+
|
57
|
+
MOUSE_BUTTON_OPTIONS = [
|
58
|
+
MouseButton::LEFT,
|
59
|
+
MouseButton::MIDDLE,
|
60
|
+
MouseButton::RIGHT,
|
61
|
+
].freeze
|
62
|
+
|
63
|
+
SCROLL_DIRECTION_OPTIONS = [
|
64
|
+
ScrollDirection::UP,
|
65
|
+
ScrollDirection::DOWN,
|
66
|
+
ScrollDirection::LEFT,
|
67
|
+
ScrollDirection::RIGHT,
|
68
|
+
].freeze
|
69
|
+
|
70
|
+
parameter :action, :string, enum: ACTIONS, description: <<~TEXT
|
71
|
+
Options:
|
72
|
+
* `#{Action::KEY}`: Press a single key / combination of keys on the keyboard:
|
73
|
+
- supports xdotool's `key` syntax (e.g. "alt+Tab", "Return", "ctrl+s", etc)
|
74
|
+
* `#{Action::HOLD_KEY}`: Hold down a key or multiple keys for a specified duration (in seconds):
|
75
|
+
- supports xdotool's `key` syntax (e.g. "alt+Tab", "Return", "ctrl+s", etc)
|
76
|
+
* `#{Action::MOUSE_POSITION}`: Get the current (x,y) pixel coordinate of the cursor on the screen.
|
77
|
+
* `#{Action::MOUSE_MOVE}`: Move the cursor to a specified (x,y) pixel coordinate on the screen.
|
78
|
+
* `#{Action::MOUSE_CLICK}`: Click the mouse button at the specified (x,y) pixel coordinate on the screen.
|
79
|
+
* `#{Action::MOUSE_DOUBLE_CLICK}`: Double click at the specified (x,y) pixel coordinate on the screen.
|
80
|
+
* `#{Action::MOUSE_TRIPLE_CLICK}`: Triple click at the specified (x,y) pixel coordinate on the screen.
|
81
|
+
* `#{Action::MOUSE_DOWN}`: Press the mouse button at the specified (x,y) pixel coordinate on the screen.
|
82
|
+
* `#{Action::MOUSE_DRAG}`: Click and drag the cursor to a specified (x, y) pixel coordinate on the screen.
|
83
|
+
* `#{Action::MOUSE_UP}`: Release the mouse button at the specified (x,y) pixel coordinate on the screen.
|
84
|
+
* `#{Action::TYPE}`: Type a string of text on the keyboard.
|
85
|
+
* `#{Action::SCROLL}`: Scroll the screen in a specified direction by a specified amount of clicks of the scroll wheel.
|
86
|
+
* `#{Action::WAIT}`: Wait for a specified duration (in seconds).
|
87
|
+
TEXT
|
88
|
+
|
89
|
+
parameter :coordinate, :object, properties: {
|
90
|
+
x: OmniAI::Schema.integer(description: "The x position in pixels"),
|
91
|
+
y: OmniAI::Schema.integer(description: "The y position in pixels"),
|
92
|
+
}, required: %i[x y], description: <<~TEXT
|
93
|
+
An (x,y) coordinate. Required for the following actions:
|
94
|
+
* `#{Action::MOUSE_MOVE}`
|
95
|
+
* `#{Action::MOUSE_CLICK}`
|
96
|
+
* `#{Action::MOUSE_DOWN}`
|
97
|
+
* `#{Action::MOUSE_DRAG}`
|
98
|
+
* `#{Action::MOUSE_UP}`
|
99
|
+
* `#{Action::MOUSE_DOUBLE_CLICK}`
|
100
|
+
* `#{Action::MOUSE_TRIPLE_CLICK}`
|
101
|
+
TEXT
|
102
|
+
|
103
|
+
parameter :text, :string, description: <<~TEXT
|
104
|
+
The text to type. Required for the following actions:
|
105
|
+
* `#{Action::KEY}`
|
106
|
+
* `#{Action::HOLD_KEY}`
|
107
|
+
* `#{Action::TYPE}`
|
108
|
+
TEXT
|
109
|
+
|
110
|
+
parameter :duration, :integer, description: <<~TEXT
|
111
|
+
A duration in seconds. Required for the following actions:
|
112
|
+
* `#{Action::HOLD_KEY}`
|
113
|
+
* `#{Action::WAIT}`
|
114
|
+
TEXT
|
115
|
+
|
116
|
+
parameter :mouse_button, :string, enum: MOUSE_BUTTON_OPTIONS, description: <<~TEXT
|
117
|
+
The mouse button to use. Required for the following actions:
|
118
|
+
* `#{Action::MOUSE_CLICK}`
|
119
|
+
* `#{Action::MOUSE_DOWN}`
|
120
|
+
* `#{Action::MOUSE_DRAG}`
|
121
|
+
* `#{Action::MOUSE_UP}`
|
122
|
+
* `#{Action::MOUSE_DOUBLE_CLICK}`
|
123
|
+
* `#{Action::MOUSE_TRIPLE_CLICK}`
|
124
|
+
TEXT
|
125
|
+
|
126
|
+
parameter :scroll_direction, :string, enum: SCROLL_DIRECTION_OPTIONS, description: <<~TEXT
|
127
|
+
The direction to scroll. Required for the following actions:
|
128
|
+
* `#{Action::SCROLL}`
|
129
|
+
TEXT
|
130
|
+
|
131
|
+
parameter :scroll_amount, :integer, description: <<~TEXT
|
132
|
+
The amount of clicks to scroll. Required for the following actions:
|
133
|
+
* `#{Action::SCROLL}`
|
134
|
+
TEXT
|
135
|
+
|
136
|
+
required %i[action]
|
137
|
+
|
138
|
+
# @param driver [Computer::Driver]
|
139
|
+
def initialize(driver:, logger: Logger.new(IO::NULL))
|
140
|
+
@driver = driver
|
141
|
+
@logger = logger
|
142
|
+
super()
|
143
|
+
end
|
144
|
+
|
145
|
+
# @param action [String]
|
146
|
+
# @param coordinate [Hash<{ width: Integer, height: Integer }>] the (x,y) coordinate
|
147
|
+
# @param text [String]
|
148
|
+
# @param duration [Integer] the duration in seconds
|
149
|
+
# @param mouse_button [String] e.g. "left", "middle", "right"
|
150
|
+
# @param scroll_direction [String] e.g. "up", "down", "left", "right"
|
151
|
+
# @param scroll_amount [Integer] the amount of clicks to scroll
|
152
|
+
def execute(
|
153
|
+
action:,
|
154
|
+
coordinate: nil,
|
155
|
+
text: nil,
|
156
|
+
duration: nil,
|
157
|
+
mouse_button: nil,
|
158
|
+
scroll_direction: nil,
|
159
|
+
scroll_amount: nil
|
160
|
+
)
|
161
|
+
@logger.info({
|
162
|
+
action:,
|
163
|
+
coordinate:,
|
164
|
+
text:,
|
165
|
+
duration:,
|
166
|
+
mouse_button:,
|
167
|
+
scroll_direction:,
|
168
|
+
scroll_amount:,
|
169
|
+
}.compact.map { |key, value| "#{key}=#{value.inspect}" }.join(" "))
|
170
|
+
|
171
|
+
case action
|
172
|
+
when Action::KEY then @driver.key(text:)
|
173
|
+
when Action::HOLD_KEY then @driver.hold_key(text:, duration:)
|
174
|
+
when Action::MOUSE_POSITION then @driver.mouse_position
|
175
|
+
when Action::MOUSE_MOVE then @driver.mouse_move(coordinate:)
|
176
|
+
when Action::MOUSE_CLICK then @driver.mouse_click(coordinate:, button: mouse_button)
|
177
|
+
when Action::MOUSE_DOUBLE_CLICK then @driver.mouse_double_click(coordinate:, button: mouse_button)
|
178
|
+
when Action::MOUSE_TRIPLE_CLICK then @driver.mouse_triple_click(coordinate:, button: mouse_button)
|
179
|
+
when Action::MOUSE_DOWN then @driver.mouse_down(coordinate:, button: mouse_button)
|
180
|
+
when Action::MOUSE_UP then @driver.mouse_up(coordinate:, button: mouse_button)
|
181
|
+
when Action::MOUSE_DRAG then @driver.mouse_drag(coordinate:, button: mouse_button)
|
182
|
+
when Action::TYPE then @driver.type(text:)
|
183
|
+
when Action::SCROLL then @driver.scroll(amount: scroll_amount, direction: scroll_direction)
|
184
|
+
when Action::WAIT then @driver.wait(duration:)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OmniAI
|
4
|
+
module Tools
|
5
|
+
module Database
|
6
|
+
# Base class for database drivers (e.g. sqlite, postgres, mysql, etc).
|
7
|
+
class BaseDriver
|
8
|
+
# @param statement [String] e.g. "SELECT * FROM people"
|
9
|
+
#
|
10
|
+
# @return [Hash] e.g. { status: :ok, result: [["id", "name"], [1, "John"], [2, "Paul"], ...] }
|
11
|
+
def perform(statement:)
|
12
|
+
raise NotImplementedError, "#{self.class}##{__method__} undefined"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OmniAI
|
4
|
+
module Tools
|
5
|
+
module Database
|
6
|
+
# @example
|
7
|
+
# connection = PG.connect(dbname: "testdb")
|
8
|
+
# driver = OmniAI::Tools::Database::PostgresDriver.new
|
9
|
+
# driver.perform(statement: "SELECT * FROM people")
|
10
|
+
class PostgresDriver < BaseDriver
|
11
|
+
# @param connection [Sqlite3::Database]
|
12
|
+
def initialize(connection:)
|
13
|
+
super()
|
14
|
+
@connection = connection
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param statement [String]
|
18
|
+
#
|
19
|
+
# @return [Hash]
|
20
|
+
def perform(statement:)
|
21
|
+
@connection.exec(statement) do |result|
|
22
|
+
{ status: :ok, result: [result.fields] + result.values }
|
23
|
+
end
|
24
|
+
rescue ::PG::Error => e
|
25
|
+
{ status: :error, message: e.message }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OmniAI
|
4
|
+
module Tools
|
5
|
+
module Database
|
6
|
+
# @example
|
7
|
+
# driver = OmniAI::Tools::Database::SqliteDriver.new
|
8
|
+
# driver.perform(statement: "SELECT * FROM people")
|
9
|
+
class SqliteDriver < BaseDriver
|
10
|
+
# @param db [Sqlite3::Database]
|
11
|
+
def initialize(db:)
|
12
|
+
super()
|
13
|
+
@db = db
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param statement [String]
|
17
|
+
#
|
18
|
+
# @return [Hash]
|
19
|
+
def perform(statement:)
|
20
|
+
result = @db.execute2(statement)
|
21
|
+
|
22
|
+
{ status: :ok, result: }
|
23
|
+
rescue ::SQLite3::Exception => e
|
24
|
+
{ status: :error, message: e.message }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OmniAI
|
4
|
+
module Tools
|
5
|
+
# @example
|
6
|
+
# db = Sqlite3::Database.new("./db.sqlite")
|
7
|
+
# driver = OmniAI::Tools::Database::Sqlite.new(db:)
|
8
|
+
# tool = OmniAI::Tools::DatabaseTool.new(driver:)
|
9
|
+
# tool.execute(statements: ["SELECT * FROM people"])
|
10
|
+
class DatabaseTool < OmniAI::Tool
|
11
|
+
description <<~TEXT
|
12
|
+
Executes SQL commands (INSERT / UPDATE / SELECT / etc) on a database.
|
13
|
+
|
14
|
+
Example:
|
15
|
+
|
16
|
+
STATEMENTS:
|
17
|
+
|
18
|
+
[
|
19
|
+
'CREATE TABLE people (id INTEGER PRIMARY KEY, name TEXT NOT NULL)',
|
20
|
+
'INSERT INTO people (name) VALUES ('John')',
|
21
|
+
'INSERT INTO people (name) VALUES ('Paul')',
|
22
|
+
'SELECT * FROM people',
|
23
|
+
'DROP TABLE people'
|
24
|
+
]
|
25
|
+
|
26
|
+
RESULT:
|
27
|
+
|
28
|
+
[
|
29
|
+
{
|
30
|
+
"status": "OK",
|
31
|
+
"statement": "CREATE TABLE people (id INTEGER PRIMARY KEY, name TEXT NOT NULL)",
|
32
|
+
"result": "..."
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"status": "OK",
|
36
|
+
"statement": "INSERT INTO people (name) VALUES ('John')"
|
37
|
+
"result": "..."
|
38
|
+
},
|
39
|
+
{
|
40
|
+
"status": "OK",
|
41
|
+
"statement": "INSERT INTO people (name) VALUES ('Paul')",
|
42
|
+
"result": "..."
|
43
|
+
},
|
44
|
+
{
|
45
|
+
"status": "OK",
|
46
|
+
"statement": "SELECT * FROM people",
|
47
|
+
"result": "..."
|
48
|
+
},
|
49
|
+
{
|
50
|
+
"status": "OK",
|
51
|
+
"statement": "DROP TABLE people",
|
52
|
+
"result": "..."
|
53
|
+
}
|
54
|
+
]
|
55
|
+
TEXT
|
56
|
+
|
57
|
+
parameter(
|
58
|
+
:statements,
|
59
|
+
:array,
|
60
|
+
description: "A list of SQL statements to run sequentially.",
|
61
|
+
items: OmniAI::Schema.string(description: 'A SQL statement to run (e.g. "SELECT * FROM ...").')
|
62
|
+
)
|
63
|
+
|
64
|
+
required %i[statements]
|
65
|
+
|
66
|
+
# @param driver [OmniAI::Tools::Database::BaseDriver]
|
67
|
+
# @param logger [IO] An optional logger for debugging executed commands.
|
68
|
+
def initialize(driver:, logger: Logger.new(IO::NULL))
|
69
|
+
super()
|
70
|
+
@driver = driver
|
71
|
+
@logger = logger
|
72
|
+
end
|
73
|
+
|
74
|
+
# @example
|
75
|
+
# tool = OmniAI::Tools::Database::BaseTool.new
|
76
|
+
# tool.execute(statements: ["SELECT * FROM people"])
|
77
|
+
#
|
78
|
+
# @param statements [Array<String>]
|
79
|
+
#
|
80
|
+
# @return [Array<Hash>]
|
81
|
+
def execute(statements:)
|
82
|
+
[].tap do |executions|
|
83
|
+
statements.map do |statement|
|
84
|
+
execution = perform(statement:).merge(statement:)
|
85
|
+
executions << execution
|
86
|
+
break unless execution[:status].eql?(:ok)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def perform(statement:)
|
92
|
+
@logger&.info("#perform statement=#{statement.inspect}")
|
93
|
+
|
94
|
+
@driver.perform(statement:).tap do |result|
|
95
|
+
@logger&.info(JSON.generate(result))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/omniai/tools/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omniai-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Sylvestre
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: omniai
|
@@ -49,14 +49,40 @@ files:
|
|
49
49
|
- bin/console
|
50
50
|
- bin/setup
|
51
51
|
- lib/omniai/tools.rb
|
52
|
+
- lib/omniai/tools/browser/base_driver.rb
|
52
53
|
- lib/omniai/tools/browser/base_tool.rb
|
53
54
|
- lib/omniai/tools/browser/button_click_tool.rb
|
55
|
+
- lib/omniai/tools/browser/element_click_tool.rb
|
56
|
+
- lib/omniai/tools/browser/elements/element_grouper.rb
|
57
|
+
- lib/omniai/tools/browser/elements/nearby_element_detector.rb
|
58
|
+
- lib/omniai/tools/browser/formatters/action_formatter.rb
|
59
|
+
- lib/omniai/tools/browser/formatters/data_entry_formatter.rb
|
60
|
+
- lib/omniai/tools/browser/formatters/element_formatter.rb
|
61
|
+
- lib/omniai/tools/browser/formatters/input_formatter.rb
|
54
62
|
- lib/omniai/tools/browser/inspect_tool.rb
|
63
|
+
- lib/omniai/tools/browser/inspect_utils.rb
|
55
64
|
- lib/omniai/tools/browser/link_click_tool.rb
|
65
|
+
- lib/omniai/tools/browser/page_inspect/button_summarizer.rb
|
66
|
+
- lib/omniai/tools/browser/page_inspect/form_summarizer.rb
|
67
|
+
- lib/omniai/tools/browser/page_inspect/html_summarizer.rb
|
68
|
+
- lib/omniai/tools/browser/page_inspect/link_summarizer.rb
|
69
|
+
- lib/omniai/tools/browser/page_inspect_tool.rb
|
70
|
+
- lib/omniai/tools/browser/page_screenshot_tool.rb
|
71
|
+
- lib/omniai/tools/browser/selector_generator.rb
|
72
|
+
- lib/omniai/tools/browser/selector_generator/base_selectors.rb
|
73
|
+
- lib/omniai/tools/browser/selector_generator/contextual_selectors.rb
|
74
|
+
- lib/omniai/tools/browser/selector_inspect_tool.rb
|
56
75
|
- lib/omniai/tools/browser/text_field_area_set_tool.rb
|
57
76
|
- lib/omniai/tools/browser/visit_tool.rb
|
58
|
-
- lib/omniai/tools/
|
59
|
-
- lib/omniai/tools/
|
77
|
+
- lib/omniai/tools/browser/watir_driver.rb
|
78
|
+
- lib/omniai/tools/browser_tool.rb
|
79
|
+
- lib/omniai/tools/computer/base_driver.rb
|
80
|
+
- lib/omniai/tools/computer/mac_driver.rb
|
81
|
+
- lib/omniai/tools/computer_tool.rb
|
82
|
+
- lib/omniai/tools/database/base_driver.rb
|
83
|
+
- lib/omniai/tools/database/postgres_driver.rb
|
84
|
+
- lib/omniai/tools/database/sqlite_driver.rb
|
85
|
+
- lib/omniai/tools/database_tool.rb
|
60
86
|
- lib/omniai/tools/disk/base_tool.rb
|
61
87
|
- lib/omniai/tools/disk/directory_create_tool.rb
|
62
88
|
- lib/omniai/tools/disk/directory_delete_tool.rb
|
@@ -92,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
118
|
- !ruby/object:Gem::Version
|
93
119
|
version: '0'
|
94
120
|
requirements: []
|
95
|
-
rubygems_version: 3.6.
|
121
|
+
rubygems_version: 3.6.9
|
96
122
|
specification_version: 4
|
97
123
|
summary: A set of tools built for usage with OmniAI.
|
98
124
|
test_files: []
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "sqlite3"
|
4
|
-
|
5
|
-
module OmniAI
|
6
|
-
module Tools
|
7
|
-
module Database
|
8
|
-
# @example
|
9
|
-
# tool = OmniAI::Tools::Database::SqliteTool.new
|
10
|
-
# tool.execute(path: "./foo/bar")
|
11
|
-
class BaseTool < OmniAI::Tool
|
12
|
-
# @param logger [IO] An optional logger for debugging executed commands.
|
13
|
-
def initialize(logger: Logger.new(IO::NULL))
|
14
|
-
super()
|
15
|
-
@logger = logger
|
16
|
-
end
|
17
|
-
|
18
|
-
# @example
|
19
|
-
# tool = OmniAI::Tools::Database::BaseTool.new
|
20
|
-
# tool.execute(statements: ["SELECT * FROM people"])
|
21
|
-
#
|
22
|
-
# @param statements [Array<String>]
|
23
|
-
#
|
24
|
-
# @return [Array<Hash>]
|
25
|
-
def execute(statements:)
|
26
|
-
[].tap do |executions|
|
27
|
-
statements.map do |statement|
|
28
|
-
execution = perform(statement:)
|
29
|
-
executions << execution
|
30
|
-
break unless execution[:status].eql?(:ok)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,110 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "sqlite3"
|
4
|
-
|
5
|
-
module OmniAI
|
6
|
-
module Tools
|
7
|
-
module Database
|
8
|
-
# @example
|
9
|
-
# tool = OmniAI::Tools::Database::SqliteTool.new
|
10
|
-
# tool.execute(path: "./foo/bar")
|
11
|
-
class SqliteTool < BaseTool
|
12
|
-
description <<~TEXT
|
13
|
-
Executes SQL commands (INSERT / UPDATE / SELECT / etc) on a database.
|
14
|
-
|
15
|
-
Example:
|
16
|
-
|
17
|
-
STATEMENTS:
|
18
|
-
|
19
|
-
[
|
20
|
-
'CREATE TABLE people (id INTEGER PRIMARY KEY, name TEXT NOT NULL)',
|
21
|
-
'INSERT INTO people (name) VALUES ('John')',
|
22
|
-
'INSERT INTO people (name) VALUES ('Paul')',
|
23
|
-
'SELECT * FROM people',
|
24
|
-
'DROP TABLE people'
|
25
|
-
]
|
26
|
-
|
27
|
-
RESULT:
|
28
|
-
|
29
|
-
[
|
30
|
-
{
|
31
|
-
"status": "OK",
|
32
|
-
"statement": "CREATE TABLE people (id INTEGER PRIMARY KEY, name TEXT NOT NULL)",
|
33
|
-
"result": "..."
|
34
|
-
},
|
35
|
-
{
|
36
|
-
"status": "OK",
|
37
|
-
"statement": "INSERT INTO people (name) VALUES ('John')"
|
38
|
-
"result": "..."
|
39
|
-
},
|
40
|
-
{
|
41
|
-
"status": "OK",
|
42
|
-
"statement": "INSERT INTO people (name) VALUES ('Paul')",
|
43
|
-
"result": "..."
|
44
|
-
},
|
45
|
-
{
|
46
|
-
"status": "OK",
|
47
|
-
"statement": "SELECT * FROM people",
|
48
|
-
"result": "..."
|
49
|
-
},
|
50
|
-
{
|
51
|
-
"status": "OK",
|
52
|
-
"statement": "DROP TABLE people",
|
53
|
-
"result": "..."
|
54
|
-
}
|
55
|
-
]
|
56
|
-
TEXT
|
57
|
-
|
58
|
-
parameter(
|
59
|
-
:statements,
|
60
|
-
:array,
|
61
|
-
description: "A list of SQL statements to run sequentially.",
|
62
|
-
items: OmniAI::Schema.string(description: 'A SQL statement to run (e.g. "SELECT * FROM ...").')
|
63
|
-
)
|
64
|
-
|
65
|
-
required %i[statements]
|
66
|
-
|
67
|
-
# @param logger [IO] An optional logger for debugging executed commands.
|
68
|
-
# @param db [SQLite3::Database] A sqlite database.
|
69
|
-
def initialize(db:, logger: Logger.new(IO::NULL))
|
70
|
-
super(logger:)
|
71
|
-
@db = db
|
72
|
-
end
|
73
|
-
|
74
|
-
# @example
|
75
|
-
# tool = OmniAI::Tools::Database::BaseTool.new
|
76
|
-
# tool.execute(statements: ["SELECT * FROM people"])
|
77
|
-
#
|
78
|
-
# @param statements [Array<String>]
|
79
|
-
#
|
80
|
-
# @return [Array<Hash>]
|
81
|
-
def execute(statements:)
|
82
|
-
@logger.info("#{self.class.name}#{__method__} statements=#{statements.inspect}")
|
83
|
-
|
84
|
-
[].tap do |executions|
|
85
|
-
statements.map do |statement|
|
86
|
-
execution = perform(statement:)
|
87
|
-
executions << execution
|
88
|
-
break unless execution[:status].eql?(:ok)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
protected
|
94
|
-
|
95
|
-
# @param statement [String]
|
96
|
-
#
|
97
|
-
# @return [Hash]
|
98
|
-
def perform(statement:)
|
99
|
-
result = @db.execute2(statement)
|
100
|
-
|
101
|
-
{ status: :ok, statement:, result: }
|
102
|
-
rescue ::SQLite3::Exception => e
|
103
|
-
@logger.warn("ERROR: #{e.message}")
|
104
|
-
|
105
|
-
{ status: :error, statement:, result: e.message }
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|