76 lines
3.9 KiB
Go
76 lines
3.9 KiB
Go
package runtime
|
|
|
|
import (
|
|
core "agent-system-core"
|
|
"testing"
|
|
)
|
|
|
|
func TestMaterialFinalReserveDecision(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
state materialBudgetState
|
|
wantFinal, wantStop bool
|
|
}{
|
|
{"first request", materialBudgetState{Limit: 30000}, false, false},
|
|
{"two saved checkpoints", materialBudgetState{Limit: 30000, Used: 16000, LastPrompt: 5000, OutputCap: 4000, SavedCheckpoints: 2, Responses: 2, UsageKnown: true}, true, false},
|
|
{"one checkpoint and limited remainder", materialBudgetState{Limit: 30000, Used: 15000, LastPrompt: 5000, OutputCap: 4000, SavedCheckpoints: 1, Responses: 1, UsageKnown: true}, true, false},
|
|
{"enough for another checkpoint", materialBudgetState{Limit: 30000, Used: 6000, LastPrompt: 3000, OutputCap: 4000, SavedCheckpoints: 1, Responses: 1, UsageKnown: true}, false, false},
|
|
{"final prompt cannot fit", materialBudgetState{Limit: 30000, Used: 27000, LastPrompt: 8000, OutputCap: 4000, SavedCheckpoints: 1, Responses: 2, UsageKnown: true}, false, true},
|
|
// Old A01's three material responses totalled 35,632 tokens; the third
|
|
// consumed 14,231. This offline check would stop before that third call.
|
|
{"old A01 before third request", materialBudgetState{Limit: 30000, Used: 35632 - 14231, LastPrompt: 10134, OutputCap: 4000, SavedCheckpoints: 1, Responses: 2, UsageKnown: true}, false, true},
|
|
// Paid A01 on the 30000-token label: the previous assistant turn was
|
|
// truncated at the 4000 output cap, so the next request carries that
|
|
// 4000-token output on top of the 5810-token prompt. The reserve only
|
|
// catches this once the estimate includes the previous completion.
|
|
{"paid continuation crosses reserve after output-cap truncation", materialBudgetState{Limit: 30000, Used: 22070, LastPrompt: 5810 + 4000, OutputCap: 4000, SavedCheckpoints: 1, Responses: 3, UsageKnown: true}, false, true},
|
|
// Normal tool round (e.g. a non-checkpoint call mid-run) under the new
|
|
// 45000 A01 label must leave room for both the next prompt and the
|
|
// configured 6000-token output cap.
|
|
{"normal tool round under new label leaves room", materialBudgetState{Limit: 45000, Used: 5878, LastPrompt: 5558 + 320, OutputCap: 6000, SavedCheckpoints: 1, Responses: 1, UsageKnown: true}, false, false},
|
|
{"provider usage missing", materialBudgetState{Limit: 30000, Responses: 1}, false, true},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
final, stop := materialFinalDecision(tc.state)
|
|
if final != tc.wantFinal || stop != tc.wantStop {
|
|
t.Fatalf("final=%v stop=%v; want final=%v stop=%v", final, stop, tc.wantFinal, tc.wantStop)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestSubRunMaterialDecisionIncludesLastCompletion locks the subRun-level
|
|
// invariant the spec demands: materialDecision must sum LastPromptTokens and
|
|
// LastCompletionTokens when estimating the next request size, so a continuation
|
|
// after a truncated assistant turn is still caught by the reserve. Reverting
|
|
// the summation to LastPromptTokens only would let the second case below pass
|
|
// through and break the third continuation under the 30000-token label.
|
|
func TestSubRunMaterialDecisionIncludesLastCompletion(t *testing.T) {
|
|
stWith := func(lastCompletion int) *subRun {
|
|
st := &subRun{
|
|
materialLimit: 30000,
|
|
materialOutputCap: 4000,
|
|
responses: 3,
|
|
usageKnown: true,
|
|
usageTotal: core.Usage{
|
|
PromptTokens: 0,
|
|
CompletionTokens: 0,
|
|
TotalTokens: 22070,
|
|
LastPromptTokens: 5810,
|
|
LastCompletionTokens: lastCompletion,
|
|
},
|
|
savedCheckpointIDs: map[string]struct{}{"cp1": {}},
|
|
}
|
|
return st
|
|
}
|
|
_, stop := stWith(4000).materialDecision()
|
|
if !stop {
|
|
t.Fatal("subRun.materialDecision did not stop after a 4000-token previous completion over the reserve")
|
|
}
|
|
_, stop = stWith(0).materialDecision()
|
|
if stop {
|
|
t.Fatal("subRun.materialDecision stopped without the previous completion in the estimate; reserve estimate regressed")
|
|
}
|
|
}
|