Class: Insika::Context::Providers::Session

Inherits:
Insika::ContextProvider show all
Defined in:
lib/insika/context/providers/session.rb

Overview

Reads the Session Store. The ONLY history provider: the three transcript sources converge here — the Executor does not pick a source. Produces :history fragments (1 per message), with priority scaled by recency with a CEILING of 79: the budget cut discards the oldest ones first and history NEVER outranks skills (80) or identity (100).

Instance Method Summary collapse

Methods inherited from Insika::ContextProvider

#enabled_for?, #id, #required?

Constructor Details

#initialize(session_store:) ⇒ Session

Returns a new instance of Session.



12
13
14
# File 'lib/insika/context/providers/session.rb', line 12

def initialize(session_store:)
  @session_store = session_store
end

Instance Method Details

#call(request) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/insika/context/providers/session.rb', line 16

def call(request)
  messages = transcript_for(request)
  return [] if messages.nil? || messages.empty?

  # 1 fragment per EVICTION UNIT (§11 R1): a plain message, OR an
  # assistant-with-tool_calls together with its tool results. Grouping at
  # the fragment level means the budget cut (apply_budget) drops a whole
  # tool cycle atomically — a tool_use is NEVER seeded without its result
  # (which providers reject), without touching apply_budget itself.
  eviction_units(messages).each_with_index.map do |unit, idx|
    ContextFragment.build(
      # single message stays a Hash (compat with existing fragments); a
      # multi-message cycle is an Array (seed_history flattens it back).
      content: unit.size == 1 ? unit.first : unit,
      placement: :history,
      # HISTORY_MAX ceiling; idx 0 = oldest (drops first in the cut)
      priority: [Context::Priority::HISTORY_BASE + idx, Context::Priority::HISTORY_MAX].min,
      source: id
    )
  end
end