Class: Crimson::ToolRegistry

Inherits:
Object
  • Object
show all
Defined in:
lib/crimson/tool_registry.rb

Overview

Central registry for tool registration, execution, and schema generation.

Instance Method Summary collapse

Constructor Details

#initializeToolRegistry

Returns a new instance of ToolRegistry.



8
9
10
11
12
# File 'lib/crimson/tool_registry.rb', line 8

def initialize
  @tools = {}
  @openai_defs = nil
  @anthropic_defs = nil
end

Instance Method Details

#anthropic_definitionsArray<Hash>

Returns Anthropic-compatible tool definitions.

Returns:

  • (Array<Hash>)

    Anthropic-compatible tool definitions



71
72
73
# File 'lib/crimson/tool_registry.rb', line 71

def anthropic_definitions
  @anthropic_defs ||= @tools.values.map(&:anthropic_definition)
end

#execute(tool_name, arguments, abort_signal: nil) ⇒ String

Execute a tool by name with the given arguments.

Parameters:

  • tool_name (String)
  • arguments (Hash, String)

    argument hash or JSON string

  • abort_signal (AbortSignal, nil) (defaults to: nil)

Returns:

  • (String)

    tool result (or error message prefixed with “Error”)



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/crimson/tool_registry.rb', line 29

def execute(tool_name, arguments, abort_signal: nil)
  tool = @tools[tool_name]
  return "Error: Unknown tool '#{tool_name}'" unless tool

  args = if arguments.is_a?(String)
           JSON.parse(arguments, symbolize_names: true)
         else
           arguments.transform_keys(&:to_sym)
         end

  if tool.respond_to?(:prepare_arguments)
    begin
      prepared = tool.prepare_arguments(args.transform_keys(&:to_s))
      args = prepared.transform_keys(&:to_sym)
    rescue => e
      return "Error preparing arguments for #{tool_name}: #{e.message}"
    end
  end

  result = if tool.respond_to?(:call_with_signal) && abort_signal
             tool.call_with_signal(**args, signal: abort_signal)
           else
             tool.call(**args)
           end

  result = apply_truncation(tool_name, result)

  result
rescue JSON::ParserError
  "Error: Invalid JSON arguments for #{tool_name}"
rescue ArgumentError => e
  "Error: Wrong arguments for #{tool_name}: #{e.message}"
rescue => e
  "Error executing #{tool_name}: #{e.message}"
end

#load_skills(skills_dir) ⇒ String

Load all skill markdown files from a directory.

Parameters:

  • skills_dir (String)

    directory path

Returns:

  • (String)

    concatenated skill content



90
91
92
93
94
95
96
# File 'lib/crimson/tool_registry.rb', line 90

def load_skills(skills_dir)
  return "" unless Dir.exist?(skills_dir)

  Dir.glob(File.join(skills_dir, "*.md")).sort.filter_map do |file|
    File.read(file).strip
  end.join("\n\n")
end

#lookup(tool_name) ⇒ Module?

Look up a tool module by name.

Parameters:

  • tool_name (String)

Returns:

  • (Module, nil)


78
79
80
# File 'lib/crimson/tool_registry.rb', line 78

def lookup(tool_name)
  @tools[tool_name]
end

#openai_definitionsArray<Hash>

Returns OpenAI-compatible tool definitions.

Returns:

  • (Array<Hash>)

    OpenAI-compatible tool definitions



66
67
68
# File 'lib/crimson/tool_registry.rb', line 66

def openai_definitions
  @openai_defs ||= @tools.values.map(&:definition)
end

#register(tool_module) ⇒ void

This method returns an undefined value.

Register a tool module by its TOOL_NAME constant.

Parameters:

  • tool_module (Module)

    a tool module with TOOL_NAME, .call, and .definition



17
18
19
20
21
22
# File 'lib/crimson/tool_registry.rb', line 17

def register(tool_module)
  name = tool_module.const_get(:TOOL_NAME)
  @tools[name] = tool_module
  @openai_defs = nil
  @anthropic_defs = nil
end

#tool_namesArray<String>

Returns all registered tool names.

Returns:

  • (Array<String>)

    all registered tool names



83
84
85
# File 'lib/crimson/tool_registry.rb', line 83

def tool_names
  @tools.keys
end