Class: Clacky::HookManager

Inherits:
Object
  • Object
show all
Defined in:
lib/clacky/agent/hook_manager.rb

Constant Summary collapse

HOOK_EVENTS =
[
  :before_tool_use,
  :after_tool_use,
  :on_tool_error,
  :on_start,
  :on_complete,
  :on_iteration,
  :session_rollback
].freeze

Instance Method Summary collapse

Constructor Details

#initializeHookManager

Returns a new instance of HookManager.



15
16
17
# File 'lib/clacky/agent/hook_manager.rb', line 15

def initialize
  @hooks = Hash.new { |h, k| h[k] = [] }
end

Instance Method Details

#add(event, &block) ⇒ Object



19
20
21
22
# File 'lib/clacky/agent/hook_manager.rb', line 19

def add(event, &block)
  validate_event!(event)
  @hooks[event] << block
end

#clear(event = nil) ⇒ Object



54
55
56
57
58
59
60
61
# File 'lib/clacky/agent/hook_manager.rb', line 54

def clear(event = nil)
  if event
    validate_event!(event)
    @hooks[event].clear
  else
    @hooks.clear
  end
end

#has_hooks?(event) ⇒ Boolean

Returns:

  • (Boolean)


50
51
52
# File 'lib/clacky/agent/hook_manager.rb', line 50

def has_hooks?(event)
  @hooks[event].any?
end

#trigger(event, *args) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/clacky/agent/hook_manager.rb', line 24

def trigger(event, *args)
  validate_event!(event)
  result = { action: :allow }

  @hooks[event].each do |hook|
    begin
      hook_result = hook.call(*args)
      next unless hook_result.is_a?(Hash)
      # First deny wins and stops the chain: a weaker later verdict must
      # never clobber a stronger earlier one, and the first deny's reason
      # is the one that reaches the agent. Rewrite hooks mutate `call` in
      # place (chained rewrite), so for non-deny results there's nothing to
      # merge — we just keep going.
      if hook_result[:action] == :deny
        result = hook_result
        break
      end
    rescue StandardError => e
      # Log error but don't fail
      Clacky::Logger.error("Hook error", event: event, error: e)
    end
  end

  result
end

#validate_event!(event) ⇒ Object

Raises:

  • (ArgumentError)


64
65
66
67
68
# File 'lib/clacky/agent/hook_manager.rb', line 64

def validate_event!(event)
  return if HOOK_EVENTS.include?(event)

  raise ArgumentError, "Invalid hook event: #{event}. Must be one of #{HOOK_EVENTS.join(', ')}"
end