pocketrb 0.1.0 → 0.3.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/CHANGELOG.md +37 -0
- data/README.md +98 -17
- data/lib/pocketrb/agent/compaction.rb +235 -22
- data/lib/pocketrb/agent/context.rb +26 -3
- data/lib/pocketrb/agent/loop.rb +53 -5
- data/lib/pocketrb/agent/spawn_tool.rb +14 -0
- data/lib/pocketrb/agent/subagent_manager.rb +24 -2
- data/lib/pocketrb/bus/events.rb +42 -1
- data/lib/pocketrb/bus/message_bus.rb +37 -0
- data/lib/pocketrb/channels/base.rb +13 -0
- data/lib/pocketrb/channels/cli.rb +16 -1
- data/lib/pocketrb/channels/telegram.rb +70 -4
- data/lib/pocketrb/channels/whatsapp.rb +49 -7
- data/lib/pocketrb/cli/chat.rb +7 -0
- data/lib/pocketrb/cli/config.rb +4 -0
- data/lib/pocketrb/cli/cron.rb +6 -0
- data/lib/pocketrb/cli.rb +0 -1
- data/lib/pocketrb/config.rb +55 -6
- data/lib/pocketrb/cron/job.rb +41 -0
- data/lib/pocketrb/cron/service.rb +44 -15
- data/lib/pocketrb/heartbeat/service.rb +21 -0
- data/lib/pocketrb/mcp/client.rb +41 -3
- data/lib/pocketrb/mcp/memory_tool.rb +33 -0
- data/lib/pocketrb/media/processor.rb +32 -1
- data/lib/pocketrb/memory.rb +12 -3
- data/lib/pocketrb/planning/manager.rb +29 -1
- data/lib/pocketrb/planning/plan.rb +52 -0
- data/lib/pocketrb/planning/tool.rb +45 -0
- data/lib/pocketrb/providers/anthropic.rb +113 -9
- data/lib/pocketrb/providers/base.rb +39 -4
- data/lib/pocketrb/providers/claude_cli.rb +79 -7
- data/lib/pocketrb/providers/claude_max_proxy.rb +72 -6
- data/lib/pocketrb/providers/openai_compatible.rb +79 -0
- data/lib/pocketrb/providers/openrouter.rb +72 -12
- data/lib/pocketrb/providers/registry.rb +24 -0
- data/lib/pocketrb/providers/ruby_llm_provider.rb +168 -54
- data/lib/pocketrb/providers/types.rb +51 -1
- data/lib/pocketrb/session/manager.rb +34 -2
- data/lib/pocketrb/session/session.rb +53 -11
- data/lib/pocketrb/skills/builtin/tmux/SKILL.md +9 -9
- data/lib/pocketrb/skills/create_tool.rb +28 -0
- data/lib/pocketrb/skills/loader.rb +22 -1
- data/lib/pocketrb/skills/modify_tool.rb +22 -0
- data/lib/pocketrb/skills/skill.rb +19 -3
- data/lib/pocketrb/tools/background_job_manager.rb +29 -0
- data/lib/pocketrb/tools/base.rb +16 -1
- data/lib/pocketrb/tools/browser.rb +40 -0
- data/lib/pocketrb/tools/browser_advanced.rb +94 -4
- data/lib/pocketrb/tools/browser_session.rb +18 -0
- data/lib/pocketrb/tools/cron.rb +46 -0
- data/lib/pocketrb/tools/edit_file.rb +16 -0
- data/lib/pocketrb/tools/exec.rb +46 -0
- data/lib/pocketrb/tools/jobs.rb +26 -2
- data/lib/pocketrb/tools/list_dir.rb +19 -0
- data/lib/pocketrb/tools/memory.rb +34 -0
- data/lib/pocketrb/tools/message.rb +15 -0
- data/lib/pocketrb/tools/para_memory.rb +47 -0
- data/lib/pocketrb/tools/read_file.rb +11 -0
- data/lib/pocketrb/tools/registry.rb +12 -4
- data/lib/pocketrb/tools/send_file.rb +29 -0
- data/lib/pocketrb/tools/think.rb +9 -0
- data/lib/pocketrb/tools/web_fetch.rb +58 -3
- data/lib/pocketrb/tools/web_search.rb +25 -0
- data/lib/pocketrb/tools/write_file.rb +10 -0
- data/lib/pocketrb/version.rb +2 -1
- data/lib/pocketrb.rb +4 -1
- data/pocketrb.gemspec +6 -8
- metadata +24 -44
|
@@ -4,6 +4,7 @@ module Pocketrb
|
|
|
4
4
|
module Tools
|
|
5
5
|
# Tool for sending files/images to chat channels
|
|
6
6
|
class SendFile < Base
|
|
7
|
+
# Allowed file extensions for sending
|
|
7
8
|
ALLOWED_EXTENSIONS = %w[
|
|
8
9
|
.jpg .jpeg .png .gif .webp .bmp
|
|
9
10
|
.pdf .txt .md .json .csv .xml
|
|
@@ -12,14 +13,20 @@ module Pocketrb
|
|
|
12
13
|
.zip .tar .gz
|
|
13
14
|
].freeze
|
|
14
15
|
|
|
16
|
+
# Tool name
|
|
17
|
+
# @return [String]
|
|
15
18
|
def name
|
|
16
19
|
"send_file"
|
|
17
20
|
end
|
|
18
21
|
|
|
22
|
+
# Tool description
|
|
23
|
+
# @return [String]
|
|
19
24
|
def description
|
|
20
25
|
"Send a file (image, document, audio, video) to the user via chat. Use this to share generated content, screenshots, reports, or any files."
|
|
21
26
|
end
|
|
22
27
|
|
|
28
|
+
# Parameter schema
|
|
29
|
+
# @return [Hash]
|
|
23
30
|
def parameters
|
|
24
31
|
{
|
|
25
32
|
type: "object",
|
|
@@ -45,6 +52,12 @@ module Pocketrb
|
|
|
45
52
|
}
|
|
46
53
|
end
|
|
47
54
|
|
|
55
|
+
# Execute file sending
|
|
56
|
+
# @param path [String] File path to send
|
|
57
|
+
# @param caption [String, nil] Optional caption text
|
|
58
|
+
# @param channel [String, nil] Target channel name
|
|
59
|
+
# @param chat_id [String, nil] Target chat identifier
|
|
60
|
+
# @return [String] Success or error message
|
|
48
61
|
def execute(path:, caption: nil, channel: nil, chat_id: nil)
|
|
49
62
|
# Resolve path
|
|
50
63
|
file_path = resolve_path(path)
|
|
@@ -84,22 +97,32 @@ module Pocketrb
|
|
|
84
97
|
success("Sent #{File.basename(file_path)} to #{channel}")
|
|
85
98
|
end
|
|
86
99
|
|
|
100
|
+
# Check if tool is available
|
|
101
|
+
# @return [Boolean] true if message bus is available
|
|
87
102
|
def available?
|
|
88
103
|
!bus.nil?
|
|
89
104
|
end
|
|
90
105
|
|
|
91
106
|
private
|
|
92
107
|
|
|
108
|
+
# Access the message bus from context
|
|
109
|
+
# @return [Object, nil]
|
|
93
110
|
def bus
|
|
94
111
|
@context[:bus]
|
|
95
112
|
end
|
|
96
113
|
|
|
114
|
+
# Resolve a path, using workspace as base for relative paths
|
|
115
|
+
# @param path [String] file path to resolve
|
|
116
|
+
# @return [String] absolute file path
|
|
97
117
|
def resolve_path(path)
|
|
98
118
|
return path if Pathname.new(path).absolute?
|
|
99
119
|
|
|
100
120
|
workspace.join(path).to_s
|
|
101
121
|
end
|
|
102
122
|
|
|
123
|
+
# Create a media object from a file path
|
|
124
|
+
# @param path [String] path to the file
|
|
125
|
+
# @return [Bus::Media] media object for sending
|
|
103
126
|
def create_media(path)
|
|
104
127
|
ext = File.extname(path).downcase
|
|
105
128
|
mime_type = detect_mime_type(ext)
|
|
@@ -114,6 +137,9 @@ module Pocketrb
|
|
|
114
137
|
)
|
|
115
138
|
end
|
|
116
139
|
|
|
140
|
+
# Detect media type from file extension
|
|
141
|
+
# @param ext [String] file extension (e.g. ".png")
|
|
142
|
+
# @return [Symbol] media type (:image, :audio, :video, or :file)
|
|
117
143
|
def detect_type(ext)
|
|
118
144
|
case ext
|
|
119
145
|
when ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp"
|
|
@@ -127,6 +153,9 @@ module Pocketrb
|
|
|
127
153
|
end
|
|
128
154
|
end
|
|
129
155
|
|
|
156
|
+
# Detect MIME type from file extension
|
|
157
|
+
# @param ext [String] file extension (e.g. ".png")
|
|
158
|
+
# @return [String] MIME type string
|
|
130
159
|
def detect_mime_type(ext)
|
|
131
160
|
{
|
|
132
161
|
".jpg" => "image/jpeg",
|
data/lib/pocketrb/tools/think.rb
CHANGED
|
@@ -4,14 +4,20 @@ module Pocketrb
|
|
|
4
4
|
module Tools
|
|
5
5
|
# Internal reasoning tool for complex problem solving
|
|
6
6
|
class Think < Base
|
|
7
|
+
# Tool name
|
|
8
|
+
# @return [String]
|
|
7
9
|
def name
|
|
8
10
|
"think"
|
|
9
11
|
end
|
|
10
12
|
|
|
13
|
+
# Tool description
|
|
14
|
+
# @return [String]
|
|
11
15
|
def description
|
|
12
16
|
"Use this tool to think through complex problems step by step. The content is not shown to the user but helps you reason through the task. Use it when you need to analyze information, plan an approach, or work through logic."
|
|
13
17
|
end
|
|
14
18
|
|
|
19
|
+
# Parameter schema
|
|
20
|
+
# @return [Hash]
|
|
15
21
|
def parameters
|
|
16
22
|
{
|
|
17
23
|
type: "object",
|
|
@@ -25,6 +31,9 @@ module Pocketrb
|
|
|
25
31
|
}
|
|
26
32
|
end
|
|
27
33
|
|
|
34
|
+
# Execute thinking process
|
|
35
|
+
# @param thought [String] Internal reasoning or analysis text
|
|
36
|
+
# @return [String] Confirmation message
|
|
28
37
|
def execute(thought:)
|
|
29
38
|
# The thought is logged but not displayed to the user
|
|
30
39
|
Pocketrb.logger.debug("Agent thought: #{thought[0..200]}...")
|
|
@@ -11,14 +11,20 @@ module Pocketrb
|
|
|
11
11
|
MAX_CONTENT_SIZE = 500_000 # characters
|
|
12
12
|
TIMEOUT = 30 # seconds
|
|
13
13
|
|
|
14
|
+
# Tool name
|
|
15
|
+
# @return [String]
|
|
14
16
|
def name
|
|
15
17
|
"web_fetch"
|
|
16
18
|
end
|
|
17
19
|
|
|
20
|
+
# Tool description
|
|
21
|
+
# @return [String]
|
|
18
22
|
def description
|
|
19
23
|
"Fetch content from a URL. Returns the text content of the page. Use for reading documentation, articles, or other web content."
|
|
20
24
|
end
|
|
21
25
|
|
|
26
|
+
# Parameter schema
|
|
27
|
+
# @return [Hash]
|
|
22
28
|
def parameters
|
|
23
29
|
{
|
|
24
30
|
type: "object",
|
|
@@ -36,6 +42,10 @@ module Pocketrb
|
|
|
36
42
|
}
|
|
37
43
|
end
|
|
38
44
|
|
|
45
|
+
# Execute web content fetching
|
|
46
|
+
# @param url [String] URL to fetch content from
|
|
47
|
+
# @param selector [String, nil] CSS selector for extracting specific content
|
|
48
|
+
# @return [String] Extracted text content or error message
|
|
39
49
|
def execute(url:, selector: nil)
|
|
40
50
|
# Validate URL
|
|
41
51
|
uri = parse_url(url)
|
|
@@ -54,6 +64,9 @@ module Pocketrb
|
|
|
54
64
|
|
|
55
65
|
private
|
|
56
66
|
|
|
67
|
+
# Parse and validate a URL, adding https if no scheme is present
|
|
68
|
+
# @param url [String] URL string to parse
|
|
69
|
+
# @return [URI, nil] parsed URI or nil if invalid
|
|
57
70
|
def parse_url(url)
|
|
58
71
|
# Add https if no scheme
|
|
59
72
|
url = "https://#{url}" unless url.match?(%r{^https?://})
|
|
@@ -66,6 +79,9 @@ module Pocketrb
|
|
|
66
79
|
nil
|
|
67
80
|
end
|
|
68
81
|
|
|
82
|
+
# Fetch content from a URI using Faraday
|
|
83
|
+
# @param uri [URI] parsed URI to fetch
|
|
84
|
+
# @return [Hash] response hash with :body/:content_type or :error
|
|
69
85
|
def fetch_url(uri)
|
|
70
86
|
conn = Faraday.new(url: uri.to_s) do |f|
|
|
71
87
|
f.options.timeout = TIMEOUT
|
|
@@ -79,12 +95,35 @@ module Pocketrb
|
|
|
79
95
|
response = conn.get
|
|
80
96
|
|
|
81
97
|
if response.success?
|
|
82
|
-
|
|
98
|
+
content_type = response.headers["content-type"]
|
|
99
|
+
{ body: to_utf8(response.body.to_s, content_type), content_type: content_type }
|
|
83
100
|
else
|
|
84
101
|
{ error: "HTTP #{response.status}" }
|
|
85
102
|
end
|
|
86
103
|
end
|
|
87
104
|
|
|
105
|
+
# Convert a raw response body to valid UTF-8
|
|
106
|
+
# @param body [String] raw response body
|
|
107
|
+
# @param content_type [String, nil] Content-Type header value
|
|
108
|
+
# @return [String] UTF-8 body with invalid bytes replaced
|
|
109
|
+
def to_utf8(body, content_type)
|
|
110
|
+
charset = content_type.to_s[/charset=["']?([^;"'\s]+)/i, 1]
|
|
111
|
+
encoding = begin
|
|
112
|
+
charset ? Encoding.find(charset) : Encoding::UTF_8
|
|
113
|
+
rescue ArgumentError
|
|
114
|
+
Encoding::UTF_8
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
body
|
|
118
|
+
.dup
|
|
119
|
+
.force_encoding(encoding)
|
|
120
|
+
.encode(Encoding::UTF_8, invalid: :replace, undef: :replace)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Extract readable content from response body
|
|
124
|
+
# @param body [String] raw response body
|
|
125
|
+
# @param selector [String, nil] CSS selector to narrow extraction
|
|
126
|
+
# @return [String] extracted text content
|
|
88
127
|
def extract_content(body, selector)
|
|
89
128
|
content_type = detect_content_type(body)
|
|
90
129
|
|
|
@@ -98,6 +137,9 @@ module Pocketrb
|
|
|
98
137
|
end
|
|
99
138
|
end
|
|
100
139
|
|
|
140
|
+
# Detect content type by inspecting the body
|
|
141
|
+
# @param body [String] response body to analyze
|
|
142
|
+
# @return [Symbol] :json, :html, or :text
|
|
101
143
|
def detect_content_type(body)
|
|
102
144
|
return :json if body.strip.start_with?("{", "[")
|
|
103
145
|
return :html if body.include?("<html") || body.include?("<body")
|
|
@@ -105,6 +147,10 @@ module Pocketrb
|
|
|
105
147
|
:text
|
|
106
148
|
end
|
|
107
149
|
|
|
150
|
+
# Convert HTML to plain text by stripping tags
|
|
151
|
+
# @param html [String] raw HTML content
|
|
152
|
+
# @param _selector [String, nil] CSS selector (unused, reserved for Nokogiri)
|
|
153
|
+
# @return [String] extracted plain text
|
|
108
154
|
def extract_html_content(html, _selector)
|
|
109
155
|
# Simple HTML to text conversion
|
|
110
156
|
# A full implementation would use nokogiri
|
|
@@ -120,11 +166,14 @@ module Pocketrb
|
|
|
120
166
|
.gsub("<", "<")
|
|
121
167
|
.gsub(">", ">")
|
|
122
168
|
.gsub(""", '"')
|
|
123
|
-
|
|
124
|
-
|
|
169
|
+
|
|
170
|
+
text = text.gsub(/&#\d+;/) do |m|
|
|
171
|
+
[m[2..].to_i].pack("U")
|
|
125
172
|
rescue StandardError
|
|
126
173
|
m
|
|
127
174
|
end
|
|
175
|
+
|
|
176
|
+
text = text
|
|
128
177
|
.gsub(/\n{3,}/, "\n\n")
|
|
129
178
|
.strip
|
|
130
179
|
|
|
@@ -132,6 +181,9 @@ module Pocketrb
|
|
|
132
181
|
text.lines.map(&:strip).reject(&:empty?).join("\n")
|
|
133
182
|
end
|
|
134
183
|
|
|
184
|
+
# Pretty-print JSON body
|
|
185
|
+
# @param body [String] raw JSON string
|
|
186
|
+
# @return [String] formatted JSON or original body on parse error
|
|
135
187
|
def format_json(body)
|
|
136
188
|
data = JSON.parse(body)
|
|
137
189
|
JSON.pretty_generate(data)
|
|
@@ -139,6 +191,9 @@ module Pocketrb
|
|
|
139
191
|
body
|
|
140
192
|
end
|
|
141
193
|
|
|
194
|
+
# Truncate content exceeding the maximum size
|
|
195
|
+
# @param content [String] extracted page text that may exceed size limits
|
|
196
|
+
# @return [String] truncated or original content
|
|
142
197
|
def truncate_content(content)
|
|
143
198
|
return content if content.length <= MAX_CONTENT_SIZE
|
|
144
199
|
|
|
@@ -7,16 +7,23 @@ module Pocketrb
|
|
|
7
7
|
module Tools
|
|
8
8
|
# Search the web using Brave Search API
|
|
9
9
|
class WebSearch < Base
|
|
10
|
+
# Brave Search API endpoint URL
|
|
10
11
|
BRAVE_API_URL = "https://api.search.brave.com/res/v1/web/search"
|
|
11
12
|
|
|
13
|
+
# Tool name
|
|
14
|
+
# @return [String]
|
|
12
15
|
def name
|
|
13
16
|
"web_search"
|
|
14
17
|
end
|
|
15
18
|
|
|
19
|
+
# Tool description
|
|
20
|
+
# @return [String]
|
|
16
21
|
def description
|
|
17
22
|
"Search the web for information. Returns relevant search results with titles, URLs, and descriptions."
|
|
18
23
|
end
|
|
19
24
|
|
|
25
|
+
# Parameter schema
|
|
26
|
+
# @return [Hash]
|
|
20
27
|
def parameters
|
|
21
28
|
{
|
|
22
29
|
type: "object",
|
|
@@ -34,10 +41,16 @@ module Pocketrb
|
|
|
34
41
|
}
|
|
35
42
|
end
|
|
36
43
|
|
|
44
|
+
# Check if tool is available
|
|
45
|
+
# @return [Boolean] true if Brave API key is configured
|
|
37
46
|
def available?
|
|
38
47
|
api_key && !api_key.empty?
|
|
39
48
|
end
|
|
40
49
|
|
|
50
|
+
# Execute web search
|
|
51
|
+
# @param query [String] Search query string
|
|
52
|
+
# @param count [Integer] Number of results to return (1-20)
|
|
53
|
+
# @return [String] Formatted search results
|
|
41
54
|
def execute(query:, count: 5)
|
|
42
55
|
return error("Web search requires BRAVE_API_KEY environment variable") unless api_key
|
|
43
56
|
|
|
@@ -60,10 +73,14 @@ module Pocketrb
|
|
|
60
73
|
|
|
61
74
|
private
|
|
62
75
|
|
|
76
|
+
# Get the Brave Search API key from context or environment
|
|
77
|
+
# @return [String, nil]
|
|
63
78
|
def api_key
|
|
64
79
|
@context[:brave_api_key] || ENV.fetch("BRAVE_API_KEY", nil)
|
|
65
80
|
end
|
|
66
81
|
|
|
82
|
+
# Build or access the Faraday HTTP client for Brave API
|
|
83
|
+
# @return [Faraday::Connection]
|
|
67
84
|
def client
|
|
68
85
|
@client ||= Faraday.new(url: BRAVE_API_URL) do |f|
|
|
69
86
|
f.headers["Accept"] = "application/json"
|
|
@@ -72,6 +89,10 @@ module Pocketrb
|
|
|
72
89
|
end
|
|
73
90
|
end
|
|
74
91
|
|
|
92
|
+
# Format search response data into readable output
|
|
93
|
+
# @param data [Hash] parsed JSON response from Brave API
|
|
94
|
+
# @param query [String] original search query
|
|
95
|
+
# @return [String] formatted search results
|
|
75
96
|
def format_results(data, query)
|
|
76
97
|
results = data.dig("web", "results") || []
|
|
77
98
|
|
|
@@ -86,6 +107,10 @@ module Pocketrb
|
|
|
86
107
|
output.join("\n")
|
|
87
108
|
end
|
|
88
109
|
|
|
110
|
+
# Format a single search result entry
|
|
111
|
+
# @param result [Hash] search result with title, url, and description
|
|
112
|
+
# @param index [Integer] result number for display
|
|
113
|
+
# @return [String] formatted result entry
|
|
89
114
|
def format_result(result, index)
|
|
90
115
|
title = result["title"] || "Untitled"
|
|
91
116
|
url = result["url"] || ""
|
|
@@ -6,14 +6,20 @@ module Pocketrb
|
|
|
6
6
|
class WriteFile < Base
|
|
7
7
|
MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
|
|
8
8
|
|
|
9
|
+
# Tool name
|
|
10
|
+
# @return [String]
|
|
9
11
|
def name
|
|
10
12
|
"write_file"
|
|
11
13
|
end
|
|
12
14
|
|
|
15
|
+
# Tool description
|
|
16
|
+
# @return [String]
|
|
13
17
|
def description
|
|
14
18
|
"Write content to a file. Creates the file if it doesn't exist, or overwrites if it does. Creates parent directories as needed."
|
|
15
19
|
end
|
|
16
20
|
|
|
21
|
+
# Parameter schema
|
|
22
|
+
# @return [Hash]
|
|
17
23
|
def parameters
|
|
18
24
|
{
|
|
19
25
|
type: "object",
|
|
@@ -31,6 +37,10 @@ module Pocketrb
|
|
|
31
37
|
}
|
|
32
38
|
end
|
|
33
39
|
|
|
40
|
+
# Execute file write operation
|
|
41
|
+
# @param path [String] File path (relative or absolute)
|
|
42
|
+
# @param content [String] File content (text or binary data) to write to disk
|
|
43
|
+
# @return [String] Success or error message
|
|
34
44
|
def execute(path:, content:)
|
|
35
45
|
resolved = resolve_path(path)
|
|
36
46
|
|
data/lib/pocketrb/version.rb
CHANGED
data/lib/pocketrb.rb
CHANGED
|
@@ -6,7 +6,6 @@ require "json"
|
|
|
6
6
|
require "yaml"
|
|
7
7
|
require "logger"
|
|
8
8
|
require "fileutils"
|
|
9
|
-
require "pathname"
|
|
10
9
|
|
|
11
10
|
# Pocketrb: Ruby AI agent with multi-LLM support and advanced planning capabilities
|
|
12
11
|
module Pocketrb
|
|
@@ -28,6 +27,9 @@ module Pocketrb
|
|
|
28
27
|
# Raised when MCP (Model Context Protocol) operations fail
|
|
29
28
|
class MCPError < Error; end
|
|
30
29
|
|
|
30
|
+
# Raised when an optional gem needed by a feature is not installed
|
|
31
|
+
class MissingDependencyError < LoadError; end
|
|
32
|
+
|
|
31
33
|
class << self
|
|
32
34
|
attr_writer :logger
|
|
33
35
|
|
|
@@ -54,6 +56,7 @@ loader.inflector.inflect(
|
|
|
54
56
|
"llm" => "LLM",
|
|
55
57
|
"mcp" => "MCP",
|
|
56
58
|
"openrouter" => "OpenRouter",
|
|
59
|
+
"openai_compatible" => "OpenAICompatible",
|
|
57
60
|
"ruby_llm_provider" => "RubyLLMProvider",
|
|
58
61
|
"claude_cli" => "ClaudeCLI",
|
|
59
62
|
"claude_max_proxy" => "ClaudeMaxProxy",
|
data/pocketrb.gemspec
CHANGED
|
@@ -21,21 +21,19 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
JSON-based memory with keyword matching.
|
|
22
22
|
DESC
|
|
23
23
|
|
|
24
|
-
spec.required_ruby_version = ">=
|
|
24
|
+
spec.required_ruby_version = ">= 4.0.0"
|
|
25
25
|
|
|
26
26
|
# Runtime dependencies
|
|
27
|
-
spec.add_dependency "anthropic", "~> 0.3"
|
|
28
27
|
spec.add_dependency "async", "~> 2.0"
|
|
29
28
|
spec.add_dependency "faraday", "~> 2.0"
|
|
30
29
|
spec.add_dependency "faraday-follow_redirects", "~> 0.3"
|
|
31
|
-
spec.add_dependency "
|
|
32
|
-
spec.add_dependency "
|
|
30
|
+
spec.add_dependency "fugit", "~> 1.11"
|
|
31
|
+
spec.add_dependency "json", ">= 2.7", "< 4"
|
|
33
32
|
spec.add_dependency "playwright-ruby-client", "~> 1.58"
|
|
34
|
-
spec.add_dependency "ruby_llm", "~>
|
|
33
|
+
spec.add_dependency "ruby_llm", "~> 2.0"
|
|
35
34
|
spec.add_dependency "telegram-bot-ruby", "~> 2.0"
|
|
36
35
|
spec.add_dependency "thor", "~> 1.3"
|
|
37
|
-
spec.add_dependency "tty-
|
|
38
|
-
spec.add_dependency "tty-prompt", "~> 0.23"
|
|
36
|
+
spec.add_dependency "tty-spinner", "~> 0.9"
|
|
39
37
|
spec.add_dependency "yaml", "~> 0.3"
|
|
40
38
|
spec.add_dependency "zeitwerk", "~> 2.6"
|
|
41
39
|
|
|
@@ -51,10 +49,10 @@ Gem::Specification.new do |spec|
|
|
|
51
49
|
"changelog_uri" => "https://github.com/mensfeld/pocketrb/blob/master/CHANGELOG.md",
|
|
52
50
|
"homepage_uri" => "https://github.com/mensfeld/pocketrb",
|
|
53
51
|
"source_code_uri" => "https://github.com/mensfeld/pocketrb/tree/master",
|
|
52
|
+
"documentation_uri" => "https://github.com/mensfeld/pocketrb",
|
|
54
53
|
"rubygems_mfa_required" => "true"
|
|
55
54
|
}
|
|
56
55
|
end
|
|
57
56
|
|
|
58
57
|
# Optional dependencies (loaded on demand)
|
|
59
58
|
# For WhatsApp bridge: gem install websocket-client-simple
|
|
60
|
-
# For cron expressions: gem install fugit
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pocketrb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Maciej Mensfeld
|
|
@@ -9,20 +9,6 @@ bindir: exe
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
-
- !ruby/object:Gem::Dependency
|
|
13
|
-
name: anthropic
|
|
14
|
-
requirement: !ruby/object:Gem::Requirement
|
|
15
|
-
requirements:
|
|
16
|
-
- - "~>"
|
|
17
|
-
- !ruby/object:Gem::Version
|
|
18
|
-
version: '0.3'
|
|
19
|
-
type: :runtime
|
|
20
|
-
prerelease: false
|
|
21
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
-
requirements:
|
|
23
|
-
- - "~>"
|
|
24
|
-
- !ruby/object:Gem::Version
|
|
25
|
-
version: '0.3'
|
|
26
12
|
- !ruby/object:Gem::Dependency
|
|
27
13
|
name: async
|
|
28
14
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -66,33 +52,39 @@ dependencies:
|
|
|
66
52
|
- !ruby/object:Gem::Version
|
|
67
53
|
version: '0.3'
|
|
68
54
|
- !ruby/object:Gem::Dependency
|
|
69
|
-
name:
|
|
55
|
+
name: fugit
|
|
70
56
|
requirement: !ruby/object:Gem::Requirement
|
|
71
57
|
requirements:
|
|
72
58
|
- - "~>"
|
|
73
59
|
- !ruby/object:Gem::Version
|
|
74
|
-
version: '
|
|
60
|
+
version: '1.11'
|
|
75
61
|
type: :runtime
|
|
76
62
|
prerelease: false
|
|
77
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
78
64
|
requirements:
|
|
79
65
|
- - "~>"
|
|
80
66
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: '
|
|
67
|
+
version: '1.11'
|
|
82
68
|
- !ruby/object:Gem::Dependency
|
|
83
|
-
name:
|
|
69
|
+
name: json
|
|
84
70
|
requirement: !ruby/object:Gem::Requirement
|
|
85
71
|
requirements:
|
|
86
|
-
- - "
|
|
72
|
+
- - ">="
|
|
87
73
|
- !ruby/object:Gem::Version
|
|
88
|
-
version: '
|
|
74
|
+
version: '2.7'
|
|
75
|
+
- - "<"
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '4'
|
|
89
78
|
type: :runtime
|
|
90
79
|
prerelease: false
|
|
91
80
|
version_requirements: !ruby/object:Gem::Requirement
|
|
92
81
|
requirements:
|
|
93
|
-
- - "
|
|
82
|
+
- - ">="
|
|
83
|
+
- !ruby/object:Gem::Version
|
|
84
|
+
version: '2.7'
|
|
85
|
+
- - "<"
|
|
94
86
|
- !ruby/object:Gem::Version
|
|
95
|
-
version: '
|
|
87
|
+
version: '4'
|
|
96
88
|
- !ruby/object:Gem::Dependency
|
|
97
89
|
name: playwright-ruby-client
|
|
98
90
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -113,14 +105,14 @@ dependencies:
|
|
|
113
105
|
requirements:
|
|
114
106
|
- - "~>"
|
|
115
107
|
- !ruby/object:Gem::Version
|
|
116
|
-
version: '
|
|
108
|
+
version: '2.0'
|
|
117
109
|
type: :runtime
|
|
118
110
|
prerelease: false
|
|
119
111
|
version_requirements: !ruby/object:Gem::Requirement
|
|
120
112
|
requirements:
|
|
121
113
|
- - "~>"
|
|
122
114
|
- !ruby/object:Gem::Version
|
|
123
|
-
version: '
|
|
115
|
+
version: '2.0'
|
|
124
116
|
- !ruby/object:Gem::Dependency
|
|
125
117
|
name: telegram-bot-ruby
|
|
126
118
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -150,33 +142,19 @@ dependencies:
|
|
|
150
142
|
- !ruby/object:Gem::Version
|
|
151
143
|
version: '1.3'
|
|
152
144
|
- !ruby/object:Gem::Dependency
|
|
153
|
-
name: tty-
|
|
154
|
-
requirement: !ruby/object:Gem::Requirement
|
|
155
|
-
requirements:
|
|
156
|
-
- - "~>"
|
|
157
|
-
- !ruby/object:Gem::Version
|
|
158
|
-
version: '0.7'
|
|
159
|
-
type: :runtime
|
|
160
|
-
prerelease: false
|
|
161
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
162
|
-
requirements:
|
|
163
|
-
- - "~>"
|
|
164
|
-
- !ruby/object:Gem::Version
|
|
165
|
-
version: '0.7'
|
|
166
|
-
- !ruby/object:Gem::Dependency
|
|
167
|
-
name: tty-prompt
|
|
145
|
+
name: tty-spinner
|
|
168
146
|
requirement: !ruby/object:Gem::Requirement
|
|
169
147
|
requirements:
|
|
170
148
|
- - "~>"
|
|
171
149
|
- !ruby/object:Gem::Version
|
|
172
|
-
version: '0.
|
|
150
|
+
version: '0.9'
|
|
173
151
|
type: :runtime
|
|
174
152
|
prerelease: false
|
|
175
153
|
version_requirements: !ruby/object:Gem::Requirement
|
|
176
154
|
requirements:
|
|
177
155
|
- - "~>"
|
|
178
156
|
- !ruby/object:Gem::Version
|
|
179
|
-
version: '0.
|
|
157
|
+
version: '0.9'
|
|
180
158
|
- !ruby/object:Gem::Dependency
|
|
181
159
|
name: yaml
|
|
182
160
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -261,6 +239,7 @@ files:
|
|
|
261
239
|
- lib/pocketrb/providers/base.rb
|
|
262
240
|
- lib/pocketrb/providers/claude_cli.rb
|
|
263
241
|
- lib/pocketrb/providers/claude_max_proxy.rb
|
|
242
|
+
- lib/pocketrb/providers/openai_compatible.rb
|
|
264
243
|
- lib/pocketrb/providers/openrouter.rb
|
|
265
244
|
- lib/pocketrb/providers/registry.rb
|
|
266
245
|
- lib/pocketrb/providers/ruby_llm_provider.rb
|
|
@@ -306,6 +285,7 @@ metadata:
|
|
|
306
285
|
changelog_uri: https://github.com/mensfeld/pocketrb/blob/master/CHANGELOG.md
|
|
307
286
|
homepage_uri: https://github.com/mensfeld/pocketrb
|
|
308
287
|
source_code_uri: https://github.com/mensfeld/pocketrb/tree/master
|
|
288
|
+
documentation_uri: https://github.com/mensfeld/pocketrb
|
|
309
289
|
rubygems_mfa_required: 'true'
|
|
310
290
|
rdoc_options: []
|
|
311
291
|
require_paths:
|
|
@@ -314,14 +294,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
314
294
|
requirements:
|
|
315
295
|
- - ">="
|
|
316
296
|
- !ruby/object:Gem::Version
|
|
317
|
-
version:
|
|
297
|
+
version: 4.0.0
|
|
318
298
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
319
299
|
requirements:
|
|
320
300
|
- - ">="
|
|
321
301
|
- !ruby/object:Gem::Version
|
|
322
302
|
version: '0'
|
|
323
303
|
requirements: []
|
|
324
|
-
rubygems_version: 4.0.
|
|
304
|
+
rubygems_version: 4.0.20
|
|
325
305
|
specification_version: 4
|
|
326
306
|
summary: Pocket-sized Ruby AI agent framework with multi-LLM support
|
|
327
307
|
test_files: []
|