@myagentroam/agent 0.11.56 → 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-economics.d.ts +1 -20
- package/dist/runtime/context/gc-economics.js +4 -47
- package/dist/runtime/context/gc.d.ts +1 -1
- package/dist/runtime/context/gc.js +5 -92
- package/dist/session/context-gc-checkpoint.js +8 -10
- package/dist/session/context-gc-contract.d.ts +4 -4
- package/package.json +1 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { ModelUsage } from '../../model/contracts.js';
|
|
2
2
|
export declare const CONTEXT_GC_POLICY: {
|
|
3
3
|
version: 1;
|
|
4
|
-
immediatePaybackRollouts: number;
|
|
5
4
|
minimumPaybackRollouts: number;
|
|
6
5
|
maximumPaybackRollouts: number;
|
|
7
6
|
contextGrowthSampleWindow: number;
|
|
@@ -11,10 +10,7 @@ export declare const CONTEXT_GC_POLICY: {
|
|
|
11
10
|
largeExecProtectionRollouts: number;
|
|
12
11
|
normalInputCostRate: number;
|
|
13
12
|
cacheReadCostRate: number;
|
|
14
|
-
outputCostRate: number;
|
|
15
|
-
minimumGrossReductionRate: number;
|
|
16
13
|
};
|
|
17
|
-
export declare const COMPACT_CREDIT_ACTIVATION_RATIO = 0.8;
|
|
18
14
|
export declare const COMPACT_THRESHOLD_RATIO: number;
|
|
19
15
|
interface ContextGcEconomicsInput {
|
|
20
16
|
readonly contextUsageTokens: number;
|
|
@@ -23,11 +19,6 @@ interface ContextGcEconomicsInput {
|
|
|
23
19
|
readonly reclaimedCachedTokens: number;
|
|
24
20
|
readonly cacheReadTokens: number;
|
|
25
21
|
readonly preservedCachedPrefixTokens: number;
|
|
26
|
-
readonly compactDeferralCreditCostUnits: number;
|
|
27
|
-
readonly projectedRolloutsUntilCompactAfterGc: number;
|
|
28
|
-
readonly contextGrowthSampleCount: number;
|
|
29
|
-
readonly minimumGrossReductionRate?: number;
|
|
30
|
-
readonly minimumReclaimedTokens?: number;
|
|
31
22
|
}
|
|
32
23
|
export interface ContextGcEconomicsResult {
|
|
33
24
|
readonly cacheRebuildPenaltyCostUnits: number;
|
|
@@ -37,18 +28,8 @@ export interface ContextGcEconomicsResult {
|
|
|
37
28
|
readonly passes: boolean;
|
|
38
29
|
}
|
|
39
30
|
export declare function evaluateContextGcEconomics(input: ContextGcEconomicsInput): ContextGcEconomicsResult;
|
|
40
|
-
export declare function
|
|
41
|
-
export declare function contextGcMinimumReclaimedTokens(contextUsageTokens: number, contextWindowTokens: number): number;
|
|
31
|
+
export declare function contextGcMinimumReclaimedTokens(contextWindowTokens: number): number;
|
|
42
32
|
export declare function contextGcEligibleUsage(usage: ModelUsage, contextWindowTokens: number): number | undefined;
|
|
43
|
-
export declare function contextGcImminentCompactAvoidanceCredit(input: {
|
|
44
|
-
readonly contextUsageTokens: number;
|
|
45
|
-
readonly contextWindowTokens: number;
|
|
46
|
-
readonly compactThresholdTokens: number;
|
|
47
|
-
readonly projectedTokensBeforeGc: number;
|
|
48
|
-
readonly projectedTokensAfterGc: number;
|
|
49
|
-
readonly contextGrowthP75Tokens: number;
|
|
50
|
-
}): number;
|
|
51
|
-
export declare function contextGcAppliedCompactCreditCostUnits(compactDeferralCreditCostUnits: number, imminentCompactAvoidanceCreditCostUnits: number): number;
|
|
52
33
|
export declare function modelContextUsage(value: ModelUsage | Record<string, unknown>): number | undefined;
|
|
53
34
|
export declare function clamp(value: number, minimum: number, maximum: number): number;
|
|
54
35
|
export {};
|
|
@@ -2,7 +2,6 @@ import { AGENT_EXECUTION_POLICY } from '../execution-policy.js';
|
|
|
2
2
|
import { CONTEXT_GC_TEXT_PROTECTION_ROLLOUTS } from '../../session/context-gc-protection.js';
|
|
3
3
|
export const CONTEXT_GC_POLICY = {
|
|
4
4
|
version: 1,
|
|
5
|
-
immediatePaybackRollouts: 3,
|
|
6
5
|
minimumPaybackRollouts: 30,
|
|
7
6
|
maximumPaybackRollouts: 60,
|
|
8
7
|
contextGrowthSampleWindow: 16,
|
|
@@ -11,17 +10,10 @@ export const CONTEXT_GC_POLICY = {
|
|
|
11
10
|
stageAProtectionRollouts: CONTEXT_GC_TEXT_PROTECTION_ROLLOUTS,
|
|
12
11
|
largeExecProtectionRollouts: CONTEXT_GC_TEXT_PROTECTION_ROLLOUTS,
|
|
13
12
|
normalInputCostRate: 1,
|
|
14
|
-
cacheReadCostRate: 0.05
|
|
15
|
-
outputCostRate: 1,
|
|
16
|
-
minimumGrossReductionRate: 0.2
|
|
13
|
+
cacheReadCostRate: 0.05
|
|
17
14
|
};
|
|
18
15
|
const CONTEXT_GC_START_RATIO = 0.5;
|
|
19
|
-
const HIGH_WATER_GROSS_REDUCTION_START_RATIO = 0.7;
|
|
20
|
-
const HIGH_WATER_MINIMUM_GROSS_REDUCTION_RATE = 0.1;
|
|
21
|
-
const MINIMUM_CONTEXT_WINDOW_REDUCTION_RATIO = 0.05;
|
|
22
|
-
export const COMPACT_CREDIT_ACTIVATION_RATIO = 0.8;
|
|
23
16
|
export const COMPACT_THRESHOLD_RATIO = AGENT_EXECUTION_POLICY.backgroundCompactionPercent / 100;
|
|
24
|
-
const IMMINENT_COMPACT_CREDIT_DISCOUNT = 0.8;
|
|
25
17
|
export function evaluateContextGcEconomics(input) {
|
|
26
18
|
const reclaimedTokens = Math.max(0, input.reclaimedTokens);
|
|
27
19
|
const cacheReadTokens = Math.max(0, input.cacheReadTokens);
|
|
@@ -55,9 +47,7 @@ export function evaluateContextGcEconomics(input) {
|
|
|
55
47
|
}
|
|
56
48
|
const expectedNetSavedCostUnits = netAt(requiredPositiveNetRollouts ?? 0) * CONTEXT_GC_POLICY.cacheReadCostRate;
|
|
57
49
|
const grossReductionRate = reclaimedTokens / Math.max(1, Math.max(0, input.contextUsageTokens));
|
|
58
|
-
const
|
|
59
|
-
const minimumReclaimedTokens = Math.max(0, input.minimumReclaimedTokens ??
|
|
60
|
-
Math.ceil(Math.max(0, input.contextUsageTokens) * minimumGrossReductionRate));
|
|
50
|
+
const minimumReclaimedTokens = contextGcMinimumReclaimedTokens(input.contextWindowTokens);
|
|
61
51
|
const usageRatio = input.contextUsageTokens / input.contextWindowTokens;
|
|
62
52
|
const progress = clamp((usageRatio - CONTEXT_GC_START_RATIO) / (COMPACT_THRESHOLD_RATIO - CONTEXT_GC_START_RATIO), 0, 1);
|
|
63
53
|
const paybackWindow = CONTEXT_GC_POLICY.minimumPaybackRollouts +
|
|
@@ -78,26 +68,8 @@ export function evaluateContextGcEconomics(input) {
|
|
|
78
68
|
passes
|
|
79
69
|
};
|
|
80
70
|
}
|
|
81
|
-
export function
|
|
82
|
-
|
|
83
|
-
return CONTEXT_GC_POLICY.minimumGrossReductionRate;
|
|
84
|
-
if (usageRatio >= COMPACT_THRESHOLD_RATIO)
|
|
85
|
-
return HIGH_WATER_MINIMUM_GROSS_REDUCTION_RATE;
|
|
86
|
-
const progress = (usageRatio - HIGH_WATER_GROSS_REDUCTION_START_RATIO) /
|
|
87
|
-
(COMPACT_THRESHOLD_RATIO - HIGH_WATER_GROSS_REDUCTION_START_RATIO);
|
|
88
|
-
return (CONTEXT_GC_POLICY.minimumGrossReductionRate -
|
|
89
|
-
progress *
|
|
90
|
-
(CONTEXT_GC_POLICY.minimumGrossReductionRate - HIGH_WATER_MINIMUM_GROSS_REDUCTION_RATE));
|
|
91
|
-
}
|
|
92
|
-
export function contextGcMinimumReclaimedTokens(contextUsageTokens, contextWindowTokens) {
|
|
93
|
-
if (!Number.isFinite(contextUsageTokens) ||
|
|
94
|
-
contextUsageTokens < 0 ||
|
|
95
|
-
!Number.isFinite(contextWindowTokens) ||
|
|
96
|
-
contextWindowTokens <= 0)
|
|
97
|
-
return 0;
|
|
98
|
-
const usageRatio = contextUsageTokens / contextWindowTokens;
|
|
99
|
-
const required = Math.max(contextUsageTokens * contextGcMinimumGrossReductionRate(usageRatio), contextWindowTokens * MINIMUM_CONTEXT_WINDOW_REDUCTION_RATIO);
|
|
100
|
-
return Math.ceil(required - 1e-9);
|
|
71
|
+
export function contextGcMinimumReclaimedTokens(contextWindowTokens) {
|
|
72
|
+
return Math.ceil(contextWindowTokens / 20);
|
|
101
73
|
}
|
|
102
74
|
export function contextGcEligibleUsage(usage, contextWindowTokens) {
|
|
103
75
|
const contextUsageTokens = modelContextUsage(usage);
|
|
@@ -110,21 +82,6 @@ export function contextGcEligibleUsage(usage, contextWindowTokens) {
|
|
|
110
82
|
return undefined;
|
|
111
83
|
return contextUsageTokens;
|
|
112
84
|
}
|
|
113
|
-
export function contextGcImminentCompactAvoidanceCredit(input) {
|
|
114
|
-
if (input.contextUsageTokens >= input.compactThresholdTokens ||
|
|
115
|
-
input.contextGrowthP75Tokens <= 0 ||
|
|
116
|
-
input.projectedTokensBeforeGc < input.compactThresholdTokens)
|
|
117
|
-
return 0;
|
|
118
|
-
const safetyMarginTokens = Math.max(input.contextWindowTokens * MINIMUM_CONTEXT_WINDOW_REDUCTION_RATIO, input.contextGrowthP75Tokens * CONTEXT_GC_POLICY.immediatePaybackRollouts);
|
|
119
|
-
if (input.projectedTokensAfterGc > input.compactThresholdTokens - safetyMarginTokens)
|
|
120
|
-
return 0;
|
|
121
|
-
return (input.contextUsageTokens *
|
|
122
|
-
CONTEXT_GC_POLICY.normalInputCostRate *
|
|
123
|
-
IMMINENT_COMPACT_CREDIT_DISCOUNT);
|
|
124
|
-
}
|
|
125
|
-
export function contextGcAppliedCompactCreditCostUnits(compactDeferralCreditCostUnits, imminentCompactAvoidanceCreditCostUnits) {
|
|
126
|
-
return Math.max(0, compactDeferralCreditCostUnits, imminentCompactAvoidanceCreditCostUnits);
|
|
127
|
-
}
|
|
128
85
|
export function modelContextUsage(value) {
|
|
129
86
|
const context = value.contextInputTokens ?? value.inputTokens;
|
|
130
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,31 +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
|
-
// Compact estimates remain diagnostic; only normal-request savings repay GC.
|
|
266
|
-
const appliedCompactCreditCostUnits = 0;
|
|
267
245
|
const economics = evaluateContextGcEconomics({
|
|
268
246
|
contextUsageTokens: state.contextUsageTokens,
|
|
269
247
|
contextWindowTokens: input.contextWindowTokens,
|
|
270
248
|
reclaimedTokens,
|
|
271
249
|
reclaimedCachedTokens: cache.reclaimedCachedTokens,
|
|
272
250
|
cacheReadTokens: input.usage.cacheReadTokens ?? 0,
|
|
273
|
-
preservedCachedPrefixTokens: cache.preservedCachedPrefixTokens
|
|
274
|
-
compactDeferralCreditCostUnits: appliedCompactCreditCostUnits,
|
|
275
|
-
projectedRolloutsUntilCompactAfterGc,
|
|
276
|
-
contextGrowthSampleCount: growthSamples.length,
|
|
277
|
-
minimumGrossReductionRate,
|
|
278
|
-
minimumReclaimedTokens
|
|
251
|
+
preservedCachedPrefixTokens: cache.preservedCachedPrefixTokens
|
|
279
252
|
});
|
|
280
253
|
return {
|
|
281
254
|
...state,
|
|
@@ -287,14 +260,10 @@ function evaluateCandidateSet(input, existing, candidates, state, mediaProjectio
|
|
|
287
260
|
reclaimedTokens,
|
|
288
261
|
contextGrowthSamples: growthSamples,
|
|
289
262
|
contextGrowthP75Tokens,
|
|
290
|
-
minimumGrossReductionRate,
|
|
291
263
|
minimumReclaimedTokens,
|
|
292
264
|
projectedRolloutsUntilCompactAfterGc,
|
|
293
265
|
projectedTokensBeforeGc,
|
|
294
266
|
projectedTokensAfterGc,
|
|
295
|
-
compactDeferralCreditCostUnits,
|
|
296
|
-
imminentCompactAvoidanceCreditCostUnits,
|
|
297
|
-
appliedCompactCreditCostUnits,
|
|
298
267
|
boundarySequence: input.records.at(-1)?.sequence ?? state.usageRecord.sequence,
|
|
299
268
|
minimumObservedRollouts: Math.min(...candidates.map((candidate) => candidate.observedRollouts)),
|
|
300
269
|
eligibleCandidateCount: candidates.length
|
|
@@ -362,59 +331,6 @@ function collectContextGrowthSamples(records, modelId, contextWindowTokens, chec
|
|
|
362
331
|
}
|
|
363
332
|
return samples.slice(-CONTEXT_GC_POLICY.contextGrowthSampleWindow);
|
|
364
333
|
}
|
|
365
|
-
function compactDeferralCredit(input, reclaimedTokens, compactThresholdTokens) {
|
|
366
|
-
const base = contextGcBaseFromRecords(input.records);
|
|
367
|
-
if (base?.type !== 'COMPACT')
|
|
368
|
-
return 0;
|
|
369
|
-
const compact = input.records.find((record) => record.sequence === base.sequence);
|
|
370
|
-
if (!compact || !isRecord(compact.payload))
|
|
371
|
-
return 0;
|
|
372
|
-
if (compact.payload.modelId !== input.modelId ||
|
|
373
|
-
compact.payload.contextWindowTokens !== input.contextWindowTokens ||
|
|
374
|
-
!isRecord(compact.payload.usage))
|
|
375
|
-
return 0;
|
|
376
|
-
const usage = compact.payload.usage;
|
|
377
|
-
const contextInput = modelContextUsage(usage);
|
|
378
|
-
const cacheRead = nonnegativeNumber(usage.cacheReadTokens);
|
|
379
|
-
const output = nonnegativeNumber(usage.outputTokens);
|
|
380
|
-
if (contextInput === undefined || cacheRead === undefined || output === undefined)
|
|
381
|
-
return 0;
|
|
382
|
-
const baseline = firstMatchingUsageAfter(input.records, compact.sequence, input.modelId, input.contextWindowTokens);
|
|
383
|
-
if (baseline === undefined || baseline >= compactThresholdTokens)
|
|
384
|
-
return 0;
|
|
385
|
-
const fresh = Math.max(0, contextInput - cacheRead);
|
|
386
|
-
const compactCost = fresh * CONTEXT_GC_POLICY.normalInputCostRate +
|
|
387
|
-
cacheRead * CONTEXT_GC_POLICY.cacheReadCostRate +
|
|
388
|
-
output * CONTEXT_GC_POLICY.outputCostRate;
|
|
389
|
-
const cycleCapacity = Math.max(1, compactThresholdTokens - baseline);
|
|
390
|
-
return compactCost * clamp(reclaimedTokens / cycleCapacity, 0, 1);
|
|
391
|
-
}
|
|
392
|
-
function firstMatchingUsageAfter(records, sequence, modelId, contextWindowTokens) {
|
|
393
|
-
let activeModelId = modelId;
|
|
394
|
-
let activeContextWindowTokens = contextWindowTokens;
|
|
395
|
-
for (const record of records) {
|
|
396
|
-
if (record.sequence <= sequence)
|
|
397
|
-
continue;
|
|
398
|
-
if (record.type === 'execution.header' && isRecord(record.payload)) {
|
|
399
|
-
if (typeof record.payload.modelId === 'string')
|
|
400
|
-
activeModelId = record.payload.modelId;
|
|
401
|
-
if (typeof record.payload.contextWindowTokens === 'number' &&
|
|
402
|
-
Number.isSafeInteger(record.payload.contextWindowTokens) &&
|
|
403
|
-
record.payload.contextWindowTokens > 0)
|
|
404
|
-
activeContextWindowTokens = record.payload.contextWindowTokens;
|
|
405
|
-
continue;
|
|
406
|
-
}
|
|
407
|
-
if (activeModelId !== modelId ||
|
|
408
|
-
activeContextWindowTokens !== contextWindowTokens ||
|
|
409
|
-
!isRecord(record.payload) ||
|
|
410
|
-
record.payload.type !== 'usage.updated')
|
|
411
|
-
continue;
|
|
412
|
-
const usage = modelContextUsage(record.payload);
|
|
413
|
-
if (usage !== undefined)
|
|
414
|
-
return usage;
|
|
415
|
-
}
|
|
416
|
-
return undefined;
|
|
417
|
-
}
|
|
418
334
|
/** Measure only affected call families, retaining native aliases for provider lowering. */
|
|
419
335
|
function createCandidateSavingsEstimator(input, existing) {
|
|
420
336
|
const byCall = new Map();
|
|
@@ -467,6 +383,3 @@ function percentile75(values) {
|
|
|
467
383
|
const sorted = [...values].sort((left, right) => left - right);
|
|
468
384
|
return sorted[Math.max(0, Math.ceil(sorted.length * 0.75) - 1)];
|
|
469
385
|
}
|
|
470
|
-
function nonnegativeNumber(value) {
|
|
471
|
-
return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : undefined;
|
|
472
|
-
}
|
|
@@ -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,15 +1109,14 @@ function isContextGcEconomicsPolicy(value) {
|
|
|
1110
1109
|
'stageAProtectionRollouts',
|
|
1111
1110
|
'largeExecProtectionRollouts'
|
|
1112
1111
|
].every((key) => isNonnegativeInteger(value[key])) &&
|
|
1113
|
-
(value
|
|
1114
|
-
|
|
1112
|
+
['minimumPaybackRollouts', 'immediatePaybackRollouts'].every((key) => value[key] === undefined || isNonnegativeInteger(value[key])) &&
|
|
1113
|
+
['normalInputCostRate', 'cacheReadCostRate'].every((key) => isNonnegativeFinite(value[key])) &&
|
|
1115
1114
|
[
|
|
1116
|
-
'
|
|
1117
|
-
'
|
|
1118
|
-
'
|
|
1119
|
-
'
|
|
1120
|
-
].every((key) => isNonnegativeFinite(value[key]))
|
|
1121
|
-
['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])));
|
|
1122
1120
|
}
|
|
1123
1121
|
function isContextGcMetrics(value) {
|
|
1124
1122
|
if (!isRecord(value) ||
|
|
@@ -1133,7 +1131,6 @@ function isContextGcMetrics(value) {
|
|
|
1133
1131
|
'reclaimedTokens',
|
|
1134
1132
|
'grossReductionRate',
|
|
1135
1133
|
'cacheRebuildPenaltyCostUnits',
|
|
1136
|
-
'compactDeferralCreditCostUnits',
|
|
1137
1134
|
'projectedRolloutsUntilCompactAfterGc',
|
|
1138
1135
|
'contextGrowthSampleCount',
|
|
1139
1136
|
'contextGrowthP75Tokens',
|
|
@@ -1144,6 +1141,7 @@ function isContextGcMetrics(value) {
|
|
|
1144
1141
|
];
|
|
1145
1142
|
const optionalNonnegative = [
|
|
1146
1143
|
'effectiveMinimumGrossReductionRate',
|
|
1144
|
+
'compactDeferralCreditCostUnits',
|
|
1147
1145
|
'minimumRequiredReclaimedTokens',
|
|
1148
1146
|
'imminentCompactAvoidanceCreditCostUnits',
|
|
1149
1147
|
'appliedCompactCreditCostUnits',
|
|
@@ -4,7 +4,7 @@ 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
8
|
readonly minimumPaybackRollouts?: number;
|
|
9
9
|
readonly maximumPaybackRollouts: number;
|
|
10
10
|
readonly contextGrowthSampleWindow: number;
|
|
@@ -15,8 +15,8 @@ export interface ContextGcEconomicsPolicy {
|
|
|
15
15
|
readonly normalInputCostRate: number;
|
|
16
16
|
readonly cacheReadCostRate: number;
|
|
17
17
|
readonly cacheWriteCostRate?: number;
|
|
18
|
-
readonly outputCostRate
|
|
19
|
-
readonly minimumGrossReductionRate
|
|
18
|
+
readonly outputCostRate?: number;
|
|
19
|
+
readonly minimumGrossReductionRate?: number;
|
|
20
20
|
readonly minimumCacheInvestmentRoi?: number;
|
|
21
21
|
}
|
|
22
22
|
export type ContextGcBase = {
|
|
@@ -109,7 +109,7 @@ export interface ContextGcMetrics {
|
|
|
109
109
|
readonly effectiveMinimumGrossReductionRate?: number;
|
|
110
110
|
readonly minimumRequiredReclaimedTokens?: number;
|
|
111
111
|
readonly cacheRebuildPenaltyCostUnits: number;
|
|
112
|
-
readonly compactDeferralCreditCostUnits
|
|
112
|
+
readonly compactDeferralCreditCostUnits?: number;
|
|
113
113
|
readonly imminentCompactAvoidanceCreditCostUnits?: number;
|
|
114
114
|
readonly appliedCompactCreditCostUnits?: number;
|
|
115
115
|
readonly requiredPositiveNetRollouts: number | null;
|