Class: Clacky::HookManager
- Inherits:
-
Object
- Object
- Clacky::HookManager
- 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 Attribute Summary collapse
-
#agent ⇒ Object
Returns the value of attribute agent.
Instance Method Summary collapse
- #add(event, &block) ⇒ Object
- #clear(event = nil) ⇒ Object
- #has_hooks?(event) ⇒ Boolean
-
#initialize(agent: nil) ⇒ HookManager
constructor
A new instance of HookManager.
-
#trigger(event, *args) ⇒ Hash
Extra trailing arg: the agent that owns this hook chain, so ext hooks can call
agent.emit_event(...). - #validate_event!(event) ⇒ Object
Constructor Details
#initialize(agent: nil) ⇒ HookManager
Returns a new instance of HookManager.
17 18 19 20 |
# File 'lib/clacky/agent/hook_manager.rb', line 17 def initialize(agent: nil) @hooks = Hash.new { |h, k| h[k] = [] } @agent = agent end |
Instance Attribute Details
#agent ⇒ Object
Returns the value of attribute agent.
15 16 17 |
# File 'lib/clacky/agent/hook_manager.rb', line 15 def agent @agent end |
Instance Method Details
#add(event, &block) ⇒ Object
22 23 24 25 |
# File 'lib/clacky/agent/hook_manager.rb', line 22 def add(event, &block) validate_event!(event) @hooks[event] << block end |
#clear(event = nil) ⇒ Object
65 66 67 68 69 70 71 72 |
# File 'lib/clacky/agent/hook_manager.rb', line 65 def clear(event = nil) if event validate_event!(event) @hooks[event].clear else @hooks.clear end end |
#has_hooks?(event) ⇒ Boolean
61 62 63 |
# File 'lib/clacky/agent/hook_manager.rb', line 61 def has_hooks?(event) @hooks[event].any? end |
#trigger(event, *args) ⇒ Hash
Extra trailing arg: the agent that owns this hook chain, so ext hooks can
call agent.emit_event(...). Blocks are procs — those declaring fewer
params (|call|, |call, result|) silently ignore it.
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 |
# File 'lib/clacky/agent/hook_manager.rb', line 32 def trigger(event, *args) validate_event!(event) result = { action: :allow } @hooks[event].each do |hook| begin hook_result = hook.call(*args, @agent) 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. # # :handled short-circuits the same way — the hook has already produced # the tool's result, so later hooks have nothing left to act on. if hook_result[:action] == :deny || hook_result[:action] == :handled 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
75 76 77 78 79 |
# File 'lib/clacky/agent/hook_manager.rb', line 75 def validate_event!(event) return if HOOK_EVENTS.include?(event) raise ArgumentError, "Invalid hook event: #{event}. Must be one of #{HOOK_EVENTS.join(', ')}" end |