import type { CtxVarsConfig } from "./config.ts"; import { VarStore } from "./store.ts"; import { fullText, kindOf, estimateTokens } from "./serialize.ts"; import { derivedId, type MessageLike } from "./ids.ts"; /** Roles that are populated into the variable store in realtime. */ const POPULATED_ROLES = new Set(["user", "assistant", "toolResult"]); /** * Realtime variable population: called on every message_end. Stores the full * message content as a variable immediately (no summary, no decisions — those * happen at compaction time). Never touches compaction state. * * @param entryId real session entry id when resolvable (see ids.ts); falls * back to a deterministic derived id so population and compaction * always agree on the same row. */ export function populateFromMessage(store: VarStore, cfg: CtxVarsConfig, message: MessageLike, entryId?: string | null): number | null { if (!cfg.realtimePopulation) return null; if (!message?.role || !POPULATED_ROLES.has(message.role)) return null; const content = fullText(message); return store.populate(entryId || derivedId(message), kindOf(message), content, estimateTokens(content)); }