Carry evidence through built-in generation retries
This commit is contained in:
@@ -28,7 +28,7 @@ type Recorder struct {
|
||||
capacityWait time.Duration
|
||||
generationDuration time.Duration
|
||||
retryDelay time.Duration
|
||||
usage usageTotals
|
||||
usage UsageAccumulator
|
||||
}
|
||||
|
||||
// Selection contains resolved identities only. Unresolved fields stay empty.
|
||||
@@ -79,8 +79,7 @@ func New(observer domain.ExecutionObserver) (*Recorder, error) {
|
||||
}
|
||||
|
||||
func newRecorder(runID string, now func() time.Time, observer domain.ExecutionObserver) *Recorder {
|
||||
return &Recorder{runID: runID, startedAt: now(), now: now, observer: observer,
|
||||
usage: newUsageTotals()}
|
||||
return &Recorder{runID: runID, startedAt: now(), now: now, observer: observer}
|
||||
}
|
||||
|
||||
// NewRunID creates the identity shared by observations and successful results.
|
||||
@@ -119,7 +118,7 @@ func (r *Recorder) Attempt(data AttemptData) {
|
||||
r.lastRepairGeneration = data.Generation
|
||||
}
|
||||
r.generationDuration = addDuration(r.generationDuration, data.GenerationDuration)
|
||||
r.usage.add(data.Usage, data.UsagePresence)
|
||||
r.usage.Add(data.Usage, data.UsagePresence)
|
||||
}
|
||||
event := r.event(domain.ExecutionAttempt)
|
||||
event.Generation = data.Generation
|
||||
@@ -171,7 +170,7 @@ func (r *Recorder) Finish(data FinishData) {
|
||||
if event.Duration < 0 {
|
||||
event.Duration = 0
|
||||
}
|
||||
event.Usage = r.usage.snapshot(r.attempts)
|
||||
event.Usage = r.usage.Observed()
|
||||
r.deliver(event)
|
||||
}
|
||||
|
||||
@@ -243,7 +242,29 @@ type usageTotals struct {
|
||||
prompt, completion, total, cached, cacheWrite usageField
|
||||
}
|
||||
|
||||
func newUsageTotals() usageTotals {
|
||||
// UsageAccumulator combines presence-aware usage across dispatched attempts.
|
||||
// Its zero value represents no dispatched attempts.
|
||||
type UsageAccumulator struct {
|
||||
totals usageTotals
|
||||
attempts uint64
|
||||
}
|
||||
|
||||
// Add includes the usage reported by one dispatched attempt.
|
||||
func (u *UsageAccumulator) Add(usage domain.TokenUsage, presence *domain.TokenUsagePresence) {
|
||||
if u.attempts == 0 {
|
||||
u.totals = completeUsageTotals()
|
||||
}
|
||||
u.attempts++
|
||||
u.totals.add(usage, presence)
|
||||
}
|
||||
|
||||
// Observed returns aggregate counts, marking every field known and complete
|
||||
// when no attempt has been added.
|
||||
func (u UsageAccumulator) Observed() domain.ObservedTokenUsage {
|
||||
return u.totals.snapshot(u.attempts)
|
||||
}
|
||||
|
||||
func completeUsageTotals() usageTotals {
|
||||
return usageTotals{prompt: usageField{complete: true}, completion: usageField{complete: true},
|
||||
total: usageField{complete: true}, cached: usageField{complete: true}, cacheWrite: usageField{complete: true}}
|
||||
}
|
||||
|
||||
27
internal/observation/usage_accumulator_test.go
Normal file
27
internal/observation/usage_accumulator_test.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package observation
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitea.maximumdirect.net/eric/promptkit/internal/domain"
|
||||
)
|
||||
|
||||
func TestUsageAccumulatorPreservesPresenceAndNoAttemptSemantics(t *testing.T) {
|
||||
var empty UsageAccumulator
|
||||
zero := empty.Observed()
|
||||
if !zero.PromptTokens.Known || !zero.PromptTokens.Complete || zero.PromptTokens.Value != 0 ||
|
||||
!zero.CacheWriteTokens.Known || !zero.CacheWriteTokens.Complete || zero.CacheWriteTokens.Value != 0 {
|
||||
t.Fatalf("zero-attempt usage = %+v", zero)
|
||||
}
|
||||
|
||||
var usage UsageAccumulator
|
||||
usage.Add(domain.TokenUsage{PromptTokens: 0}, &domain.TokenUsagePresence{PromptTokens: true})
|
||||
usage.Add(domain.TokenUsage{PromptTokens: 3}, &domain.TokenUsagePresence{PromptTokens: true})
|
||||
observed := usage.Observed()
|
||||
if observed.PromptTokens.Value != 3 || !observed.PromptTokens.Known || !observed.PromptTokens.Complete {
|
||||
t.Fatalf("reported prompt usage = %+v", observed.PromptTokens)
|
||||
}
|
||||
if observed.CompletionTokens.Known || observed.CompletionTokens.Complete {
|
||||
t.Fatalf("unreported completion usage = %+v", observed.CompletionTokens)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user