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 = {}, abort_controller = nil) ⇒ Object
- #description ⇒ Object
- #execute(**args) ⇒ Object
- #inspect ⇒ Object
- #name ⇒ Object
- #parameters ⇒ Object
- #params_schema ⇒ Object
- #provider_params ⇒ Object
- #tool_definition ⇒ Object
Class Method Details
.build_schema_from_params ⇒ Object
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/ask/tools/tool.rb', line 64 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
87 88 89 90 91 92 93 |
# File 'lib/ask/tools/tool.rb', line 87 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
29 30 31 32 |
# File 'lib/ask/tools/tool.rb', line 29 def description(text = nil) return @description unless text @description = text end |
.description(text = nil) ⇒ Object
25 26 27 28 |
# File 'lib/ask/tools/tool.rb', line 25 def description(text = nil) return @description unless text @description = text end |
.inherited(subclass) ⇒ Object
17 18 19 20 21 22 23 |
# File 'lib/ask/tools/tool.rb', line 17 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
31 32 33 34 35 36 37 38 |
# File 'lib/ask/tools/tool.rb', line 31 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
44 45 46 |
# File 'lib/ask/tools/tool.rb', line 44 def parameters @parameters ||= {} end |
.params(schema = nil, &block) ⇒ Object
40 41 42 |
# File 'lib/ask/tools/tool.rb', line 40 def params(schema = nil, &block) @params_schema_definition = schema || block end |
.params_schema ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/ask/tools/tool.rb', line 52 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
48 49 50 |
# File 'lib/ask/tools/tool.rb', line 48 def provider_params @provider_params ||= {} end |
.resolve_params_schema(definition) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/ask/tools/tool.rb', line 75 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 = {}, abort_controller = nil) ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/ask/tools/tool.rb', line 136 def call(args = {}, abort_controller = nil) normalized = normalize_args(args) validation = validate(normalized) return Ask::Result.failure(validation) if validation normalized[:_abort_controller] = abort_controller if abort_controller execute_kwargs = normalized.reject { |k, _| k == :_abort_controller || k == :abort_controller } execute(**execute_kwargs) 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
128 129 130 |
# File 'lib/ask/tools/tool.rb', line 128 def description self.class.description end |
#execute(**args) ⇒ Object
149 150 151 |
# File 'lib/ask/tools/tool.rb', line 149 def execute(**args) raise NotImplementedError, "#{self.class} must implement #execute(**args)" end |
#inspect ⇒ Object
172 173 174 |
# File 'lib/ask/tools/tool.rb', line 172 def inspect "#<#{self.class.name} name=#{name.inspect}>" end |
#name ⇒ Object
117 118 119 120 121 122 123 124 125 126 |
# File 'lib/ask/tools/tool.rb', line 117 def name klass_name = self.class.name.to_s.split("::").last || "" 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
132 133 134 |
# File 'lib/ask/tools/tool.rb', line 132 def parameters self.class.parameters end |
#params_schema ⇒ Object
153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/ask/tools/tool.rb', line 153 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
113 114 115 |
# File 'lib/ask/tools/tool.rb', line 113 def provider_params self.class.provider_params end |
#tool_definition ⇒ Object
166 167 168 169 170 |
# File 'lib/ask/tools/tool.rb', line 166 def tool_definition defn = { name: name, description: description } defn[:input_schema] = params_schema if params_schema defn end |