@brunobracaioli/aibrain 0.1.0-beta.1 → 0.3.0-beta.13
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/README.md +87 -6
- package/dist/assets/claude/.claude-plugin/plugin.json +103 -1
- package/dist/assets/claude/hooks/context-compaction.ts +6263 -677
- package/dist/assets/claude/hooks/provider-window.js +263 -0
- package/dist/assets/claude/hooks/state-fitting.d.mts +47 -0
- package/dist/assets/claude/hooks/state-fitting.mjs +324 -0
- package/dist/assets/codex-context-compaction.mjs +2874 -262
- package/dist/assets/context-selection-fitting.mjs +194 -0
- package/dist/assets/context-state-fitting.mjs +324 -0
- package/dist/assets/context-telemetry-reporter.mjs +305 -0
- package/dist/assets/jev-paid-pilot-terminal.mjs +591 -125
- package/dist/claude-checkpoint.mjs +1338 -0
- package/dist/claude-observation.mjs +1336 -0
- package/dist/cli.mjs +396 -29
- package/dist/codex-compatibility.mjs +467 -0
- package/dist/codex-diagnostics.mjs +426 -0
- package/dist/codex-permissions.mjs +590 -0
- package/dist/codex-protocol-fingerprint.json +131 -0
- package/dist/context-telemetry.mjs +257 -0
- package/dist/launch.mjs +369 -23
- package/dist/mcp.mjs +577 -5
- package/dist/monitor.mjs +61 -1
- package/dist/package.json +1 -1
- package/dist/platform.mjs +33 -3
- package/dist/policy.mjs +218 -0
- package/dist/state.mjs +132 -25
- package/dist/telemetry-report.mjs +133 -0
- package/package.json +1 -1
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
export const SELECTION_FIT_OVERHEAD_TOKENS = 256;
|
|
2
|
+
export const SELECTION_FIT_MAX_BATCHES = 4;
|
|
3
|
+
export const SELECTION_FIT_ESTIMATOR = 'utf8-bytes-v1';
|
|
4
|
+
function utf8ByteLength(value) {
|
|
5
|
+
return new TextEncoder().encode(value).byteLength;
|
|
6
|
+
}
|
|
7
|
+
export function estimateSelectionTokens(value) {
|
|
8
|
+
return utf8ByteLength(JSON.stringify(value));
|
|
9
|
+
}
|
|
10
|
+
function freezeProviderState(value) {
|
|
11
|
+
if (typeof value === 'object' && value !== null) {
|
|
12
|
+
Object.freeze(value);
|
|
13
|
+
for (const nested of Object.values(value)) freezeProviderState(nested);
|
|
14
|
+
}
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
function marker(text, size) {
|
|
18
|
+
if (text.length <= size) return text;
|
|
19
|
+
const head = Math.floor(size * 0.7);
|
|
20
|
+
const tail = Math.floor(size * 0.3);
|
|
21
|
+
return `${text.slice(0, head)}…[omitted ${text.length - size} chars]…${text.slice(-tail)}`;
|
|
22
|
+
}
|
|
23
|
+
export function normalizeSelectionItems(projection, preserveRecentItems) {
|
|
24
|
+
const protectedIds = new Set(
|
|
25
|
+
projection.items
|
|
26
|
+
.slice(Math.max(0, projection.items.length - preserveRecentItems))
|
|
27
|
+
.map((item) => item.id),
|
|
28
|
+
);
|
|
29
|
+
for (const item of projection.items) {
|
|
30
|
+
if (
|
|
31
|
+
item.protected ||
|
|
32
|
+
item.kind === 'user_message' ||
|
|
33
|
+
item.kind === 'plan' ||
|
|
34
|
+
item.kind === 'reference' ||
|
|
35
|
+
item.pinReasons.length > 0
|
|
36
|
+
)
|
|
37
|
+
protectedIds.add(item.id);
|
|
38
|
+
}
|
|
39
|
+
return projection.items.map((item) =>
|
|
40
|
+
protectedIds.has(item.id)
|
|
41
|
+
? {
|
|
42
|
+
...item,
|
|
43
|
+
protected: true,
|
|
44
|
+
pinReasons:
|
|
45
|
+
item.pinReasons.length > 0
|
|
46
|
+
? item.pinReasons
|
|
47
|
+
: [
|
|
48
|
+
item.kind === 'user_message'
|
|
49
|
+
? 'user_message'
|
|
50
|
+
: item.kind === 'plan'
|
|
51
|
+
? 'plan'
|
|
52
|
+
: item.kind === 'reference'
|
|
53
|
+
? 'reference'
|
|
54
|
+
: 'recent',
|
|
55
|
+
],
|
|
56
|
+
}
|
|
57
|
+
: item,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
export function eligibleSelectionItems(normalized) {
|
|
61
|
+
return normalized.filter(
|
|
62
|
+
(item) => !item.protected && (item.kind === 'assistant_message' || item.kind === 'tool_result'),
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
export function selectionQuestion(item) {
|
|
66
|
+
return {
|
|
67
|
+
type: 'noul',
|
|
68
|
+
instructions: `Should recovery item ${item.id} remain useful for continuing the approved goal? Keep explicit constraints and evidence when uncertain.`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export function selectionQuestions(items) {
|
|
72
|
+
return Object.fromEntries(items.map((item) => [`item_${item.id}`, selectionQuestion(item)]));
|
|
73
|
+
}
|
|
74
|
+
function stateFor(projection, items) {
|
|
75
|
+
return freezeProviderState({
|
|
76
|
+
goal: projection.goal,
|
|
77
|
+
items: items.map((item) => ({
|
|
78
|
+
id: item.id,
|
|
79
|
+
kind: item.kind,
|
|
80
|
+
text: item.text,
|
|
81
|
+
local_chars: item.localChars,
|
|
82
|
+
})),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
function completeBatches(batches, eligible, stateTokens, maxRequestTokens) {
|
|
86
|
+
const expected = new Set(eligible.map((item) => item.id));
|
|
87
|
+
const seen = new Set();
|
|
88
|
+
for (const batch of batches) {
|
|
89
|
+
for (const item of batch) {
|
|
90
|
+
if (!expected.has(item.id) || seen.has(item.id)) return null;
|
|
91
|
+
seen.add(item.id);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (seen.size !== expected.size) return null;
|
|
95
|
+
const requestTokens = Math.max(
|
|
96
|
+
...batches.map(
|
|
97
|
+
(batch) =>
|
|
98
|
+
stateTokens +
|
|
99
|
+
SELECTION_FIT_OVERHEAD_TOKENS +
|
|
100
|
+
estimateSelectionTokens(selectionQuestions(batch)),
|
|
101
|
+
),
|
|
102
|
+
);
|
|
103
|
+
return requestTokens <= maxRequestTokens ? { requestTokens } : null;
|
|
104
|
+
}
|
|
105
|
+
export function preflightSelectionState(input) {
|
|
106
|
+
const normalized = normalizeSelectionItems(input.projection, input.options.preserveRecentItems);
|
|
107
|
+
const eligible = eligibleSelectionItems(normalized);
|
|
108
|
+
const originalState = stateFor(input.projection, normalized);
|
|
109
|
+
const beforeStateTokens = estimateSelectionTokens(originalState);
|
|
110
|
+
if (eligible.length === 0)
|
|
111
|
+
return {
|
|
112
|
+
ok: true,
|
|
113
|
+
normalized,
|
|
114
|
+
eligible,
|
|
115
|
+
state: originalState,
|
|
116
|
+
batches: [],
|
|
117
|
+
fitting: {
|
|
118
|
+
version: 'state-fit-v1',
|
|
119
|
+
stage: 'original',
|
|
120
|
+
estimator: SELECTION_FIT_ESTIMATOR,
|
|
121
|
+
beforeEstimatedStateTokens: beforeStateTokens,
|
|
122
|
+
afterEstimatedStateTokens: beforeStateTokens,
|
|
123
|
+
},
|
|
124
|
+
beforeStateTokens,
|
|
125
|
+
stateTokens: beforeStateTokens,
|
|
126
|
+
requestTokens: 0,
|
|
127
|
+
};
|
|
128
|
+
const stages = [
|
|
129
|
+
{ stage: 'original', items: normalized },
|
|
130
|
+
{
|
|
131
|
+
stage: 'text_head_tail',
|
|
132
|
+
items: normalized.map((item) =>
|
|
133
|
+
eligible.some((candidate) => candidate.id === item.id)
|
|
134
|
+
? { ...item, text: marker(item.text, 300) }
|
|
135
|
+
: item,
|
|
136
|
+
),
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
stage: 'text_omitted',
|
|
140
|
+
items: normalized.map((item) =>
|
|
141
|
+
eligible.some((candidate) => candidate.id === item.id)
|
|
142
|
+
? { ...item, text: `[item omitted; ${item.text.length} chars]` }
|
|
143
|
+
: item,
|
|
144
|
+
),
|
|
145
|
+
},
|
|
146
|
+
];
|
|
147
|
+
for (const candidate of stages) {
|
|
148
|
+
const state = stateFor(input.projection, candidate.items);
|
|
149
|
+
const stateTokens = estimateSelectionTokens(state);
|
|
150
|
+
if (stateTokens > input.options.maxStateTokens) continue;
|
|
151
|
+
const available = input.options.maxRequestTokens - stateTokens - SELECTION_FIT_OVERHEAD_TOKENS;
|
|
152
|
+
if (available <= 0) continue;
|
|
153
|
+
const batches = [];
|
|
154
|
+
let current = [];
|
|
155
|
+
let currentTokens = 0;
|
|
156
|
+
let complete = true;
|
|
157
|
+
for (const item of eligible) {
|
|
158
|
+
const itemTokens = estimateSelectionTokens(selectionQuestions([item]));
|
|
159
|
+
if (itemTokens > available) {
|
|
160
|
+
complete = false;
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
if (current.length > 0 && currentTokens + itemTokens > available) {
|
|
164
|
+
batches.push(current);
|
|
165
|
+
current = [];
|
|
166
|
+
currentTokens = 0;
|
|
167
|
+
}
|
|
168
|
+
current.push(item);
|
|
169
|
+
currentTokens += itemTokens;
|
|
170
|
+
}
|
|
171
|
+
if (current.length > 0) batches.push(current);
|
|
172
|
+
if (!complete || batches.length === 0 || batches.length > SELECTION_FIT_MAX_BATCHES) continue;
|
|
173
|
+
const checked = completeBatches(batches, eligible, stateTokens, input.options.maxRequestTokens);
|
|
174
|
+
if (checked === null) continue;
|
|
175
|
+
return {
|
|
176
|
+
ok: true,
|
|
177
|
+
normalized,
|
|
178
|
+
eligible,
|
|
179
|
+
state,
|
|
180
|
+
batches,
|
|
181
|
+
fitting: {
|
|
182
|
+
version: 'state-fit-v1',
|
|
183
|
+
stage: candidate.stage,
|
|
184
|
+
estimator: SELECTION_FIT_ESTIMATOR,
|
|
185
|
+
beforeEstimatedStateTokens: beforeStateTokens,
|
|
186
|
+
afterEstimatedStateTokens: stateTokens,
|
|
187
|
+
},
|
|
188
|
+
beforeStateTokens,
|
|
189
|
+
stateTokens,
|
|
190
|
+
requestTokens: checked.requestTokens,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
return { ok: false, reason: 'state_budget_exceeded' };
|
|
194
|
+
}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
export const UTF8_ESTIMATOR_VERSION = 'utf8-bytes-v1';
|
|
2
|
+
export const FIT_OVERHEAD_TOKENS = 256;
|
|
3
|
+
export const FIT_MAX_BATCHES = 4;
|
|
4
|
+
const textEncoder = typeof TextEncoder === 'function' ? new TextEncoder() : undefined;
|
|
5
|
+
function utf8ByteLength(value) {
|
|
6
|
+
if (textEncoder !== undefined) return textEncoder.encode(value).byteLength;
|
|
7
|
+
const buffer = globalThis.Buffer;
|
|
8
|
+
if (buffer !== undefined) return buffer.byteLength(value, 'utf8');
|
|
9
|
+
throw new Error('utf8_encoder_unavailable');
|
|
10
|
+
}
|
|
11
|
+
export function estimateUtf8Tokens(value) {
|
|
12
|
+
return utf8ByteLength(JSON.stringify(value));
|
|
13
|
+
}
|
|
14
|
+
export function freezeProviderState(value) {
|
|
15
|
+
if (typeof value === 'object' && value !== null) {
|
|
16
|
+
Object.freeze(value);
|
|
17
|
+
for (const nested of Object.values(value)) freezeProviderState(nested);
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
function marker(text, head, tail = head) {
|
|
22
|
+
const codePoints = Array.from(text);
|
|
23
|
+
if (codePoints.length <= head + tail + 32) return text;
|
|
24
|
+
return `${codePoints.slice(0, head).join('')}…[omitted ${codePoints.length - head - tail} chars]…${codePoints.slice(-tail).join('')}`;
|
|
25
|
+
}
|
|
26
|
+
function takeCodePoints(text, count) {
|
|
27
|
+
return Array.from(text).slice(0, count).join('');
|
|
28
|
+
}
|
|
29
|
+
function codePointLength(text) {
|
|
30
|
+
return Array.from(text).length;
|
|
31
|
+
}
|
|
32
|
+
function stateFor(
|
|
33
|
+
projection,
|
|
34
|
+
pairs,
|
|
35
|
+
messages = projection.messages,
|
|
36
|
+
compactIds = new Set(),
|
|
37
|
+
omittedProtectedPairCount = 0,
|
|
38
|
+
) {
|
|
39
|
+
return freezeProviderState({
|
|
40
|
+
goal: projection.goal,
|
|
41
|
+
messages: messages.map((message) => ({
|
|
42
|
+
id: message.id,
|
|
43
|
+
role: message.role,
|
|
44
|
+
text: message.text,
|
|
45
|
+
call_ids: [...message.callIds],
|
|
46
|
+
result_ids: [...message.resultIds],
|
|
47
|
+
})),
|
|
48
|
+
pairs: pairs.map((pair) =>
|
|
49
|
+
compactIds.has(pair.id)
|
|
50
|
+
? {
|
|
51
|
+
id: pair.id,
|
|
52
|
+
compact_record: `${pair.id}|${pair.tool}|${takeCodePoints(pair.inputText, 12)}|result_chars=${pair.resultChars}|error=${pair.resultIsError}`,
|
|
53
|
+
}
|
|
54
|
+
: {
|
|
55
|
+
id: pair.id,
|
|
56
|
+
tool: pair.tool,
|
|
57
|
+
input_text: pair.inputText,
|
|
58
|
+
result_chars: pair.resultChars,
|
|
59
|
+
result_is_error: pair.resultIsError,
|
|
60
|
+
},
|
|
61
|
+
),
|
|
62
|
+
protected_item_count: projection.protectedItemCount,
|
|
63
|
+
...(omittedProtectedPairCount > 0
|
|
64
|
+
? { omitted_protected_pair_count: omittedProtectedPairCount }
|
|
65
|
+
: {}),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
export function compactionQuestions(pairs) {
|
|
69
|
+
return Object.fromEntries(
|
|
70
|
+
pairs.flatMap((pair) => [
|
|
71
|
+
[
|
|
72
|
+
`call_${pair.id}`,
|
|
73
|
+
{
|
|
74
|
+
type: 'noul',
|
|
75
|
+
instructions: `Should the call occurrence and input for pair ${pair.id} (${pair.tool}) remain useful for continuing the approved goal? Answer yes only when retaining the call is needed.`,
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
[
|
|
79
|
+
`result_${pair.id}`,
|
|
80
|
+
{
|
|
81
|
+
type: 'noul',
|
|
82
|
+
instructions: `Should the full result for pair ${pair.id} (${pair.resultChars} characters) remain useful for continuing the approved goal? Answer yes only when the result itself is needed.`,
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
]),
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
export function estimateCompactionQuestions(pairs) {
|
|
89
|
+
return estimateUtf8Tokens(compactionQuestions(pairs));
|
|
90
|
+
}
|
|
91
|
+
function makeBatches(eligible, stateTokens, maxRequestTokens) {
|
|
92
|
+
const available = maxRequestTokens - stateTokens - FIT_OVERHEAD_TOKENS;
|
|
93
|
+
if (available <= 0) return null;
|
|
94
|
+
const batches = [];
|
|
95
|
+
let current = [];
|
|
96
|
+
let currentTokens = 0;
|
|
97
|
+
for (const pair of eligible) {
|
|
98
|
+
const pairTokens = estimateCompactionQuestions([pair]);
|
|
99
|
+
if (pairTokens > available) return null;
|
|
100
|
+
if (current.length > 0 && currentTokens + pairTokens > available) {
|
|
101
|
+
batches.push(current);
|
|
102
|
+
current = [];
|
|
103
|
+
currentTokens = 0;
|
|
104
|
+
}
|
|
105
|
+
current.push(pair);
|
|
106
|
+
currentTokens += pairTokens;
|
|
107
|
+
}
|
|
108
|
+
if (current.length > 0) batches.push(current);
|
|
109
|
+
if (batches.length > FIT_MAX_BATCHES) return null;
|
|
110
|
+
return {
|
|
111
|
+
batches,
|
|
112
|
+
requestTokens: batches.reduce(
|
|
113
|
+
(max, batch) =>
|
|
114
|
+
Math.max(max, stateTokens + FIT_OVERHEAD_TOKENS + estimateCompactionQuestions(batch)),
|
|
115
|
+
0,
|
|
116
|
+
),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function isPinnedMessage(projection, messageIndex, recent, protectedIds, pinnedMessageIds) {
|
|
120
|
+
if (pinnedMessageIds.has(projection.messages[messageIndex]?.id ?? '')) return true;
|
|
121
|
+
return (
|
|
122
|
+
projection.messages[messageIndex]?.callIds.some((id) => protectedIds.has(id)) === true ||
|
|
123
|
+
projection.messages[messageIndex]?.resultIds.some((id) => protectedIds.has(id)) === true
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
function stageProjection(projection, eligibleIds, recent, stage, pinnedMessageIds) {
|
|
127
|
+
const protectedIds = new Set(
|
|
128
|
+
projection.pairs.filter((pair) => !eligibleIds.has(pair.id)).map((pair) => pair.id),
|
|
129
|
+
);
|
|
130
|
+
const pairs = projection.pairs.map((pair) => {
|
|
131
|
+
if (!eligibleIds.has(pair.id)) return pair;
|
|
132
|
+
if (stage === 'inputs_1000')
|
|
133
|
+
return { ...pair, inputText: takeCodePoints(pair.inputText, 1_000) };
|
|
134
|
+
if (stage === 'inputs_200') return { ...pair, inputText: takeCodePoints(pair.inputText, 200) };
|
|
135
|
+
if (stage === 'inputs_60') return { ...pair, inputText: takeCodePoints(pair.inputText, 60) };
|
|
136
|
+
if (stage === 'text_head_tail') return { ...pair, inputText: marker(pair.inputText, 30, 30) };
|
|
137
|
+
if (stage === 'text_omitted')
|
|
138
|
+
return codePointLength(pair.inputText) > 60
|
|
139
|
+
? { ...pair, inputText: `[input omitted; ${codePointLength(pair.inputText)} chars]` }
|
|
140
|
+
: pair;
|
|
141
|
+
if (stage === 'compact_calls')
|
|
142
|
+
return { ...pair, inputText: `${pair.tool}(${marker(pair.inputText, 24, 12)})` };
|
|
143
|
+
return pair;
|
|
144
|
+
});
|
|
145
|
+
let messages = projection.messages;
|
|
146
|
+
if (stage === 'text_head_tail') {
|
|
147
|
+
messages = projection.messages.map((message, index) =>
|
|
148
|
+
isPinnedMessage(projection, index, recent, protectedIds, pinnedMessageIds)
|
|
149
|
+
? message
|
|
150
|
+
: { ...message, text: marker(message.text, 80, 40) },
|
|
151
|
+
);
|
|
152
|
+
} else if (stage === 'text_omitted') {
|
|
153
|
+
messages = projection.messages.map((message, index) =>
|
|
154
|
+
isPinnedMessage(projection, index, recent, protectedIds, pinnedMessageIds)
|
|
155
|
+
? message
|
|
156
|
+
: codePointLength(message.text) > 120
|
|
157
|
+
? { ...message, text: `[message omitted; ${codePointLength(message.text)} chars]` }
|
|
158
|
+
: message,
|
|
159
|
+
);
|
|
160
|
+
} else if (stage === 'compact_calls') {
|
|
161
|
+
messages = projection.messages.map((message, index) =>
|
|
162
|
+
// At this stage pair identity and question binding live in `pairs`. Keep
|
|
163
|
+
// protected message wiring available while abbreviating only its text.
|
|
164
|
+
// A later fitting stage folds this wiring only if the complete state still
|
|
165
|
+
// cannot fit, so ordinary histories retain more useful provider context.
|
|
166
|
+
isPinnedMessage(projection, index, recent, protectedIds, pinnedMessageIds)
|
|
167
|
+
? message
|
|
168
|
+
: {
|
|
169
|
+
...message,
|
|
170
|
+
text: `call:${message.callIds.join(',')};result:${message.resultIds.join(',')}`,
|
|
171
|
+
},
|
|
172
|
+
);
|
|
173
|
+
} else if (stage === 'callless_omitted') {
|
|
174
|
+
messages = projection.messages.filter(
|
|
175
|
+
(message, index) =>
|
|
176
|
+
isPinnedMessage(projection, index, recent, protectedIds, pinnedMessageIds) ||
|
|
177
|
+
message.callIds.length > 0 ||
|
|
178
|
+
message.resultIds.length > 0,
|
|
179
|
+
);
|
|
180
|
+
} else if (stage === 'runs_folded') {
|
|
181
|
+
const folded = [];
|
|
182
|
+
const usedIds = new Set(projection.messages.map((message) => message.id));
|
|
183
|
+
let markerSequence = 0;
|
|
184
|
+
let omittedRun;
|
|
185
|
+
let omittedCount = 0;
|
|
186
|
+
const flushOmitted = () => {
|
|
187
|
+
if (omittedRun === undefined) return;
|
|
188
|
+
let id = 'provider-history-omitted';
|
|
189
|
+
while (usedIds.has(id)) id = `provider-history-omitted-${++markerSequence}`;
|
|
190
|
+
usedIds.add(id);
|
|
191
|
+
folded.push({
|
|
192
|
+
id,
|
|
193
|
+
role: omittedRun.role,
|
|
194
|
+
text: `[${omittedCount} historical messages omitted from provider metadata]`,
|
|
195
|
+
callIds: [],
|
|
196
|
+
resultIds: [],
|
|
197
|
+
});
|
|
198
|
+
omittedRun = undefined;
|
|
199
|
+
omittedCount = 0;
|
|
200
|
+
};
|
|
201
|
+
for (let index = 0; index < projection.messages.length; index += 1) {
|
|
202
|
+
const message = projection.messages[index];
|
|
203
|
+
if (message === undefined) continue;
|
|
204
|
+
if (pinnedMessageIds.has(message.id)) {
|
|
205
|
+
flushOmitted();
|
|
206
|
+
folded.push(message);
|
|
207
|
+
} else {
|
|
208
|
+
omittedRun ??= message;
|
|
209
|
+
omittedCount += 1;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
flushOmitted();
|
|
213
|
+
messages = folded;
|
|
214
|
+
}
|
|
215
|
+
return { pairs, messages };
|
|
216
|
+
}
|
|
217
|
+
export function fitProviderState(projection, eligible, options) {
|
|
218
|
+
const beforeState = stateFor(projection, projection.pairs);
|
|
219
|
+
const beforeTokens = estimateUtf8Tokens(beforeState);
|
|
220
|
+
const eligibleIds = new Set(eligible.map((pair) => pair.id));
|
|
221
|
+
const pinnedMessageIds = new Set(
|
|
222
|
+
projection.messages
|
|
223
|
+
.slice(0, 1)
|
|
224
|
+
.concat(
|
|
225
|
+
projection.messages.slice(
|
|
226
|
+
Math.max(0, projection.messages.length - options.preserveRecentMessages),
|
|
227
|
+
),
|
|
228
|
+
)
|
|
229
|
+
.map((message) => message.id),
|
|
230
|
+
);
|
|
231
|
+
const stages = [
|
|
232
|
+
'original',
|
|
233
|
+
'inputs_1000',
|
|
234
|
+
'inputs_200',
|
|
235
|
+
'inputs_60',
|
|
236
|
+
'text_head_tail',
|
|
237
|
+
'text_omitted',
|
|
238
|
+
'compact_calls',
|
|
239
|
+
'callless_omitted',
|
|
240
|
+
'runs_folded',
|
|
241
|
+
];
|
|
242
|
+
let current = { pairs: projection.pairs, messages: projection.messages };
|
|
243
|
+
for (const [stageIndex, stage] of stages.entries()) {
|
|
244
|
+
if (stage !== 'original')
|
|
245
|
+
current = stageProjection(
|
|
246
|
+
{ ...projection, pairs: current.pairs, messages: current.messages },
|
|
247
|
+
eligibleIds,
|
|
248
|
+
options.preserveRecentMessages,
|
|
249
|
+
stage,
|
|
250
|
+
pinnedMessageIds,
|
|
251
|
+
);
|
|
252
|
+
let transformed = current;
|
|
253
|
+
let omittedProtectedPairCount = 0;
|
|
254
|
+
if (stage === 'runs_folded') {
|
|
255
|
+
const retainedPairIds = new Set(
|
|
256
|
+
transformed.messages.flatMap((message) => [...message.callIds, ...message.resultIds]),
|
|
257
|
+
);
|
|
258
|
+
const retainedPairs = transformed.pairs.filter(
|
|
259
|
+
(pair) => eligibleIds.has(pair.id) || retainedPairIds.has(pair.id),
|
|
260
|
+
);
|
|
261
|
+
omittedProtectedPairCount = transformed.pairs.length - retainedPairs.length;
|
|
262
|
+
transformed = { ...transformed, pairs: retainedPairs };
|
|
263
|
+
}
|
|
264
|
+
// Once we reach the explicit compact-calls stage, abbreviate pair metadata
|
|
265
|
+
// while retaining identity, tool, size and outcome. Eligible inputs have
|
|
266
|
+
// already passed through bounded input stages, and the compact record keeps
|
|
267
|
+
// a short prefix for the provider's final question context.
|
|
268
|
+
const compactIds =
|
|
269
|
+
stageIndex >= stages.indexOf('compact_calls')
|
|
270
|
+
? new Set(projection.pairs.map((pair) => pair.id))
|
|
271
|
+
: new Set();
|
|
272
|
+
const state = stateFor(
|
|
273
|
+
projection,
|
|
274
|
+
transformed.pairs,
|
|
275
|
+
transformed.messages,
|
|
276
|
+
compactIds,
|
|
277
|
+
omittedProtectedPairCount,
|
|
278
|
+
);
|
|
279
|
+
const stateTokens = estimateUtf8Tokens(state);
|
|
280
|
+
if (stateTokens > options.maxStateTokens) continue;
|
|
281
|
+
const packed = makeBatches(eligible, stateTokens, options.maxRequestTokens);
|
|
282
|
+
if (packed === null) continue;
|
|
283
|
+
return {
|
|
284
|
+
state,
|
|
285
|
+
fitting: {
|
|
286
|
+
version: 'state-fit-v1',
|
|
287
|
+
stage,
|
|
288
|
+
estimator: UTF8_ESTIMATOR_VERSION,
|
|
289
|
+
beforeEstimatedStateTokens: beforeTokens,
|
|
290
|
+
afterEstimatedStateTokens: stateTokens,
|
|
291
|
+
},
|
|
292
|
+
batches: packed.batches,
|
|
293
|
+
stateTokens,
|
|
294
|
+
requestTokens: packed.requestTokens,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
throw new Error('state_fit_budget_exceeded');
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Narrow, side-effect-free contract for the Claude provider-window planner.
|
|
301
|
+
* It intentionally does not expose the prepared provider state or transcript.
|
|
302
|
+
*/
|
|
303
|
+
export function preflightProviderState(projection, eligible, options) {
|
|
304
|
+
try {
|
|
305
|
+
const fitted = fitProviderState(projection, eligible, options);
|
|
306
|
+
return {
|
|
307
|
+
fits: true,
|
|
308
|
+
reason: 'fits',
|
|
309
|
+
stage: fitted.fitting.stage,
|
|
310
|
+
stateTokens: fitted.stateTokens,
|
|
311
|
+
requestTokens: fitted.requestTokens,
|
|
312
|
+
batchCount: fitted.batches.length,
|
|
313
|
+
};
|
|
314
|
+
} catch {
|
|
315
|
+
return {
|
|
316
|
+
fits: false,
|
|
317
|
+
reason: 'budget_exceeded',
|
|
318
|
+
stage: null,
|
|
319
|
+
stateTokens: null,
|
|
320
|
+
requestTokens: null,
|
|
321
|
+
batchCount: 0,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
}
|