Class: Norn::Tool

Inherits:
Object
  • Object
show all
Defined in:
lib/norn/tool.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, description, parameters, required_capabilities: [:sys_execute], system_instructions: nil, dangerous: false, &block) ⇒ Tool

Returns a new instance of Tool.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/norn/tool.rb', line 5

def initialize(name, description, parameters, required_capabilities: [:sys_execute], system_instructions: nil, dangerous: false, &block)
  @name = name.to_s
  @description = description
  @parameters = parameters
  @required_capabilities = Array(required_capabilities)
  @system_instructions = system_instructions
  @dangerous = dangerous
  @block = block

  # Enforce strict arity/signature checks on tool registration to fail fast on invalid bindings
  if @block && ![-1, 0, 1, 2].include?(@block.arity)
    raise Norn::Error, "Interface Violation: Tool '#{name}' block must accept either (args) or (args, context) signature."
  end
end

Instance Attribute Details

#blockObject (readonly)

Returns the value of attribute block.



3
4
5
# File 'lib/norn/tool.rb', line 3

def block
  @block
end

#dangerousObject (readonly)

Returns the value of attribute dangerous.



3
4
5
# File 'lib/norn/tool.rb', line 3

def dangerous
  @dangerous
end

#descriptionObject (readonly)

Returns the value of attribute description.



3
4
5
# File 'lib/norn/tool.rb', line 3

def description
  @description
end

#nameObject (readonly)

Returns the value of attribute name.



3
4
5
# File 'lib/norn/tool.rb', line 3

def name
  @name
end

#parametersObject (readonly)

Returns the value of attribute parameters.



3
4
5
# File 'lib/norn/tool.rb', line 3

def parameters
  @parameters
end

#required_capabilitiesObject (readonly)

Returns the value of attribute required_capabilities.



3
4
5
# File 'lib/norn/tool.rb', line 3

def required_capabilities
  @required_capabilities
end

#system_instructionsObject (readonly)

Returns the value of attribute system_instructions.



3
4
5
# File 'lib/norn/tool.rb', line 3

def system_instructions
  @system_instructions
end

Instance Method Details

#allow_session_danger?Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/norn/tool.rb', line 49

def allow_session_danger?
  @dangerous
end

#call(args, context = nil) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/norn/tool.rb', line 53

def call(args, context = nil)
  # Ensure arguments are symbolized for easy access
  symbolized_args = symbolize_keys(args)
  
  # Pass both arguments and the execution context (the calling mode instance) to the block
  result = if @block.arity == 2
    @block.call(symbolized_args, context)
  else
    @block.call(symbolized_args)
  end

  sanitize_output(result)
end

#capabilities_for(args = {}) ⇒ Object



20
21
22
23
24
# File 'lib/norn/tool.rb', line 20

def capabilities_for(args = {})
  # Default to baseline static capabilities. 
  # Subclasses or specific tools can override this to inspect arguments dynamically.
  @required_capabilities
end

#dangerous?(args = {}) ⇒ Boolean

Returns:

  • (Boolean)


26
27
28
29
30
# File 'lib/norn/tool.rb', line 26

def dangerous?(args = {})
  # Default to baseline static danger classification.
  # Parametric/dynamic tools can override this to inspect arguments dynamically (e.g. true for 'reset --hard', false for 'status').
  @dangerous
end

#session_approval_label(args = {}) ⇒ Object



32
33
34
# File 'lib/norn/tool.rb', line 32

def session_approval_label(args = {})
  "Approve '#{name}' for the rest of this session"
end

#session_approval_pattern(args = {}) ⇒ Object



36
37
38
# File 'lib/norn/tool.rb', line 36

def session_approval_pattern(args = {})
  { tool_name: name }
end

#session_approved?(session, args) ⇒ Boolean

Returns:

  • (Boolean)


40
41
42
43
44
45
46
47
# File 'lib/norn/tool.rb', line 40

def session_approved?(session, args)
  return false if session.nil?
  
  approvals = session.get(:session_approvals) || []
  has_approval = approvals.any? { |app| app[:tool_name] == name }
  
  has_approval && (!dangerous?(args) || allow_session_danger?)
end