charai 0.1.0 → 0.2.0.beta1
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/README.md +3 -0
- data/lib/charai/agent.rb +1 -1
- data/lib/charai/browsing_context.rb +103 -6
- data/lib/charai/driver.rb +44 -9
- data/lib/charai/injectedScriptSource.js +34 -0
- data/lib/charai/injected_script.rb +40 -0
- data/lib/charai/input_tool.rb +59 -0
- data/lib/charai/openai_configuration.rb +20 -0
- data/lib/charai/version.rb +1 -1
- data/lib/charai.rb +1 -0
- metadata +4 -2
@@ -0,0 +1,40 @@
|
|
1
|
+
module Charai
|
2
|
+
class InjectedScript
|
3
|
+
def initialize(realm, handle)
|
4
|
+
@realm = realm
|
5
|
+
@handle = handle
|
6
|
+
end
|
7
|
+
|
8
|
+
def e(value)
|
9
|
+
@realm.script_evaluate(value, as_handle: false)
|
10
|
+
end
|
11
|
+
|
12
|
+
def h(value)
|
13
|
+
@realm.script_evaluate(value, as_handle: true)
|
14
|
+
end
|
15
|
+
|
16
|
+
def getprop(name, as_handle: false)
|
17
|
+
c(
|
18
|
+
function_declaration: "(injected) => injected.#{name}",
|
19
|
+
as_handle: as_handle,
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def call(name, *args, as_handle: false)
|
24
|
+
c(
|
25
|
+
function_declaration: "(injected, ...args) => injected.#{name}(...args)",
|
26
|
+
args: args,
|
27
|
+
as_handle: as_handle,
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def c(function_declaration:, args: [], as_handle: false)
|
34
|
+
@realm.script_call_function(
|
35
|
+
function_declaration,
|
36
|
+
arguments: [@handle, *args],
|
37
|
+
as_handle: as_handle)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/charai/input_tool.rb
CHANGED
@@ -31,6 +31,31 @@ module Charai
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
def aria_snapshot(root_locator: 'document.body', ref: false)
|
35
|
+
trigger_callback(:on_action_start, 'aria_snapshot', { root_locator: root_locator, ref: ref })
|
36
|
+
|
37
|
+
current_url = @browsing_context.url
|
38
|
+
snapshot = @browsing_context.default_realm._with_injected_script do |script|
|
39
|
+
if ref
|
40
|
+
body_handle = script.getprop("document.body", as_handle: true)
|
41
|
+
result = script.call(:ariaSnapshot, body_handle, { mode: 'ai' })
|
42
|
+
result.split("\n")
|
43
|
+
else
|
44
|
+
not_found = script.e("!#{root_locator}")
|
45
|
+
if not_found
|
46
|
+
raise ArgumentError, "Element not found: #{root_locator}"
|
47
|
+
end
|
48
|
+
result = script.call(:ariaSnapshot, script.h(root_locator), { mode: 'autoexpect' })
|
49
|
+
result.split("\n")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
if @message_sender
|
54
|
+
message = Agent::Message.new(text: "ARIA snapshot of #{current_url}\n\n#{snapshot}")
|
55
|
+
@message_sender.call(message)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
34
59
|
def capture_screenshot
|
35
60
|
trigger_callback(:on_action_start, 'capture_screenshot', {})
|
36
61
|
|
@@ -73,6 +98,23 @@ module Charai
|
|
73
98
|
result
|
74
99
|
end
|
75
100
|
|
101
|
+
def execute_script_with_ref(ref, element_function_declaration)
|
102
|
+
resolved = resolve_selector_for_ref(ref)
|
103
|
+
trigger_callback(:on_action_start, 'execute_script_with_ref', { script: element_function_declaration, ref: ref, selector: resolved[:selector] })
|
104
|
+
|
105
|
+
begin
|
106
|
+
result = @browsing_context.default_realm.script_call_function(
|
107
|
+
element_function_declaration,
|
108
|
+
arguments: [resolved[:element_handle]])
|
109
|
+
rescue BrowsingContext::Realm::ScriptEvaluationError => e
|
110
|
+
result = e.message
|
111
|
+
end
|
112
|
+
|
113
|
+
notify_to_sender(result) unless "#{result}" == ''
|
114
|
+
|
115
|
+
result
|
116
|
+
end
|
117
|
+
|
76
118
|
def on_pressing_key(key, &block)
|
77
119
|
trigger_callback(:on_action_start, 'key_down', { key: key })
|
78
120
|
|
@@ -175,6 +217,23 @@ module Charai
|
|
175
217
|
end
|
176
218
|
end
|
177
219
|
|
220
|
+
def resolve_selector_for_ref(ref)
|
221
|
+
@browsing_context.default_realm._with_injected_script do |script|
|
222
|
+
parsed = script.call(:parseSelector, "aria-ref=#{ref}")
|
223
|
+
|
224
|
+
# ensure ref is attached.
|
225
|
+
body_handle = script.getprop("document.body", as_handle: true)
|
226
|
+
script.call(:ariaSnapshot, body_handle, { mode: 'ai' })
|
227
|
+
|
228
|
+
document_handle = script.getprop('document', as_handle: true)
|
229
|
+
element_handle = script.call(:querySelector, parsed, document_handle, false, as_handle: true)
|
230
|
+
|
231
|
+
selector = script.call(:generateSelectorSimple, element_handle, { omitInternalEngines: true })
|
232
|
+
|
233
|
+
{ selector: selector, element_handle: element_handle }
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
178
237
|
# ref: https://github.com/puppeteer/puppeteer/blob/puppeteer-v23.5.3/packages/puppeteer-core/src/bidi/Input.ts#L52
|
179
238
|
# Converted using ChatGPT 4o
|
180
239
|
def convert_key(key)
|
@@ -19,6 +19,26 @@ module Charai
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
class GeminiOpenaiConfiguration
|
23
|
+
def initialize(model:, api_key:)
|
24
|
+
@endpoint_url = 'https://generativelanguage.googleapis.com/v1beta/openai/'
|
25
|
+
@model = model
|
26
|
+
@api_key = api_key
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_reader :endpoint_url
|
30
|
+
|
31
|
+
def add_auth_header(headers)
|
32
|
+
headers['Authorization'] = "Bearer #{@api_key}"
|
33
|
+
headers
|
34
|
+
end
|
35
|
+
|
36
|
+
def decorate_body(payload)
|
37
|
+
payload[:model] = @model
|
38
|
+
payload
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
22
42
|
class AzureOpenaiConfiguration
|
23
43
|
def initialize(endpoint_url:, api_key:)
|
24
44
|
@endpoint_url = endpoint_url
|
data/lib/charai/version.rb
CHANGED
data/lib/charai.rb
CHANGED
@@ -10,6 +10,7 @@ require 'charai/browser_launcher'
|
|
10
10
|
require 'charai/browser_process'
|
11
11
|
require 'charai/browsing_context'
|
12
12
|
require 'charai/driver'
|
13
|
+
require 'charai/injected_script'
|
13
14
|
require 'charai/input_tool'
|
14
15
|
require 'charai/openai_chat'
|
15
16
|
require 'charai/openai_configuration'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: charai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- YusukeIwaki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capybara
|
@@ -75,6 +75,8 @@ files:
|
|
75
75
|
- lib/charai/browser_process.rb
|
76
76
|
- lib/charai/browsing_context.rb
|
77
77
|
- lib/charai/driver.rb
|
78
|
+
- lib/charai/injectedScriptSource.js
|
79
|
+
- lib/charai/injected_script.rb
|
78
80
|
- lib/charai/input_tool.rb
|
79
81
|
- lib/charai/openai_chat.rb
|
80
82
|
- lib/charai/openai_configuration.rb
|