Dashboard › opencode › Distillation
ff0b62c7-0b5c-486f-b84c-e12916cb3ec9["lore_tm_v1_Mc4FIlKE0e4rTNjn6CP7rhNL90eokMXr7KmxY-0VlFY","lore_tm_v1__rCQs9LA2qKDOwgiaxuyPxCs82YVIVRSJ9v9Ri639O0","lore_tm_v1_PiGniP1Dh66J6ND8da83RFNvMTVnw8MC0eJOI754A_c"]
Date: Sep 17, 2026
packages/core/src/session/compaction.ts implements automatic Session context compaction with defaults DEFAULT_BUFFER = 20_000, DEFAULT_KEEP_TOKENS = 8_000, TOOL_OUTPUT_MAX_CHARS = 2_000, and SUMMARY_OUTPUT_TOKENS = 4_096.SUMMARY_TEMPLATE requires exactly ordered Markdown sections: ## Objective; ## Important Details; ## Work State with ### Completed, ### Active, and ### Blocked; ## Next Move with 2 numbered actions; and ## Relevant Files. It requires every section even when empty, terse bullets, preservation of exact paths/symbols/commands/errors/URLs/identifiers, and no mention of compaction or the summary process.SUMMARY_UPDATE_INSTRUCTIONS tells the model to combine <prior-summary> with the newer <conversation>, preserve still-needed objectives, constraints, directives, decisions, and parallel workstreams, prefer newer conflicting facts, add new progress/context, move finished work from Active to Completed, update resolved blockers, and refresh Objective and Next Move.settings(documents) reads info.compaction from Config.Document entries and reduces them in order; each document may override auto, buffer, and keep.tokens, with defaults { auto: true, buffer: 20_000, tokens: 8_000 }.packages/core/src/session/compaction.ts labels message content as [User], [Assistant], [Assistant reasoning], [Assistant tool call], [Tool result], [Tool error], [System update], [Synthetic context], or [Shell]; user/file attachments are rendered as [Attached ${mime}: ${name ?? uri}], and tool attachments as [Attached ${mime}${name === undefined ? "" : \: ${name}`}]`.truncate(value) limits serialized tool and shell output to 2_000 characters and appends \n[truncated]; serializeToolContent(...) joins tool content items with newlines.select(entries, tokens) excludes messages whose type is "compaction", serializes the rest, discards empty serialization, and walks backward to retain the newest messages fitting within the token budget; it returns older serialized content as head and retained content as recent.buildPrompt(...) supports 2 paths: without a prior summary, it asks for a new anchored summary from <conversation>; with one, it includes both <conversation> and <prior-summary>, then applies SUMMARY_UPDATE_INSTRUCTIONS. Both paths append SUMMARY_TEMPLATE.SessionCompaction.compactIfNeeded returns false when automatic compaction is disabled, the model context limit is absent/nonpositive, or estimated request tokens fit within context - Math.max(output, config.buffer); otherwise it delegates to compactAfterOverflow.SessionCompaction.compactAfterOverflow returns false when the context limit is absent/nonpositive, no usable conversation is selected, there is neither older head content nor a prior compaction, or the summary prompt exceeds context - summaryOutput.compactAfterOverflow uses the first "compaction" entry as previousSummary; its prompt context combines that entryβs saved recent text with newly selected head, while the prior summary text is supplied separately to buildPrompt.input.request.http, sends one Message.user(summaryPrompt), disables tools with tools: [], and sets generation.maxTokens to Math.min(configuredOutput || 4_096, 4_096).compactAfterOverflow publishes SessionEvent.Compaction.Started with a fresh SessionMessage.ID, current DateTime, and reason: "auto"; input.eventCommit is attached to this start event when provided, and optional input.beforeStream() runs after the start publication but before calling the LLM.LLMEvent.is.textDelta chunks and marks any LLMEvent.is.providerError as failure; an LLM.Error, provider error, unsuccessful stream, or blank summary returns false.SessionEvent.Compaction.Ended with the same messageID, current DateTime, reason: "auto", generated text, and recent: selected.recent; this end event uses { commit: input.commit }, after which compactAfterOverflow returns true.SessionCompaction.make(dependencies) exposes exactly compactIfNeeded and compactAfterOverflow; dependencies are EventV2.Interface, an LLM stream(request) function, and readonly Config.Entry[].