summaryrefslogtreecommitdiffhomepage
path: root/lib/dispatch/tools/definition.rb
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-03-31 21:36:46 +0900
committerAdam Malczewski <[email protected]>2026-03-31 21:36:46 +0900
commit6b6e158d0614806dc970f7307fb63d392f0cb976 (patch)
treeea19a4ccfe97b05b17a3418461daebb1d0543505 /lib/dispatch/tools/definition.rb
parent7221a9d38fcd29d89794bc3041f11c5358b3155e (diff)
downloaddispatch-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.rb74
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