@triflux/remote 10.62.0 → 10.64.0
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.
|
@@ -58,6 +58,28 @@ function beginTurn(state) {
|
|
|
58
58
|
function acceptEntry(state, entry, marker) {
|
|
59
59
|
if (entry?.isSidechain) return;
|
|
60
60
|
const message = entry?.message;
|
|
61
|
+
if (
|
|
62
|
+
entry?.type === "attachment" &&
|
|
63
|
+
entry.attachment?.type === "goal_status"
|
|
64
|
+
) {
|
|
65
|
+
const goal = entry.attachment;
|
|
66
|
+
const cleared = goal.met === true && goal.sentinel === true;
|
|
67
|
+
state.goal = {
|
|
68
|
+
state: cleared ? "none" : goal.met ? "complete" : "active",
|
|
69
|
+
objective: cleared ? null : goal.condition,
|
|
70
|
+
judgedBy: "evaluator",
|
|
71
|
+
...(goal.reason !== undefined ? { reason: goal.reason } : {}),
|
|
72
|
+
...(goal.tokens !== undefined ? { tokensUsed: goal.tokens } : {}),
|
|
73
|
+
updatedAt: entry.timestamp ?? null,
|
|
74
|
+
};
|
|
75
|
+
if (goal.sentinel === true) {
|
|
76
|
+
state.goalSentinel = {
|
|
77
|
+
...goal,
|
|
78
|
+
updatedAt: entry.timestamp,
|
|
79
|
+
count: (state.goalSentinel?.count ?? 0) + 1,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
61
83
|
if (entry?.type === "system" && entry.subtype === "compact_boundary") {
|
|
62
84
|
state.compactCount += 1;
|
|
63
85
|
state.compact = {
|
|
@@ -211,6 +233,8 @@ export async function readClaudeTranscript(transcriptPath, { requestId } = {}) {
|
|
|
211
233
|
measuredAt: null,
|
|
212
234
|
compactCount: 0,
|
|
213
235
|
compact: null,
|
|
236
|
+
goal: { state: "none", objective: null, judgedBy: "evaluator" },
|
|
237
|
+
goalSentinel: null,
|
|
214
238
|
};
|
|
215
239
|
}
|
|
216
240
|
try {
|
|
@@ -248,6 +272,7 @@ export async function readClaudeTranscript(transcriptPath, { requestId } = {}) {
|
|
|
248
272
|
model: state.model,
|
|
249
273
|
measuredAt: state.measuredAt,
|
|
250
274
|
},
|
|
275
|
+
enqueued: state.queuedContent !== null,
|
|
251
276
|
userSeen: state.userSeen,
|
|
252
277
|
response: state.response,
|
|
253
278
|
error: state.error,
|
|
@@ -255,5 +280,7 @@ export async function readClaudeTranscript(transcriptPath, { requestId } = {}) {
|
|
|
255
280
|
sectionClosed: state.sectionClosed,
|
|
256
281
|
compactCount: state.compactCount,
|
|
257
282
|
compact: state.compact,
|
|
283
|
+
goal: state.goal,
|
|
284
|
+
goalSentinel: state.goalSentinel,
|
|
258
285
|
};
|
|
259
286
|
}
|
|
@@ -23,14 +23,21 @@ const MODEL_CONTEXT = [
|
|
|
23
23
|
},
|
|
24
24
|
];
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
const CONTEXT_THRESHOLDS = {
|
|
27
27
|
claude: { warnContextPct: 60, maxContextPct: 90 },
|
|
28
|
-
codex: { warnContextPct:
|
|
28
|
+
codex: { warnContextPct: 60, maxContextPct: 85 },
|
|
29
29
|
};
|
|
30
|
+
// rollout 실행 창을 못 읽으면 1.05M 표 값이 분모라 실제 창보다 비율이 작게 나온다.
|
|
31
|
+
const CODEX_MODEL_WINDOW_THRESHOLDS = { warnContextPct: 15, maxContextPct: 22 };
|
|
30
32
|
|
|
31
33
|
const rolloutCache = new Map();
|
|
32
34
|
|
|
33
|
-
export function modelContext(
|
|
35
|
+
export function modelContext(
|
|
36
|
+
cli,
|
|
37
|
+
model,
|
|
38
|
+
estimatedContextTokens = null,
|
|
39
|
+
rolloutContextWindow = null,
|
|
40
|
+
) {
|
|
34
41
|
const entry = MODEL_CONTEXT.find(
|
|
35
42
|
(item) => item.cli === cli && item.model.test(model || ""),
|
|
36
43
|
);
|
|
@@ -38,18 +45,20 @@ export function modelContext(cli, model, estimatedContextTokens = null) {
|
|
|
38
45
|
const executionContextLimitTokens =
|
|
39
46
|
cli === "claude" && process.env.CLAUDE_CODE_DISABLE_1M_CONTEXT === "1"
|
|
40
47
|
? 200_000
|
|
41
|
-
:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
: rolloutContextWindow;
|
|
49
|
+
// Codex 는 rollout 이 보고한 창이 실제 실행 한도라 표 값과 무관하게 그 창을 쓴다.
|
|
50
|
+
const effectiveLimit =
|
|
51
|
+
cli === "codex"
|
|
52
|
+
? (executionContextLimitTokens ?? contextLimitTokens)
|
|
53
|
+
: contextLimitTokens &&
|
|
54
|
+
Math.min(contextLimitTokens, executionContextLimitTokens ?? Infinity);
|
|
46
55
|
return {
|
|
47
56
|
estimatedContextTokens,
|
|
48
57
|
contextLimitTokens,
|
|
49
58
|
contextLimitSource: entry?.source ?? null,
|
|
50
59
|
...(executionContextLimitTokens ? { executionContextLimitTokens } : {}),
|
|
51
60
|
contextPct:
|
|
52
|
-
|
|
61
|
+
effectiveLimit && Number.isFinite(estimatedContextTokens)
|
|
53
62
|
? (estimatedContextTokens / effectiveLimit) * 100
|
|
54
63
|
: null,
|
|
55
64
|
};
|
|
@@ -60,7 +69,10 @@ export function contextGuard(
|
|
|
60
69
|
context,
|
|
61
70
|
{ warnContextPct, maxContextPct } = {},
|
|
62
71
|
) {
|
|
63
|
-
const defaults =
|
|
72
|
+
const defaults =
|
|
73
|
+
cli === "codex" && !context?.executionContextLimitTokens
|
|
74
|
+
? CODEX_MODEL_WINDOW_THRESHOLDS
|
|
75
|
+
: CONTEXT_THRESHOLDS[cli];
|
|
64
76
|
const warn = warnContextPct ?? defaults?.warnContextPct ?? 0;
|
|
65
77
|
const max = maxContextPct ?? defaults?.maxContextPct ?? 0;
|
|
66
78
|
const fields = {
|
|
@@ -90,6 +102,7 @@ export function contextGuard(
|
|
|
90
102
|
inputSent: false,
|
|
91
103
|
hint: "세션을 승계한 뒤 새 세션에 요청하라.",
|
|
92
104
|
...fields,
|
|
105
|
+
thresholdPct: max,
|
|
93
106
|
};
|
|
94
107
|
}
|
|
95
108
|
return warn > 0 && fields.contextPct >= warn
|
|
@@ -137,12 +150,19 @@ function acceptCodexLine(state, line) {
|
|
|
137
150
|
} catch {
|
|
138
151
|
return false;
|
|
139
152
|
}
|
|
153
|
+
if (entry?.type === "compacted") {
|
|
154
|
+
state.compactCount += 1;
|
|
155
|
+
state.compact = { preTokens: state.tokens, postTokens: null };
|
|
156
|
+
}
|
|
140
157
|
if (entry?.type === "turn_context")
|
|
141
158
|
state.model = entry.payload?.model || state.model;
|
|
142
159
|
if (entry?.type === "event_msg" && entry.payload?.type === "token_count") {
|
|
143
160
|
const info = entry.payload.info;
|
|
144
|
-
if (Number.isFinite(info?.last_token_usage?.total_tokens))
|
|
161
|
+
if (Number.isFinite(info?.last_token_usage?.total_tokens)) {
|
|
145
162
|
state.tokens = info.last_token_usage.total_tokens;
|
|
163
|
+
if (state.compact && state.compact.postTokens === null)
|
|
164
|
+
state.compact.postTokens = state.tokens;
|
|
165
|
+
}
|
|
146
166
|
if (Number.isFinite(info?.model_context_window))
|
|
147
167
|
state.executionContextLimitTokens = info.model_context_window;
|
|
148
168
|
}
|
|
@@ -172,6 +192,8 @@ export async function readCodexContext(rolloutPath, threadId) {
|
|
|
172
192
|
decoder: new StringDecoder("utf8"),
|
|
173
193
|
model: null,
|
|
174
194
|
tokens: null,
|
|
195
|
+
compactCount: 0,
|
|
196
|
+
compact: null,
|
|
175
197
|
executionContextLimitTokens: null,
|
|
176
198
|
};
|
|
177
199
|
}
|
|
@@ -197,8 +219,15 @@ export async function readCodexContext(rolloutPath, threadId) {
|
|
|
197
219
|
state.mtimeMs = stat.mtimeMs;
|
|
198
220
|
rolloutCache.set(rolloutPath, state);
|
|
199
221
|
return {
|
|
200
|
-
...modelContext(
|
|
222
|
+
...modelContext(
|
|
223
|
+
"codex",
|
|
224
|
+
state.model,
|
|
225
|
+
state.tokens,
|
|
226
|
+
state.executionContextLimitTokens,
|
|
227
|
+
),
|
|
201
228
|
model: state.model,
|
|
229
|
+
compactCount: state.compactCount,
|
|
230
|
+
compact: state.compact,
|
|
202
231
|
executionContextLimitTokens: state.executionContextLimitTokens,
|
|
203
232
|
};
|
|
204
233
|
}
|