@myagentroam/agent 0.11.55 → 0.11.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/runtime/context/gc-candidates-code.js +5 -6
- package/dist/runtime/context/gc-candidates-exec.js +2 -2
- package/dist/runtime/context/gc-candidates-read-patch.js +3 -3
- package/dist/runtime/context/gc-candidates-web.js +6 -8
- package/dist/runtime/context/gc-economics.d.ts +13 -19
- package/dist/runtime/context/gc-economics.js +18 -66
- package/dist/runtime/context/gc.d.ts +1 -1
- package/dist/runtime/context/gc.js +5 -91
- package/dist/session/context-gc-checkpoint.js +12 -12
- package/dist/session/context-gc-contract.d.ts +5 -4
- package/dist/session/context-gc-protection.d.ts +5 -0
- package/dist/session/context-gc-protection.js +4 -0
- package/dist/session/context-gc-replacements.js +4 -4
- package/dist/session/store/jsonl/fork-session.js +38 -3
- package/dist/session/store/jsonl/history-replacement.d.ts +2 -1
- package/dist/session/store/jsonl/history-replacement.js +16 -5
- package/dist/session/store/jsonl/history.d.ts +5 -0
- package/dist/session/store/jsonl/history.js +84 -24
- package/dist/session/store/jsonl/jsonl-store.js +25 -8
- package/dist/session/store/jsonl/transaction-files.d.ts +2 -0
- package/dist/session/store/jsonl/transaction-files.js +22 -0
- package/dist/session/store/jsonl/transaction-recovery.js +11 -14
- package/dist/session/tool-result-resources.d.ts +10 -1
- package/dist/session/tool-result-resources.js +109 -38
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ import { retainedCodeInputs } from '../../session/context-gc-observations.js';
|
|
|
2
2
|
import { contextGcTargetKey } from '../../session/context-gc-checkpoint.js';
|
|
3
3
|
import { codeCellCompletionSequence, contextGcCodeModeInputReplacement, contextGcCodeModeOutputReplacement, hasGenericContextGcPreview, normalizeContextGcCodeModeInput } from '../../session/context-gc-replacements.js';
|
|
4
4
|
import { CONTEXT_GC_POLICY } from './gc-economics.js';
|
|
5
|
+
import { contextGcProtectionMature } from '../../session/context-gc-protection.js';
|
|
5
6
|
import { targetFor, isRecord } from './gc-candidates.js';
|
|
6
7
|
export function collectCodeModeCandidates(input, groups, existingTargets, candidateSavings) {
|
|
7
8
|
const eligible = [];
|
|
@@ -41,8 +42,7 @@ export function collectCodeModeCandidates(input, groups, existingTargets, candid
|
|
|
41
42
|
const reclaimedTokens = candidateSavings(candidate);
|
|
42
43
|
if (reclaimedTokens <= 0)
|
|
43
44
|
continue;
|
|
44
|
-
if (
|
|
45
|
-
protection.thinking >= 3)
|
|
45
|
+
if (contextGcProtectionMature(protection))
|
|
46
46
|
eligible.push(candidate);
|
|
47
47
|
else if (candidate.observedRollouts < CONTEXT_GC_POLICY.largeExecProtectionRollouts) {
|
|
48
48
|
protectedTokens += reclaimedTokens;
|
|
@@ -74,12 +74,12 @@ export function collectCodeModeCandidates(input, groups, existingTargets, candid
|
|
|
74
74
|
replacementArguments: contextGcCodeModeInputReplacement(code, group.result.message.observations
|
|
75
75
|
? retainedCodeInputs(input.records, group.callId, (original, successor) => {
|
|
76
76
|
const maturity = input.protection.after(Math.max(evidenceSequence, completionSequence, original.sequence, successor.sequence));
|
|
77
|
-
return maturity
|
|
77
|
+
return contextGcProtectionMature(maturity);
|
|
78
78
|
}, {
|
|
79
79
|
activeProcessIds: input.activeProcessIds,
|
|
80
80
|
evidenceMature: (sequence) => {
|
|
81
81
|
const maturity = input.protection.after(Math.max(evidenceSequence, completionSequence, sequence));
|
|
82
|
-
return maturity
|
|
82
|
+
return contextGcProtectionMature(maturity);
|
|
83
83
|
}
|
|
84
84
|
})
|
|
85
85
|
: []),
|
|
@@ -105,8 +105,7 @@ export function collectCodeModeCandidates(input, groups, existingTargets, candid
|
|
|
105
105
|
const reclaimedTokens = candidateSavings(candidate);
|
|
106
106
|
if (reclaimedTokens <= 0)
|
|
107
107
|
continue;
|
|
108
|
-
if (
|
|
109
|
-
protection.thinking >= 3)
|
|
108
|
+
if (contextGcProtectionMature(protection))
|
|
110
109
|
eligible.push(candidate);
|
|
111
110
|
else if (observedRollouts < CONTEXT_GC_POLICY.largeExecProtectionRollouts) {
|
|
112
111
|
protectedTokens += reclaimedTokens;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { contextGcTargetKey } from '../../session/context-gc-checkpoint.js';
|
|
2
2
|
import { contextGcExecInputReplacement, contextGcExecOutputReplacement, normalizeContextGcExecResult } from '../../session/context-gc-replacements.js';
|
|
3
3
|
import { CONTEXT_GC_POLICY } from './gc-economics.js';
|
|
4
|
+
import { contextGcProtectionMature } from '../../session/context-gc-protection.js';
|
|
4
5
|
import { targetFor, isRecord } from './gc-candidates.js';
|
|
5
6
|
import { terminalExecLifecycles } from '../../session/context-gc-exec-lifecycle.js';
|
|
6
7
|
export function collectExecCandidates(input, groups, existingTargets, candidateSavings) {
|
|
@@ -80,8 +81,7 @@ export function collectExecCandidates(input, groups, existingTargets, candidateS
|
|
|
80
81
|
let observedRollouts = Infinity;
|
|
81
82
|
for (const replacement of replacements) {
|
|
82
83
|
const protection = input.protection.after(Math.max(evidenceSequence, replacement.target.sequence));
|
|
83
|
-
if (protection
|
|
84
|
-
protection.thinking >= 3) {
|
|
84
|
+
if (contextGcProtectionMature(protection)) {
|
|
85
85
|
mature.push(replacement);
|
|
86
86
|
observedRollouts = Math.min(observedRollouts, protection.rollouts);
|
|
87
87
|
}
|
|
@@ -2,6 +2,7 @@ import { contextGcLogicalPathKey, contextGcTargetKey } from '../../session/conte
|
|
|
2
2
|
import { contextGcApplyPatchInputReplacement, contextGcPatchResultFromCompletedPayload, contextGcPatchResultFromFailedPayload, contextGcStaleReadReplacement, contextGcReadRangeCovers, contextGcCoveredReadReplacement } from '../../session/context-gc-replacements.js';
|
|
3
3
|
import { parseReadContextOutput } from '../../prompts/read-context.js';
|
|
4
4
|
import { CONTEXT_GC_POLICY } from './gc-economics.js';
|
|
5
|
+
import { contextGcProtectionMature } from '../../session/context-gc-protection.js';
|
|
5
6
|
import { targetFor } from './gc-candidates.js';
|
|
6
7
|
export function collectDeterministicCandidates(input, groups, existingReplacements, existingTargets, candidateSavings) {
|
|
7
8
|
const eligible = [];
|
|
@@ -103,8 +104,7 @@ export function collectDeterministicCandidates(input, groups, existingReplacemen
|
|
|
103
104
|
let observedRollouts = Infinity;
|
|
104
105
|
for (const replacement of replacements) {
|
|
105
106
|
const protection = input.protection.after(Math.max(evidenceSequence, replacement.target.sequence));
|
|
106
|
-
if (protection
|
|
107
|
-
protection.thinking >= 3) {
|
|
107
|
+
if (contextGcProtectionMature(protection)) {
|
|
108
108
|
mature.push(replacement);
|
|
109
109
|
observedRollouts = Math.min(observedRollouts, protection.rollouts);
|
|
110
110
|
}
|
|
@@ -162,7 +162,7 @@ export function collectDeterministicCandidates(input, groups, existingReplacemen
|
|
|
162
162
|
?.items.some((prior) => prior.index === candidate.index)));
|
|
163
163
|
const successor = later.findLast((entry) => {
|
|
164
164
|
const count = input.protection.after(entry.target.sequence);
|
|
165
|
-
return count
|
|
165
|
+
return contextGcProtectionMature(count);
|
|
166
166
|
});
|
|
167
167
|
if (!successor)
|
|
168
168
|
continue;
|
|
@@ -2,6 +2,7 @@ import { contextGcTargetKey } from '../../session/context-gc-checkpoint.js';
|
|
|
2
2
|
import { completedTodoWrite, todoInputReplacement, todoSnapshotReplacement, visibleTodoSnapshot } from '../../session/context-gc-todo.js';
|
|
3
3
|
import { contextGcWebOutputReplacement, contextGcToolOutputReplacement, contextGcSkillOutputReplacement, hasGenericContextGcPreview, isGenericContextGcTool } from '../../session/context-gc-replacements.js';
|
|
4
4
|
import { CONTEXT_GC_POLICY } from './gc-economics.js';
|
|
5
|
+
import { contextGcProtectionMature } from '../../session/context-gc-protection.js';
|
|
5
6
|
import { targetFor, isRecord } from './gc-candidates.js';
|
|
6
7
|
export function collectWebCandidates(input, groups, existingTargets, candidateSavings) {
|
|
7
8
|
const eligible = [];
|
|
@@ -46,8 +47,7 @@ export function collectWebCandidates(input, groups, existingTargets, candidateSa
|
|
|
46
47
|
const reclaimedTokens = candidateSavings(candidate);
|
|
47
48
|
if (reclaimedTokens <= 0)
|
|
48
49
|
continue;
|
|
49
|
-
if (
|
|
50
|
-
protection.thinking >= 3)
|
|
50
|
+
if (contextGcProtectionMature(protection))
|
|
51
51
|
eligible.push(candidate);
|
|
52
52
|
else if (observedRollouts < CONTEXT_GC_POLICY.largeExecProtectionRollouts) {
|
|
53
53
|
protectedTokens += reclaimedTokens;
|
|
@@ -82,7 +82,7 @@ export function collectToolOutputCandidates(input, groups, existingTargets, cand
|
|
|
82
82
|
candidate.result.message.toolSearchTools.some((item) => item.name === tool.name) &&
|
|
83
83
|
(() => {
|
|
84
84
|
const count = input.protection.after(Math.max(target.sequence, candidate.result.record.sequence));
|
|
85
|
-
return count
|
|
85
|
+
return contextGcProtectionMature(count);
|
|
86
86
|
})());
|
|
87
87
|
if (successor)
|
|
88
88
|
evidence.push(successor.result.record.sequence);
|
|
@@ -133,8 +133,7 @@ export function collectToolOutputCandidates(input, groups, existingTargets, cand
|
|
|
133
133
|
continue;
|
|
134
134
|
const successor = writes
|
|
135
135
|
.filter((write) => write.revision > currentRevision &&
|
|
136
|
-
input.protection.after(Math.max(target.sequence, group.completed.sequence, write.record.sequence))
|
|
137
|
-
input.protection.after(Math.max(target.sequence, group.completed.sequence, write.record.sequence)).thinking >= 3)
|
|
136
|
+
contextGcProtectionMature(input.protection.after(Math.max(target.sequence, group.completed.sequence, write.record.sequence))))
|
|
138
137
|
.sort((a, b) => b.revision - a.revision)[0];
|
|
139
138
|
if (!successor)
|
|
140
139
|
continue;
|
|
@@ -196,7 +195,7 @@ export function collectToolOutputCandidates(input, groups, existingTargets, cand
|
|
|
196
195
|
});
|
|
197
196
|
const successor = later.findLast((candidate) => {
|
|
198
197
|
const count = input.protection.after(Math.max(target.sequence, candidate.result.record.sequence));
|
|
199
|
-
return count
|
|
198
|
+
return contextGcProtectionMature(count);
|
|
200
199
|
});
|
|
201
200
|
if (!successor)
|
|
202
201
|
continue;
|
|
@@ -259,8 +258,7 @@ export function collectToolOutputCandidates(input, groups, existingTargets, cand
|
|
|
259
258
|
const reclaimedTokens = candidateSavings(candidate);
|
|
260
259
|
if (reclaimedTokens <= 0)
|
|
261
260
|
continue;
|
|
262
|
-
if (
|
|
263
|
-
protection.thinking >= 3)
|
|
261
|
+
if (contextGcProtectionMature(protection))
|
|
264
262
|
eligible.push(candidate);
|
|
265
263
|
else if (observedRollouts < CONTEXT_GC_POLICY.largeExecProtectionRollouts) {
|
|
266
264
|
protectedTokens += reclaimedTokens;
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import type { ModelUsage } from '../../model/contracts.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
export declare const CONTEXT_GC_POLICY: {
|
|
3
|
+
version: 1;
|
|
4
|
+
minimumPaybackRollouts: number;
|
|
5
|
+
maximumPaybackRollouts: number;
|
|
6
|
+
contextGrowthSampleWindow: number;
|
|
7
|
+
minimumContextGrowthSamples: number;
|
|
8
|
+
minimumObservationRollouts: number;
|
|
9
|
+
stageAProtectionRollouts: number;
|
|
10
|
+
largeExecProtectionRollouts: number;
|
|
11
|
+
normalInputCostRate: number;
|
|
12
|
+
cacheReadCostRate: number;
|
|
13
|
+
};
|
|
5
14
|
export declare const COMPACT_THRESHOLD_RATIO: number;
|
|
6
15
|
interface ContextGcEconomicsInput {
|
|
7
16
|
readonly contextUsageTokens: number;
|
|
@@ -10,11 +19,6 @@ interface ContextGcEconomicsInput {
|
|
|
10
19
|
readonly reclaimedCachedTokens: number;
|
|
11
20
|
readonly cacheReadTokens: number;
|
|
12
21
|
readonly preservedCachedPrefixTokens: number;
|
|
13
|
-
readonly compactDeferralCreditCostUnits: number;
|
|
14
|
-
readonly projectedRolloutsUntilCompactAfterGc: number;
|
|
15
|
-
readonly contextGrowthSampleCount: number;
|
|
16
|
-
readonly minimumGrossReductionRate?: number;
|
|
17
|
-
readonly minimumReclaimedTokens?: number;
|
|
18
22
|
}
|
|
19
23
|
export interface ContextGcEconomicsResult {
|
|
20
24
|
readonly cacheRebuildPenaltyCostUnits: number;
|
|
@@ -24,18 +28,8 @@ export interface ContextGcEconomicsResult {
|
|
|
24
28
|
readonly passes: boolean;
|
|
25
29
|
}
|
|
26
30
|
export declare function evaluateContextGcEconomics(input: ContextGcEconomicsInput): ContextGcEconomicsResult;
|
|
27
|
-
export declare function
|
|
28
|
-
export declare function contextGcMinimumReclaimedTokens(contextUsageTokens: number, contextWindowTokens: number): number;
|
|
31
|
+
export declare function contextGcMinimumReclaimedTokens(contextWindowTokens: number): number;
|
|
29
32
|
export declare function contextGcEligibleUsage(usage: ModelUsage, contextWindowTokens: number): number | undefined;
|
|
30
|
-
export declare function contextGcImminentCompactAvoidanceCredit(input: {
|
|
31
|
-
readonly contextUsageTokens: number;
|
|
32
|
-
readonly contextWindowTokens: number;
|
|
33
|
-
readonly compactThresholdTokens: number;
|
|
34
|
-
readonly projectedTokensBeforeGc: number;
|
|
35
|
-
readonly projectedTokensAfterGc: number;
|
|
36
|
-
readonly contextGrowthP75Tokens: number;
|
|
37
|
-
}): number;
|
|
38
|
-
export declare function contextGcAppliedCompactCreditCostUnits(compactDeferralCreditCostUnits: number, imminentCompactAvoidanceCreditCostUnits: number): number;
|
|
39
33
|
export declare function modelContextUsage(value: ModelUsage | Record<string, unknown>): number | undefined;
|
|
40
34
|
export declare function clamp(value: number, minimum: number, maximum: number): number;
|
|
41
35
|
export {};
|
|
@@ -1,25 +1,19 @@
|
|
|
1
1
|
import { AGENT_EXECUTION_POLICY } from '../execution-policy.js';
|
|
2
|
+
import { CONTEXT_GC_TEXT_PROTECTION_ROLLOUTS } from '../../session/context-gc-protection.js';
|
|
2
3
|
export const CONTEXT_GC_POLICY = {
|
|
3
4
|
version: 1,
|
|
4
|
-
|
|
5
|
-
maximumPaybackRollouts:
|
|
5
|
+
minimumPaybackRollouts: 30,
|
|
6
|
+
maximumPaybackRollouts: 60,
|
|
6
7
|
contextGrowthSampleWindow: 16,
|
|
7
8
|
minimumContextGrowthSamples: 6,
|
|
8
9
|
minimumObservationRollouts: 1,
|
|
9
|
-
stageAProtectionRollouts:
|
|
10
|
-
largeExecProtectionRollouts:
|
|
10
|
+
stageAProtectionRollouts: CONTEXT_GC_TEXT_PROTECTION_ROLLOUTS,
|
|
11
|
+
largeExecProtectionRollouts: CONTEXT_GC_TEXT_PROTECTION_ROLLOUTS,
|
|
11
12
|
normalInputCostRate: 1,
|
|
12
|
-
cacheReadCostRate: 0.05
|
|
13
|
-
outputCostRate: 1,
|
|
14
|
-
minimumGrossReductionRate: 0.2
|
|
13
|
+
cacheReadCostRate: 0.05
|
|
15
14
|
};
|
|
16
15
|
const CONTEXT_GC_START_RATIO = 0.5;
|
|
17
|
-
const HIGH_WATER_GROSS_REDUCTION_START_RATIO = 0.7;
|
|
18
|
-
const HIGH_WATER_MINIMUM_GROSS_REDUCTION_RATE = 0.1;
|
|
19
|
-
const MINIMUM_CONTEXT_WINDOW_REDUCTION_RATIO = 0.05;
|
|
20
|
-
export const COMPACT_CREDIT_ACTIVATION_RATIO = 0.8;
|
|
21
16
|
export const COMPACT_THRESHOLD_RATIO = AGENT_EXECUTION_POLICY.backgroundCompactionPercent / 100;
|
|
22
|
-
const IMMINENT_COMPACT_CREDIT_DISCOUNT = 0.8;
|
|
23
17
|
export function evaluateContextGcEconomics(input) {
|
|
24
18
|
const reclaimedTokens = Math.max(0, input.reclaimedTokens);
|
|
25
19
|
const cacheReadTokens = Math.max(0, input.cacheReadTokens);
|
|
@@ -34,16 +28,13 @@ export function evaluateContextGcEconomics(input) {
|
|
|
34
28
|
const reclaimedUncachedTokens = Math.max(0, reclaimedTokens - reclaimedCachedTokens);
|
|
35
29
|
const firstRolloutSavings = reclaimedCachedTokens + reclaimedUncachedTokens * unitsPerNormalInput;
|
|
36
30
|
const steadyRolloutSavings = reclaimedTokens;
|
|
37
|
-
const netAt = (rollouts) =>
|
|
31
|
+
const netAt = (rollouts) => rollouts <= 0
|
|
38
32
|
? -cacheRebuildPenalty
|
|
39
33
|
: firstRolloutSavings +
|
|
40
34
|
Math.max(0, rollouts - 1) * steadyRolloutSavings -
|
|
41
|
-
cacheRebuildPenalty
|
|
42
|
-
input.compactDeferralCreditCostUnits / CONTEXT_GC_POLICY.cacheReadCostRate;
|
|
35
|
+
cacheRebuildPenalty;
|
|
43
36
|
let requiredPositiveNetRollouts;
|
|
44
|
-
if (netAt(
|
|
45
|
-
requiredPositiveNetRollouts = 0;
|
|
46
|
-
else if (netAt(1) > 0)
|
|
37
|
+
if (netAt(1) > 0)
|
|
47
38
|
requiredPositiveNetRollouts = 1;
|
|
48
39
|
else if (steadyRolloutSavings <= 0)
|
|
49
40
|
requiredPositiveNetRollouts = null;
|
|
@@ -56,23 +47,17 @@ export function evaluateContextGcEconomics(input) {
|
|
|
56
47
|
}
|
|
57
48
|
const expectedNetSavedCostUnits = netAt(requiredPositiveNetRollouts ?? 0) * CONTEXT_GC_POLICY.cacheReadCostRate;
|
|
58
49
|
const grossReductionRate = reclaimedTokens / Math.max(1, Math.max(0, input.contextUsageTokens));
|
|
59
|
-
const
|
|
60
|
-
const minimumReclaimedTokens = Math.max(0, input.minimumReclaimedTokens ??
|
|
61
|
-
Math.ceil(Math.max(0, input.contextUsageTokens) * minimumGrossReductionRate));
|
|
50
|
+
const minimumReclaimedTokens = contextGcMinimumReclaimedTokens(input.contextWindowTokens);
|
|
62
51
|
const usageRatio = input.contextUsageTokens / input.contextWindowTokens;
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
: requiredPositiveNetRollouts *
|
|
69
|
-
(thresholdPercent * input.contextWindowTokens - 100 * input.contextUsageTokens) <=
|
|
70
|
-
CONTEXT_GC_POLICY.maximumPaybackRollouts *
|
|
71
|
-
(thresholdPercent - activationPercent) *
|
|
72
|
-
input.contextWindowTokens);
|
|
52
|
+
const progress = clamp((usageRatio - CONTEXT_GC_START_RATIO) / (COMPACT_THRESHOLD_RATIO - CONTEXT_GC_START_RATIO), 0, 1);
|
|
53
|
+
const paybackWindow = CONTEXT_GC_POLICY.minimumPaybackRollouts +
|
|
54
|
+
progress *
|
|
55
|
+
(CONTEXT_GC_POLICY.maximumPaybackRollouts - CONTEXT_GC_POLICY.minimumPaybackRollouts);
|
|
56
|
+
const withinWindow = requiredPositiveNetRollouts !== null && requiredPositiveNetRollouts <= paybackWindow;
|
|
73
57
|
const passes = reclaimedTokens > 0 &&
|
|
74
58
|
reclaimedTokens >= minimumReclaimedTokens &&
|
|
75
59
|
Number.isFinite(usageRatio) &&
|
|
60
|
+
usageRatio >= CONTEXT_GC_START_RATIO &&
|
|
76
61
|
usageRatio < COMPACT_THRESHOLD_RATIO &&
|
|
77
62
|
withinWindow;
|
|
78
63
|
return {
|
|
@@ -83,26 +68,8 @@ export function evaluateContextGcEconomics(input) {
|
|
|
83
68
|
passes
|
|
84
69
|
};
|
|
85
70
|
}
|
|
86
|
-
export function
|
|
87
|
-
|
|
88
|
-
return CONTEXT_GC_POLICY.minimumGrossReductionRate;
|
|
89
|
-
if (usageRatio >= COMPACT_THRESHOLD_RATIO)
|
|
90
|
-
return HIGH_WATER_MINIMUM_GROSS_REDUCTION_RATE;
|
|
91
|
-
const progress = (usageRatio - HIGH_WATER_GROSS_REDUCTION_START_RATIO) /
|
|
92
|
-
(COMPACT_THRESHOLD_RATIO - HIGH_WATER_GROSS_REDUCTION_START_RATIO);
|
|
93
|
-
return (CONTEXT_GC_POLICY.minimumGrossReductionRate -
|
|
94
|
-
progress *
|
|
95
|
-
(CONTEXT_GC_POLICY.minimumGrossReductionRate - HIGH_WATER_MINIMUM_GROSS_REDUCTION_RATE));
|
|
96
|
-
}
|
|
97
|
-
export function contextGcMinimumReclaimedTokens(contextUsageTokens, contextWindowTokens) {
|
|
98
|
-
if (!Number.isFinite(contextUsageTokens) ||
|
|
99
|
-
contextUsageTokens < 0 ||
|
|
100
|
-
!Number.isFinite(contextWindowTokens) ||
|
|
101
|
-
contextWindowTokens <= 0)
|
|
102
|
-
return 0;
|
|
103
|
-
const usageRatio = contextUsageTokens / contextWindowTokens;
|
|
104
|
-
const required = Math.max(contextUsageTokens * contextGcMinimumGrossReductionRate(usageRatio), contextWindowTokens * MINIMUM_CONTEXT_WINDOW_REDUCTION_RATIO);
|
|
105
|
-
return Math.ceil(required - 1e-9);
|
|
71
|
+
export function contextGcMinimumReclaimedTokens(contextWindowTokens) {
|
|
72
|
+
return Math.ceil(contextWindowTokens / 20);
|
|
106
73
|
}
|
|
107
74
|
export function contextGcEligibleUsage(usage, contextWindowTokens) {
|
|
108
75
|
const contextUsageTokens = modelContextUsage(usage);
|
|
@@ -115,21 +82,6 @@ export function contextGcEligibleUsage(usage, contextWindowTokens) {
|
|
|
115
82
|
return undefined;
|
|
116
83
|
return contextUsageTokens;
|
|
117
84
|
}
|
|
118
|
-
export function contextGcImminentCompactAvoidanceCredit(input) {
|
|
119
|
-
if (input.contextUsageTokens >= input.compactThresholdTokens ||
|
|
120
|
-
input.contextGrowthP75Tokens <= 0 ||
|
|
121
|
-
input.projectedTokensBeforeGc < input.compactThresholdTokens)
|
|
122
|
-
return 0;
|
|
123
|
-
const safetyMarginTokens = Math.max(input.contextWindowTokens * MINIMUM_CONTEXT_WINDOW_REDUCTION_RATIO, input.contextGrowthP75Tokens * CONTEXT_GC_POLICY.immediatePaybackRollouts);
|
|
124
|
-
if (input.projectedTokensAfterGc > input.compactThresholdTokens - safetyMarginTokens)
|
|
125
|
-
return 0;
|
|
126
|
-
return (input.contextUsageTokens *
|
|
127
|
-
CONTEXT_GC_POLICY.normalInputCostRate *
|
|
128
|
-
IMMINENT_COMPACT_CREDIT_DISCOUNT);
|
|
129
|
-
}
|
|
130
|
-
export function contextGcAppliedCompactCreditCostUnits(compactDeferralCreditCostUnits, imminentCompactAvoidanceCreditCostUnits) {
|
|
131
|
-
return Math.max(0, compactDeferralCreditCostUnits, imminentCompactAvoidanceCreditCostUnits);
|
|
132
|
-
}
|
|
133
85
|
export function modelContextUsage(value) {
|
|
134
86
|
const context = value.contextInputTokens ?? value.inputTokens;
|
|
135
87
|
return typeof context === 'number' && Number.isSafeInteger(context) && context >= 0
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ContextGcPlan, type ContextGcInspection, type ContextGcPlannerInput } from './gc-contracts.js';
|
|
2
|
-
export { CONTEXT_GC_POLICY, type ContextGcEconomicsResult, evaluateContextGcEconomics,
|
|
2
|
+
export { CONTEXT_GC_POLICY, type ContextGcEconomicsResult, evaluateContextGcEconomics, contextGcMinimumReclaimedTokens, contextGcEligibleUsage } from './gc-economics.js';
|
|
3
3
|
export { type ContextGcPlan, type ContextGcInspection, type ContextGcPlannerInput } from './gc-contracts.js';
|
|
4
4
|
export declare function planContextGc(input: ContextGcPlannerInput): ContextGcPlan | undefined;
|
|
5
5
|
export declare function inspectContextGc(input: ContextGcPlannerInput): ContextGcInspection;
|
|
@@ -2,13 +2,13 @@ import { ContextGcCheckpointCache, contextGcBaseFromRecords, contextGcCheckpoint
|
|
|
2
2
|
import { buildContextGcProtection } from '../../session/context-gc-protection.js';
|
|
3
3
|
import { CONTEXT_GC_TOKEN_ESTIMATOR, contextGcCacheImpact, contextGcMessageTokens, contextGcPrefixTokens, contextGcReclaimedTokens } from './gc-tokens.js';
|
|
4
4
|
import { applyContextGcReplacementsToMessages, providerToolCallId } from './projection.js';
|
|
5
|
-
import { CONTEXT_GC_POLICY,
|
|
5
|
+
import { CONTEXT_GC_POLICY, COMPACT_THRESHOLD_RATIO, evaluateContextGcEconomics, contextGcMinimumReclaimedTokens, contextGcEligibleUsage, modelContextUsage } from './gc-economics.js';
|
|
6
6
|
import { buildToolGroups, countSuccessfulNormalRollouts, isRecord } from './gc-candidates.js';
|
|
7
7
|
import { collectCodeModeCandidates } from './gc-candidates-code.js';
|
|
8
8
|
import { collectDeterministicCandidates } from './gc-candidates-read-patch.js';
|
|
9
9
|
import { collectExecCandidates } from './gc-candidates-exec.js';
|
|
10
10
|
import { collectToolOutputCandidates, collectWebCandidates } from './gc-candidates-web.js';
|
|
11
|
-
export { CONTEXT_GC_POLICY, evaluateContextGcEconomics,
|
|
11
|
+
export { CONTEXT_GC_POLICY, evaluateContextGcEconomics, contextGcMinimumReclaimedTokens, contextGcEligibleUsage } from './gc-economics.js';
|
|
12
12
|
export function planContextGc(input) {
|
|
13
13
|
return inspectContextGc(input).plan;
|
|
14
14
|
}
|
|
@@ -31,7 +31,6 @@ export function inspectContextGc(input) {
|
|
|
31
31
|
const state = {
|
|
32
32
|
stage: text.plan?.stage ?? 'INLINE_MEDIA',
|
|
33
33
|
contextUsageTokens,
|
|
34
|
-
usageRatio: contextUsageTokens / input.contextWindowTokens,
|
|
35
34
|
usageRecord,
|
|
36
35
|
normalRolloutOrdinal: countSuccessfulNormalRollouts(input.records, input.modelId, input.contextWindowTokens),
|
|
37
36
|
protectedCandidateTokens: text.plan?.metrics.protectedCandidateTokens ?? 0
|
|
@@ -73,7 +72,6 @@ function inspectTextGc(input) {
|
|
|
73
72
|
checkpointCache: input.checkpointCache ?? new ContextGcCheckpointCache(),
|
|
74
73
|
protection: buildContextGcProtection(input.records, input.modelId, input.contextWindowTokens)
|
|
75
74
|
};
|
|
76
|
-
const usageRatio = contextUsageTokens / input.contextWindowTokens;
|
|
77
75
|
const usageRecord = latestUsageRecord(input.records, input.modelId);
|
|
78
76
|
if (!usageRecord)
|
|
79
77
|
return {};
|
|
@@ -129,7 +127,6 @@ function inspectTextGc(input) {
|
|
|
129
127
|
], {
|
|
130
128
|
stage: 'UNIFIED',
|
|
131
129
|
contextUsageTokens,
|
|
132
|
-
usageRatio,
|
|
133
130
|
usageRecord,
|
|
134
131
|
normalRolloutOrdinal,
|
|
135
132
|
protectedCandidateTokens
|
|
@@ -148,8 +145,7 @@ function inspectTextGc(input) {
|
|
|
148
145
|
}
|
|
149
146
|
return protectedCandidateTokens > 0 &&
|
|
150
147
|
(combined?.economics.passes ||
|
|
151
|
-
protectedCandidateTokens >=
|
|
152
|
-
contextGcMinimumReclaimedTokens(contextUsageTokens, input.contextWindowTokens)) &&
|
|
148
|
+
protectedCandidateTokens >= contextGcMinimumReclaimedTokens(input.contextWindowTokens)) &&
|
|
153
149
|
Number.isFinite(retryAfterRollouts)
|
|
154
150
|
? { retryAfterRollouts }
|
|
155
151
|
: {};
|
|
@@ -175,12 +171,8 @@ function finalizePlan(input, evaluated, includeMedia = false) {
|
|
|
175
171
|
afterTokens: evaluated.afterTokens,
|
|
176
172
|
reclaimedTokens: evaluated.reclaimedTokens,
|
|
177
173
|
grossReductionRate: evaluated.economics.grossReductionRate,
|
|
178
|
-
effectiveMinimumGrossReductionRate: evaluated.minimumGrossReductionRate,
|
|
179
174
|
minimumRequiredReclaimedTokens: evaluated.minimumReclaimedTokens,
|
|
180
175
|
cacheRebuildPenaltyCostUnits: evaluated.economics.cacheRebuildPenaltyCostUnits,
|
|
181
|
-
compactDeferralCreditCostUnits: evaluated.compactDeferralCreditCostUnits,
|
|
182
|
-
imminentCompactAvoidanceCreditCostUnits: evaluated.imminentCompactAvoidanceCreditCostUnits,
|
|
183
|
-
appliedCompactCreditCostUnits: evaluated.appliedCompactCreditCostUnits,
|
|
184
176
|
requiredPositiveNetRollouts: evaluated.economics.requiredPositiveNetRollouts,
|
|
185
177
|
projectedRolloutsUntilCompactAfterGc: evaluated.projectedRolloutsUntilCompactAfterGc,
|
|
186
178
|
projectedTokensBeforeGc: evaluated.projectedTokensBeforeGc,
|
|
@@ -231,8 +223,7 @@ function evaluateCandidateSet(input, existing, candidates, state, mediaProjectio
|
|
|
231
223
|
const projected = applyContextGcReplacementsToMessages(input.messages, input.messageSources, replacements);
|
|
232
224
|
const projectedMessages = mediaProjection?.(projected.messages) ?? projected.messages;
|
|
233
225
|
const reclaimedTokens = contextGcReclaimedTokens(input, input.messages, projectedMessages);
|
|
234
|
-
const
|
|
235
|
-
const minimumReclaimedTokens = contextGcMinimumReclaimedTokens(state.contextUsageTokens, input.contextWindowTokens);
|
|
226
|
+
const minimumReclaimedTokens = contextGcMinimumReclaimedTokens(input.contextWindowTokens);
|
|
236
227
|
if (!state.mediaOnly && reclaimedTokens < minimumReclaimedTokens)
|
|
237
228
|
return undefined;
|
|
238
229
|
const beforeTokens = contextGcPrefixTokens(input) + contextGcMessageTokens(input, input.messages);
|
|
@@ -251,30 +242,13 @@ function evaluateCandidateSet(input, existing, candidates, state, mediaProjectio
|
|
|
251
242
|
const projectedRolloutsUntilCompactAfterGc = contextGrowthP75Tokens <= 0
|
|
252
243
|
? 0
|
|
253
244
|
: Math.max(0, Math.floor((compactThresholdTokens - projectedTokensAfterGc) / Math.max(1, contextGrowthP75Tokens)));
|
|
254
|
-
const compactDeferralCreditCostUnits = state.usageRatio >= COMPACT_CREDIT_ACTIVATION_RATIO
|
|
255
|
-
? compactDeferralCredit(input, reclaimedTokens, compactThresholdTokens)
|
|
256
|
-
: 0;
|
|
257
|
-
const imminentCompactAvoidanceCreditCostUnits = contextGcImminentCompactAvoidanceCredit({
|
|
258
|
-
contextUsageTokens: state.contextUsageTokens,
|
|
259
|
-
contextWindowTokens: input.contextWindowTokens,
|
|
260
|
-
compactThresholdTokens,
|
|
261
|
-
projectedTokensBeforeGc,
|
|
262
|
-
projectedTokensAfterGc,
|
|
263
|
-
contextGrowthP75Tokens
|
|
264
|
-
});
|
|
265
|
-
const appliedCompactCreditCostUnits = contextGcAppliedCompactCreditCostUnits(compactDeferralCreditCostUnits, imminentCompactAvoidanceCreditCostUnits);
|
|
266
245
|
const economics = evaluateContextGcEconomics({
|
|
267
246
|
contextUsageTokens: state.contextUsageTokens,
|
|
268
247
|
contextWindowTokens: input.contextWindowTokens,
|
|
269
248
|
reclaimedTokens,
|
|
270
249
|
reclaimedCachedTokens: cache.reclaimedCachedTokens,
|
|
271
250
|
cacheReadTokens: input.usage.cacheReadTokens ?? 0,
|
|
272
|
-
preservedCachedPrefixTokens: cache.preservedCachedPrefixTokens
|
|
273
|
-
compactDeferralCreditCostUnits: appliedCompactCreditCostUnits,
|
|
274
|
-
projectedRolloutsUntilCompactAfterGc,
|
|
275
|
-
contextGrowthSampleCount: growthSamples.length,
|
|
276
|
-
minimumGrossReductionRate,
|
|
277
|
-
minimumReclaimedTokens
|
|
251
|
+
preservedCachedPrefixTokens: cache.preservedCachedPrefixTokens
|
|
278
252
|
});
|
|
279
253
|
return {
|
|
280
254
|
...state,
|
|
@@ -286,14 +260,10 @@ function evaluateCandidateSet(input, existing, candidates, state, mediaProjectio
|
|
|
286
260
|
reclaimedTokens,
|
|
287
261
|
contextGrowthSamples: growthSamples,
|
|
288
262
|
contextGrowthP75Tokens,
|
|
289
|
-
minimumGrossReductionRate,
|
|
290
263
|
minimumReclaimedTokens,
|
|
291
264
|
projectedRolloutsUntilCompactAfterGc,
|
|
292
265
|
projectedTokensBeforeGc,
|
|
293
266
|
projectedTokensAfterGc,
|
|
294
|
-
compactDeferralCreditCostUnits,
|
|
295
|
-
imminentCompactAvoidanceCreditCostUnits,
|
|
296
|
-
appliedCompactCreditCostUnits,
|
|
297
267
|
boundarySequence: input.records.at(-1)?.sequence ?? state.usageRecord.sequence,
|
|
298
268
|
minimumObservedRollouts: Math.min(...candidates.map((candidate) => candidate.observedRollouts)),
|
|
299
269
|
eligibleCandidateCount: candidates.length
|
|
@@ -361,59 +331,6 @@ function collectContextGrowthSamples(records, modelId, contextWindowTokens, chec
|
|
|
361
331
|
}
|
|
362
332
|
return samples.slice(-CONTEXT_GC_POLICY.contextGrowthSampleWindow);
|
|
363
333
|
}
|
|
364
|
-
function compactDeferralCredit(input, reclaimedTokens, compactThresholdTokens) {
|
|
365
|
-
const base = contextGcBaseFromRecords(input.records);
|
|
366
|
-
if (base?.type !== 'COMPACT')
|
|
367
|
-
return 0;
|
|
368
|
-
const compact = input.records.find((record) => record.sequence === base.sequence);
|
|
369
|
-
if (!compact || !isRecord(compact.payload))
|
|
370
|
-
return 0;
|
|
371
|
-
if (compact.payload.modelId !== input.modelId ||
|
|
372
|
-
compact.payload.contextWindowTokens !== input.contextWindowTokens ||
|
|
373
|
-
!isRecord(compact.payload.usage))
|
|
374
|
-
return 0;
|
|
375
|
-
const usage = compact.payload.usage;
|
|
376
|
-
const contextInput = modelContextUsage(usage);
|
|
377
|
-
const cacheRead = nonnegativeNumber(usage.cacheReadTokens);
|
|
378
|
-
const output = nonnegativeNumber(usage.outputTokens);
|
|
379
|
-
if (contextInput === undefined || cacheRead === undefined || output === undefined)
|
|
380
|
-
return 0;
|
|
381
|
-
const baseline = firstMatchingUsageAfter(input.records, compact.sequence, input.modelId, input.contextWindowTokens);
|
|
382
|
-
if (baseline === undefined || baseline >= compactThresholdTokens)
|
|
383
|
-
return 0;
|
|
384
|
-
const fresh = Math.max(0, contextInput - cacheRead);
|
|
385
|
-
const compactCost = fresh * CONTEXT_GC_POLICY.normalInputCostRate +
|
|
386
|
-
cacheRead * CONTEXT_GC_POLICY.cacheReadCostRate +
|
|
387
|
-
output * CONTEXT_GC_POLICY.outputCostRate;
|
|
388
|
-
const cycleCapacity = Math.max(1, compactThresholdTokens - baseline);
|
|
389
|
-
return compactCost * clamp(reclaimedTokens / cycleCapacity, 0, 1);
|
|
390
|
-
}
|
|
391
|
-
function firstMatchingUsageAfter(records, sequence, modelId, contextWindowTokens) {
|
|
392
|
-
let activeModelId = modelId;
|
|
393
|
-
let activeContextWindowTokens = contextWindowTokens;
|
|
394
|
-
for (const record of records) {
|
|
395
|
-
if (record.sequence <= sequence)
|
|
396
|
-
continue;
|
|
397
|
-
if (record.type === 'execution.header' && isRecord(record.payload)) {
|
|
398
|
-
if (typeof record.payload.modelId === 'string')
|
|
399
|
-
activeModelId = record.payload.modelId;
|
|
400
|
-
if (typeof record.payload.contextWindowTokens === 'number' &&
|
|
401
|
-
Number.isSafeInteger(record.payload.contextWindowTokens) &&
|
|
402
|
-
record.payload.contextWindowTokens > 0)
|
|
403
|
-
activeContextWindowTokens = record.payload.contextWindowTokens;
|
|
404
|
-
continue;
|
|
405
|
-
}
|
|
406
|
-
if (activeModelId !== modelId ||
|
|
407
|
-
activeContextWindowTokens !== contextWindowTokens ||
|
|
408
|
-
!isRecord(record.payload) ||
|
|
409
|
-
record.payload.type !== 'usage.updated')
|
|
410
|
-
continue;
|
|
411
|
-
const usage = modelContextUsage(record.payload);
|
|
412
|
-
if (usage !== undefined)
|
|
413
|
-
return usage;
|
|
414
|
-
}
|
|
415
|
-
return undefined;
|
|
416
|
-
}
|
|
417
334
|
/** Measure only affected call families, retaining native aliases for provider lowering. */
|
|
418
335
|
function createCandidateSavingsEstimator(input, existing) {
|
|
419
336
|
const byCall = new Map();
|
|
@@ -466,6 +383,3 @@ function percentile75(values) {
|
|
|
466
383
|
const sorted = [...values].sort((left, right) => left - right);
|
|
467
384
|
return sorted[Math.max(0, Math.ceil(sorted.length * 0.75) - 1)];
|
|
468
385
|
}
|
|
469
|
-
function nonnegativeNumber(value) {
|
|
470
|
-
return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : undefined;
|
|
471
|
-
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { posix, win32 } from 'node:path';
|
|
2
2
|
import { isDeepStrictEqual } from 'node:util';
|
|
3
3
|
import { inlineMediaGcAnchored, parseInlineMediaGc } from './inline-media.js';
|
|
4
|
-
import { buildContextGcProtection } from './context-gc-protection.js';
|
|
4
|
+
import { buildContextGcProtection, contextGcProtectionMature } from './context-gc-protection.js';
|
|
5
5
|
import { completedTodoWrite, todoInputReplacement, todoSnapshotReplacement, visibleTodoSnapshot } from './context-gc-todo.js';
|
|
6
6
|
import { contextGcRetainedInputMarkup } from './context-gc-markup.js';
|
|
7
7
|
import { codeCallEvidence, codePartialPatchCallEvidence, callsFromRecord, codeObservationEvidence, observationsFromRecord, retainedCodeInputs } from './context-gc-observations.js';
|
|
@@ -239,7 +239,7 @@ export function validateContextGcCheckpoint(records, record, workspace = session
|
|
|
239
239
|
}
|
|
240
240
|
if (anchors.some((anchor) => {
|
|
241
241
|
const count = protection.after(anchor);
|
|
242
|
-
return count
|
|
242
|
+
return !contextGcProtectionMature(count);
|
|
243
243
|
}))
|
|
244
244
|
return undefined;
|
|
245
245
|
if (!replacementMatchesRecords(replacement, records, recordsBySequence, workspace, payload.trigger.platform, payload.replacements, protection, committed.get(contextGcReplacementKey(replacement))))
|
|
@@ -408,12 +408,12 @@ function replacementMatchesRecords(replacement, records, recordsBySequence, work
|
|
|
408
408
|
isDeepStrictEqual(replacement.replacementArguments, contextGcCodeModeInputReplacement(input, observationsFromRecord(evidence.result)
|
|
409
409
|
? retainedCodeInputs(records, replacement.callId, (original, successor) => {
|
|
410
410
|
const count = protection.after(Math.max(replacement.target.sequence, replacement.evidenceSequence, codeCellCompletionSequence(records, evidence.completed) ?? 0, original.sequence, successor.sequence));
|
|
411
|
-
return count
|
|
411
|
+
return contextGcProtectionMature(count);
|
|
412
412
|
}, {
|
|
413
413
|
activeProcessIds: new Set(),
|
|
414
414
|
evidenceMature: (sequence) => {
|
|
415
415
|
const count = protection.after(Math.max(replacement.target.sequence, replacement.evidenceSequence, codeCellCompletionSequence(records, evidence.completed) ?? 0, sequence));
|
|
416
|
-
return count
|
|
416
|
+
return contextGcProtectionMature(count);
|
|
417
417
|
},
|
|
418
418
|
selected: (callId, toolName, summary) => {
|
|
419
419
|
const argument = replacement.replacementArguments;
|
|
@@ -1102,7 +1102,6 @@ function isContextGcEconomicsPolicy(value) {
|
|
|
1102
1102
|
return (isRecord(value) &&
|
|
1103
1103
|
value.version === 1 &&
|
|
1104
1104
|
[
|
|
1105
|
-
'immediatePaybackRollouts',
|
|
1106
1105
|
'maximumPaybackRollouts',
|
|
1107
1106
|
'contextGrowthSampleWindow',
|
|
1108
1107
|
'minimumContextGrowthSamples',
|
|
@@ -1110,13 +1109,14 @@ function isContextGcEconomicsPolicy(value) {
|
|
|
1110
1109
|
'stageAProtectionRollouts',
|
|
1111
1110
|
'largeExecProtectionRollouts'
|
|
1112
1111
|
].every((key) => isNonnegativeInteger(value[key])) &&
|
|
1112
|
+
['minimumPaybackRollouts', 'immediatePaybackRollouts'].every((key) => value[key] === undefined || isNonnegativeInteger(value[key])) &&
|
|
1113
|
+
['normalInputCostRate', 'cacheReadCostRate'].every((key) => isNonnegativeFinite(value[key])) &&
|
|
1113
1114
|
[
|
|
1114
|
-
'
|
|
1115
|
-
'
|
|
1116
|
-
'
|
|
1117
|
-
'
|
|
1118
|
-
].every((key) => isNonnegativeFinite(value[key]))
|
|
1119
|
-
['cacheWriteCostRate', 'minimumCacheInvestmentRoi'].every((key) => value[key] === undefined || isNonnegativeFinite(value[key])));
|
|
1115
|
+
'cacheWriteCostRate',
|
|
1116
|
+
'minimumCacheInvestmentRoi',
|
|
1117
|
+
'minimumGrossReductionRate',
|
|
1118
|
+
'outputCostRate'
|
|
1119
|
+
].every((key) => value[key] === undefined || isNonnegativeFinite(value[key])));
|
|
1120
1120
|
}
|
|
1121
1121
|
function isContextGcMetrics(value) {
|
|
1122
1122
|
if (!isRecord(value) ||
|
|
@@ -1131,7 +1131,6 @@ function isContextGcMetrics(value) {
|
|
|
1131
1131
|
'reclaimedTokens',
|
|
1132
1132
|
'grossReductionRate',
|
|
1133
1133
|
'cacheRebuildPenaltyCostUnits',
|
|
1134
|
-
'compactDeferralCreditCostUnits',
|
|
1135
1134
|
'projectedRolloutsUntilCompactAfterGc',
|
|
1136
1135
|
'contextGrowthSampleCount',
|
|
1137
1136
|
'contextGrowthP75Tokens',
|
|
@@ -1142,6 +1141,7 @@ function isContextGcMetrics(value) {
|
|
|
1142
1141
|
];
|
|
1143
1142
|
const optionalNonnegative = [
|
|
1144
1143
|
'effectiveMinimumGrossReductionRate',
|
|
1144
|
+
'compactDeferralCreditCostUnits',
|
|
1145
1145
|
'minimumRequiredReclaimedTokens',
|
|
1146
1146
|
'imminentCompactAvoidanceCreditCostUnits',
|
|
1147
1147
|
'appliedCompactCreditCostUnits',
|
|
@@ -4,7 +4,8 @@ export type ContextGcSubagentToolName = 'agent_start' | 'agent_wait' | 'agent_me
|
|
|
4
4
|
export type ContextGcPlatform = 'linux' | 'darwin' | 'win32';
|
|
5
5
|
export interface ContextGcEconomicsPolicy {
|
|
6
6
|
readonly version: 1;
|
|
7
|
-
readonly immediatePaybackRollouts
|
|
7
|
+
readonly immediatePaybackRollouts?: number;
|
|
8
|
+
readonly minimumPaybackRollouts?: number;
|
|
8
9
|
readonly maximumPaybackRollouts: number;
|
|
9
10
|
readonly contextGrowthSampleWindow: number;
|
|
10
11
|
readonly minimumContextGrowthSamples: number;
|
|
@@ -14,8 +15,8 @@ export interface ContextGcEconomicsPolicy {
|
|
|
14
15
|
readonly normalInputCostRate: number;
|
|
15
16
|
readonly cacheReadCostRate: number;
|
|
16
17
|
readonly cacheWriteCostRate?: number;
|
|
17
|
-
readonly outputCostRate
|
|
18
|
-
readonly minimumGrossReductionRate
|
|
18
|
+
readonly outputCostRate?: number;
|
|
19
|
+
readonly minimumGrossReductionRate?: number;
|
|
19
20
|
readonly minimumCacheInvestmentRoi?: number;
|
|
20
21
|
}
|
|
21
22
|
export type ContextGcBase = {
|
|
@@ -108,7 +109,7 @@ export interface ContextGcMetrics {
|
|
|
108
109
|
readonly effectiveMinimumGrossReductionRate?: number;
|
|
109
110
|
readonly minimumRequiredReclaimedTokens?: number;
|
|
110
111
|
readonly cacheRebuildPenaltyCostUnits: number;
|
|
111
|
-
readonly compactDeferralCreditCostUnits
|
|
112
|
+
readonly compactDeferralCreditCostUnits?: number;
|
|
112
113
|
readonly imminentCompactAvoidanceCreditCostUnits?: number;
|
|
113
114
|
readonly appliedCompactCreditCostUnits?: number;
|
|
114
115
|
readonly requiredPositiveNetRollouts: number | null;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import type { SessionRecord } from './record-contract.js';
|
|
2
|
+
export declare const CONTEXT_GC_TEXT_PROTECTION_ROLLOUTS = 10;
|
|
3
|
+
export declare function contextGcProtectionMature(count: {
|
|
4
|
+
readonly rollouts: number;
|
|
5
|
+
readonly thinking: number;
|
|
6
|
+
}): boolean;
|
|
2
7
|
/** One immutable boundary index, shared by all candidate anchors in this evaluation. */
|
|
3
8
|
export declare function buildContextGcProtection(records: readonly SessionRecord[], modelId: string, contextWindowTokens: number): {
|
|
4
9
|
after(anchor: number): {
|