ruby-pi 0.1.3 → 0.1.5
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 +51 -0
- data/README.md +77 -29
- data/lib/ruby_pi/agent/core.rb +59 -4
- data/lib/ruby_pi/agent/events.rb +17 -3
- data/lib/ruby_pi/agent/loop.rb +103 -18
- data/lib/ruby_pi/agent/result.rb +46 -7
- data/lib/ruby_pi/agent/state.rb +12 -0
- data/lib/ruby_pi/configuration.rb +28 -7
- data/lib/ruby_pi/context/compaction.rb +17 -2
- data/lib/ruby_pi/context/transform.rb +67 -3
- data/lib/ruby_pi/errors.rb +19 -1
- data/lib/ruby_pi/llm/anthropic.rb +231 -59
- data/lib/ruby_pi/llm/base_provider.rb +44 -46
- data/lib/ruby_pi/llm/fallback.rb +106 -1
- data/lib/ruby_pi/llm/gemini.rb +161 -41
- data/lib/ruby_pi/llm/openai.rb +173 -42
- data/lib/ruby_pi/llm/stream_event.rb +13 -3
- data/lib/ruby_pi/llm/tool_call.rb +26 -3
- data/lib/ruby_pi/tools/executor.rb +130 -21
- data/lib/ruby_pi/tools/registry.rb +26 -16
- data/lib/ruby_pi/version.rb +1 -1
- data/lib/ruby_pi.rb +2 -1
- metadata +5 -39
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
#
|
|
7
7
|
# The Registry holds a collection of tool definitions and provides methods
|
|
8
8
|
# for looking them up by name, filtering by category, and extracting subsets.
|
|
9
|
-
#
|
|
9
|
+
# All public methods are protected by a Mutex for thread safety, ensuring
|
|
10
|
+
# safe concurrent access from agent loops and parallel tool execution.
|
|
10
11
|
#
|
|
11
12
|
# Usage:
|
|
12
13
|
# registry = RubyPi::Tools::Registry.new
|
|
@@ -27,8 +28,9 @@ module RubyPi
|
|
|
27
28
|
|
|
28
29
|
# Registers a tool definition in the registry.
|
|
29
30
|
#
|
|
30
|
-
# If a tool with the same name already exists, it will be overwritten
|
|
31
|
-
#
|
|
31
|
+
# If a tool with the same name already exists, it will be overwritten.
|
|
32
|
+
# A debug-level log message is emitted if a logger is configured;
|
|
33
|
+
# otherwise the overwrite is silent (no warn to stderr).
|
|
32
34
|
#
|
|
33
35
|
# @param tool [RubyPi::Tools::Definition] The tool to register.
|
|
34
36
|
# @return [RubyPi::Tools::Definition] The registered tool.
|
|
@@ -40,7 +42,12 @@ module RubyPi
|
|
|
40
42
|
|
|
41
43
|
@mutex.synchronize do
|
|
42
44
|
if @tools.key?(tool.name)
|
|
43
|
-
|
|
45
|
+
# Use the configured logger at debug level instead of unconditional
|
|
46
|
+
# warn to stderr, which is noisy in production environments.
|
|
47
|
+
logger = RubyPi.configuration.logger
|
|
48
|
+
if logger
|
|
49
|
+
logger.debug("RubyPi::Tools::Registry: overwriting existing tool '#{tool.name}'")
|
|
50
|
+
end
|
|
44
51
|
end
|
|
45
52
|
@tools[tool.name] = tool
|
|
46
53
|
end
|
|
@@ -48,17 +55,18 @@ module RubyPi
|
|
|
48
55
|
tool
|
|
49
56
|
end
|
|
50
57
|
|
|
51
|
-
# Finds a tool by name.
|
|
58
|
+
# Finds a tool by name. Thread-safe.
|
|
52
59
|
#
|
|
53
60
|
# @param name [String, Symbol] The name of the tool to look up.
|
|
54
61
|
# @return [RubyPi::Tools::Definition, nil] The tool, or nil if not found.
|
|
55
62
|
def find(name)
|
|
56
|
-
@tools[name.to_sym]
|
|
63
|
+
@mutex.synchronize { @tools[name.to_sym] }
|
|
57
64
|
end
|
|
58
65
|
|
|
59
66
|
# Returns a new Registry containing only the tools with the given names.
|
|
60
67
|
#
|
|
61
68
|
# Tools that are not found in this registry are silently skipped.
|
|
69
|
+
# Thread-safe.
|
|
62
70
|
#
|
|
63
71
|
# @param names [Array<String, Symbol>] The tool names to include.
|
|
64
72
|
# @return [RubyPi::Tools::Registry] A new registry with the matching tools.
|
|
@@ -71,42 +79,44 @@ module RubyPi
|
|
|
71
79
|
sub
|
|
72
80
|
end
|
|
73
81
|
|
|
74
|
-
# Returns all tools that belong to the given category.
|
|
82
|
+
# Returns all tools that belong to the given category. Thread-safe.
|
|
75
83
|
#
|
|
76
84
|
# @param category [Symbol, String] The category to filter by.
|
|
77
85
|
# @return [Array<RubyPi::Tools::Definition>] Tools matching the category.
|
|
78
86
|
def by_category(category)
|
|
79
87
|
cat = category.to_sym
|
|
80
|
-
@
|
|
88
|
+
@mutex.synchronize do
|
|
89
|
+
@tools.values.select { |tool| tool.category == cat }
|
|
90
|
+
end
|
|
81
91
|
end
|
|
82
92
|
|
|
83
|
-
# Returns all registered tool definitions.
|
|
93
|
+
# Returns all registered tool definitions. Thread-safe.
|
|
84
94
|
#
|
|
85
95
|
# @return [Array<RubyPi::Tools::Definition>] All tools in registration order.
|
|
86
96
|
def all
|
|
87
|
-
@tools.values
|
|
97
|
+
@mutex.synchronize { @tools.values }
|
|
88
98
|
end
|
|
89
99
|
|
|
90
|
-
# Returns the names of all registered tools.
|
|
100
|
+
# Returns the names of all registered tools. Thread-safe.
|
|
91
101
|
#
|
|
92
102
|
# @return [Array<Symbol>] An array of tool name symbols.
|
|
93
103
|
def names
|
|
94
|
-
@tools.keys
|
|
104
|
+
@mutex.synchronize { @tools.keys }
|
|
95
105
|
end
|
|
96
106
|
|
|
97
|
-
# Returns the number of registered tools.
|
|
107
|
+
# Returns the number of registered tools. Thread-safe.
|
|
98
108
|
#
|
|
99
109
|
# @return [Integer] The count of tools.
|
|
100
110
|
def size
|
|
101
|
-
@tools.size
|
|
111
|
+
@mutex.synchronize { @tools.size }
|
|
102
112
|
end
|
|
103
113
|
|
|
104
|
-
# Checks whether a tool with the given name is registered.
|
|
114
|
+
# Checks whether a tool with the given name is registered. Thread-safe.
|
|
105
115
|
#
|
|
106
116
|
# @param name [String, Symbol] The tool name to check.
|
|
107
117
|
# @return [Boolean] true if the tool exists in the registry.
|
|
108
118
|
def registered?(name)
|
|
109
|
-
@tools.key?(name.to_sym)
|
|
119
|
+
@mutex.synchronize { @tools.key?(name.to_sym) }
|
|
110
120
|
end
|
|
111
121
|
|
|
112
122
|
# Provides a human-readable string representation.
|
data/lib/ruby_pi/version.rb
CHANGED
data/lib/ruby_pi.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-pi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- RubyPi Contributors
|
|
@@ -23,40 +23,20 @@ dependencies:
|
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '2.0'
|
|
26
|
-
- !ruby/object:Gem::Dependency
|
|
27
|
-
name: faraday-retry
|
|
28
|
-
requirement: !ruby/object:Gem::Requirement
|
|
29
|
-
requirements:
|
|
30
|
-
- - "~>"
|
|
31
|
-
- !ruby/object:Gem::Version
|
|
32
|
-
version: '2.0'
|
|
33
|
-
type: :runtime
|
|
34
|
-
prerelease: false
|
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
-
requirements:
|
|
37
|
-
- - "~>"
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: '2.0'
|
|
40
26
|
- !ruby/object:Gem::Dependency
|
|
41
27
|
name: faraday-net_http
|
|
42
28
|
requirement: !ruby/object:Gem::Requirement
|
|
43
29
|
requirements:
|
|
44
|
-
- - "
|
|
30
|
+
- - "~>"
|
|
45
31
|
- !ruby/object:Gem::Version
|
|
46
32
|
version: '3.0'
|
|
47
|
-
- - "<"
|
|
48
|
-
- !ruby/object:Gem::Version
|
|
49
|
-
version: '3.4'
|
|
50
33
|
type: :runtime
|
|
51
34
|
prerelease: false
|
|
52
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
53
36
|
requirements:
|
|
54
|
-
- - "
|
|
37
|
+
- - "~>"
|
|
55
38
|
- !ruby/object:Gem::Version
|
|
56
39
|
version: '3.0'
|
|
57
|
-
- - "<"
|
|
58
|
-
- !ruby/object:Gem::Version
|
|
59
|
-
version: '3.4'
|
|
60
40
|
- !ruby/object:Gem::Dependency
|
|
61
41
|
name: concurrent-ruby
|
|
62
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -71,20 +51,6 @@ dependencies:
|
|
|
71
51
|
- - "~>"
|
|
72
52
|
- !ruby/object:Gem::Version
|
|
73
53
|
version: '1.2'
|
|
74
|
-
- !ruby/object:Gem::Dependency
|
|
75
|
-
name: ostruct
|
|
76
|
-
requirement: !ruby/object:Gem::Requirement
|
|
77
|
-
requirements:
|
|
78
|
-
- - "~>"
|
|
79
|
-
- !ruby/object:Gem::Version
|
|
80
|
-
version: '0.6'
|
|
81
|
-
type: :runtime
|
|
82
|
-
prerelease: false
|
|
83
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
84
|
-
requirements:
|
|
85
|
-
- - "~>"
|
|
86
|
-
- !ruby/object:Gem::Version
|
|
87
|
-
version: '0.6'
|
|
88
54
|
- !ruby/object:Gem::Dependency
|
|
89
55
|
name: rspec
|
|
90
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -135,7 +101,7 @@ description: RubyPi is a minimal, composable AI agent harness for Ruby. Build pr
|
|
|
135
101
|
Ideal for building autonomous AI agents, ReAct agents, tool-using LLM agents, and
|
|
136
102
|
chatbots in Ruby.
|
|
137
103
|
email:
|
|
138
|
-
-
|
|
104
|
+
- ejwhite7@users.noreply.github.com
|
|
139
105
|
executables: []
|
|
140
106
|
extensions: []
|
|
141
107
|
extra_rdoc_files: []
|
|
@@ -191,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
191
157
|
- !ruby/object:Gem::Version
|
|
192
158
|
version: '0'
|
|
193
159
|
requirements: []
|
|
194
|
-
rubygems_version:
|
|
160
|
+
rubygems_version: 3.6.9
|
|
195
161
|
specification_version: 4
|
|
196
162
|
summary: AI agent harness for Ruby — build LLM agents with tool calling, streaming,
|
|
197
163
|
and a unified interface to OpenAI, Anthropic Claude, and Google Gemini.
|