@bman654/clodex 2.1.6 → 2.1.7

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/dist/cli.js CHANGED
@@ -217,7 +217,7 @@ import { join } from "path";
217
217
  // package.json
218
218
  var package_default = {
219
219
  name: "@bman654/clodex",
220
- version: "2.1.6",
220
+ version: "2.1.7",
221
221
  publishConfig: {
222
222
  access: "public"
223
223
  },
@@ -4406,6 +4406,9 @@ function normalizeToolCallJson(value) {
4406
4406
  } catch {
4407
4407
  }
4408
4408
  }
4409
+ if (record.type === "reasoning" && Array.isArray(record.content) && record.content.length === 0) {
4410
+ delete out.content;
4411
+ }
4409
4412
  return out;
4410
4413
  }
4411
4414
  function arraysEqual(left, right) {
@@ -4421,7 +4424,37 @@ function conversationItemKind(value) {
4421
4424
  function conversationItemHash(value) {
4422
4425
  return createHash3("sha256").update(canonicalJson(normalizeToolCallJson(value))).digest("hex").slice(0, 16);
4423
4426
  }
4424
- function continuationMismatchDetails(entry, payload) {
4427
+ function reasoningNormalizationGap(expected, actual) {
4428
+ if (conversationItemKind(expected) !== "reasoning" || conversationItemKind(actual) !== "reasoning") return void 0;
4429
+ const left = expected;
4430
+ const right = actual;
4431
+ const blob = left.encrypted_content;
4432
+ if (typeof blob !== "string" || !blob || blob !== right.encrypted_content) return void 0;
4433
+ const fields = [.../* @__PURE__ */ new Set([...Object.keys(left), ...Object.keys(right)])].sort().filter((key) => canonicalJson(normalizeToolCallJson(left[key])) !== canonicalJson(normalizeToolCallJson(right[key])));
4434
+ return fields.length ? fields : void 0;
4435
+ }
4436
+ var warnedReasoningGaps = /* @__PURE__ */ new Set();
4437
+ var MAX_REASONING_GAP_WARNINGS = 3;
4438
+ function warnReasoningNormalizationGap(fields, log12) {
4439
+ const signature = fields.join(",");
4440
+ const message = `clodex: warning: a reasoning item with identical encrypted_content failed the continuation match on field(s): ${signature}. Prompt caching is degraded for this turn \u2014 this is a clodex normalization gap, please report it at https://github.com/bman654/clodex/issues`;
4441
+ try {
4442
+ log12?.(`reasoning normalization gap: ${signature}`);
4443
+ } catch {
4444
+ }
4445
+ if (warnedReasoningGaps.has(signature)) return;
4446
+ if (warnedReasoningGaps.size >= MAX_REASONING_GAP_WARNINGS) return;
4447
+ warnedReasoningGaps.add(signature);
4448
+ try {
4449
+ process.stderr.write(`${message}
4450
+ `);
4451
+ if (warnedReasoningGaps.size === MAX_REASONING_GAP_WARNINGS) {
4452
+ process.stderr.write("clodex: warning: further reasoning-normalization warnings suppressed.\n");
4453
+ }
4454
+ } catch {
4455
+ }
4456
+ }
4457
+ function continuationMismatchDetails(entry, payload, log12) {
4425
4458
  const full = inputArray(payload);
4426
4459
  const prefix = [...entry.requestInput ?? [], ...entry.expectedAssistant ?? []];
4427
4460
  const comparable = Math.min(full.length, prefix.length);
@@ -4434,6 +4467,8 @@ function continuationMismatchDetails(entry, payload) {
4434
4467
  }
4435
4468
  const expected = mismatch < prefix.length ? prefix[mismatch] : void 0;
4436
4469
  const actual = mismatch < full.length ? full[mismatch] : void 0;
4470
+ const reasoningGap = reasoningNormalizationGap(expected, actual);
4471
+ if (reasoningGap) warnReasoningNormalizationGap(reasoningGap, log12);
4437
4472
  return {
4438
4473
  fullItems: full.length,
4439
4474
  expectedPrefixItems: prefix.length,
@@ -4441,11 +4476,12 @@ function continuationMismatchDetails(entry, payload) {
4441
4476
  expectedKind: expected === void 0 ? "none" : conversationItemKind(expected),
4442
4477
  actualKind: actual === void 0 ? "none" : conversationItemKind(actual),
4443
4478
  ...expected !== void 0 ? { expectedHash: conversationItemHash(expected) } : {},
4444
- ...actual !== void 0 ? { actualHash: conversationItemHash(actual) } : {}
4479
+ ...actual !== void 0 ? { actualHash: conversationItemHash(actual) } : {},
4480
+ ...reasoningGap ? { reasoningNormalizationGap: reasoningGap } : {}
4445
4481
  };
4446
4482
  }
4447
- function continuationMismatchSummary(entry, payload) {
4448
- const details = continuationMismatchDetails(entry, payload);
4483
+ function continuationMismatchSummary(entry, payload, log12) {
4484
+ const details = continuationMismatchDetails(entry, payload, log12);
4449
4485
  return `full_items=${details.fullItems} expected_prefix_items=${details.expectedPrefixItems} first_mismatch=${details.firstMismatch} expected=${details.expectedKind} actual=${details.actualKind}`;
4450
4486
  }
4451
4487
  function continuationMatch(entry, payload) {
@@ -5272,7 +5308,7 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
5272
5308
  debug("parallel request using an isolated socket");
5273
5309
  } else if (diagnosticEntry) {
5274
5310
  debug(
5275
- `history mismatch starting an additional chain; retained ${candidates.length} existing head(s) (${continuationMismatchSummary(diagnosticEntry, payload)})`
5311
+ `history mismatch starting an additional chain; retained ${candidates.length} existing head(s) (${continuationMismatchSummary(diagnosticEntry, payload, debug)})`
5276
5312
  );
5277
5313
  decision = "history_mismatch_new_head";
5278
5314
  } else if (partitionKey) {
@@ -5332,7 +5368,7 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
5332
5368
  ttlPausedMs: entry.ttlPausedMs,
5333
5369
  idleMs: Math.max(0, now - entry.lastUsedAt),
5334
5370
  promptChanges: changedPromptFields(entry.promptFieldHashes, promptFieldHashes),
5335
- mismatch: continuationMismatchDetails(entry, payload)
5371
+ mismatch: continuationMismatchDetails(entry, payload, debug)
5336
5372
  })),
5337
5373
  evictions
5338
5374
  }, diagnosticCorrelation);