@bman654/clodex 2.1.7 → 2.1.9

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.7",
220
+ version: "2.1.9",
221
221
  publishConfig: {
222
222
  access: "public"
223
223
  },
@@ -4406,8 +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;
4409
+ if (record.type === "reasoning") {
4410
+ if (Array.isArray(record.content) && record.content.length === 0) delete out.content;
4411
+ if (typeof record.encrypted_content === "string" && record.encrypted_content) delete out.summary;
4411
4412
  }
4412
4413
  return out;
4413
4414
  }
@@ -4430,9 +4431,38 @@ function reasoningNormalizationGap(expected, actual) {
4430
4431
  const right = actual;
4431
4432
  const blob = left.encrypted_content;
4432
4433
  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
+ const normalizedLeft = normalizeToolCallJson(left);
4435
+ const normalizedRight = normalizeToolCallJson(right);
4436
+ const fields = [.../* @__PURE__ */ new Set([...Object.keys(normalizedLeft), ...Object.keys(normalizedRight)])].sort().filter((key) => canonicalJson(normalizedLeft[key]) !== canonicalJson(normalizedRight[key]));
4434
4437
  return fields.length ? fields : void 0;
4435
4438
  }
4439
+ function reasoningGapShape(expected, actual, full, storedTail, index) {
4440
+ const describe = (value) => {
4441
+ const record = value ?? {};
4442
+ return {
4443
+ keys: Object.keys(record).sort(),
4444
+ summaryParts: Array.isArray(record.summary) ? record.summary.length : 0,
4445
+ contentItems: Array.isArray(record.content) ? record.content.length : 0
4446
+ };
4447
+ };
4448
+ const blob = expected.encrypted_content;
4449
+ const runFrom = (items, start) => {
4450
+ let count = 0;
4451
+ for (let at = start; at < items.length; at += 1) {
4452
+ const item = items[at];
4453
+ if (conversationItemKind(item) !== "reasoning" || item?.encrypted_content !== blob) break;
4454
+ count += 1;
4455
+ }
4456
+ return count;
4457
+ };
4458
+ const storedStart = storedTail.findIndex((item) => item?.encrypted_content === blob);
4459
+ return {
4460
+ expected: describe(expected),
4461
+ actual: describe(actual),
4462
+ clientReasoningRun: runFrom(full, index),
4463
+ storedReasoningRun: storedStart < 0 ? 0 : runFrom(storedTail, storedStart)
4464
+ };
4465
+ }
4436
4466
  var warnedReasoningGaps = /* @__PURE__ */ new Set();
4437
4467
  var MAX_REASONING_GAP_WARNINGS = 3;
4438
4468
  function warnReasoningNormalizationGap(fields, log12) {
@@ -4454,7 +4484,7 @@ function warnReasoningNormalizationGap(fields, log12) {
4454
4484
  } catch {
4455
4485
  }
4456
4486
  }
4457
- function continuationMismatchDetails(entry, payload, log12) {
4487
+ function continuationMismatchDetails(entry, payload, log12, warnOnGap = false) {
4458
4488
  const full = inputArray(payload);
4459
4489
  const prefix = [...entry.requestInput ?? [], ...entry.expectedAssistant ?? []];
4460
4490
  const comparable = Math.min(full.length, prefix.length);
@@ -4468,7 +4498,7 @@ function continuationMismatchDetails(entry, payload, log12) {
4468
4498
  const expected = mismatch < prefix.length ? prefix[mismatch] : void 0;
4469
4499
  const actual = mismatch < full.length ? full[mismatch] : void 0;
4470
4500
  const reasoningGap = reasoningNormalizationGap(expected, actual);
4471
- if (reasoningGap) warnReasoningNormalizationGap(reasoningGap, log12);
4501
+ if (reasoningGap && warnOnGap) warnReasoningNormalizationGap(reasoningGap, log12);
4472
4502
  return {
4473
4503
  fullItems: full.length,
4474
4504
  expectedPrefixItems: prefix.length,
@@ -4477,27 +4507,44 @@ function continuationMismatchDetails(entry, payload, log12) {
4477
4507
  actualKind: actual === void 0 ? "none" : conversationItemKind(actual),
4478
4508
  ...expected !== void 0 ? { expectedHash: conversationItemHash(expected) } : {},
4479
4509
  ...actual !== void 0 ? { actualHash: conversationItemHash(actual) } : {},
4480
- ...reasoningGap ? { reasoningNormalizationGap: reasoningGap } : {}
4510
+ ...reasoningGap ? {
4511
+ reasoningNormalizationGap: reasoningGap,
4512
+ reasoningGapShape: reasoningGapShape(
4513
+ expected,
4514
+ actual,
4515
+ full,
4516
+ entry.expectedAssistant ?? [],
4517
+ mismatch
4518
+ )
4519
+ } : {}
4481
4520
  };
4482
4521
  }
4483
4522
  function continuationMismatchSummary(entry, payload, log12) {
4484
- const details = continuationMismatchDetails(entry, payload, log12);
4523
+ const details = continuationMismatchDetails(entry, payload, log12, true);
4485
4524
  return `full_items=${details.fullItems} expected_prefix_items=${details.expectedPrefixItems} first_mismatch=${details.firstMismatch} expected=${details.expectedKind} actual=${details.actualKind}`;
4486
4525
  }
4487
- function continuationMatch(entry, payload) {
4526
+ function canonicalItemStrings(items) {
4527
+ return items.map((item) => canonicalJson(normalizeToolCallJson([item])));
4528
+ }
4529
+ function isStrictPrefix(head, client) {
4530
+ if (client.length <= head.length) return false;
4531
+ for (let index = 0; index < head.length; index += 1) {
4532
+ if (head[index] !== client[index]) return false;
4533
+ }
4534
+ return true;
4535
+ }
4536
+ function continuationMatch(entry, payload, clientItems) {
4488
4537
  if (!entry.responseId || !entry.requestInput || !entry.expectedAssistant) return void 0;
4489
4538
  const full = inputArray(payload);
4490
- const exactPrefix = [...entry.requestInput, ...entry.expectedAssistant];
4491
- if (full.length > exactPrefix.length && arraysEqual(full.slice(0, exactPrefix.length), exactPrefix)) {
4492
- return { delta: full.slice(exactPrefix.length), mode: "exact" };
4539
+ entry.canonicalPrefix ??= canonicalItemStrings([...entry.requestInput, ...entry.expectedAssistant]);
4540
+ if (isStrictPrefix(entry.canonicalPrefix, clientItems)) {
4541
+ return { delta: full.slice(entry.canonicalPrefix.length), mode: "exact" };
4493
4542
  }
4494
4543
  const echoedAssistant = entry.expectedAssistant.filter((item) => conversationItemKind(item) !== "reasoning");
4495
4544
  if (echoedAssistant.length === entry.expectedAssistant.length) return void 0;
4496
- const echoablePrefix = [...entry.requestInput, ...echoedAssistant];
4497
- if (full.length <= echoablePrefix.length || !arraysEqual(full.slice(0, echoablePrefix.length), echoablePrefix)) {
4498
- return void 0;
4499
- }
4500
- return { delta: full.slice(echoablePrefix.length), mode: "omitted_reasoning" };
4545
+ entry.canonicalEchoablePrefix ??= canonicalItemStrings([...entry.requestInput, ...echoedAssistant]);
4546
+ if (!isStrictPrefix(entry.canonicalEchoablePrefix, clientItems)) return void 0;
4547
+ return { delta: full.slice(entry.canonicalEchoablePrefix.length), mode: "omitted_reasoning" };
4501
4548
  }
4502
4549
  function eventType(event) {
4503
4550
  return event && typeof event === "object" && typeof event.type === "string" ? event.type : void 0;
@@ -5117,6 +5164,8 @@ function handleSocketMessage(entry, data) {
5117
5164
  entry.responseId = ctx.responseId;
5118
5165
  entry.requestInput = inputArray(ctx.originalPayload);
5119
5166
  entry.expectedAssistant = expectedAssistantItems(ctx);
5167
+ entry.canonicalPrefix = void 0;
5168
+ entry.canonicalEchoablePrefix = void 0;
5120
5169
  entry.promptFieldHashes = ctx.promptFieldHashes;
5121
5170
  entry.instructionsSnapshot = ctx.instructionsSnapshot;
5122
5171
  entry.lastUsedAt = now;
@@ -5224,6 +5273,19 @@ function createConnection(WebSocket, wsUrl, headers, persistent, key, options, d
5224
5273
  });
5225
5274
  return entry;
5226
5275
  }
5276
+ function envConnectionCap(name, log12) {
5277
+ const raw = process.env[name];
5278
+ if (raw === void 0 || raw.trim() === "") return void 0;
5279
+ const value = Number(raw.trim());
5280
+ if (!Number.isInteger(value) || value < 1 || value > 1024) {
5281
+ try {
5282
+ log12?.(`ws: ignoring ${name}=${raw} (expected an integer between 1 and 1024)`);
5283
+ } catch {
5284
+ }
5285
+ return void 0;
5286
+ }
5287
+ return value;
5288
+ }
5227
5289
  function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
5228
5290
  const debug = (message) => {
5229
5291
  try {
@@ -5235,8 +5297,8 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
5235
5297
  hardTtlMs: options.hardTtlMs ?? RESPONSES_WS_HARD_TTL_MS,
5236
5298
  idleTtlMs: options.idleTtlMs ?? RESPONSES_WS_IDLE_TTL_MS,
5237
5299
  nurseryIdleTtlMs: options.nurseryIdleTtlMs ?? Math.min(RESPONSES_WS_NURSERY_IDLE_TTL_MS, options.idleTtlMs ?? RESPONSES_WS_IDLE_TTL_MS),
5238
- maxConnections: options.maxConnections ?? RESPONSES_WS_MAX_CONNECTIONS,
5239
- maxNurseryConnections: options.maxNurseryConnections ?? RESPONSES_WS_MAX_NURSERY_CONNECTIONS,
5300
+ maxConnections: options.maxConnections ?? envConnectionCap("CLODEX_WS_MAX_CONNECTIONS", log12) ?? RESPONSES_WS_MAX_CONNECTIONS,
5301
+ maxNurseryConnections: options.maxNurseryConnections ?? envConnectionCap("CLODEX_WS_MAX_NURSERY_CONNECTIONS", log12) ?? RESPONSES_WS_MAX_NURSERY_CONNECTIONS,
5240
5302
  now: options.now ?? Date.now
5241
5303
  };
5242
5304
  return async (_input, init) => {
@@ -5266,7 +5328,8 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
5266
5328
  const evictions = cleanupExpiredConnections(now);
5267
5329
  const candidates = partitionKey ? connectionEntries(partitionKey) : [];
5268
5330
  const idleCandidates = candidates.filter((entry) => !entry.inFlight);
5269
- const matches = idleCandidates.map((entry) => ({ entry, match: continuationMatch(entry, payload) })).filter((candidate) => candidate.match !== void 0).sort((left, right) => left.match.delta.length - right.match.delta.length || (left.match.mode === right.match.mode ? 0 : left.match.mode === "exact" ? -1 : 1));
5331
+ const clientItems = idleCandidates.length ? canonicalItemStrings(inputArray(payload)) : [];
5332
+ const matches = idleCandidates.map((entry) => ({ entry, match: continuationMatch(entry, payload, clientItems) })).filter((candidate) => candidate.match !== void 0).sort((left, right) => left.match.delta.length - right.match.delta.length || (left.match.mode === right.match.mode ? 0 : left.match.mode === "exact" ? -1 : 1));
5270
5333
  let selected = matches[0]?.entry;
5271
5334
  const selectedMatch = matches[0]?.match;
5272
5335
  const selectedDelta = selectedMatch?.delta;