@myagentroam/agent 0.11.54 → 0.11.55
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.
|
@@ -2,9 +2,10 @@ import type { ModelUsage } from '../../model/contracts.js';
|
|
|
2
2
|
import { type ContextGcEconomicsPolicy } from '../../session/context-gc-checkpoint.js';
|
|
3
3
|
export declare const CONTEXT_GC_POLICY: ContextGcEconomicsPolicy;
|
|
4
4
|
export declare const COMPACT_CREDIT_ACTIVATION_RATIO = 0.8;
|
|
5
|
-
export declare const COMPACT_THRESHOLD_RATIO
|
|
5
|
+
export declare const COMPACT_THRESHOLD_RATIO: number;
|
|
6
6
|
interface ContextGcEconomicsInput {
|
|
7
7
|
readonly contextUsageTokens: number;
|
|
8
|
+
readonly contextWindowTokens: number;
|
|
8
9
|
readonly reclaimedTokens: number;
|
|
9
10
|
readonly reclaimedCachedTokens: number;
|
|
10
11
|
readonly cacheReadTokens: number;
|
|
@@ -17,10 +18,8 @@ interface ContextGcEconomicsInput {
|
|
|
17
18
|
}
|
|
18
19
|
export interface ContextGcEconomicsResult {
|
|
19
20
|
readonly cacheRebuildPenaltyCostUnits: number;
|
|
20
|
-
readonly requiredPositiveNetRollouts: number;
|
|
21
|
-
readonly requiredTargetRoiRollouts: number;
|
|
21
|
+
readonly requiredPositiveNetRollouts: number | null;
|
|
22
22
|
readonly expectedNetSavedCostUnits: number;
|
|
23
|
-
readonly cacheInvestmentRoi: number;
|
|
24
23
|
readonly grossReductionRate: number;
|
|
25
24
|
readonly passes: boolean;
|
|
26
25
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AGENT_EXECUTION_POLICY } from '../execution-policy.js';
|
|
1
2
|
export const CONTEXT_GC_POLICY = {
|
|
2
3
|
version: 1,
|
|
3
4
|
immediatePaybackRollouts: 3,
|
|
@@ -8,18 +9,16 @@ export const CONTEXT_GC_POLICY = {
|
|
|
8
9
|
stageAProtectionRollouts: 6,
|
|
9
10
|
largeExecProtectionRollouts: 6,
|
|
10
11
|
normalInputCostRate: 1,
|
|
11
|
-
cacheReadCostRate: 0.
|
|
12
|
-
cacheWriteCostRate: 1.25,
|
|
12
|
+
cacheReadCostRate: 0.05,
|
|
13
13
|
outputCostRate: 1,
|
|
14
|
-
minimumGrossReductionRate: 0.2
|
|
15
|
-
minimumCacheInvestmentRoi: 0.1
|
|
14
|
+
minimumGrossReductionRate: 0.2
|
|
16
15
|
};
|
|
17
16
|
const CONTEXT_GC_START_RATIO = 0.5;
|
|
18
17
|
const HIGH_WATER_GROSS_REDUCTION_START_RATIO = 0.7;
|
|
19
18
|
const HIGH_WATER_MINIMUM_GROSS_REDUCTION_RATE = 0.1;
|
|
20
19
|
const MINIMUM_CONTEXT_WINDOW_REDUCTION_RATIO = 0.05;
|
|
21
20
|
export const COMPACT_CREDIT_ACTIVATION_RATIO = 0.8;
|
|
22
|
-
export const COMPACT_THRESHOLD_RATIO =
|
|
21
|
+
export const COMPACT_THRESHOLD_RATIO = AGENT_EXECUTION_POLICY.backgroundCompactionPercent / 100;
|
|
23
22
|
const IMMINENT_COMPACT_CREDIT_DISCOUNT = 0.8;
|
|
24
23
|
export function evaluateContextGcEconomics(input) {
|
|
25
24
|
const reclaimedTokens = Math.max(0, input.reclaimedTokens);
|
|
@@ -28,49 +27,58 @@ export function evaluateContextGcEconomics(input) {
|
|
|
28
27
|
const invalidatedCachedSuffixTokens = cacheReadTokens - preservedCachedPrefixTokens;
|
|
29
28
|
const reclaimedCachedTokens = clamp(input.reclaimedCachedTokens, 0, invalidatedCachedSuffixTokens);
|
|
30
29
|
const invalidatedRetainedCachedTokens = Math.max(0, invalidatedCachedSuffixTokens - reclaimedCachedTokens);
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
// Calculate token-derived costs in cache-read units to keep exact zero exact.
|
|
31
|
+
const unitsPerNormalInput = CONTEXT_GC_POLICY.normalInputCostRate / CONTEXT_GC_POLICY.cacheReadCostRate;
|
|
32
|
+
const cacheRebuildPenalty = invalidatedRetainedCachedTokens * (unitsPerNormalInput - 1);
|
|
33
|
+
const cacheRebuildPenaltyCostUnits = cacheRebuildPenalty * CONTEXT_GC_POLICY.cacheReadCostRate;
|
|
33
34
|
const reclaimedUncachedTokens = Math.max(0, reclaimedTokens - reclaimedCachedTokens);
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
35
|
+
const firstRolloutSavings = reclaimedCachedTokens + reclaimedUncachedTokens * unitsPerNormalInput;
|
|
36
|
+
const steadyRolloutSavings = reclaimedTokens;
|
|
37
|
+
const netAt = (rollouts) => (rollouts <= 0
|
|
38
|
+
? -cacheRebuildPenalty
|
|
39
|
+
: firstRolloutSavings +
|
|
40
|
+
Math.max(0, rollouts - 1) * steadyRolloutSavings -
|
|
41
|
+
cacheRebuildPenalty) +
|
|
42
|
+
input.compactDeferralCreditCostUnits / CONTEXT_GC_POLICY.cacheReadCostRate;
|
|
43
|
+
let requiredPositiveNetRollouts;
|
|
44
|
+
if (netAt(0) > 0)
|
|
45
|
+
requiredPositiveNetRollouts = 0;
|
|
46
|
+
else if (netAt(1) > 0)
|
|
47
|
+
requiredPositiveNetRollouts = 1;
|
|
48
|
+
else if (steadyRolloutSavings <= 0)
|
|
49
|
+
requiredPositiveNetRollouts = null;
|
|
50
|
+
else {
|
|
51
|
+
requiredPositiveNetRollouts = Math.max(2, Math.floor(-netAt(1) / steadyRolloutSavings) + 2);
|
|
52
|
+
if (netAt(requiredPositiveNetRollouts - 1) > 0)
|
|
53
|
+
requiredPositiveNetRollouts--;
|
|
54
|
+
else if (netAt(requiredPositiveNetRollouts) <= 0)
|
|
55
|
+
requiredPositiveNetRollouts++;
|
|
56
|
+
}
|
|
57
|
+
const expectedNetSavedCostUnits = netAt(requiredPositiveNetRollouts ?? 0) * CONTEXT_GC_POLICY.cacheReadCostRate;
|
|
56
58
|
const grossReductionRate = reclaimedTokens / Math.max(1, Math.max(0, input.contextUsageTokens));
|
|
57
59
|
const minimumGrossReductionRate = Math.max(0, input.minimumGrossReductionRate ?? CONTEXT_GC_POLICY.minimumGrossReductionRate);
|
|
58
60
|
const minimumReclaimedTokens = Math.max(0, input.minimumReclaimedTokens ??
|
|
59
61
|
Math.ceil(Math.max(0, input.contextUsageTokens) * minimumGrossReductionRate));
|
|
60
|
-
const
|
|
62
|
+
const usageRatio = input.contextUsageTokens / input.contextWindowTokens;
|
|
63
|
+
const thresholdPercent = AGENT_EXECUTION_POLICY.backgroundCompactionPercent;
|
|
64
|
+
const activationPercent = COMPACT_CREDIT_ACTIVATION_RATIO * 100;
|
|
65
|
+
const withinWindow = requiredPositiveNetRollouts !== null &&
|
|
66
|
+
(usageRatio <= COMPACT_CREDIT_ACTIVATION_RATIO
|
|
67
|
+
? requiredPositiveNetRollouts <= CONTEXT_GC_POLICY.maximumPaybackRollouts
|
|
68
|
+
: requiredPositiveNetRollouts *
|
|
69
|
+
(thresholdPercent * input.contextWindowTokens - 100 * input.contextUsageTokens) <=
|
|
70
|
+
CONTEXT_GC_POLICY.maximumPaybackRollouts *
|
|
71
|
+
(thresholdPercent - activationPercent) *
|
|
72
|
+
input.contextWindowTokens);
|
|
61
73
|
const passes = reclaimedTokens > 0 &&
|
|
62
74
|
reclaimedTokens >= minimumReclaimedTokens &&
|
|
63
|
-
Number.isFinite(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
input.contextGrowthSampleCount >= CONTEXT_GC_POLICY.minimumContextGrowthSamples &&
|
|
67
|
-
requiredTargetRoiRollouts <= input.projectedRolloutsUntilCompactAfterGc));
|
|
75
|
+
Number.isFinite(usageRatio) &&
|
|
76
|
+
usageRatio < COMPACT_THRESHOLD_RATIO &&
|
|
77
|
+
withinWindow;
|
|
68
78
|
return {
|
|
69
79
|
cacheRebuildPenaltyCostUnits,
|
|
70
80
|
requiredPositiveNetRollouts,
|
|
71
|
-
requiredTargetRoiRollouts,
|
|
72
81
|
expectedNetSavedCostUnits,
|
|
73
|
-
cacheInvestmentRoi,
|
|
74
82
|
grossReductionRate,
|
|
75
83
|
passes
|
|
76
84
|
};
|
|
@@ -128,12 +136,6 @@ export function modelContextUsage(value) {
|
|
|
128
136
|
? context
|
|
129
137
|
: undefined;
|
|
130
138
|
}
|
|
131
|
-
function firstMatchingRollout(limit, predicate) {
|
|
132
|
-
for (let rollouts = 0; rollouts <= limit; rollouts++)
|
|
133
|
-
if (predicate(rollouts))
|
|
134
|
-
return rollouts;
|
|
135
|
-
return Number.POSITIVE_INFINITY;
|
|
136
|
-
}
|
|
137
139
|
export function clamp(value, minimum, maximum) {
|
|
138
140
|
return Math.min(maximum, Math.max(minimum, value));
|
|
139
141
|
}
|
|
@@ -181,19 +181,13 @@ function finalizePlan(input, evaluated, includeMedia = false) {
|
|
|
181
181
|
compactDeferralCreditCostUnits: evaluated.compactDeferralCreditCostUnits,
|
|
182
182
|
imminentCompactAvoidanceCreditCostUnits: evaluated.imminentCompactAvoidanceCreditCostUnits,
|
|
183
183
|
appliedCompactCreditCostUnits: evaluated.appliedCompactCreditCostUnits,
|
|
184
|
-
requiredPositiveNetRollouts:
|
|
185
|
-
? evaluated.economics.requiredPositiveNetRollouts
|
|
186
|
-
: null,
|
|
187
|
-
requiredTargetRoiRollouts: Number.isFinite(evaluated.economics.requiredTargetRoiRollouts)
|
|
188
|
-
? evaluated.economics.requiredTargetRoiRollouts
|
|
189
|
-
: null,
|
|
184
|
+
requiredPositiveNetRollouts: evaluated.economics.requiredPositiveNetRollouts,
|
|
190
185
|
projectedRolloutsUntilCompactAfterGc: evaluated.projectedRolloutsUntilCompactAfterGc,
|
|
191
186
|
projectedTokensBeforeGc: evaluated.projectedTokensBeforeGc,
|
|
192
187
|
projectedTokensAfterGc: evaluated.projectedTokensAfterGc,
|
|
193
188
|
contextGrowthSampleCount: evaluated.contextGrowthSamples.length,
|
|
194
189
|
contextGrowthP75Tokens: evaluated.contextGrowthP75Tokens,
|
|
195
190
|
expectedNetSavedCostUnits: evaluated.economics.expectedNetSavedCostUnits,
|
|
196
|
-
cacheInvestmentRoi: evaluated.economics.cacheInvestmentRoi,
|
|
197
191
|
minimumObservedRollouts: evaluated.minimumObservedRollouts,
|
|
198
192
|
protectedCandidateTokens: evaluated.protectedCandidateTokens,
|
|
199
193
|
eligibleCandidateCount: evaluated.eligibleCandidateCount,
|
|
@@ -254,8 +248,6 @@ function evaluateCandidateSet(input, existing, candidates, state, mediaProjectio
|
|
|
254
248
|
const pendingTokens = Math.max(0, input.usage.outputTokens ?? 0) + contextGcMessageTokens(input, pendingMessages);
|
|
255
249
|
const projectedTokensBeforeGc = state.contextUsageTokens + pendingTokens;
|
|
256
250
|
const projectedTokensAfterGc = Math.max(0, projectedTokensBeforeGc - reclaimedTokens);
|
|
257
|
-
if (!state.mediaOnly && projectedTokensAfterGc >= compactThresholdTokens)
|
|
258
|
-
return undefined;
|
|
259
251
|
const projectedRolloutsUntilCompactAfterGc = contextGrowthP75Tokens <= 0
|
|
260
252
|
? 0
|
|
261
253
|
: Math.max(0, Math.floor((compactThresholdTokens - projectedTokensAfterGc) / Math.max(1, contextGrowthP75Tokens)));
|
|
@@ -273,6 +265,7 @@ function evaluateCandidateSet(input, existing, candidates, state, mediaProjectio
|
|
|
273
265
|
const appliedCompactCreditCostUnits = contextGcAppliedCompactCreditCostUnits(compactDeferralCreditCostUnits, imminentCompactAvoidanceCreditCostUnits);
|
|
274
266
|
const economics = evaluateContextGcEconomics({
|
|
275
267
|
contextUsageTokens: state.contextUsageTokens,
|
|
268
|
+
contextWindowTokens: input.contextWindowTokens,
|
|
276
269
|
reclaimedTokens,
|
|
277
270
|
reclaimedCachedTokens: cache.reclaimedCachedTokens,
|
|
278
271
|
cacheReadTokens: input.usage.cacheReadTokens ?? 0,
|
|
@@ -382,20 +375,15 @@ function compactDeferralCredit(input, reclaimedTokens, compactThresholdTokens) {
|
|
|
382
375
|
const usage = compact.payload.usage;
|
|
383
376
|
const contextInput = modelContextUsage(usage);
|
|
384
377
|
const cacheRead = nonnegativeNumber(usage.cacheReadTokens);
|
|
385
|
-
const cacheWrite = nonnegativeNumber(usage.cacheWriteTokens);
|
|
386
378
|
const output = nonnegativeNumber(usage.outputTokens);
|
|
387
|
-
if (contextInput === undefined ||
|
|
388
|
-
cacheRead === undefined ||
|
|
389
|
-
cacheWrite === undefined ||
|
|
390
|
-
output === undefined)
|
|
379
|
+
if (contextInput === undefined || cacheRead === undefined || output === undefined)
|
|
391
380
|
return 0;
|
|
392
381
|
const baseline = firstMatchingUsageAfter(input.records, compact.sequence, input.modelId, input.contextWindowTokens);
|
|
393
382
|
if (baseline === undefined || baseline >= compactThresholdTokens)
|
|
394
383
|
return 0;
|
|
395
|
-
const fresh = Math.max(0, contextInput - cacheRead
|
|
384
|
+
const fresh = Math.max(0, contextInput - cacheRead);
|
|
396
385
|
const compactCost = fresh * CONTEXT_GC_POLICY.normalInputCostRate +
|
|
397
386
|
cacheRead * CONTEXT_GC_POLICY.cacheReadCostRate +
|
|
398
|
-
cacheWrite * CONTEXT_GC_POLICY.cacheWriteCostRate +
|
|
399
387
|
output * CONTEXT_GC_POLICY.outputCostRate;
|
|
400
388
|
const cycleCapacity = Math.max(1, compactThresholdTokens - baseline);
|
|
401
389
|
return compactCost * clamp(reclaimedTokens / cycleCapacity, 0, 1);
|
|
@@ -1113,11 +1113,10 @@ function isContextGcEconomicsPolicy(value) {
|
|
|
1113
1113
|
[
|
|
1114
1114
|
'normalInputCostRate',
|
|
1115
1115
|
'cacheReadCostRate',
|
|
1116
|
-
'cacheWriteCostRate',
|
|
1117
1116
|
'outputCostRate',
|
|
1118
|
-
'minimumGrossReductionRate'
|
|
1119
|
-
|
|
1120
|
-
].every((key) => isNonnegativeFinite(value[key])));
|
|
1117
|
+
'minimumGrossReductionRate'
|
|
1118
|
+
].every((key) => isNonnegativeFinite(value[key])) &&
|
|
1119
|
+
['cacheWriteCostRate', 'minimumCacheInvestmentRoi'].every((key) => value[key] === undefined || isNonnegativeFinite(value[key])));
|
|
1121
1120
|
}
|
|
1122
1121
|
function isContextGcMetrics(value) {
|
|
1123
1122
|
if (!isRecord(value) ||
|
|
@@ -1150,10 +1149,13 @@ function isContextGcMetrics(value) {
|
|
|
1150
1149
|
'projectedTokensAfterGc'
|
|
1151
1150
|
];
|
|
1152
1151
|
return (nonnegative.every((key) => isNonnegativeFinite(value[key])) &&
|
|
1153
|
-
[
|
|
1152
|
+
[
|
|
1153
|
+
'requiredPositiveNetRollouts',
|
|
1154
|
+
...(value.requiredTargetRoiRollouts === undefined ? [] : ['requiredTargetRoiRollouts'])
|
|
1155
|
+
].every((key) => isNonnegativeFinite(value[key]) || (value.stage === 'INLINE_MEDIA' && value[key] === null)) &&
|
|
1154
1156
|
optionalNonnegative.every((key) => value[key] === undefined || isNonnegativeFinite(value[key])) &&
|
|
1155
1157
|
Number.isFinite(value.expectedNetSavedCostUnits) &&
|
|
1156
|
-
Number.isFinite(value.cacheInvestmentRoi) &&
|
|
1158
|
+
(value.cacheInvestmentRoi === undefined || Number.isFinite(value.cacheInvestmentRoi)) &&
|
|
1157
1159
|
(value.tokenEstimator === undefined || value.tokenEstimator === 'UTF8_BYTES_V1') &&
|
|
1158
1160
|
(value.cachePenaltyKnown === undefined || typeof value.cachePenaltyKnown === 'boolean'));
|
|
1159
1161
|
}
|
|
@@ -13,10 +13,10 @@ export interface ContextGcEconomicsPolicy {
|
|
|
13
13
|
readonly largeExecProtectionRollouts: number;
|
|
14
14
|
readonly normalInputCostRate: number;
|
|
15
15
|
readonly cacheReadCostRate: number;
|
|
16
|
-
readonly cacheWriteCostRate
|
|
16
|
+
readonly cacheWriteCostRate?: number;
|
|
17
17
|
readonly outputCostRate: number;
|
|
18
18
|
readonly minimumGrossReductionRate: number;
|
|
19
|
-
readonly minimumCacheInvestmentRoi
|
|
19
|
+
readonly minimumCacheInvestmentRoi?: number;
|
|
20
20
|
}
|
|
21
21
|
export type ContextGcBase = {
|
|
22
22
|
readonly type: 'SESSION_START';
|
|
@@ -112,14 +112,14 @@ export interface ContextGcMetrics {
|
|
|
112
112
|
readonly imminentCompactAvoidanceCreditCostUnits?: number;
|
|
113
113
|
readonly appliedCompactCreditCostUnits?: number;
|
|
114
114
|
readonly requiredPositiveNetRollouts: number | null;
|
|
115
|
-
readonly requiredTargetRoiRollouts
|
|
115
|
+
readonly requiredTargetRoiRollouts?: number | null;
|
|
116
116
|
readonly projectedRolloutsUntilCompactAfterGc: number;
|
|
117
117
|
readonly projectedTokensBeforeGc?: number;
|
|
118
118
|
readonly projectedTokensAfterGc?: number;
|
|
119
119
|
readonly contextGrowthSampleCount: number;
|
|
120
120
|
readonly contextGrowthP75Tokens: number;
|
|
121
121
|
readonly expectedNetSavedCostUnits: number;
|
|
122
|
-
readonly cacheInvestmentRoi
|
|
122
|
+
readonly cacheInvestmentRoi?: number;
|
|
123
123
|
readonly minimumObservedRollouts: number;
|
|
124
124
|
readonly protectedCandidateTokens: number;
|
|
125
125
|
readonly eligibleCandidateCount: number;
|