Skip to content
Kward Search API index

Module: Kward::Hooks::Catalog

Defined in:
lib/kward/hooks/catalog.rb

Overview

Known lifecycle hook events and their safety defaults.

Defined Under Namespace

Classes: EventDefinition

Constant Summary collapse

DEFAULT_FAILURE_POLICY =
"warn"
VALID_FAILURE_POLICIES =
%w[allow warn deny ask].freeze
DEFINITIONS =
[
  EventDefinition.new(name: "turn_start", failure_policy: "warn", modifiable_fields: %w[input display_input]),
  EventDefinition.new(name: "turn_context_build_before", failure_policy: "warn"),
  EventDefinition.new(name: "turn_context_build_after", failure_policy: "warn"),
  EventDefinition.new(name: "model_request_before", failure_policy: "warn", modifiable_fields: %w[messages tools provider model reasoning]),
  EventDefinition.new(name: "turn_model_request_before", failure_policy: "warn"),
  EventDefinition.new(name: "model_response_after_parse", failure_policy: "warn"),
  EventDefinition.new(name: "turn_model_response_complete", failure_policy: "warn"),
  EventDefinition.new(name: "turn_end", failure_policy: "warn"),
  EventDefinition.new(name: "session_create", failure_policy: "warn"),
  EventDefinition.new(name: "session_resume", failure_policy: "warn"),
  EventDefinition.new(name: "session_clone", failure_policy: "warn"),
  EventDefinition.new(name: "session_fork", failure_policy: "warn"),
  EventDefinition.new(name: "session_rename", failure_policy: "warn"),
  EventDefinition.new(name: "session_export_before", failure_policy: "deny"),
  EventDefinition.new(name: "session_export_after", failure_policy: "warn"),
  EventDefinition.new(name: "session_compact_before", failure_policy: "deny"),
  EventDefinition.new(name: "session_compact_after", failure_policy: "warn"),
  EventDefinition.new(name: "tool_output_compact_before", failure_policy: "warn"),
  EventDefinition.new(name: "tool_output_compact_after", failure_policy: "warn"),
  EventDefinition.new(name: "tool_call_before", failure_policy: "deny", modifiable_fields: %w[arguments]),
  EventDefinition.new(name: "tool_call_after", failure_policy: "warn"),
  EventDefinition.new(name: "tool_call_error", failure_policy: "warn"),
  EventDefinition.new(name: "mcp_tool_before", failure_policy: "deny"),
  EventDefinition.new(name: "mcp_tool_after", failure_policy: "warn"),
  EventDefinition.new(name: "mcp_tool_error", failure_policy: "warn"),
  EventDefinition.new(name: "shell_command_before", failure_policy: "deny", modifiable_fields: %w[command timeout_seconds]),
  EventDefinition.new(name: "shell_command_after", failure_policy: "warn"),
  EventDefinition.new(name: "file_change_before", failure_policy: "deny"),
  EventDefinition.new(name: "file_change_after", failure_policy: "warn"),
  EventDefinition.new(name: "git_status_after", failure_policy: "warn"),
  EventDefinition.new(name: "git_diff_before", failure_policy: "deny"),
  EventDefinition.new(name: "git_diff_after", failure_policy: "warn"),
  EventDefinition.new(name: "git_stage_before", failure_policy: "deny"),
  EventDefinition.new(name: "git_stage_after", failure_policy: "warn"),
  EventDefinition.new(name: "git_commit_before", failure_policy: "deny"),
  EventDefinition.new(name: "git_commit_after", failure_policy: "warn"),
  EventDefinition.new(name: "worker_job_create", failure_policy: "warn"),
  EventDefinition.new(name: "worker_job_start_before", failure_policy: "warn"),
  EventDefinition.new(name: "worker_job_start_after", failure_policy: "warn"),
  EventDefinition.new(name: "worker_job_ready_for_review", failure_policy: "warn"),
  EventDefinition.new(name: "worker_job_failed", failure_policy: "warn")
].each_with_object({}) { |definition, result| result[definition.name] = definition }.freeze

Class Method Summary collapse

Class Method Details

.definition(event_name) ⇒ Object



61
62
63
# File 'lib/kward/hooks/catalog.rb', line 61

def definition(event_name)
  DEFINITIONS[event_name.to_s]
end

.event_namesObject



57
58
59
# File 'lib/kward/hooks/catalog.rb', line 57

def event_names
  DEFINITIONS.keys.sort
end

.failure_decision(policy, message, metadata: nil) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/kward/hooks/catalog.rb', line 96

def failure_decision(policy, message, metadata: nil)
  case normalize_failure_policy(policy)
  when "allow"
    Decision.allow(message, metadata: )
  when "warn"
    Decision.warn(message, metadata: )
  when "deny"
    Decision.deny(message, metadata: )
  when "ask"
    Decision.ask(message, metadata: )
  end
end

.failure_policy(event_name, explicit_policy = nil) ⇒ Object



69
70
71
# File 'lib/kward/hooks/catalog.rb', line 69

def failure_policy(event_name, explicit_policy = nil)
  normalize_failure_policy(explicit_policy || definition(event_name)&.failure_policy || DEFAULT_FAILURE_POLICY)
end

.filter_modifications(event_name, payload) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
# File 'lib/kward/hooks/catalog.rb', line 84

def filter_modifications(event_name, payload)
  definition = definition(event_name)
  return payload unless definition

  fields = Array(definition.modifiable_fields)
  return {} if fields.empty?

  payload.each_with_object({}) do |(key, value), result|
    result[key] = value if fields.include?(key.to_s)
  end
end

.known?(event_name) ⇒ Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/kward/hooks/catalog.rb', line 65

def known?(event_name)
  DEFINITIONS.key?(event_name.to_s)
end

.modifiable_fields(event_name) ⇒ Object



80
81
82
# File 'lib/kward/hooks/catalog.rb', line 80

def modifiable_fields(event_name)
  Array(definition(event_name)&.modifiable_fields)
end

.normalize_failure_policy(policy) ⇒ Object

Raises:

  • (ArgumentError)


73
74
75
76
77
78
# File 'lib/kward/hooks/catalog.rb', line 73

def normalize_failure_policy(policy)
  value = policy.to_s
  return value if VALID_FAILURE_POLICIES.include?(value)

  raise ArgumentError, "Unknown hook failure policy: #{policy}"
end