@cjhyy/code-shell-capability-coding 0.9.21 → 0.9.23
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.
|
@@ -37,6 +37,10 @@ export declare class CodexEventTranslator {
|
|
|
37
37
|
private readonly codeshellServer;
|
|
38
38
|
private turnNumber;
|
|
39
39
|
private activeTurnId;
|
|
40
|
+
private usageTurnId;
|
|
41
|
+
private cumulativeUsage;
|
|
42
|
+
private turnUsageBaseline;
|
|
43
|
+
private turnUsage;
|
|
40
44
|
/** Turns that reached a terminal state. Late events for these are dropped. */
|
|
41
45
|
private readonly finishedTurns;
|
|
42
46
|
/**
|
|
@@ -64,6 +68,8 @@ export declare class CodexEventTranslator {
|
|
|
64
68
|
private onError;
|
|
65
69
|
private onAgentDelta;
|
|
66
70
|
private onReasoningDelta;
|
|
71
|
+
private resetTurnUsage;
|
|
72
|
+
private updateTurnUsage;
|
|
67
73
|
private onTokenUsage;
|
|
68
74
|
/**
|
|
69
75
|
* A CodeShell Host Tool call must not produce a card here — `ToolExecutor`
|
|
@@ -70,6 +70,10 @@ export class CodexEventTranslator {
|
|
|
70
70
|
codeshellServer;
|
|
71
71
|
turnNumber = 0;
|
|
72
72
|
activeTurnId;
|
|
73
|
+
usageTurnId;
|
|
74
|
+
cumulativeUsage = {};
|
|
75
|
+
turnUsageBaseline = {};
|
|
76
|
+
turnUsage = {};
|
|
73
77
|
/** Turns that reached a terminal state. Late events for these are dropped. */
|
|
74
78
|
finishedTurns = new Set();
|
|
75
79
|
/**
|
|
@@ -157,7 +161,13 @@ export class CodexEventTranslator {
|
|
|
157
161
|
// must not reactivate the session.
|
|
158
162
|
if (turnId && this.finishedTurns.has(turnId))
|
|
159
163
|
return [];
|
|
164
|
+
if (turnId && turnId === this.activeTurnId)
|
|
165
|
+
return [];
|
|
160
166
|
this.activeTurnId = turnId;
|
|
167
|
+
// Usage may arrive before turn/started. Keep the counts already attributed
|
|
168
|
+
// to this turn, and reset only when a different user turn begins.
|
|
169
|
+
if (!turnId || turnId !== this.usageTurnId)
|
|
170
|
+
this.resetTurnUsage(turnId);
|
|
161
171
|
this.turnNumber += 1;
|
|
162
172
|
return [{ type: "stream_request_start", turnNumber: this.turnNumber }];
|
|
163
173
|
}
|
|
@@ -214,8 +224,40 @@ export class CodexEventTranslator {
|
|
|
214
224
|
const delta = str(params.delta);
|
|
215
225
|
return delta ? [{ type: "thinking_delta", text: delta }] : [];
|
|
216
226
|
}
|
|
227
|
+
resetTurnUsage(turnId) {
|
|
228
|
+
this.usageTurnId = turnId;
|
|
229
|
+
this.turnUsageBaseline = { ...this.cumulativeUsage };
|
|
230
|
+
this.turnUsage = {};
|
|
231
|
+
}
|
|
232
|
+
updateTurnUsage(key, last, total) {
|
|
233
|
+
if (total !== undefined) {
|
|
234
|
+
if (this.turnUsage[key] === undefined &&
|
|
235
|
+
this.turnUsageBaseline[key] !== undefined &&
|
|
236
|
+
total < this.turnUsageBaseline[key]) {
|
|
237
|
+
// A provider accounting window can restart between turns. Rebase the
|
|
238
|
+
// first update only: a lower snapshot during the same turn may instead
|
|
239
|
+
// be an out-of-order delivery, which must not count as fresh work.
|
|
240
|
+
this.turnUsageBaseline[key] = 0;
|
|
241
|
+
this.cumulativeUsage[key] = 0;
|
|
242
|
+
}
|
|
243
|
+
// A resumed thread has history, but no local baseline yet. Its first
|
|
244
|
+
// update identifies that history as total - last. Subsequent updates use
|
|
245
|
+
// cumulative differences, so repeated notifications never add usage twice
|
|
246
|
+
// and intermediate model requests remain counted throughout the turn.
|
|
247
|
+
this.turnUsageBaseline[key] ??= Math.max(0, total - (last ?? 0));
|
|
248
|
+
this.turnUsage[key] = Math.max(this.turnUsage[key] ?? 0, total - this.turnUsageBaseline[key]);
|
|
249
|
+
this.cumulativeUsage[key] = Math.max(this.cumulativeUsage[key] ?? 0, total);
|
|
250
|
+
}
|
|
251
|
+
else if (last !== undefined) {
|
|
252
|
+
// Older/partial notifications have no reliable request identity. Preserve
|
|
253
|
+
// the snapshot without adding it repeatedly as if each delivery were work.
|
|
254
|
+
this.turnUsage[key] = Math.max(this.turnUsage[key] ?? 0, last);
|
|
255
|
+
}
|
|
256
|
+
return this.turnUsage[key];
|
|
257
|
+
}
|
|
217
258
|
onTokenUsage(params) {
|
|
218
|
-
|
|
259
|
+
const turnId = str(params.turnId) ?? this.activeTurnId;
|
|
260
|
+
if (this.isStale(turnId))
|
|
219
261
|
return [];
|
|
220
262
|
const usage = asRecord(params.tokenUsage);
|
|
221
263
|
const total = asRecord(usage?.total);
|
|
@@ -224,6 +266,8 @@ export class CodexEventTranslator {
|
|
|
224
266
|
const promptTokens = number(last?.inputTokens);
|
|
225
267
|
if (promptTokens === undefined)
|
|
226
268
|
return [];
|
|
269
|
+
if (turnId && turnId !== this.usageTurnId)
|
|
270
|
+
this.resetTurnUsage(turnId);
|
|
227
271
|
const cacheReadTokens = number(last?.cachedInputTokens);
|
|
228
272
|
const cumulativePromptTokens = number(total?.inputTokens);
|
|
229
273
|
const cumulativeCacheReadTokens = number(total?.cachedInputTokens);
|
|
@@ -231,6 +275,9 @@ export class CodexEventTranslator {
|
|
|
231
275
|
const cumulativeCacheCreationTokens = number(total?.cacheWriteInputTokens);
|
|
232
276
|
const completionTokens = number(last?.outputTokens);
|
|
233
277
|
const cumulativeCompletionTokens = number(total?.outputTokens);
|
|
278
|
+
const singleTurnPromptTokens = this.updateTurnUsage("promptTokens", promptTokens, cumulativePromptTokens);
|
|
279
|
+
const singleTurnCacheReadTokens = this.updateTurnUsage("cacheReadTokens", cacheReadTokens, cumulativeCacheReadTokens);
|
|
280
|
+
const singleTurnCacheCreationTokens = this.updateTurnUsage("cacheCreationTokens", cacheCreationTokens, cumulativeCacheCreationTokens);
|
|
234
281
|
return [
|
|
235
282
|
{
|
|
236
283
|
type: "usage_update",
|
|
@@ -239,11 +286,9 @@ export class CodexEventTranslator {
|
|
|
239
286
|
promptTokensConfidence: "high",
|
|
240
287
|
...(cacheReadTokens !== undefined ? { cacheReadTokens } : {}),
|
|
241
288
|
...(cacheCreationTokens !== undefined ? { cacheCreationTokens } : {}),
|
|
242
|
-
singleTurnPromptTokens
|
|
243
|
-
...(
|
|
244
|
-
...(
|
|
245
|
-
? { singleTurnCacheCreationTokens: cacheCreationTokens }
|
|
246
|
-
: {}),
|
|
289
|
+
singleTurnPromptTokens,
|
|
290
|
+
...(singleTurnCacheReadTokens !== undefined ? { singleTurnCacheReadTokens } : {}),
|
|
291
|
+
...(singleTurnCacheCreationTokens !== undefined ? { singleTurnCacheCreationTokens } : {}),
|
|
247
292
|
...(cumulativePromptTokens !== undefined ? { cumulativePromptTokens } : {}),
|
|
248
293
|
...(cumulativeCacheReadTokens !== undefined ? { cumulativeCacheReadTokens } : {}),
|
|
249
294
|
...(cumulativeCacheCreationTokens !== undefined ? { cumulativeCacheCreationTokens } : {}),
|
|
@@ -49,20 +49,6 @@ export function threadIdFromMeta(params) {
|
|
|
49
49
|
}
|
|
50
50
|
return undefined;
|
|
51
51
|
}
|
|
52
|
-
function turnIdFromMeta(params) {
|
|
53
|
-
if (!params || typeof params !== "object")
|
|
54
|
-
return undefined;
|
|
55
|
-
const meta = params._meta;
|
|
56
|
-
if (!meta || typeof meta !== "object")
|
|
57
|
-
return undefined;
|
|
58
|
-
const turn = meta["x-codex-turn-metadata"];
|
|
59
|
-
if (turn && typeof turn === "object") {
|
|
60
|
-
const id = turn.turn_id;
|
|
61
|
-
if (typeof id === "string" && id)
|
|
62
|
-
return id;
|
|
63
|
-
}
|
|
64
|
-
return undefined;
|
|
65
|
-
}
|
|
66
52
|
/** Model-facing text for a routing refusal. Says what happened without leaking
|
|
67
53
|
* which other sessions exist. */
|
|
68
54
|
function missMessage(reason) {
|
|
@@ -271,7 +257,10 @@ export async function startLoopbackMcpBridge(options) {
|
|
|
271
257
|
const started = Date.now();
|
|
272
258
|
// The host is the authorization boundary; the bridge only routes.
|
|
273
259
|
const outcome = await resolved.host.execute({
|
|
274
|
-
|
|
260
|
+
// One turn can contain many calls, including parallel ones. A turn id
|
|
261
|
+
// aliases their transcript/UI entries and overwrites navigate with a
|
|
262
|
+
// later observe error. Mint a host identity for each actual invocation.
|
|
263
|
+
id: `mcp-${randomBytes(12).toString("hex")}`,
|
|
275
264
|
name,
|
|
276
265
|
input: params?.arguments ?? {},
|
|
277
266
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cjhyy/code-shell-capability-coding",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.23",
|
|
4
4
|
"description": "Coding capability pack for the generic code-shell agent core.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\""
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@cjhyy/code-shell-core": "0.9.
|
|
42
|
+
"@cjhyy/code-shell-core": "0.9.23"
|
|
43
43
|
},
|
|
44
44
|
"engines": {
|
|
45
45
|
"node": ">=20.10"
|