diff options
| author | Adam Malczewski <[email protected]> | 2026-03-31 21:36:46 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-03-31 21:36:46 +0900 |
| commit | 6b6e158d0614806dc970f7307fb63d392f0cb976 (patch) | |
| tree | ea19a4ccfe97b05b17a3418461daebb1d0543505 /lib/dispatch/tools/definition.rb | |
| parent | 7221a9d38fcd29d89794bc3041f11c5358b3155e (diff) | |
| download | dispatch-tools-interface-6b6e158d0614806dc970f7307fb63d392f0cb976.tar.gz dispatch-tools-interface-6b6e158d0614806dc970f7307fb63d392f0cb976.zip | |
imp
Diffstat (limited to 'lib/dispatch/tools/definition.rb')
| -rw-r--r-- | lib/dispatch/tools/definition.rb | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/lib/dispatch/tools/definition.rb b/lib/dispatch/tools/definition.rb new file mode 100644 index 0000000..2e386f0 --- /dev/null +++ b/lib/dispatch/tools/definition.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +require "json_schemer" + +module Dispatch + module Tools + class Definition + attr_reader :name, :description, :parameters + + def initialize(name:, description:, parameters:, &block) + @name = name + @description = description + @parameters = parameters + @block = block + @schemer = JSONSchemer.schema(deep_stringify_keys(parameters)) + end + + def call(params, context: {}) + symbolized = symbolize_keys(params) + valid, errors = validate_params(params) + + unless valid + return Result.failure(error: "Parameter validation failed: #{errors.join('; ')}") + end + + begin + @block.call(symbolized, context) + rescue Exception => e # rubocop:disable Lint/RescueException + Result.failure(error: "#{e.class}: #{e.message}") + end + end + + def to_h + { name:, description:, parameters: } + end + + def to_tool_definition + to_h + end + + def validate_params(params) + stringified = deep_stringify_keys(params) + errors = @schemer.validate(stringified).map { |err| err["error"] || err.fetch("type", "unknown error") } + + if errors.empty? + [true, []] + else + [false, errors] + end + end + + private + + def symbolize_keys(hash) + hash.each_with_object({}) do |(key, value), result| + result[key.to_sym] = value + end + end + + def deep_stringify_keys(obj) + case obj + when Hash + obj.each_with_object({}) do |(key, value), result| + result[key.to_s] = deep_stringify_keys(value) + end + when Array + obj.map { |item| deep_stringify_keys(item) } + else + obj + end + end + end + end +end |
