@gleapai/kai-bridge 0.10.1 → 0.10.2

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.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@gleapai/kai-bridge",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@gleapai/kai-bridge",
9
- "version": "0.10.1",
9
+ "version": "0.10.2",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gleapai/kai-bridge",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
4
4
  "description": "Kai Code Bridge runs Kai Code on your computer or server with your own coding subscriptions and local previews.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -302,7 +302,12 @@ export const HARNESSES = {
302
302
  */
303
303
  supportsPromptSuggestions: (ctx) => !ctx.isPlanMode && !ctx.isArtifactWriter && claudeAdapterForwardsSuggestions(ctx),
304
304
  /** ACP session modes to try, in order (`session/set_mode`) — the adapter's own ids. */
305
- sessionModePreference: (ctx) => (ctx.isPlanMode ? ["plan"] : ctx.isArtifactWriter ? ["dontAsk", "plan"] : ["bypassPermissions", "acceptEdits", "default"]),
305
+ // Artifact writers: `dontAsk` where the adapter still offers it, else
306
+ // `default` (the runner's permissionPolicy answers each request: `.kai/**`
307
+ // writes allowed, repo mutations denied). Never `plan` — it declines the
308
+ // `.kai/` write too, and claude-agent-acp ≥0.71 no longer offers
309
+ // `dontAsk` (mirrors gleap_code_analyzer#70).
310
+ sessionModePreference: (ctx) => (ctx.isPlanMode ? ["plan"] : ctx.isArtifactWriter ? ["dontAsk", "default", "plan"] : ["bypassPermissions", "acceptEdits", "default"]),
306
311
  /** A prior turn's transcript on disk is what makes `resume` viable. */
307
312
  hasResumableSession: (ctx) => !!findClaudeTranscript(ctx.configDir, ctx.workDir, ctx.resumeSessionId),
308
313
  /**
@@ -194,9 +194,18 @@ export function readClaudePriorCostUsd({ configDir, cwd, sessionId }) {
194
194
  /**
195
195
  * Codex rollout `token_count` events report `last_token_usage` (the
196
196
  * most recent request) and a running `total_token_usage`. The per-
197
- * request rows are the `last_token_usage` deltas; `cached_input_tokens`
198
- * is INCLUDED in `input_tokens` (OpenAI convention — the tracker treats
199
- * `inputTokens` as cache-inclusive too, so pass it through unchanged).
197
+ * request rows are the `last_token_usage` deltas.
198
+ *
199
+ * OpenAI conventions (verified on a live GPT-6 rollout 2026-09-23:
200
+ * `total_tokens === input_tokens + output_tokens` on every request):
201
+ * - `cached_input_tokens` is a SUBSET of `input_tokens`; the tracker's
202
+ * `inputTokens` is FRESH input (the Anthropic shape), so the row carries
203
+ * `input_tokens - cached_input_tokens`. Passing the inclusive figure
204
+ * counted every cached token twice — reported input ~1.9x the real
205
+ * volume, cache rate ~46% instead of ~85%, and the double-counted
206
+ * cached volume billed at the FULL input rate.
207
+ * - `reasoning_output_tokens` is a SUBSET of `output_tokens`; adding it
208
+ * double-billed reasoning.
200
209
  */
201
210
  export function parseCodexRollout(text, { sinceTs, model } = {}) {
202
211
  const since = sinceTs ? new Date(sinceTs).getTime() : 0;
@@ -226,13 +235,14 @@ export function parseCodexRollout(text, { sinceTs, model } = {}) {
226
235
  }
227
236
  const input = num(last.input_tokens);
228
237
  if (input <= 0 && num(last.output_tokens) <= 0) continue;
238
+ const cached = Math.min(num(last.cached_input_tokens), input);
229
239
  rows.push({
230
240
  id: `${ts || rows.length}`,
231
241
  model: activeModel,
232
- inputTokens: input,
233
- cachedInputTokens: num(last.cached_input_tokens),
242
+ inputTokens: input - cached,
243
+ cachedInputTokens: cached,
234
244
  cacheWriteInputTokens: 0,
235
- outputTokens: num(last.output_tokens) + num(last.reasoning_output_tokens),
245
+ outputTokens: num(last.output_tokens),
236
246
  sidechain: false,
237
247
  timestamp: ts || null,
238
248
  });