Class: Insika::OverlayToolRegistry
- Inherits:
-
Object
- Object
- Insika::OverlayToolRegistry
- Defined in:
- lib/insika/overlay_tool_registry.rb
Overview
DYNAMIC tool registry: composes the CODE registry (base, built at boot, immutable) with the DATA-DEFINED tools from the ToolStore. Drop-in for ToolRegistry — the Executor/ToolCatalog/ToolEnvelope only use entries/resolve/side_effect?.,
Rules:
- COLLISION: the base (code) ALWAYS wins — a data-tool cannot hijack
the name of a code tool (security, R3). The authoring Command also
refuses to create with a colliding name (code_tool?), but the defense stays here.
- HOT: `reload` re-reads the store and swaps the dynamic index atomically — a
new/edited data-tool takes effect on the next turn without a restart, mirroring
SkillCatalog.reload. An in-flight turn has already captured the index.
PARITY: empty ToolStore ⇒ entries/resolve/side_effect? identical to the pure base. The base (config/wiring.rb) does not even use the overlay — zero regression.
The data-tools enter as NORMAL Registry::Entry (optional: false) — they obey the same per-agent allow/deny as code tools; exposure is the operator's (the /tools matrix), not automatic just because they are "data-defined".
Instance Method Summary collapse
-
#code_tool?(name) ⇒ Boolean
Is it a CODE tool (base)? Used by the authoring Command's validation.
-
#entries ⇒ Object
Base + dynamic, except dynamic ones that collide with the base (base wins).
-
#initialize(base:, tool_store:, http:, egress: Insika::EgressGuard, egress_options: {}, event_stream: nil) ⇒ OverlayToolRegistry
constructor
A new instance of OverlayToolRegistry.
- #names ⇒ Object
-
#reload ⇒ Object
Atomic swap of the dynamic index (after writing/removing a data-tool).
-
#resolve(name) ⇒ Object
-> instance (base wins) | raise NotFoundError.
-
#side_effect?(name) ⇒ Boolean
-> bool; consumed by ToolEnvelope (checkpoint/skip-on-resume).
Constructor Details
#initialize(base:, tool_store:, http:, egress: Insika::EgressGuard, egress_options: {}, event_stream: nil) ⇒ OverlayToolRegistry
Returns a new instance of OverlayToolRegistry.
22 23 24 25 26 27 28 29 |
# File 'lib/insika/overlay_tool_registry.rb', line 22 def initialize(base:, tool_store:, http:, egress: Insika::EgressGuard, egress_options: {}, event_stream: nil) @base = base @tool_store = tool_store @http = http @egress = egress @egress_options = @event_stream = event_stream end |
Instance Method Details
#code_tool?(name) ⇒ Boolean
Is it a CODE tool (base)? Used by the authoring Command's validation.
67 |
# File 'lib/insika/overlay_tool_registry.rb', line 67 def code_tool?(name) = @base.names.include?(name.to_s) |
#entries ⇒ Object
Base + dynamic, except dynamic ones that collide with the base (base wins).
32 33 34 |
# File 'lib/insika/overlay_tool_registry.rb', line 32 def entries @base.entries + dynamic.reject { |e| code_tool?(e.name) } end |
#names ⇒ Object
36 37 38 |
# File 'lib/insika/overlay_tool_registry.rb', line 36 def names (@base.names + dynamic.map(&:name)).uniq end |
#reload ⇒ Object
Atomic swap of the dynamic index (after writing/removing a data-tool).
61 62 63 64 |
# File 'lib/insika/overlay_tool_registry.rb', line 61 def reload @dynamic = build_dynamic self end |
#resolve(name) ⇒ Object
-> instance (base wins) | raise NotFoundError.
41 42 43 44 45 46 47 48 49 |
# File 'lib/insika/overlay_tool_registry.rb', line 41 def resolve(name) key = name.to_s return @base.resolve(key) if code_tool?(key) entry = dynamic.find { |e| e.name == key } raise Insika::NotFoundError, "'#{name}' not registered in #{self.class}" unless entry entry.factory.call end |
#side_effect?(name) ⇒ Boolean
-> bool; consumed by ToolEnvelope (checkpoint/skip-on-resume). Base wins.
52 53 54 55 56 57 58 |
# File 'lib/insika/overlay_tool_registry.rb', line 52 def side_effect?(name) key = name.to_s return @base.side_effect?(key) if code_tool?(key) entry = dynamic.find { |e| e.name == key } entry ? !!entry.[:side_effect] : false end |