Skip to content
Kward Search API index

Module: Kward::ToolCall

Defined in:
lib/kward/tools/tool_call.rb

Overview

Reads and normalizes model tool-call hashes.

Tool calls arrive from several providers and may be restored from session files. This module keeps provider/string/symbol compatibility in one place and exposes small helpers used by the agent loop, tool registry, transcript formatters, and RPC event normalizers.

Constant Summary collapse

TOOL_NAME_MAP =
{
  "read_file" => "read",
  "edit_file" => "edit",
  "write_file" => "write",
  "run_shell_command" => "bash",
  "list_directory" => "list_directory",
  "code_search" => "code_search",
  "summarize_file_structure" => "summarize_file_structure",
  "context_for_task" => "context_for_task",
  "context_budget_stats" => "context_budget_stats",
  "retrieve_tool_output" => "retrieve_tool_output",
  "web_search" => "web_search",
  "fetch_content" => "fetch_content",
  "fetch_raw" => "fetch_raw",
  "read_skill" => "read_skill",
  "ask_user_question" => "ask_user_question"
}.freeze

Class Method Summary collapse

Class Method Details

.arguments(tool_call) ⇒ Hash

Parses the requested tool arguments.

Returns:

  • (Hash)

    decoded argument object, or an empty hash for invalid JSON



54
55
56
# File 'lib/kward/tools/tool_call.rb', line 54

def arguments(tool_call)
  parse_arguments(raw_arguments(tool_call))
end

.camelize_args(args) ⇒ Hash

Recursively converts snake_case hash keys to camelCase symbols.

Returns:

  • (Hash)

    camelized copy of args



94
95
96
97
98
99
100
# File 'lib/kward/tools/tool_call.rb', line 94

def camelize_args(args)
  return {} unless args.is_a?(Hash)

  args.each_with_object({}) do |(key, item), result|
    result[camelize_key(key)] = camelize_value(item)
  end
end

.camelize_key(key) ⇒ Object



117
118
119
# File 'lib/kward/tools/tool_call.rb', line 117

def camelize_key(key)
  key.to_s.gsub(/_([a-z])/) { Regexp.last_match(1).upcase }.to_sym
end

.camelize_value(item) ⇒ Object



106
107
108
109
110
111
112
113
114
115
# File 'lib/kward/tools/tool_call.rb', line 106

def camelize_value(item)
  case item
  when Hash
    camelize_args(item)
  when Array
    item.map { |entry| camelize_value(entry) }
  else
    item
  end
end

.display_name(tool_call) ⇒ String

Returns the short name used in compact UI labels.

Returns:

  • (String)

    display label such as read, edit, or bash



46
47
48
49
# File 'lib/kward/tools/tool_call.rb', line 46

def display_name(tool_call)
  raw_name = name(tool_call)
  normalized_name(raw_name) || raw_name || "unknown_tool"
end

.file_change_tool?(name) ⇒ Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/kward/tools/tool_call.rb', line 74

def file_change_tool?(name)
  %w[edit_file write_file edit write].include?(name.to_s)
end

.function(tool_call) ⇒ Object



62
63
64
# File 'lib/kward/tools/tool_call.rb', line 62

def function(tool_call)
  value(tool_call, :function) || {}
end

.id(tool_call) ⇒ String?

Returns provider tool-call id.

Returns:

  • (String, nil)

    provider tool-call id



34
35
36
# File 'lib/kward/tools/tool_call.rb', line 34

def id(tool_call)
  value(tool_call, :id)
end

.name(tool_call) ⇒ String?

Returns requested tool/function name.

Returns:

  • (String, nil)

    requested tool/function name



39
40
41
# File 'lib/kward/tools/tool_call.rb', line 39

def name(tool_call)
  value(function(tool_call), :name)
end

.normalized_name(name) ⇒ Object



66
67
68
# File 'lib/kward/tools/tool_call.rb', line 66

def normalized_name(name)
  TOOL_NAME_MAP[name.to_s]
end

.parse_arguments(arguments) ⇒ Object

Converts provider argument payloads into hashes.

Providers normally send JSON strings, while tests and compatibility callers may pass hashes directly.



82
83
84
85
86
87
88
89
# File 'lib/kward/tools/tool_call.rb', line 82

def parse_arguments(arguments)
  return {} if arguments.nil? || (arguments.respond_to?(:empty?) && arguments.empty?)
  return arguments if arguments.is_a?(Hash)

  JSON.parse(arguments.to_s)
rescue JSON::ParserError
  {}
end

.raw_arguments(tool_call) ⇒ Object



58
59
60
# File 'lib/kward/tools/tool_call.rb', line 58

def raw_arguments(tool_call)
  value(function(tool_call), :arguments)
end

.value(object, key) ⇒ Object



102
103
104
# File 'lib/kward/tools/tool_call.rb', line 102

def value(object, key)
  MessageAccess.value(object, key)
end

.write_lock_required?(name) ⇒ Boolean

Returns:

  • (Boolean)


70
71
72
# File 'lib/kward/tools/tool_call.rb', line 70

def write_lock_required?(name)
  %w[edit_file write_file run_shell_command edit write bash].include?(name.to_s)
end