From 6b6e158d0614806dc970f7307fb63d392f0cb976 Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Tue, 31 Mar 2026 21:36:46 +0900 Subject: imp --- lib/dispatch/tools/definition.rb | 74 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 lib/dispatch/tools/definition.rb (limited to 'lib/dispatch/tools/definition.rb') 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 -- cgit v1.2.3