Module: Legion::LLM::Tools::Interceptor

Extended by:
Legion::Logging::Helper
Defined in:
lib/legion/llm/tools/interceptor.rb

Class Method Summary collapse

Class Method Details

.intercept(tool_name, **args) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/legion/llm/tools/interceptor.rb', line 20

def intercept(tool_name, **args)
  snapshot = @mutex.synchronize { @registry.dup }
  snapshot.each do |name, entry|
    next unless entry[:matcher].call(tool_name)

    log.info "[llm][interceptor] action=interceptor_fired interceptor=#{name} tool=#{tool_name}"
    rewritten_args = entry[:rewrite].call(tool_name, **args)
    unless rewritten_args.is_a?(Hash)
      raise ArgumentError,
            "interceptor #{name.inspect} must return a Hash, got #{rewritten_args.class}"
    end

    changed_keys = rewritten_args.keys.reject { |k| rewritten_args[k] == args[k] }
    if changed_keys.any?
      log.debug "[llm][interceptor] action=args_rewritten interceptor=#{name} " \
                "tool=#{tool_name} changed_keys=#{changed_keys.join(',')}"
    end
    args = rewritten_args
  end
  args
end

.load_defaultsObject



50
51
52
53
# File 'lib/legion/llm/tools/interceptor.rb', line 50

def load_defaults
  require_relative 'interceptors/python_venv'
  Interceptors::PythonVenv.register!
end

.register(name, matcher:, &block) ⇒ Object



16
17
18
# File 'lib/legion/llm/tools/interceptor.rb', line 16

def register(name, matcher:, &block)
  @mutex.synchronize { @registry = @registry.merge(name.to_sym => { matcher: matcher, rewrite: block }) }
end

.registeredObject



42
43
44
# File 'lib/legion/llm/tools/interceptor.rb', line 42

def registered
  @mutex.synchronize { @registry.keys }
end

.reset!Object



46
47
48
# File 'lib/legion/llm/tools/interceptor.rb', line 46

def reset!
  @mutex.synchronize { @registry = {} }
end