ask-tools 0.6.0 → 0.6.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aff9f4752095dc3224f21ed08a1bc6768ff211af1f48dcfc51bb1b7c41cab0e3
4
- data.tar.gz: acccd4fc9f40e57520e51c55cb71faf302dfd05fa4c7ca4159ffacf4da8b8d19
3
+ metadata.gz: b7722a402e1411950d63a055707c676b7c68af27550284f56a7d3cb5b316af78
4
+ data.tar.gz: 19012fdeba501720ae891cc7b62b1a797482170a3ccbfef5cee59218d8446c59
5
5
  SHA512:
6
- metadata.gz: 5f37ccab34db3b16d504eb980830dae8ae1acb27c9de568fd3654a4da8604efcf5e27d6b917f280a74c4e6d3815862d54ebcd4bb6e9d2395ecbde0c3aa5730f3
7
- data.tar.gz: ca97d4e8122b3d3ae161318f23780b0539c64d450d746a05e88fe56ab32a791ed3d161568ad8288d3d8ef4913a0b7e3bc7812e9c90ab68bb87df1630634bd20c
6
+ metadata.gz: 18cc40a7fe9902a71b658aa857693f1734d25456dc1c03d38334596e1b840e80b605f0401a3237a7009423903c890a577a2829c12a59dfea2debc22d832823b4
7
+ data.tar.gz: 5a9c6578a61fed0c87210332be3efe8d3d98a1fa2a16bfa0546bba6a0de8b713c1ab5eacdb6bedc8883451a9f911ca6eee0a12733cdb37af90f21cbfe2060a20
@@ -99,8 +99,32 @@ module Ask
99
99
  @params_schema_definition = schema || block
100
100
  end
101
101
 
102
+ # The tool's declared parameters — or, when none are declared,
103
+ # inferred from the execute signature so a tool is never silently
104
+ # uncallable: a tool whose execute takes keyword arguments but
105
+ # declares no params would otherwise reject every call ("unknown
106
+ # parameters"). Inference is a fallback, never an override: an
107
+ # explicit `params`/`param` declaration wins.
102
108
  def parameters
103
109
  @parameters ||= {}
110
+ if @parameters.empty? && @params_schema_definition.nil? && !@parameters_inferred
111
+ infer_parameters_from_execute
112
+ end
113
+ @parameters
114
+ end
115
+
116
+ # Derive parameters from `def execute(project_id:, title:, ...)`:
117
+ # required keywords become required string parameters. Ruby types
118
+ # aren't introspectable, so everything infers as string (JSON
119
+ # numbers coerce); tools that need real types declare `params`.
120
+ def infer_parameters_from_execute
121
+ @parameters_inferred = true
122
+ instance_method(:execute).parameters.each do |kind, name|
123
+ next unless %i[keyreq key opt].include?(kind)
124
+ next if name.nil? || name == :_abort_controller
125
+
126
+ @parameters[name] = Parameter.new(name: name, type: "string", required: kind == :keyreq)
127
+ end
104
128
  end
105
129
 
106
130
  def provider_params
@@ -111,7 +135,7 @@ module Ask
111
135
  @params_schema ||= begin
112
136
  if @params_schema_definition
113
137
  deep_stringify_keys(resolve_params_schema(@params_schema_definition))
114
- elsif @parameters && @parameters.any?
138
+ elsif parameters.any?
115
139
  build_schema_from_params
116
140
  else
117
141
  nil
@@ -245,8 +269,42 @@ module Ask
245
269
  "#<#{self.class.name} name=#{name.inspect}>"
246
270
  end
247
271
 
272
+ # Validate normalized (symbol-keyed) arguments. Returns nil when
273
+ # valid, or an actionable message — one that names what was expected
274
+ # — so the model (or a repair pass) can correct the call instead of
275
+ # guessing. Public: ask-agent's tool-call repair validates through
276
+ # this. Tools with a declared `params` block validate against the
277
+ # resolved schema (required keys + unknown keys when strict).
278
+ def validate(normalized)
279
+ return validate_against_schema(normalized) if params_schema_definition
280
+
281
+ expected = self.class.parameters.keys
282
+ missing = expected.select { |name| self.class.parameters[name].required && !normalized.key?(name) }
283
+ return "missing required parameters: #{missing.map(&:inspect).join(', ')} — expected: #{expected.map(&:inspect).join(', ')}" unless missing.empty?
284
+
285
+ unknown = normalized.keys - expected
286
+ return "unknown parameters: #{unknown.map(&:inspect).join(', ')} — expected: #{expected.map(&:inspect).join(', ')}" unless unknown.empty?
287
+
288
+ nil
289
+ end
290
+
248
291
  private
249
292
 
293
+ def validate_against_schema(normalized)
294
+ schema = params_schema || {}
295
+ expected = Array(schema["required"])
296
+ missing = expected - normalized.keys.map(&:to_s)
297
+ return "missing required parameters: #{missing.map(&:inspect).join(', ')} — expected: #{expected.map(&:inspect).join(', ')}" unless missing.empty?
298
+
299
+ properties = schema["properties"] || {}
300
+ if schema["additionalProperties"] == false
301
+ unknown = normalized.keys.map(&:to_s) - properties.keys
302
+ return "unknown parameters: #{unknown.map(&:inspect).join(', ')} — expected: #{properties.keys.map(&:inspect).join(', ')}" unless unknown.empty?
303
+ end
304
+
305
+ nil
306
+ end
307
+
250
308
  def params_schema_definition
251
309
  self.class.instance_variable_get(:@params_schema_definition)
252
310
  end
@@ -294,15 +352,6 @@ module Ask
294
352
  args.respond_to?(:transform_keys) ? args.transform_keys(&:to_sym) : {}
295
353
  end
296
354
 
297
- def validate(normalized)
298
- return nil if params_schema_definition
299
- missing = self.class.parameters.select { |_, p| p.required && !normalized.key?(p.name) }
300
- return "missing required parameters: #{missing.keys.map(&:inspect).join(', ')}" unless missing.empty?
301
- unknown = normalized.keys - self.class.parameters.keys
302
- return "unknown parameters: #{unknown.map(&:inspect).join(', ')}" unless unknown.empty?
303
- nil
304
- end
305
-
306
355
  VALID_JSON_SCHEMA_TYPES = %i[string integer number boolean array object].freeze
307
356
 
308
357
  class Parameter
data/lib/ask/version.rb CHANGED
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ask
4
4
  module Tools
5
- VERSION = "0.6.0"
5
+ VERSION = "0.6.1"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto
@@ -29,14 +29,14 @@ dependencies:
29
29
  requirements:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: '0.1'
32
+ version: 0.1.2
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: '0.1'
39
+ version: 0.1.2
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: minitest
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -115,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
115
  - !ruby/object:Gem::Version
116
116
  version: '0'
117
117
  requirements: []
118
- rubygems_version: 4.0.3
118
+ rubygems_version: 4.0.18
119
119
  specification_version: 4
120
120
  summary: Tool framework for the ask-rb ecosystem
121
121
  test_files: []