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.
@@ -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
- # It uses a Mutex for thread safety when registering tools concurrently.
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
- # and a warning is emitted to stderr.
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
- warn "RubyPi::Tools::Registry: overwriting existing tool '#{tool.name}'"
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
- @tools.values.select { |tool| tool.category == cat }
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.
@@ -7,5 +7,5 @@
7
7
 
8
8
  module RubyPi
9
9
  # The current version of the RubyPi gem, following Semantic Versioning.
10
- VERSION = "0.1.3"
10
+ VERSION = "0.1.5"
11
11
  end
data/lib/ruby_pi.rb CHANGED
@@ -10,7 +10,8 @@
10
10
 
11
11
  require "json"
12
12
  require "faraday"
13
- require "faraday/retry"
13
+ # Issue #20: Removed faraday/retry — retry logic is handled by BaseProvider#complete
14
+ # require "faraday/retry"
14
15
  require "faraday/net_http"
15
16
  require "concurrent-ruby"
16
17
 
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.3
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
- - ruby-pi@example.com
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: 4.0.3
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.