Class: Insika::Context::Providers::Knowledge

Inherits:
Insika::ContextProvider show all
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

Methods inherited from Insika::ContextProvider

#id, #layer, #required?

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.message.to_s, top_k: top_k)
  return [] if matches.empty?

  hits = matches.map { |c| [c, "top-K match"] } +
         expand_links(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

#enabled_for?(profile) ⇒ Boolean

Per-agent opt-in (knowledge.retrieve), like Memory's profile.memory.

Returns:

  • (Boolean)


26
# File 'lib/insika/context/providers/knowledge.rb', line 26

def enabled_for?(profile) = !!(profile.knowledge && Coercion.truthy?(profile.knowledge["retrieve"]))