diff --git a/internal/runtime/agent/compact_accounting.go b/internal/runtime/agent/compact_accounting.go deleted file mode 100644 index d6303faad1..0000000000 --- a/internal/runtime/agent/compact_accounting.go +++ /dev/null @@ -1,48 +0,0 @@ -package agent - -import ( - "context" - "reasonix/internal/state/sessionstore" - "sync" -) - -type compactionSpendKey struct{} - -// compactionSpend accumulates a transaction's bill. It is reached through the -// context rather than passed down because the alternative is every call site -// remembering to return its usage, and the paths that lost usage were the ones -// that discarded a result: a discarded answer is still a charge. -type compactionSpend struct { - mu sync.Mutex - total sessionstore.CompactionUsage -} - -// withCompactionSpend opens a transaction. A nested call keeps the outer one so -// the whole compaction lands in a single bill. -func withCompactionSpend(ctx context.Context) (context.Context, *compactionSpend) { - if ctx == nil { - ctx = context.Background() - } - if spend, _ := ctx.Value(compactionSpendKey{}).(*compactionSpend); spend != nil { - return ctx, spend - } - spend := &compactionSpend{} - return context.WithValue(ctx, compactionSpendKey{}, spend), spend -} - -func compactionSpendFrom(ctx context.Context) *compactionSpend { - if ctx == nil { - return nil - } - spend, _ := ctx.Value(compactionSpendKey{}).(*compactionSpend) - return spend -} - -func (s *compactionSpend) read() sessionstore.CompactionUsage { - if s == nil { - return sessionstore.CompactionUsage{} - } - s.mu.Lock() - defer s.mu.Unlock() - return s.total -} diff --git a/internal/runtime/agent/compact_commit.go b/internal/runtime/agent/compact_commit.go index c09cb25fe6..37490d9e9f 100644 --- a/internal/runtime/agent/compact_commit.go +++ b/internal/runtime/agent/compact_commit.go @@ -20,9 +20,6 @@ type summaryProjectionCommit struct { activeTurn int64 trigger, summary, inputHash, outputHash string sourceTokens, projectionTokens int - // summaryUsage is what the transaction spent producing this projection, - // which has nothing to do with sourceTokens above. - summaryUsage sessionstore.CompactionUsage } // commitSummaryProjection CAS-installs a checkpoint under compactionMu: @@ -76,7 +73,6 @@ func (a *contextWindow) summaryProjectionState(commit summaryProjectionCommit) s InputHash: commit.inputHash, OutputHash: commit.outputHash, InputTokens: commit.sourceTokens, ResultTokens: commit.projectionTokens, SavedTokens: max(0, commit.sourceTokens-commit.projectionTokens), SummaryHash: summaryHash, CacheBreak: true, CreatedAt: now, - SummaryUsage: commit.summaryUsage, } // LastReceipt is authoritative; do not mirror last_trigger/last_mode/token // counters or top-level blocked_* fields (stripped again on save). diff --git a/internal/runtime/agent/compact_fold_input.go b/internal/runtime/agent/compact_fold_input.go index 1206feccc4..8b0eff8016 100644 --- a/internal/runtime/agent/compact_fold_input.go +++ b/internal/runtime/agent/compact_fold_input.go @@ -12,8 +12,6 @@ import ( type foldSummary struct { Text string Mode string - RequestID string - Usage *provider.Usage FoldTokens int Spans int } @@ -35,9 +33,8 @@ func (a *contextWindow) summaryInputTokens(msgs []provider.Message) int { // foldArchived writes the fold to its archive file. A failure to write it is // the fold's failure: nothing else stands in for the archive. func (a *contextWindow) foldArchived(ctx context.Context, trigger string, fold []provider.Message, instructions string, sourceTokens int) (foldSummary, CompactionTelemetry, error) { - spend := compactionSpendFrom(ctx) res, err := a.foldToArchive(fold, instructions) - tele := compactionTelemetryFromSummary(trigger, a.cacheState(), sourceTokens, res, spend.read()) + tele := compactionTelemetryFromSummary(trigger, a.cacheState(), sourceTokens, res) if err != nil { tele.Error = err.Error() } diff --git a/internal/runtime/agent/compact_projection.go b/internal/runtime/agent/compact_projection.go index 9ccbbbdc5b..8a61bc6f9f 100644 --- a/internal/runtime/agent/compact_projection.go +++ b/internal/runtime/agent/compact_projection.go @@ -166,7 +166,6 @@ func (a *contextWindow) compressVisibleRange( preview string, instructions string, ) (tool.CompressResult, error) { - ctx, spend := withCompactionSpend(ctx) a.sess.win.compactionRunMu.Lock() defer a.sess.win.compactionRunMu.Unlock() if !a.explicitCompressionSnapshotCurrent(snap) { @@ -197,7 +196,7 @@ func (a *contextWindow) compressVisibleRange( res, err := a.foldToArchive(prepared.fold, prepared.instructions) summary := res.Text - tele := compactionTelemetryFromSummary(trigger, a.cacheState(), result.SourceTokens, res, spend.read()) + tele := compactionTelemetryFromSummary(trigger, a.cacheState(), result.SourceTokens, res) if err != nil { tele.Error = err.Error() a.emitCompactionTelemetry(tele) @@ -237,7 +236,6 @@ func (a *contextWindow) compressVisibleRange( transcriptVersion: snap.transcriptVersion, projectionVersion: snap.projectionVersion, generation: snap.generation, activeTurn: a.activeTurnCreatedAt.Load(), trigger: trigger, summary: summary, inputHash: inputHash, outputHash: outputHash, sourceTokens: result.SourceTokens, projectionTokens: projectionTokens, - summaryUsage: tele.SummaryUsage, }) if err != nil { if errors.Is(err, errCompressStaleContext) { @@ -361,20 +359,11 @@ func buildVisibleCompressionProjection(visible []provider.Message, plan visibleC // spend is the transaction's bill, not the adopted call's usage: a repair that // improved nothing, failed, or was discarded was charged all the same, and the // answer that got kept is not the question "what did this cost" is asking. -func compactionTelemetryFromSummary(trigger, cacheState string, sourceTokens int, res foldSummary, spend sessionstore.CompactionUsage) CompactionTelemetry { +func compactionTelemetryFromSummary(trigger, cacheState string, sourceTokens int, res foldSummary) CompactionTelemetry { return CompactionTelemetry{ Trigger: trigger, CacheState: cacheState, Mode: res.Mode, - SourceTokens: sourceTokens, - ProviderRequestID: res.RequestID, - FoldTokens: res.FoldTokens, - Spans: spend.Calls, - SummaryUsage: spend, - InputTokens: spend.InputTokens, - OutputTokens: spend.OutputTokens, - CacheHitTokens: spend.CacheHitTokens, - CacheMissTokens: spend.CacheMissTokens, - CacheWriteTokens: spend.CacheWriteTokens, - RequestCount: spend.RequestAttempts, + SourceTokens: sourceTokens, + FoldTokens: res.FoldTokens, } } @@ -398,7 +387,6 @@ type compactionScope struct { // was foldable; callers at physical overflow must treat that as hard failure. // mustFree marks the fold the caller cannot proceed without. func (a *contextWindow) compactToProjection(ctx context.Context, trigger, instructions string, scope compactionScope, mustFree bool) (CompactionOutcome, CompactionNoopReason, error) { - ctx, _ = withCompactionSpend(ctx) a.sess.win.compactionRunMu.Lock() defer a.sess.win.compactionRunMu.Unlock() activeTurn := a.activeTurnCreatedAt.Load() @@ -492,7 +480,7 @@ func (a *contextWindow) compactToProjection(ctx context.Context, trigger, instru transcriptVersion: transcriptVersion, projectionVersion: startProjectionVersion, generation: startGeneration, activeTurn: activeTurn, trigger: trigger, summary: summary, inputHash: viewInputHash, outputHash: viewOutputHash, - sourceTokens: sourceTokens, projectionTokens: projTokens, summaryUsage: tele.SummaryUsage, + sourceTokens: sourceTokens, projectionTokens: projTokens, }) if err != nil { a.emitCompactionAborted(trigger, compactionFailureCode(err)) diff --git a/internal/runtime/agent/projection.go b/internal/runtime/agent/projection.go index 1580be373c..0b2376ad02 100644 --- a/internal/runtime/agent/projection.go +++ b/internal/runtime/agent/projection.go @@ -124,18 +124,15 @@ type CompactionTelemetry struct { CoverageRequired int `json:"coverage_required,omitempty"` CoverageMissing int `json:"coverage_missing,omitempty"` // CoverageBackstopped: the host wrote the dropped facts in itself. - CoverageBackstopped bool `json:"coverage_backstopped,omitempty"` - // SummaryUsage is the transaction's whole bill. The flat fields below are - // its input/output/cache halves, kept for the existing detail line. - SummaryUsage sessionstore.CompactionUsage `json:"summary_usage,omitzero"` - InputTokens int `json:"input_tokens"` - OutputTokens int `json:"output_tokens"` - CacheHitTokens int `json:"cache_hit_tokens"` - CacheMissTokens int `json:"cache_miss_tokens"` - CacheWriteTokens int `json:"cache_write_tokens"` - RequestCount int `json:"request_count"` - ProviderRequestID string `json:"provider_request_id,omitempty"` - Error string `json:"error,omitempty"` + CoverageBackstopped bool `json:"coverage_backstopped,omitempty"` + InputTokens int `json:"input_tokens"` + OutputTokens int `json:"output_tokens"` + CacheHitTokens int `json:"cache_hit_tokens"` + CacheMissTokens int `json:"cache_miss_tokens"` + CacheWriteTokens int `json:"cache_write_tokens"` + RequestCount int `json:"request_count"` + ProviderRequestID string `json:"provider_request_id,omitempty"` + Error string `json:"error,omitempty"` } // summaryContentHash fingerprints a compaction summary for projection metadata.