Documentation
¶
Overview ¶
Ports packages/coding-agent/src/core/compaction/branch-summarization.ts Branch summarization for tree navigation.
When navigating to a different point in the session tree, this generates a summary of the branch being left so context isn't lost.
Mirrors upstream:
.upstream/current/packages/coding-agent/src/core/compaction/branch-summarization.ts
Package compaction: core compaction logic.
Mirrors upstream:
.upstream/current/packages/coding-agent/src/core/compaction/compaction.ts
All functions are pure except Compact (one LLM call via SimpleCompleter).
Retry policy for summarization LLM calls.
Mirrors upstream:
.upstream/current/packages/ai/src/utils/retry.ts (RetryPolicy, RetryCallbacks, retryAssistantCall) .upstream/current/packages/agent/src/harness/compaction/compaction.ts (completeSimpleWithRetries)
Compaction and branch-summary summarization calls reuse settings.retry so a single transient stream drop no longer fails the whole operation.
Package compaction provides shared utilities for context compaction and branch summarization.
Mirrors upstream:
.upstream/current/packages/coding-agent/src/core/compaction/utils.ts
All functions are pure: no LLM calls, no I/O, no side effects.
Index ¶
- Constants
- Variables
- func ComputeFileLists(ops FileOperations) (readFiles, modifiedFiles []string)
- func EstimateContextTokens(messages []agent.AgentMessage) agent.ContextUsageEstimate
- func EstimateProjectedContextTokens(projection codingagent.SessionProjection, ...) agent.ContextUsageEstimate
- func EstimateTokens(message agent.AgentMessage) int
- func ExtractFileOpsFromMessage(msg agent.AgentMessage, ops *FileOperations)
- func FindTurnStartIndex(entries []codingagent.SessionEntry, entryIndex, startIndex int) int
- func FormatFileOperations(readFiles, modifiedFiles []string) string
- func GenerateBugReportSummary(ctx context.Context, opts GenerateBugReportSummaryOptions) (string, error)
- func GetLastAssistantUsage(entries []codingagent.SessionEntry) *ai.Usage
- func SerializeConversation(messages []ai.Message) string
- func ShouldCompact(contextTokens, contextWindow int, s CompactionSettings) bool
- type BranchPreparation
- type BranchSummaryDetails
- type BranchSummaryResult
- type BranchSummarySettings
- type CollectEntriesResult
- type CompactionDetails
- type CompactionPreparation
- type CompactionResult
- type CompactionSettings
- type CutPointResult
- type FileOperations
- type GenerateBranchSummaryOptions
- type GenerateBugReportSummaryOptions
- type ReadonlySession
- type RetryCallbacks
- type RetryOptions
- type RetryPolicy
- type SimpleCompleter
- type StreamFn
Constants ¶
const BRANCH_SUMMARY_PREAMBLE = "The user explored a different conversation branch before returning here.\nSummary of that exploration:\n\n"
BRANCH_SUMMARY_PREAMBLE is prepended to every generated branch summary so the model understands the provenance of the text. Verbatim from upstream branch-summarization.ts.
const BRANCH_SUMMARY_PROMPT = `` /* 689-byte string literal not displayed */
BRANCH_SUMMARY_PROMPT is the instruction prompt for branch summarization. Verbatim from upstream branch-summarization.ts.
const SUMMARIZATION_PROMPT = `` /* 879-byte string literal not displayed */
SUMMARIZATION_PROMPT is the prompt for initial context summarization. Verbatim from upstream compaction.ts:454.
const SummarizationSystemPrompt = `` /* 310-byte string literal not displayed */
SummarizationSystemPrompt is the system prompt used when requesting a context summary from the LLM. Verbatim from upstream compaction.ts.
const UPDATE_SUMMARIZATION_PROMPT = `` /* 1257-byte string literal not displayed */
UPDATE_SUMMARIZATION_PROMPT is the prompt used when updating an existing summary. Verbatim from upstream compaction.ts:487.
Variables ¶
var DefaultCompactionSettings = CompactionSettings{ Enabled: true, ReserveTokens: 16384, KeepRecentTokens: 20000, }
DefaultCompactionSettings mirrors upstream DEFAULT_COMPACTION_SETTINGS.
var ErrSummarizationToolCall = errors.New("summarization attempted to call a tool")
ErrSummarizationToolCall rejects a provider response containing a tool call; standalone summarization requests never provide executable tools.
Functions ¶
func ComputeFileLists ¶
func ComputeFileLists(ops FileOperations) (readFiles, modifiedFiles []string)
ComputeFileLists returns read-only and modified paths in JavaScript sort order.
func EstimateContextTokens ¶
func EstimateContextTokens(messages []agent.AgentMessage) agent.ContextUsageEstimate
EstimateContextTokens estimates context size from the last valid assistant usage plus an estimate of the messages after it, or from the messages alone when no usage exists (compaction.ts estimateContextTokens). LastUsageIndex is -1 for Pi's null.
func EstimateProjectedContextTokens ¶
func EstimateProjectedContextTokens(projection codingagent.SessionProjection, branchEntries []codingagent.SessionEntry) agent.ContextUsageEstimate
EstimateProjectedContextTokens estimates a projected context without trusting usage captured before a later context edit or compaction on the branch (compaction.ts estimateProjectedContextTokens). Without trusted usage, it counts the replayed current system state once plus every non-system projected message.
func EstimateTokens ¶
func EstimateTokens(message agent.AgentMessage) int
EstimateTokens estimates one context message with the chars/4 heuristic, counting JavaScript string lengths (compaction.ts estimateTokens). Unknown roles count as zero.
func ExtractFileOpsFromMessage ¶
func ExtractFileOpsFromMessage(msg agent.AgentMessage, ops *FileOperations)
ExtractFileOpsFromMessage records read/write/edit tool calls in an assistant message, or the nested calls recorded on a tool result. Calls made from codemode scripts are recorded on the script's result.
upstream: .upstream/current/packages/coding-agent/src/core/compaction/utils.ts (extractFileOpsFromMessage, addFileOp)
func FindTurnStartIndex ¶
func FindTurnStartIndex(entries []codingagent.SessionEntry, entryIndex, startIndex int) int
FindTurnStartIndex returns the index of the context-visible user-role entry that starts the span containing entryIndex, or -1 when none exists at or after startIndex (compaction.ts findTurnStartIndex).
func FormatFileOperations ¶
FormatFileOperations renders the shared summary metadata tags.
func GenerateBugReportSummary ¶
func GenerateBugReportSummary(ctx context.Context, opts GenerateBugReportSummaryOptions) (string, error)
GenerateBugReportSummary asks the session model for a report when the user does not share the transcript. Mirrors upstream generateBugReportSummary.
func GetLastAssistantUsage ¶
func GetLastAssistantUsage(entries []codingagent.SessionEntry) *ai.Usage
GetLastAssistantUsage returns the usage of the last assistant message with valid usage in entries (compaction.ts getLastAssistantUsage).
func SerializeConversation ¶
SerializeConversation converts wire-format LLM messages to a plain-text representation suitable for summarization. Call convertToLLM first to normalise custom message types (bashExecution, compactionSummary, etc.) before passing the slice here.
Roles handled:
- "user" → [User]: <text>
- "assistant" → [Assistant thinking]: … / [Assistant]: … / [Assistant tool calls]: …
- "tool" → [Tool result]: <text> (truncated to 2000 chars)
Mirrors upstream serializeConversation (utils.ts).
func ShouldCompact ¶
func ShouldCompact(contextTokens, contextWindow int, s CompactionSettings) bool
ShouldCompact reports whether compaction should trigger. Mirrors upstream shouldCompact (compaction.ts).
Types ¶
type BranchPreparation ¶
type BranchPreparation struct {
// Messages extracted for summarization, in chronological order.
Messages []agent.AgentMessage
// FileOps extracted from tool calls and prior branch_summary details.
FileOps FileOperations
// TotalTokens is the estimated token count of Messages.
TotalTokens int
}
BranchPreparation is the output of PrepareBranchEntries. Mirrors upstream BranchPreparation (branch-summarization.ts:55).
func PrepareBranchEntries ¶
func PrepareBranchEntries(entries []codingagent.SessionEntry, tokenBudget int) BranchPreparation
PrepareBranchEntries builds the message list and file-op summary for a slice of branch entries, respecting the given token budget.
Two-pass algorithm:
- Collect file ops from ALL entries (even if they exceed the budget). File ops from prior branch_summary entries seed the cumulative tracker.
- Walk newest-to-oldest, adding messages until the budget is hit. Summary entries (compaction, branch_summary) get priority fit when totalTokens < 90% of the budget.
tokenBudget == 0 means no limit.
Mirrors upstream prepareBranchEntries (branch-summarization.ts:196).
type BranchSummaryDetails ¶
type BranchSummaryDetails struct {
ReadFiles []string `json:"readFiles"`
ModifiedFiles []string `json:"modifiedFiles"`
}
BranchSummaryDetails is stored in BranchSummaryEntry.details for cumulative file tracking across nested branch summaries. Mirrors upstream BranchSummaryDetails (branch-summarization.ts:43).
type BranchSummaryResult ¶
type BranchSummaryResult struct {
Summary string
ReadFiles []string
ModifiedFiles []string
Aborted bool
Error string
// Usage is the summarization LLM call usage, if reported.
Usage *ai.Usage
}
BranchSummaryResult is the return type of GenerateBranchSummary. Mirrors upstream BranchSummaryResult (branch-summarization.ts:31).
func GenerateBranchSummary ¶
func GenerateBranchSummary(ctx context.Context, entries []codingagent.SessionEntry, opts GenerateBranchSummaryOptions) BranchSummaryResult
GenerateBranchSummary produces a structured summary of abandoned branch entries by calling the LLM via opts.Completer.
Returns BranchSummaryResult{Aborted: true} when ctx is cancelled. Returns BranchSummaryResult{Error: "..."} with Pi's operation label and tool-call diagnostic on LLM failure.
Mirrors upstream generateBranchSummary (branch-summarization.ts:250).
type BranchSummarySettings ¶
type BranchSummarySettings struct {
ReserveTokens int
}
BranchSummarySettings controls the token budget for branch summarization. Mirrors upstream BranchSummarySettings (branch-summarization.ts).
type CollectEntriesResult ¶
type CollectEntriesResult struct {
// Entries to summarize, in chronological order.
Entries []codingagent.SessionEntry
// CommonAncestorID is the deepest node on both the old and target paths,
// or "" if none found.
CommonAncestorID string
}
CollectEntriesResult is the output of CollectEntriesForBranchSummary. Mirrors upstream CollectEntriesResult (branch-summarization.ts:62).
func CollectEntriesForBranchSummary ¶
func CollectEntriesForBranchSummary(session ReadonlySession, oldLeafID, targetID string) CollectEntriesResult
CollectEntriesForBranchSummary finds the entries that should be summarized when navigating from oldLeafID to a different position in the tree.
It walks from oldLeafID back to the deepest common ancestor with targetID and returns the collected entries in chronological order.
If oldLeafID is empty, returns an empty result (nothing to summarize).
Mirrors upstream collectEntriesForBranchSummary (branch-summarization.ts:104).
type CompactionDetails ¶
type CompactionDetails struct {
ReadFiles []string `json:"readFiles"`
ModifiedFiles []string `json:"modifiedFiles"`
}
CompactionDetails is stored in a CompactionEntry.Details for file tracking across compactions. Mirrors upstream CompactionDetails (compaction.ts:36).
type CompactionPreparation ¶
type CompactionPreparation struct {
FirstKeptEntryID string `json:"firstKeptEntryId"`
MessagesToSummarize []agent.AgentMessage `json:"messagesToSummarize"`
TurnPrefixMessages []agent.AgentMessage `json:"turnPrefixMessages"`
IsSplitTurn bool `json:"isSplitTurn"`
TokensBefore int `json:"tokensBefore"`
PreviousSummary string `json:"previousSummary,omitempty"`
FileOps FileOperations `json:"fileOps"`
Settings CompactionSettings `json:"settings"`
}
CompactionPreparation is the output of PrepareCompaction. Mirrors upstream CompactionPreparation (compaction.ts:600).
Extensions receive it in session_before_compact, so the JSON keys are upstream's field names.
func PrepareCompaction ¶
func PrepareCompaction( pathEntries []codingagent.SessionEntry, s CompactionSettings, ) *CompactionPreparation
PrepareCompaction selects what a compaction of pathEntries, a root-to-leaf branch, summarizes and keeps (compaction.ts prepareCompaction). It works on the canonical session projection, so context edits, omissions, and the previous compaction's retained range all apply. It returns nil when the branch ends in a compaction or nothing would be summarized.
type CompactionResult ¶
type CompactionResult struct {
Summary string
FirstKeptEntryID string
TokensBefore int
Details CompactionDetails
// Usage is the combined usage of the summarization LLM call(s), if the
// completer reported it. Mirrors upstream CompactionResult.usage.
Usage *ai.Usage
}
CompactionResult is the output of Compact. Mirrors upstream CompactionResult (compaction.ts:100).
func Compact ¶
func Compact( ctx context.Context, prep CompactionPreparation, model *ai.Model, completer SimpleCompleter, streamFn StreamFn, customInstructions string, thinkingLevel ai.ThinkingLevel, retry *RetryOptions, sessionID string, ) (CompactionResult, error)
Compact generates summaries for compaction using PrepareCompaction output. thinkingLevel applies to reasoning-capable models; an empty sessionID gives each summary request a fresh routing ID. Mirrors upstream compact (compaction.ts:714).
type CompactionSettings ¶
type CompactionSettings struct {
Enabled bool `json:"enabled"`
ReserveTokens int `json:"reserveTokens"` // tokens reserved for response; default 16384
KeepRecentTokens int `json:"keepRecentTokens"` // tokens to keep from recent history; default 20000
}
CompactionSettings controls when and how compaction runs. Mirrors upstream CompactionSettings (compaction.ts:115).
type CutPointResult ¶
type CutPointResult struct {
// FirstKeptEntryIndex is the index in entries[] of the first entry to keep.
FirstKeptEntryIndex int
// TurnStartIndex is the index of the user/bash message starting the split
// turn, or -1 if not splitting.
TurnStartIndex int
// IsSplitTurn is true when the cut lands in the middle of a turn.
IsSplitTurn bool
}
CutPointResult from FindCutPoint. Mirrors upstream CutPointResult (compaction.ts:383).
func FindCutPoint ¶
func FindCutPoint(entries []codingagent.SessionEntry, startIndex, endIndex, keepRecentTokens int) CutPointResult
FindCutPoint finds the raw-entry cut point that keeps approximately keepRecentTokens of recent context between startIndex and endIndex (exclusive) (compaction.ts findCutPoint).
type FileOperations ¶
type FileOperations struct {
Read map[string]struct{}
Written map[string]struct{}
Edited map[string]struct{}
}
FileOperations tracks files read/written/edited during a session segment. Mirrors upstream FileOperations (utils.ts): three Sets of paths.
func NewFileOps ¶
func NewFileOps() FileOperations
NewFileOps initializes the shared file-operation accumulator.
func (FileOperations) MarshalJSON ¶
func (ops FileOperations) MarshalJSON() ([]byte, error)
MarshalJSON carries each Set on the subprocess wire as a sorted string array.
type GenerateBranchSummaryOptions ¶
type GenerateBranchSummaryOptions struct {
// Model to use for summarization.
Model *ai.Model
// Completer handles the actual LLM call.
Completer SimpleCompleter
// StreamFn overrides Completer when supplied, as in compaction.
StreamFn StreamFn
// CustomInstructions are appended to (or replace) the default prompt.
CustomInstructions string
// ReplaceInstructions, when true, replaces the default prompt entirely.
ReplaceInstructions bool
// ReserveTokens are subtracted from the model context window for the
// prompt + response budget. Default 16384.
ReserveTokens int
// Retry, when non-nil, retries transient summarization errors with bounded
// exponential backoff. Mirrors upstream branch-summarization retry wiring.
Retry *RetryOptions
}
GenerateBranchSummaryOptions controls how GenerateBranchSummary runs. Mirrors upstream GenerateBranchSummaryOptions (branch-summarization.ts:69).
type GenerateBugReportSummaryOptions ¶
type GenerateBugReportSummaryOptions struct {
Messages []agent.AgentMessage
Hint string
Model *ai.Model
Completer SimpleCompleter
StreamFn StreamFn
Retry *RetryOptions
// ThinkingLevel applies to reasoning-capable models.
ThinkingLevel ai.ThinkingLevel
// SessionID is the routing session ID forwarded without prompt caching.
SessionID string
}
GenerateBugReportSummaryOptions configures GenerateBugReportSummary.
type ReadonlySession ¶
type ReadonlySession interface {
// Branch returns the root-first path ending at leafID.
// Returns nil if leafID is not found.
Branch(leafID string) []codingagent.SessionEntry
// EntryByID looks up a single entry by ID.
// Returns (zero, false) if not found.
EntryByID(id string) (codingagent.SessionEntry, bool)
}
ReadonlySession provides read-only access needed for branch entry collection. Mirrors upstream ReadonlySessionManager used in branch-summarization.ts.
*codingagent.Session satisfies this interface via its Branch and EntryByID methods.
type RetryCallbacks ¶
type RetryCallbacks struct {
// OnRetryScheduled fires before the backoff sleep of each retry (1-indexed).
OnRetryScheduled func(attempt, maxAttempts, delayMs int, errMsg string)
// OnRetryAttemptStart fires after the backoff sleep, before the retried call.
OnRetryAttemptStart func()
// OnRetryFinished fires once when a retried loop ends.
OnRetryFinished func()
}
RetryCallbacks are emitted around each retry. Nil fields are skipped. Mirrors upstream RetryCallbacks.
type RetryOptions ¶
type RetryOptions struct {
Policy RetryPolicy
IsRetryable func(errMsg string) bool
Callbacks RetryCallbacks
}
RetryOptions bundles the policy, transient-error classifier, and callbacks. A nil *RetryOptions disables retries. IsRetryable is injected so this package need not import the coding-layer classifier (which would be an import cycle).
type RetryPolicy ¶
type RetryPolicy struct {
Enabled bool
// MaxRetries is the max retry attempts (0 = no retries). The initial call
// never counts as a retry.
MaxRetries int
// BaseDelayMs is the base backoff; per-attempt delay is
// BaseDelayMs * 2^(attempt-1).
BaseDelayMs int
// MaxAgentDelayMs caps each delay; nil uses ai.DefaultMaxAgentRetryDelayMs.
MaxAgentDelayMs *int
}
RetryPolicy is the bounded-attempts, exponential-backoff policy for summarization retries. Mirrors upstream RetryPolicy.
type SimpleCompleter ¶
type SimpleCompleter interface {
CompleteSimple(ctx context.Context, model *ai.Model, systemPrompt string, messages []agent.AgentMessage, options ai.StreamOptions) (string, *ai.Usage, error)
}
SimpleCompleter is a minimal interface for LLM calls used by Compact. Allows test injection without live LLM calls. options are the request options completeSummarization built (upstream SimpleStreamOptions).
type StreamFn ¶
type StreamFn func(ctx context.Context, model *ai.Model, systemPrompt string, messages []agent.AgentMessage, options ai.StreamOptions) (string, *ai.Usage, error)
StreamFn is an optional summarization path used instead of CompleteSimple. Mirrors upstream's streamFn forwarding for compaction requests.