Class: KairosMcp::InvocationContext
- Inherits:
-
Object
- Object
- KairosMcp::InvocationContext
- Defined in:
- lib/kairos_mcp/invocation_context.rb
Overview
Tracks invocation chain metadata for internal tool-to-tool calls. Carries depth, caller, mandate, and policy (whitelist/blacklist) through the entire invocation chain. Created by BaseTool#invoke_tool, threaded through ToolRegistry#call_tool.
Defined Under Namespace
Classes: DepthExceededError, PolicyDeniedError
Constant Summary collapse
- MAX_DEPTH =
10
Instance Attribute Summary collapse
-
#blacklist ⇒ Object
readonly
Returns the value of attribute blacklist.
-
#caller_tool ⇒ Object
readonly
Returns the value of attribute caller_tool.
-
#depth ⇒ Object
readonly
Returns the value of attribute depth.
-
#mandate_id ⇒ Object
readonly
Returns the value of attribute mandate_id.
-
#root_invocation_id ⇒ Object
readonly
Returns the value of attribute root_invocation_id.
-
#token_budget ⇒ Object
readonly
Returns the value of attribute token_budget.
-
#whitelist ⇒ Object
readonly
Returns the value of attribute whitelist.
Class Method Summary collapse
-
.from_h(hash) ⇒ Object
Reconstruct policy from a Hash (e.g., parsed from tool arguments).
- .from_json(json_string) ⇒ Object
Instance Method Summary collapse
-
#allowed?(tool_name) ⇒ Boolean
Check if a tool is allowed by whitelist/blacklist policy.
-
#child(caller_tool:) ⇒ Object
Create a child context for a nested invocation.
-
#derive(blacklist_remove: [], blacklist_add: []) ⇒ Object
Derive a new context with modified blacklist, preserving all other fields.
-
#initialize(depth: 0, caller_tool: nil, mandate_id: nil, token_budget: nil, whitelist: nil, blacklist: nil, root_invocation_id: nil) ⇒ InvocationContext
constructor
A new instance of InvocationContext.
-
#to_h ⇒ Object
Serialize to a plain Hash for passing through tool arguments.
- #to_json(*args) ⇒ Object
Constructor Details
#initialize(depth: 0, caller_tool: nil, mandate_id: nil, token_budget: nil, whitelist: nil, blacklist: nil, root_invocation_id: nil) ⇒ InvocationContext
Returns a new instance of InvocationContext.
16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/kairos_mcp/invocation_context.rb', line 16 def initialize(depth: 0, caller_tool: nil, mandate_id: nil, token_budget: nil, whitelist: nil, blacklist: nil, root_invocation_id: nil) @depth = depth @caller_tool = caller_tool @mandate_id = mandate_id @token_budget = token_budget @whitelist = whitelist @blacklist = blacklist @root_invocation_id = root_invocation_id || SecureRandom.hex(8) end |
Instance Attribute Details
#blacklist ⇒ Object (readonly)
Returns the value of attribute blacklist.
13 14 15 |
# File 'lib/kairos_mcp/invocation_context.rb', line 13 def blacklist @blacklist end |
#caller_tool ⇒ Object (readonly)
Returns the value of attribute caller_tool.
13 14 15 |
# File 'lib/kairos_mcp/invocation_context.rb', line 13 def caller_tool @caller_tool end |
#depth ⇒ Object (readonly)
Returns the value of attribute depth.
13 14 15 |
# File 'lib/kairos_mcp/invocation_context.rb', line 13 def depth @depth end |
#mandate_id ⇒ Object (readonly)
Returns the value of attribute mandate_id.
13 14 15 |
# File 'lib/kairos_mcp/invocation_context.rb', line 13 def mandate_id @mandate_id end |
#root_invocation_id ⇒ Object (readonly)
Returns the value of attribute root_invocation_id.
13 14 15 |
# File 'lib/kairos_mcp/invocation_context.rb', line 13 def root_invocation_id @root_invocation_id end |
#token_budget ⇒ Object (readonly)
Returns the value of attribute token_budget.
13 14 15 |
# File 'lib/kairos_mcp/invocation_context.rb', line 13 def token_budget @token_budget end |
#whitelist ⇒ Object (readonly)
Returns the value of attribute whitelist.
13 14 15 |
# File 'lib/kairos_mcp/invocation_context.rb', line 13 def whitelist @whitelist end |
Class Method Details
.from_h(hash) ⇒ Object
Reconstruct policy from a Hash (e.g., parsed from tool arguments). Only restores policy fields — depth and caller are not transferred.
81 82 83 84 85 86 87 88 89 90 |
# File 'lib/kairos_mcp/invocation_context.rb', line 81 def self.from_h(hash) return nil if hash.nil? new( whitelist: hash['whitelist'], blacklist: hash['blacklist'], mandate_id: hash['mandate_id'], token_budget: hash['token_budget'] ) end |
.from_json(json_string) ⇒ Object
92 93 94 95 |
# File 'lib/kairos_mcp/invocation_context.rb', line 92 def self.from_json(json_string) require 'json' from_h(JSON.parse(json_string)) end |
Instance Method Details
#allowed?(tool_name) ⇒ Boolean
Check if a tool is allowed by whitelist/blacklist policy. Blacklist is checked first (deny wins). Both use fnmatch patterns. For namespaced tools (e.g., “peer1/agent_start”), also checks the bare name (“agent_start”) to prevent blacklist bypass via remote proxy tool namespace prefix.
102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/kairos_mcp/invocation_context.rb', line 102 def allowed?(tool_name) names = [tool_name] names << tool_name.split('/').last if tool_name.include?('/') if @blacklist return false if names.any? { |n| @blacklist.any? { |pat| File.fnmatch(pat, n) } } end if @whitelist return names.any? { |n| @whitelist.any? { |pat| File.fnmatch(pat, n) } } end true end |
#child(caller_tool:) ⇒ Object
Create a child context for a nested invocation. Inherits all policy from the parent; increments depth.
30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/kairos_mcp/invocation_context.rb', line 30 def child(caller_tool:) raise DepthExceededError, "Max invocation depth (#{MAX_DEPTH}) exceeded" if @depth >= MAX_DEPTH self.class.new( depth: @depth + 1, caller_tool: caller_tool, mandate_id: @mandate_id, token_budget: @token_budget, whitelist: @whitelist&.dup, blacklist: @blacklist&.dup, root_invocation_id: @root_invocation_id ) end |
#derive(blacklist_remove: [], blacklist_add: []) ⇒ Object
Derive a new context with modified blacklist, preserving all other fields. Used by agent ACT phase to selectively unblock autoexec tools. Does NOT increment depth — child() does that at invoke_tool time.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/kairos_mcp/invocation_context.rb', line 47 def derive(blacklist_remove: [], blacklist_add: []) new_blacklist = Array(@blacklist).dup blacklist_remove.each { |pat| new_blacklist.delete(pat) } blacklist_add.each { |pat| new_blacklist << pat unless new_blacklist.include?(pat) } self.class.new( depth: @depth, caller_tool: @caller_tool, mandate_id: @mandate_id, token_budget: @token_budget, whitelist: @whitelist&.dup, blacklist: new_blacklist.empty? ? nil : new_blacklist, root_invocation_id: @root_invocation_id ) end |
#to_h ⇒ Object
Serialize to a plain Hash for passing through tool arguments. Only includes policy-relevant fields (whitelist, blacklist, mandate_id, token_budget).
65 66 67 68 69 70 71 72 |
# File 'lib/kairos_mcp/invocation_context.rb', line 65 def to_h { 'whitelist' => @whitelist, 'blacklist' => @blacklist, 'mandate_id' => @mandate_id, 'token_budget' => @token_budget } end |
#to_json(*args) ⇒ Object
74 75 76 77 |
# File 'lib/kairos_mcp/invocation_context.rb', line 74 def to_json(*args) require 'json' to_h.to_json(*args) end |