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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f361e26584723aa8d30ba41edaefafb44a7e08c5c6345656dbf25e37c965448d
4
- data.tar.gz: c718feeb39dfdd1c2c5ff9a2976ece26eec48aae12f52405724fc21209101d32
3
+ metadata.gz: d27871f61c1d70be893cce085bf33c0b3d9280686ff1a0ba64f35835b7bf10d4
4
+ data.tar.gz: 6dfddb639a3cbb99069cbb890bb5d8529bf152e5c246bcc90aaf344505758ea9
5
5
  SHA512:
6
- metadata.gz: fa14b3333edc0b235e046d9f408f75f201ea37be76435d897873fb7585999cd0aeac3d36c86c16e72a772ab6a28f48dd40560074767720736583de79a80d8847
7
- data.tar.gz: 6ec511fc27bae83abdf0d827572ad2784419039b0d37d128d5670b19d58645a8e6efd82bfb7132397473181b56897f966314396a76172aaec33883826ff14f12
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: }
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OmniAI
4
4
  module Tools
5
- VERSION = "0.4.0"
5
+ VERSION = "0.5.0"
6
6
  end
7
7
  end
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.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-14 00:00:00.000000000 Z
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