omniai-tools 0.4.0 → 0.5.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 +6 -0
- data/README.md +54 -0
- data/lib/omniai/tools/browser/base_tool.rb +23 -0
- data/lib/omniai/tools/browser/button_click_tool.rb +40 -0
- data/lib/omniai/tools/browser/inspect_tool.rb +31 -0
- data/lib/omniai/tools/browser/link_click_tool.rb +38 -0
- data/lib/omniai/tools/browser/text_field_area_set_tool.rb +59 -0
- data/lib/omniai/tools/browser/visit_tool.rb +28 -0
- data/lib/omniai/tools/database/sqlite_tool.rb +2 -2
- data/lib/omniai/tools/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d27871f61c1d70be893cce085bf33c0b3d9280686ff1a0ba64f35835b7bf10d4
|
4
|
+
data.tar.gz: 6dfddb639a3cbb99069cbb890bb5d8529bf152e5c246bcc90aaf344505758ea9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff02138674bc5176e869badb4268530d025e5543ca993eaea8aa74ee2ad114592bd5ac3e8ecd8ad8a882ec0af6dd57b9d74448b04669d3fe8295db3c9176e7b8
|
7
|
+
data.tar.gz: c8a79aa2542b81475148b878ab7785d8bea1b32e4649718bd2a5d4684ba897e010da3d392ce9f3da38374f51e10ea2fc074a3a07a2392172a6c68e93f9298aa5
|
data/Gemfile
CHANGED
@@ -6,6 +6,11 @@ gemspec
|
|
6
6
|
|
7
7
|
gem "factory_bot"
|
8
8
|
gem "irb"
|
9
|
+
gem "nokogiri"
|
10
|
+
gem "omniai-anthropic"
|
11
|
+
gem "omniai-google"
|
12
|
+
gem "omniai-mistral"
|
13
|
+
gem "omniai-openai"
|
9
14
|
gem "rake"
|
10
15
|
gem "redcarpet"
|
11
16
|
gem "rspec"
|
@@ -17,4 +22,5 @@ gem "rubocop-rake"
|
|
17
22
|
gem "rubocop-rspec"
|
18
23
|
gem "simplecov"
|
19
24
|
gem "sqlite3"
|
25
|
+
gem "watir"
|
20
26
|
gem "yard"
|
data/README.md
CHANGED
@@ -8,6 +8,60 @@
|
|
8
8
|
|
9
9
|
`OmniAI::Tools` is a library of pre-built tools to simplify integrating common tasks with [OmniAI](https://github.com/ksylvest/omniai).
|
10
10
|
|
11
|
+
## Browser
|
12
|
+
|
13
|
+
Database tools are focused on running SQL statements:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
require "omniai/openai"
|
17
|
+
require "omniai/tools"
|
18
|
+
|
19
|
+
require "watir"
|
20
|
+
|
21
|
+
browser = Watir::Browser.new(:chrome)
|
22
|
+
|
23
|
+
client = OmniAI::OpenAI::Client.new
|
24
|
+
logger = Logger.new($stdout)
|
25
|
+
|
26
|
+
tools = [
|
27
|
+
OmniAI::Tools::Browser::VisitTool,
|
28
|
+
OmniAI::Tools::Browser::InspectTool,
|
29
|
+
OmniAI::Tools::Browser::ButtonClickTool,
|
30
|
+
OmniAI::Tools::Browser::LinkClickTool,
|
31
|
+
OmniAI::Tools::Browser::TextFieldAreaSetTool,
|
32
|
+
].map { |klass| klass.new(browser:, logger:) }
|
33
|
+
|
34
|
+
puts "Type 'exit' or 'quit' to leave."
|
35
|
+
|
36
|
+
prompt = OmniAI::Chat::Prompt.build do |builder|
|
37
|
+
builder.system <<~TEXT
|
38
|
+
You are tasked with assisting a user in browsing the web.
|
39
|
+
TEXT
|
40
|
+
end
|
41
|
+
|
42
|
+
loop do
|
43
|
+
print "# "
|
44
|
+
text = gets.strip
|
45
|
+
break if %w[exit quit].include?(text)
|
46
|
+
|
47
|
+
prompt.user(text)
|
48
|
+
response = client.chat(prompt, stream: $stdout, tools:)
|
49
|
+
prompt.assistant(response.text)
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
```
|
54
|
+
Type 'exit' or 'quit' to leave.
|
55
|
+
# Visit news.ycombinator.com and list the top 5 posts.
|
56
|
+
|
57
|
+
[browser] OmniAI::Tools::Browser::VisitTool#execute url="https://news.ycombinator.com"
|
58
|
+
[browser] OmniAI::Tools::Browser::InspectTool#execute
|
59
|
+
|
60
|
+
Here are the top 5 posts on Hacker News right now:
|
61
|
+
|
62
|
+
...
|
63
|
+
```
|
64
|
+
|
11
65
|
## Database
|
12
66
|
|
13
67
|
Database tools are focused on running SQL statements:
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "watir"
|
4
|
+
|
5
|
+
module OmniAI
|
6
|
+
module Tools
|
7
|
+
module Browser
|
8
|
+
# @example
|
9
|
+
# class SeleniumTool < BaseTool
|
10
|
+
# # ...
|
11
|
+
# end
|
12
|
+
class BaseTool < OmniAI::Tool
|
13
|
+
# @param logger [IO] An optional logger for debugging executed commands.
|
14
|
+
# @param browser [Watir::Browser]
|
15
|
+
def initialize(browser:, logger: Logger.new(IO::NULL))
|
16
|
+
super()
|
17
|
+
@logger = logger
|
18
|
+
@browser = browser
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sqlite3"
|
4
|
+
|
5
|
+
module OmniAI
|
6
|
+
module Tools
|
7
|
+
module Browser
|
8
|
+
# @example
|
9
|
+
# browser = Watir::Browser.new(:chrome)
|
10
|
+
# tool = OmniAI::Tools::Browser::VisitTool.new(browser:)
|
11
|
+
# tool.click_link(selector: "link_id")
|
12
|
+
class ButtonClickTool < BaseTool
|
13
|
+
description "A browser automation tool for clicking a specific button."
|
14
|
+
|
15
|
+
parameter :selector, :string, description: "The ID or text of the button to interact with."
|
16
|
+
|
17
|
+
required %i[selector]
|
18
|
+
|
19
|
+
# @param to [String] The URL to navigate to.
|
20
|
+
def execute(selector:)
|
21
|
+
@logger.info("#{self.class.name}##{__method__} selector=#{selector.inspect}")
|
22
|
+
|
23
|
+
element = find(text: selector) || find(id: selector)
|
24
|
+
|
25
|
+
return { error: "unknown selector=#{selector}" } if element.nil?
|
26
|
+
|
27
|
+
element.click
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
# @return [Watir::Anchor, nil]
|
33
|
+
def find(selector)
|
34
|
+
element = @browser.button(selector)
|
35
|
+
element if element.exists?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "nokogiri"
|
4
|
+
|
5
|
+
module OmniAI
|
6
|
+
module Tools
|
7
|
+
module Browser
|
8
|
+
# @example
|
9
|
+
# browser = Watir::Browser.new(:chrome)
|
10
|
+
# tool = OmniAI::Tools::Browser::InspectTool.new(browser:)
|
11
|
+
# tool.execute
|
12
|
+
class InspectTool < BaseTool
|
13
|
+
description "A browser automation tool for viewing the HTML for the browser."
|
14
|
+
|
15
|
+
# @return [String]
|
16
|
+
def execute
|
17
|
+
@logger.info("#{self.class.name}##{__method__}")
|
18
|
+
|
19
|
+
html = @browser.html
|
20
|
+
doc = Nokogiri::HTML(html)
|
21
|
+
|
22
|
+
doc.css("link").each(&:remove)
|
23
|
+
doc.css("style").each(&:remove)
|
24
|
+
doc.css("script").each(&:remove)
|
25
|
+
|
26
|
+
doc.to_html
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sqlite3"
|
4
|
+
|
5
|
+
module OmniAI
|
6
|
+
module Tools
|
7
|
+
module Browser
|
8
|
+
# @example
|
9
|
+
# browser = Watir::Browser.new(:chrome)
|
10
|
+
# tool = OmniAI::Tools::Browser::VisitTool.new(browser:)
|
11
|
+
# tool.click_link(selector: "link_id")
|
12
|
+
class LinkClickTool < BaseTool
|
13
|
+
description "A browser automation tool for clicking a specific link."
|
14
|
+
|
15
|
+
parameter :selector, :string, description: "The ID or text of the link to interact with."
|
16
|
+
|
17
|
+
# @param to [String] The ID or text of the link to interact with.
|
18
|
+
def execute(selector:)
|
19
|
+
@logger.info("#{self.class.name}##{__method__} selector=#{selector.inspect}")
|
20
|
+
|
21
|
+
element = find(text: selector) || find(value: selector) || find(id: selector)
|
22
|
+
|
23
|
+
return { error: "unknown selector=#{selector}" } if element.nil?
|
24
|
+
|
25
|
+
element.click
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
# @return [Watir::Anchor, nil]
|
31
|
+
def find(selector)
|
32
|
+
element = @browser.a(selector)
|
33
|
+
element if element.exists?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sqlite3"
|
4
|
+
|
5
|
+
module OmniAI
|
6
|
+
module Tools
|
7
|
+
module Browser
|
8
|
+
# @example
|
9
|
+
# browser = Watir::Browser.new(:chrome)
|
10
|
+
# tool = OmniAI::Tools::Browser::TextFieldSetTool.new(browser:)
|
11
|
+
# tool.execute(selector: "...", text: "...")
|
12
|
+
class TextFieldAreaSetTool < BaseTool
|
13
|
+
description "A browser automation tool for clicking a specific link."
|
14
|
+
|
15
|
+
parameter :selector, :string, description: "The ID / name of the text field / area to interact with."
|
16
|
+
parameter :text, :string, description: "The text to set."
|
17
|
+
|
18
|
+
required %i[selector]
|
19
|
+
|
20
|
+
# @param selector [String] The ID / name of the text field / text area to interact with.
|
21
|
+
# @param text [String] The text to set.
|
22
|
+
def execute(selector:, text:)
|
23
|
+
@logger.info("#{self.class.name}##{__method__} selector=#{selector.inspect} text=#{text.inspect}")
|
24
|
+
|
25
|
+
element = find(id: selector) || find(name: selector)
|
26
|
+
|
27
|
+
return { error: "unknown selector=#{selector}" } if element.nil?
|
28
|
+
|
29
|
+
element.set(text)
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
# @param selector [Hash]
|
35
|
+
#
|
36
|
+
# @return [Watir::TextArea, Watir::TextField, nil]
|
37
|
+
def find(selector)
|
38
|
+
find_text_area(selector) || find_text_field(selector)
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param selector [Hash]
|
42
|
+
#
|
43
|
+
# @return [Watir::TextArea, nil]
|
44
|
+
def find_text_area(selector)
|
45
|
+
element = @browser.textarea(selector)
|
46
|
+
element if element.exists?
|
47
|
+
end
|
48
|
+
|
49
|
+
# @param selector [Hash]
|
50
|
+
#
|
51
|
+
# @return [Watir::TextField, nil]
|
52
|
+
def find_text_field(selector)
|
53
|
+
element = @browser.text_field(selector)
|
54
|
+
element if element.exists?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sqlite3"
|
4
|
+
|
5
|
+
module OmniAI
|
6
|
+
module Tools
|
7
|
+
module Browser
|
8
|
+
# @example
|
9
|
+
# driver = Selenium::WebDriver.for :chrome
|
10
|
+
# tool = OmniAI::Tools::Browser::VisitTool.new(driver:)
|
11
|
+
# tool.execute(to: "https://news.ycombinator.com")
|
12
|
+
class VisitTool < BaseTool
|
13
|
+
description "A browser automation tool for navigating to a specific URL."
|
14
|
+
|
15
|
+
parameter :url, :string, description: "A URL (e.g. https://news.ycombinator.com)."
|
16
|
+
|
17
|
+
required %i[url]
|
18
|
+
|
19
|
+
# @param url [String] A URL (e.g. https://news.ycombinator.com).
|
20
|
+
def execute(url:)
|
21
|
+
@logger.info("#{self.class.name}##{__method__} url=#{url.inspect}")
|
22
|
+
|
23
|
+
@browser.goto(url)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -79,6 +79,8 @@ module OmniAI
|
|
79
79
|
#
|
80
80
|
# @return [Array<Hash>]
|
81
81
|
def execute(statements:)
|
82
|
+
@logger.info("#{self.class.name}#{__method__} statements=#{statements.inspect}")
|
83
|
+
|
82
84
|
[].tap do |executions|
|
83
85
|
statements.map do |statement|
|
84
86
|
execution = perform(statement:)
|
@@ -94,8 +96,6 @@ module OmniAI
|
|
94
96
|
#
|
95
97
|
# @return [Hash]
|
96
98
|
def perform(statement:)
|
97
|
-
@logger.info(%(#{self.class.name}#perform statement=#{statement.inspect}))
|
98
|
-
|
99
99
|
result = @db.execute2(statement)
|
100
100
|
|
101
101
|
{ status: :ok, statement:, result: }
|
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.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Sylvestre
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-05-
|
10
|
+
date: 2025-05-15 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: omniai
|
@@ -49,6 +49,12 @@ files:
|
|
49
49
|
- bin/console
|
50
50
|
- bin/setup
|
51
51
|
- lib/omniai/tools.rb
|
52
|
+
- lib/omniai/tools/browser/base_tool.rb
|
53
|
+
- lib/omniai/tools/browser/button_click_tool.rb
|
54
|
+
- lib/omniai/tools/browser/inspect_tool.rb
|
55
|
+
- lib/omniai/tools/browser/link_click_tool.rb
|
56
|
+
- lib/omniai/tools/browser/text_field_area_set_tool.rb
|
57
|
+
- lib/omniai/tools/browser/visit_tool.rb
|
52
58
|
- lib/omniai/tools/database/base_tool.rb
|
53
59
|
- lib/omniai/tools/database/sqlite_tool.rb
|
54
60
|
- lib/omniai/tools/disk/base_tool.rb
|