mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 02:36:01 -10:00
fix(agent): a compact asked for by hand no longer answers "too little added" after a checkpoint; asking waives how much was added, and an unchanged context is still declined
This commit is contained in:
1 parent
26f72585ee
commit
756c6159a6
4 files changed
+19
-19
No files matched your search
@@ -609,9 +609,9 @@ func (a *Agent) SetSink(sink event.Sink) {
|
||||
func (a *Agent) CompactRatio() float64 { return a.compactRatio }
|
||||
|
||||
// CompactNow runs one requested projection compaction (canonical transcript
|
||||
// untouched). Asking waives the automatic threshold; it does not waive what the
|
||||
// fold has to be worth, so a context nothing was added to is declined rather
|
||||
// than summarized a second time. Only IgnoreEconomics waives that.
|
||||
// untouched). Asking waives the automatic threshold and how much was added since
|
||||
// the last checkpoint, but a context nothing was added to is still declined
|
||||
// rather than summarized a second time. Only IgnoreEconomics waives that.
|
||||
func (a *Agent) CompactNow(ctx context.Context, req CompactRequest) (CompactVerdict, error) {
|
||||
prepared, err := a.window().contextManager().Prepare(ctx, ContextPreparePolicy{
|
||||
Trigger: CompactionTriggerManual,
|
||||
|
||||
@@ -80,10 +80,10 @@ func TestManualCompactOnAnUnchangedContextBuysNothing(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// A checkpoint costs the whole prefix cache, so a second one waits for enough
|
||||
// new closed history to pay for it — the same rule the automatic path uses,
|
||||
// now applied to the path that actually fires in practice.
|
||||
func TestManualCompactWaitsForEnoughNewHistory(t *testing.T) {
|
||||
// Asking is the person deciding the fold is worth it: a few new turns after a
|
||||
// checkpoint do not make /compact answer "too little", only an unchanged
|
||||
// context does.
|
||||
func TestManualCompactFoldsAfterALittleNewHistory(t *testing.T) {
|
||||
sess := foldableSessionOverForce(60)
|
||||
a, _ := manualAgent(t, sess)
|
||||
if _, err := a.CompactNow(context.Background(), CompactRequest{}); err != nil {
|
||||
@@ -91,19 +91,13 @@ func TestManualCompactWaitsForEnoughNewHistory(t *testing.T) {
|
||||
}
|
||||
first := archivedFolds(a)
|
||||
|
||||
addTurns(sess, 1, 5)
|
||||
addTurns(sess, 12, 120)
|
||||
verdict, err := a.CompactNow(context.Background(), CompactRequest{})
|
||||
if err != nil {
|
||||
t.Fatalf("CompactNow after a little more history: %v", err)
|
||||
}
|
||||
if archivedFolds(a) != first {
|
||||
t.Errorf("a few hundred new tokens bought %d more folds", archivedFolds(a)-first)
|
||||
}
|
||||
if verdict.Compacted() || verdict.Reason == "" {
|
||||
t.Errorf("verdict = %+v, want a declined one carrying its reason", verdict)
|
||||
}
|
||||
if CompactDeclineText(verdict.Reason) == "" {
|
||||
t.Errorf("no words for reason %q", verdict.Reason)
|
||||
if !verdict.Compacted() || archivedFolds(a)-first != 1 {
|
||||
t.Errorf("verdict = %+v folds=%d, want one more fold when asked by hand", verdict, archivedFolds(a)-first)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -386,6 +386,10 @@ func compactionTelemetryFromSummary(trigger, cacheState string, sourceTokens int
|
||||
type compactionScope struct {
|
||||
ignoreThreshold bool
|
||||
ignoreEconomics bool
|
||||
// ignoreAmount waives only how much was added since the last checkpoint:
|
||||
// a request by hand has decided the fold is worth it, but still declines a
|
||||
// context that has not changed at all.
|
||||
ignoreAmount bool
|
||||
}
|
||||
|
||||
// compactToProjection installs one content-driven summary checkpoint:
|
||||
@@ -423,7 +427,7 @@ func (a *contextWindow) compactToProjection(ctx context.Context, trigger, instru
|
||||
// Every checkpoint costs the whole prefix cache, so a second one waits
|
||||
// for a tail's worth of new closed history — otherwise a small window
|
||||
// folds every few rounds and spends more than the fold frees.
|
||||
if a.estimatedPromptTokens(msgs[held:start]) < a.refoldMinTokens() {
|
||||
if !scope.ignoreAmount && a.estimatedPromptTokens(msgs[held:start]) < a.refoldMinTokens() {
|
||||
return CompactionNoop, NoopFoldBelowEconomics, nil
|
||||
}
|
||||
}
|
||||
@@ -431,7 +435,7 @@ func (a *contextWindow) compactToProjection(ctx context.Context, trigger, instru
|
||||
// original stays whole for resume and rewind.
|
||||
region := msgs[head:start]
|
||||
kept, fold := a.partitionFold(region, msgs[start:])
|
||||
if len(fold) == 0 || (!scope.ignoreEconomics && !a.foldEconomics(fold)) {
|
||||
if len(fold) == 0 || (!scope.ignoreEconomics && !scope.ignoreAmount && !a.foldEconomics(fold)) {
|
||||
return CompactionNoop, NoopFoldBelowEconomics, nil
|
||||
}
|
||||
reason, err := a.foldCannotFit(trigger, msgs, head, start)
|
||||
|
||||
@@ -138,11 +138,13 @@ func (m ContextManager) prepareOnce(ctx context.Context, policy ContextPreparePo
|
||||
return prepared, nil
|
||||
}
|
||||
// Asking, overflow and a physical ceiling each waive the trigger. Only the
|
||||
// last two, and an explicit force, waive what the fold has to be worth.
|
||||
// last two, and an explicit force, waive what the fold has to be worth; asking
|
||||
// by hand waives only how much was added.
|
||||
scope := compactionScope{
|
||||
ignoreThreshold: policy.IgnoreThreshold || policy.Trigger == CompactionTriggerManual ||
|
||||
policy.Trigger == CompactionTriggerOverflow || est >= hard,
|
||||
ignoreEconomics: policy.IgnoreEconomics || policy.Trigger == CompactionTriggerOverflow || est >= hard,
|
||||
ignoreAmount: policy.Trigger == CompactionTriggerManual,
|
||||
}
|
||||
if pressure < fold && !scope.ignoreThreshold {
|
||||
return prepared, nil
|
||||
|
||||
Reference in new issue
Block a user