Class: Ask::Agent::ToolCallRepair
- Inherits:
-
Object
- Object
- Ask::Agent::ToolCallRepair
- Defined in:
- lib/ask/agent/tool_call_repair.rb
Overview
Repairs malformed tool calls before they execute.
When a model emits a tool call with unparseable arguments or an unknown tool name, execution currently fails and the model burns a turn seeing the error. Repair intercepts those calls before execution, asks the model to re-emit them corrected (one internal LLM round-trip), and executes the corrected versions — remapped to the original call ids so tool results stay consistent with the conversation history.
Enable with Session.new(tool_call_repair: true) for the built-in
repair prompt, or pass a callable for full control:
Session.new(tool_call_repair: ->(chat, calls, tools) {
{ calls.keys.first => ToolCallInfo.new(
id: calls.keys.first, name: "bash", arguments: "{}"
) }
})
The callable receives the chat, the malformed calls hash (id => ToolCallInfo), and the available tools; it returns a hash of corrections keyed by the ORIGINAL call ids. Calls without a correction are dropped — the model saw them in the prompt and declined to fix them.
Class Method Summary collapse
-
.repair_info(tool_call, tools) ⇒ String?
Why the call is repairable, or nil when it is well-formed and executable.
Instance Method Summary collapse
-
#call(chat:, calls:, tools:) ⇒ Hash{String => ToolCallInfo}
Ask the model to correct the malformed calls.
-
#initialize(callable = nil) ⇒ ToolCallRepair
constructor
A new instance of ToolCallRepair.
Constructor Details
#initialize(callable = nil) ⇒ ToolCallRepair
Returns a new instance of ToolCallRepair.
53 54 55 |
# File 'lib/ask/agent/tool_call_repair.rb', line 53 def initialize(callable = nil) @callable = callable end |
Class Method Details
.repair_info(tool_call, tools) ⇒ String?
Returns why the call is repairable, or nil when it is well-formed and executable.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/ask/agent/tool_call_repair.rb', line 35 def self.repair_info(tool_call, tools) unless tools.any? { |t| t.respond_to?(:name) && t.name == tool_call.name } return "unknown tool '#{tool_call.name}'" end args = tool_call.arguments return nil if args.is_a?(Hash) parsed = JSON.parse(args.to_s) return nil if parsed.is_a?(Hash) "arguments must be a JSON object, got #{parsed.class}" rescue JSON::ParserError => e "arguments are not valid JSON: #{e.}" end |
Instance Method Details
#call(chat:, calls:, tools:) ⇒ Hash{String => ToolCallInfo}
Ask the model to correct the malformed calls.
65 66 67 68 69 70 71 |
# File 'lib/ask/agent/tool_call_repair.rb', line 65 def call(chat:, calls:, tools:) if @callable normalize(@callable.call(chat, calls, tools)) else built_in(chat, calls, tools) end end |