Class: Ask::Tool
- Inherits:
-
Object
- Object
- Ask::Tool
- Defined in:
- lib/ask/tools/tool.rb
Defined Under Namespace
Class Method Summary collapse
- .build_schema_from_params ⇒ Object
- .deep_stringify_keys(obj) ⇒ Object
- .desc ⇒ Object
- .description(text = nil) ⇒ Object
- .inherited(subclass) ⇒ Object
- .param(name, type:, desc: nil, description: nil, required: true) ⇒ Object
- .parameters ⇒ Object
- .params(schema = nil, &block) ⇒ Object
- .params_schema ⇒ Object
- .provider_params ⇒ Object
- .resolve_params_schema(definition) ⇒ Object
Instance Method Summary collapse
- #call(args = {}) ⇒ Object
- #description ⇒ Object
- #execute ⇒ Object
- #inspect ⇒ Object
- #name ⇒ Object
- #parameters ⇒ Object
- #params_schema ⇒ Object
- #provider_params ⇒ Object
- #tool_definition ⇒ Object
Class Method Details
.build_schema_from_params ⇒ Object
63 64 65 66 67 68 69 70 71 72 |
# File 'lib/ask/tools/tool.rb', line 63 def build_schema_from_params properties = parameters.to_h do |_name, param| schema = { type: param.type } schema[:description] = param.description if param.description schema[:items] = { type: "string" } if param.type == "array" [param.name.to_s, schema] end required = parameters.select { |_, p| p.required }.keys.map(&:to_s) { type: "object", properties: properties, required: required, additionalProperties: false } end |
.deep_stringify_keys(obj) ⇒ Object
86 87 88 89 90 91 92 |
# File 'lib/ask/tools/tool.rb', line 86 def deep_stringify_keys(obj) case obj when Hash then obj.each_with_object({}) { |(k, v), h| h[k.to_s] = deep_stringify_keys(v) } when Array then obj.map { |v| deep_stringify_keys(v) } else obj end end |
.desc ⇒ Object
28 29 30 31 |
# File 'lib/ask/tools/tool.rb', line 28 def description(text = nil) return @description unless text @description = text end |
.description(text = nil) ⇒ Object
24 25 26 27 |
# File 'lib/ask/tools/tool.rb', line 24 def description(text = nil) return @description unless text @description = text end |
.inherited(subclass) ⇒ Object
16 17 18 19 20 21 22 |
# File 'lib/ask/tools/tool.rb', line 16 def inherited(subclass) super @parameters = {} if @parameters.nil? subclass.instance_variable_set(:@description, nil) subclass.instance_variable_set(:@parameters, {}) subclass.instance_variable_set(:@params_schema_definition, nil) end |
.param(name, type:, desc: nil, description: nil, required: true) ⇒ Object
30 31 32 33 34 35 36 37 |
# File 'lib/ask/tools/tool.rb', line 30 def param(name, type:, desc: nil, description: nil, required: true) type = type.to_s.downcase.to_sym validate_param_type!(type, name) parameters[name] = Parameter.new( name: name, type: map_type(type), description: desc || description, required: required ) end |
.parameters ⇒ Object
43 44 45 |
# File 'lib/ask/tools/tool.rb', line 43 def parameters @parameters ||= {} end |
.params(schema = nil, &block) ⇒ Object
39 40 41 |
# File 'lib/ask/tools/tool.rb', line 39 def params(schema = nil, &block) @params_schema_definition = schema || block end |
.params_schema ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/ask/tools/tool.rb', line 51 def params_schema @params_schema ||= begin if @params_schema_definition deep_stringify_keys(resolve_params_schema(@params_schema_definition)) elsif @parameters && @parameters.any? build_schema_from_params else nil end end end |
.provider_params ⇒ Object
47 48 49 |
# File 'lib/ask/tools/tool.rb', line 47 def provider_params @provider_params ||= {} end |
.resolve_params_schema(definition) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/ask/tools/tool.rb', line 74 def resolve_params_schema(definition) case definition when Proc schema_class = Ask::Schema.create(&definition) schema_class.new.to_json_schema.dig(:schema) when Hash then definition when ->(d) { d.respond_to?(:to_json_schema) } definition.to_json_schema.dig(:schema) else nil end end |
Instance Method Details
#call(args = {}) ⇒ Object
135 136 137 138 139 140 141 142 143 144 |
# File 'lib/ask/tools/tool.rb', line 135 def call(args = {}) normalized = normalize_args(args) validation = validate(normalized) return Ask::Result.failure(validation) if validation execute(**normalized) rescue Halt => e Ask::Result.ok(data: e.content, metadata: { halted: true }) rescue StandardError => e Ask::Result.failure("#{self.class.name.split('::').last} raised #{e.class}: #{e.}") end |
#description ⇒ Object
127 128 129 |
# File 'lib/ask/tools/tool.rb', line 127 def description self.class.description end |
#execute ⇒ Object
146 147 148 |
# File 'lib/ask/tools/tool.rb', line 146 def execute(**) raise NotImplementedError, "#{self.class} must implement #execute(**args)" end |
#inspect ⇒ Object
169 170 171 |
# File 'lib/ask/tools/tool.rb', line 169 def inspect "#<#{self.class.name} name=#{name.inspect}>" end |
#name ⇒ Object
116 117 118 119 120 121 122 123 124 125 |
# File 'lib/ask/tools/tool.rb', line 116 def name klass_name = self.class.name.to_s || "" normalized = klass_name.dup.force_encoding("UTF-8").unicode_normalize(:nfkd) normalized.encode("ASCII", replace: "") .gsub(/[^a-zA-Z0-9_-]/, "-") .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2') .gsub(/([a-z\d])([A-Z])/, '\1_\2') .downcase .delete_suffix("_tool") end |
#parameters ⇒ Object
131 132 133 |
# File 'lib/ask/tools/tool.rb', line 131 def parameters self.class.parameters end |
#params_schema ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/ask/tools/tool.rb', line 150 def params_schema return @params_schema if defined?(@params_schema) @params_schema = begin if params_schema_definition deep_stringify_keys(resolve_params_schema(params_schema_definition)) elsif parameters.any? build_schema_from_params else nil end end end |
#provider_params ⇒ Object
112 113 114 |
# File 'lib/ask/tools/tool.rb', line 112 def provider_params self.class.provider_params end |
#tool_definition ⇒ Object
163 164 165 166 167 |
# File 'lib/ask/tools/tool.rb', line 163 def tool_definition defn = { name: name, description: description } defn[:input_schema] = params_schema if params_schema defn end |