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",
  "git_commit" => "git_commit",
  "read_skill" => "read_skill",
  "ask_user_question" => "ask_user_question",
  "open_editor" => "open_editor",
  "typesafe_evaluate" => "typesafe_evaluate",
  "datetime" => "datetime"
}.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



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

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



50
51
52
53
# File 'lib/kward/tools/tool_call.rb', line 50

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



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

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



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

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



43
44
45
# File 'lib/kward/tools/tool_call.rb', line 43

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

.normalized_name(name) ⇒ Object



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

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



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

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