Class: Insika::Context::Providers::Knowledge
- Inherits:
-
Insika::ContextProvider
- Object
- Insika::ContextProvider
- Insika::Context::Providers::Knowledge
- Defined in:
- lib/insika/context/providers/knowledge.rb
Overview
Level 1 (progressive disclosure) of what the engine has LEARNED, as
opposed to what a human curated (Skill) or the model wrote mid-turn
(Memory). Retrieval is per-message and dynamic, so — like
SkillTrigger, unlike the static CatalogProvider subclasses — this
builds its <knowledge> block directly in call, never a fixed list.
Instance Method Summary collapse
-
#call(request) ⇒ Object
required? == false (default): a store failure degrades to a :provider_warning, never aborts the turn.
-
#enabled_for?(profile) ⇒ Boolean
Per-agent opt-in (
knowledge.retrieve), like Memory'sprofile.memory. -
#initialize(store:) ⇒ Knowledge
constructor
A new instance of Knowledge.
Methods inherited from Insika::ContextProvider
Constructor Details
#initialize(store:) ⇒ Knowledge
Returns a new instance of Knowledge.
12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/insika/context/providers/knowledge.rb', line 12 def initialize(store:) @store = store # One Index PER TYPE, built once and reused for every agent/turn — # never per call. This provider instance itself lives for the # process's lifetime (built once at boot, see wiring), so an # Index rebuilt fresh each call would throw away its own read # cache (Index::Scan's dominant cost is re-parsing YAML # frontmatter; measured, not assumed) on every single turn. # Keyed by the config's `index` string so a future FTS5 agent # gets its own instance, never Scan's. @indexes = Hash.new { |h, index_name| h[index_name] = Insika::Knowledge::Index.build({ "index" => index_name }, store: @store) } end |
Instance Method Details
#call(request) ⇒ Object
required? == false (default): a store failure degrades to a :provider_warning, never aborts the turn.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/insika/context/providers/knowledge.rb', line 30 def call(request) config = request.profile.knowledge return [] unless config top_k = positive_int(config["top_k"]) || 5 index = @indexes[config["index"].to_s] matches = index.search(request.profile.id, tenant: request.tenant, query: request..to_s, top_k: top_k) return [] if matches.empty? hits = matches.map { |c| [c, "top-K match"] } + (matches, request, top_k).map { |c| [c, "one-hop link"] } [ContextFragment.build( content: format_block(hits), placement: :system, priority: Context::Priority::KNOWLEDGE, source: id, labels: hits.map { |c, reason| { "name" => c[:name], "reason" => reason } } )] end |