Class: Phronomy::Agent::Context::Capability::Base
- Inherits:
-
RubyLLM::Tool
- Object
- RubyLLM::Tool
- Phronomy::Agent::Context::Capability::Base
show all
- Defined in:
- lib/phronomy/agent/context/capability/base.rb
Overview
Base class extending RubyLLM::Tool with Phronomy-specific DSL.
Class Method Summary
collapse
Instance Method Summary
collapse
Class Method Details
.approval_facts(&block) ⇒ Object
185
186
187
188
189
190
191
192
193
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 185
def approval_facts(&block)
if block
@approval_facts = block
elsif instance_variable_defined?(:@approval_facts)
@approval_facts
elsif superclass.respond_to?(:approval_facts)
superclass.approval_facts
end
end
|
.description(text = nil) ⇒ Object
Also known as:
desc
RubyLLM stores Tool descriptions in a class-instance variable.
Preserve normal class inheritance semantics so Phronomy's anonymous
decorator subclasses do not lose their parent's description.
21
22
23
24
25
26
27
28
29
30
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 21
def description(text = nil)
unless text
return @description if instance_variable_defined?(:@description)
return superclass.description if superclass.respond_to?(:description)
return nil
end
@description = text
end
|
.execution_mode(value = nil) ⇒ Object
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 117
def execution_mode(value = nil)
if value.nil?
return @execution_mode if instance_variable_defined?(:@execution_mode)
return superclass.execution_mode if superclass.respond_to?(:execution_mode)
return :blocking_io
end
valid = %i[cooperative blocking_io cpu_bound external_process]
unless valid.include?(value)
raise ArgumentError,
"execution_mode must be one of #{valid.inspect}, got #{value.inspect}"
end
@execution_mode = value
end
|
.max_result_size(value = :__unset__) ⇒ Object
206
207
208
209
210
211
212
213
214
215
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 206
def max_result_size(value = :__unset__)
if value == :__unset__
return @max_result_size if instance_variable_defined?(:@max_result_size)
return superclass.max_result_size if superclass.respond_to?(:max_result_size)
return nil
end
@max_result_size = value
end
|
.on_error(behavior = nil) ⇒ Object
Configures execution-error handling. Supported values are :raise
and :suppress only.
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 136
def on_error(behavior = nil)
if behavior.nil?
return @on_error if instance_variable_defined?(:@on_error)
return superclass.on_error if superclass.respond_to?(:on_error)
return :raise
end
valid = %i[raise suppress]
unless valid.include?(behavior)
raise ArgumentError,
"on_error must be one of #{valid.inspect}, got #{behavior.inspect}"
end
@on_error = behavior
end
|
.on_schema_error(behavior = nil) ⇒ Object
153
154
155
156
157
158
159
160
161
162
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 153
def on_schema_error(behavior = nil)
if behavior.nil?
return @on_schema_error if instance_variable_defined?(:@on_schema_error)
return superclass.on_schema_error if superclass.respond_to?(:on_schema_error)
return :return_error
end
@on_schema_error = behavior
end
|
.param(name, enum: nil, properties: nil, **options) ⇒ Object
66
67
68
69
70
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 66
def param(name, enum: nil, properties: nil, **options)
super(name, **options)
param_enums[name] = duplicate_configuration(enum) if enum
param_schemas[name] = normalize_nested_schema(properties) if properties
end
|
.param_enums ⇒ Object
73
74
75
76
77
78
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 73
def param_enums
return @param_enums if instance_variable_defined?(:@param_enums)
parent = superclass.respond_to?(:param_enums) ? superclass.param_enums : {}
@param_enums = duplicate_configuration(parent)
end
|
.param_schemas ⇒ Object
81
82
83
84
85
86
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 81
def param_schemas
return @param_schemas if instance_variable_defined?(:@param_schemas)
parent = superclass.respond_to?(:param_schemas) ? superclass.param_schemas : {}
@param_schemas = duplicate_configuration(parent)
end
|
.parameters ⇒ Object
RubyLLM stores declared parameters in a class-instance variable.
Copy the parent's registry on first access so child classes inherit
existing parameters while remaining free to add their own.
37
38
39
40
41
42
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 37
def parameters
return @parameters if instance_variable_defined?(:@parameters)
parent = superclass.respond_to?(:parameters) ? superclass.parameters : {}
@parameters = parent.dup
end
|
.params_schema_definition ⇒ Object
RubyLLM stores an explicit .params schema definition in a
class-instance variable. Readers must fall back to the parent.
47
48
49
50
51
52
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 47
def params_schema_definition
return @params_schema_definition if instance_variable_defined?(:@params_schema_definition)
return superclass.params_schema_definition if superclass.respond_to?(:params_schema_definition)
nil
end
|
.provider_params ⇒ Object
RubyLLM provider params are also class-instance state. Copy them on
first access to preserve inheritance without sharing the top-level
mutable Hash between parent and child.
58
59
60
61
62
63
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 58
def provider_params
return @provider_params if instance_variable_defined?(:@provider_params)
parent = superclass.respond_to?(:provider_params) ? superclass.provider_params : {}
@provider_params = duplicate_configuration(parent)
end
|
.redact_params(*names) ⇒ Object
196
197
198
199
200
201
202
203
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 196
def redact_params(*names)
if names.empty?
parent = superclass.respond_to?(:redact_params) ? superclass.redact_params : []
((@redacted_params || []) + parent).uniq
else
@redacted_params = ((@redacted_params || []) + names.map(&:to_sym)).uniq
end
end
|
.requires_approval(value = :__unset__, &block) ⇒ Object
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 165
def requires_approval(value = :__unset__, &block)
if block
unless value == :__unset__
raise ArgumentError, "pass either a value or a block to requires_approval"
end
@requires_approval = block
elsif value == :__unset__
return @requires_approval if instance_variable_defined?(:@requires_approval)
return superclass.requires_approval if superclass.respond_to?(:requires_approval)
false
else
unless value == true || value == false || value.respond_to?(:call)
raise ArgumentError, "requires_approval must be true, false, or callable"
end
@requires_approval = value
end
end
|
11
12
13
14
15
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 11
def tool_name(value = nil)
return @tool_name if value.nil?
@tool_name = value.to_s
end
|
Instance Method Details
322
323
324
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 322
def approval_metadata
{}
end
|
#call(args, cancellation_token: nil) ⇒ Object
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 262
def call(args, cancellation_token: nil)
cancellation_token&.raise_if_cancelled!
validated_args, schema_error = validate_and_coerce(args)
if schema_error
case self.class.on_schema_error
when :raise
raise Phronomy::ToolError,
"#{self.class.name} schema error: #{schema_error}"
else
return "Schema validation failed: #{schema_error}"
end
end
if cancellation_token && execute_accepts_cancellation_token?
validated_args = validated_args.merge(cancellation_token: cancellation_token)
end
result = super(validated_args)
truncate_result_if_needed(result)
rescue Phronomy::ToolError, Phronomy::CancellationError
raise
rescue => error
if self.class.on_error == :suppress
msg = "[Phronomy] Tool #{self.class.name} suppressed error: " \
"#{error.class}: #{error.message}"
if Phronomy.configuration.logger
Phronomy.configuration.logger.warn(msg)
else
warn msg
end
"Tool error suppressed: #{error.message}"
else
raise Phronomy::ToolError,
"#{self.class.name} execution failed: #{error.message}"
end
end
|
#call_async(args, cancellation_token: nil, config: {}) ⇒ Object
299
300
301
302
303
304
305
306
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 299
def call_async(args, cancellation_token: nil, config: {})
Phronomy::Agent::ToolExecutor.call_async(
tool: self,
args: args,
cancellation_token: cancellation_token,
config: config
)
end
|
#execute(**_args) ⇒ Object
327
328
329
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 327
def execute(**_args)
raise NotImplementedError, "#{self.class}#execute is not implemented"
end
|
#name ⇒ Object
218
219
220
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 218
def name
self.class.tool_name || super
end
|
#params_schema ⇒ Object
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 222
def params_schema
schema = super
return schema if schema.nil?
properties = schema.dig("properties") || schema.dig(:properties)
return schema unless properties
self.class.param_enums.each do |param_name, values|
key = properties.key?(param_name.to_s) ? param_name.to_s : param_name.to_sym
next unless properties[key]
param_type = properties[key]["type"]
properties[key]["enum"] = values.map do |value|
case param_type
when "integer"
value.is_a?(Integer) ? value : Integer(value.to_s)
when "number"
value.is_a?(Numeric) ? value : Float(value.to_s)
when "boolean"
unless value == true || value == false
raise ArgumentError,
"boolean enum values must be true or false (got: #{value.inspect})"
end
value
else
value.to_s
end
end
end
self.class.param_schemas.each do |param_name, nested|
key = properties.key?(param_name.to_s) ? param_name.to_s : param_name.to_sym
next unless properties[key]
properties[key]["properties"] = nested_schema_to_json_schema(nested)
end
schema
end
|
#requires_approval ⇒ Object
308
309
310
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 308
def requires_approval
self.class.requires_approval
end
|
#requires_approval? ⇒ Boolean
312
313
314
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 312
def requires_approval?
self.class.requires_approval
end
|
317
318
319
|
# File 'lib/phronomy/agent/context/capability/base.rb', line 317
def tool_origin
:local
end
|