@bman654/clodex 2.11.6 → 2.11.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/README.md +3 -0
- package/dist/cli.js +43 -14
- package/dist/cli.js.map +1 -1
- package/docs/windows-setup.md +300 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -106,6 +106,9 @@ flowchart LR
|
|
|
106
106
|
> [!TIP]
|
|
107
107
|
> Using Claude Code's agents view or background agents? Ask your Claude Code agent to read [docs/background-agents.md](docs/background-agents.md) and set it up for you — one global `clodex server --proxy` plus the `clodex-claude` wrapper bin bridges every claude process automatically.
|
|
108
108
|
|
|
109
|
+
> [!TIP]
|
|
110
|
+
> On Windows with the Claude Code VS Code extension? See [docs/windows-setup.md](docs/windows-setup.md) — proxy-mode env vars route the extension through clodex, and an optional process wrapper makes clodex models appear in its model picker.
|
|
111
|
+
|
|
109
112
|
## CLI reference
|
|
110
113
|
|
|
111
114
|
### `clodex claude [options] [claude-flags]`
|
package/dist/cli.js
CHANGED
|
@@ -382,7 +382,7 @@ import { join } from "path";
|
|
|
382
382
|
// package.json
|
|
383
383
|
var package_default = {
|
|
384
384
|
name: "@bman654/clodex",
|
|
385
|
-
version: "2.11.
|
|
385
|
+
version: "2.11.7",
|
|
386
386
|
publishConfig: {
|
|
387
387
|
access: "public"
|
|
388
388
|
},
|
|
@@ -8717,8 +8717,8 @@ var FAILURE_EVENT_TYPES = /* @__PURE__ */ new Set(["error", "response.failed", "
|
|
|
8717
8717
|
var RESPONSES_WS_HARD_TTL_MS = 55 * 6e4;
|
|
8718
8718
|
var RESPONSES_WS_IDLE_TTL_MS = 30 * 6e4;
|
|
8719
8719
|
var RESPONSES_WS_NURSERY_IDLE_TTL_MS = 5 * 6e4;
|
|
8720
|
-
var RESPONSES_WS_MAX_CONNECTIONS =
|
|
8721
|
-
var RESPONSES_WS_MAX_NURSERY_CONNECTIONS =
|
|
8720
|
+
var RESPONSES_WS_MAX_CONNECTIONS = 64;
|
|
8721
|
+
var RESPONSES_WS_MAX_NURSERY_CONNECTIONS = 48;
|
|
8722
8722
|
var diagnosticContext = new AsyncLocalStorage();
|
|
8723
8723
|
function withResponsesWebSocketDiagnosticContext(context, fn) {
|
|
8724
8724
|
return diagnosticContext.run(context, fn);
|
|
@@ -9100,13 +9100,16 @@ function mismatchDumpLine(items, index) {
|
|
|
9100
9100
|
function canonicalItemStrings(items) {
|
|
9101
9101
|
return items.map((item) => canonicalJson(normalizeToolCallJson([item])));
|
|
9102
9102
|
}
|
|
9103
|
-
function
|
|
9104
|
-
if (client.length
|
|
9103
|
+
function isPrefixOrEqual(head, client) {
|
|
9104
|
+
if (client.length < head.length) return false;
|
|
9105
9105
|
for (let index = 0; index < head.length; index += 1) {
|
|
9106
9106
|
if (head[index] !== client[index]) return false;
|
|
9107
9107
|
}
|
|
9108
9108
|
return true;
|
|
9109
9109
|
}
|
|
9110
|
+
function isStrictPrefix(head, client) {
|
|
9111
|
+
return client.length > head.length && isPrefixOrEqual(head, client);
|
|
9112
|
+
}
|
|
9110
9113
|
function continuationMatch(entry, payload, clientItems) {
|
|
9111
9114
|
if (!entry.responseId || !entry.requestInput || !entry.expectedAssistant) return void 0;
|
|
9112
9115
|
const full = inputArray(payload);
|
|
@@ -9599,11 +9602,16 @@ function evictOldestIdleGeneration(generation, maxConnections, reason) {
|
|
|
9599
9602
|
while (connectionCountByGeneration(generation) >= maxConnections && idle.length) {
|
|
9600
9603
|
const oldest = idle.shift();
|
|
9601
9604
|
if (oldest) {
|
|
9605
|
+
const idleMs = Math.max(0, oldest.options.now() - oldest.lastUsedAt);
|
|
9606
|
+
oldest.debug(
|
|
9607
|
+
`evicting the oldest idle ${generation} connection to stay within its cap: connection=${oldest.debugId} idle_ms=${idleMs} cap=${maxConnections} reason=${reason}`
|
|
9608
|
+
);
|
|
9602
9609
|
evictions.push({
|
|
9603
9610
|
connectionId: oldest.debugId,
|
|
9604
9611
|
partitionKey: oldest.key,
|
|
9605
9612
|
generation: oldest.generation,
|
|
9606
|
-
reason
|
|
9613
|
+
reason,
|
|
9614
|
+
idleMs
|
|
9607
9615
|
});
|
|
9608
9616
|
deleteEntry(oldest);
|
|
9609
9617
|
}
|
|
@@ -10023,16 +10031,28 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
|
|
|
10023
10031
|
const diagnosticCorrelation = diagnosticContext.getStore();
|
|
10024
10032
|
let now = resolvedOptions.now();
|
|
10025
10033
|
const evictions = cleanupExpiredConnections(now);
|
|
10034
|
+
let canonicalClientItems;
|
|
10035
|
+
const clientItems = () => canonicalClientItems ??= canonicalItemStrings(inputArray(payload));
|
|
10026
10036
|
const scanForHeads = () => {
|
|
10027
10037
|
const scanned = partitionKey ? connectionEntries(partitionKey) : [];
|
|
10028
10038
|
const idle = scanned.filter((entry) => !entry.inFlight);
|
|
10029
|
-
const
|
|
10039
|
+
const canonical = idle.length ? clientItems() : [];
|
|
10030
10040
|
return {
|
|
10031
10041
|
candidates: scanned,
|
|
10032
10042
|
idleCandidates: idle,
|
|
10033
|
-
matches: idle.map((entry) => ({ entry, match: continuationMatch(entry, payload,
|
|
10043
|
+
matches: idle.map((entry) => ({ entry, match: continuationMatch(entry, payload, canonical) })).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))
|
|
10034
10044
|
};
|
|
10035
10045
|
};
|
|
10046
|
+
const couldPrecedeThisRequest = (entry) => {
|
|
10047
|
+
if (entry.responseId && entry.requestInput && entry.expectedAssistant) {
|
|
10048
|
+
return continuationMatch(entry, payload, clientItems()) !== void 0;
|
|
10049
|
+
}
|
|
10050
|
+
const streaming = entry.current;
|
|
10051
|
+
if (!streaming) return true;
|
|
10052
|
+
streaming.canonicalInput ??= canonicalItemStrings(inputArray(streaming.originalPayload));
|
|
10053
|
+
return isPrefixOrEqual(streaming.canonicalInput, clientItems());
|
|
10054
|
+
};
|
|
10055
|
+
const blockingHead = (entries) => entries.find((entry) => entry.inFlight && couldPrecedeThisRequest(entry));
|
|
10036
10056
|
let { candidates, idleCandidates, matches } = scanForHeads();
|
|
10037
10057
|
let selected = matches[0]?.entry;
|
|
10038
10058
|
let selectedMatch = matches[0]?.match;
|
|
@@ -10075,9 +10095,10 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
|
|
|
10075
10095
|
);
|
|
10076
10096
|
return "continuation";
|
|
10077
10097
|
};
|
|
10098
|
+
let arrivalBlockingHead = selected ? void 0 : blockingHead(candidates);
|
|
10078
10099
|
if (selected && selectedDelta) {
|
|
10079
10100
|
decision = continueOnHead(selected, selectedMatch);
|
|
10080
|
-
} else if (
|
|
10101
|
+
} else if (arrivalBlockingHead) {
|
|
10081
10102
|
selected = void 0;
|
|
10082
10103
|
persistent = false;
|
|
10083
10104
|
decision = "parallel_isolated";
|
|
@@ -10176,11 +10197,15 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
|
|
|
10176
10197
|
pacingRescanOutcome = "no_change";
|
|
10177
10198
|
}
|
|
10178
10199
|
}
|
|
10179
|
-
if (!selected && persistent && partitionKey
|
|
10180
|
-
|
|
10181
|
-
|
|
10182
|
-
|
|
10183
|
-
|
|
10200
|
+
if (!selected && persistent && partitionKey) {
|
|
10201
|
+
const blocked = blockingHead(connectionEntries(partitionKey));
|
|
10202
|
+
if (blocked) {
|
|
10203
|
+
arrivalBlockingHead = blocked;
|
|
10204
|
+
persistent = false;
|
|
10205
|
+
decision = "parallel_isolated";
|
|
10206
|
+
debug("parallel request using an isolated socket after pacing");
|
|
10207
|
+
if (pacingRescanOutcome === "no_change") pacingRescanOutcome = "parallel_isolated";
|
|
10208
|
+
}
|
|
10184
10209
|
}
|
|
10185
10210
|
}
|
|
10186
10211
|
let suppressedMismatchWarnings;
|
|
@@ -10236,6 +10261,10 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
|
|
|
10236
10261
|
createdConnectionId: selected ? void 0 : nextConnectionDebugId,
|
|
10237
10262
|
...pacingWaitedMs !== void 0 ? { pacingWaitedMs } : {},
|
|
10238
10263
|
...pacingRescanOutcome !== void 0 ? { pacingRescanOutcome } : {},
|
|
10264
|
+
// Which busy head this request could not be told apart from. Without it an
|
|
10265
|
+
// isolated turn reads as unexplained, and isolation is the single largest
|
|
10266
|
+
// source of uncached prompt tokens on this transport.
|
|
10267
|
+
...decision === "parallel_isolated" && arrivalBlockingHead ? { isolatedByConnectionId: arrivalBlockingHead.debugId } : {},
|
|
10239
10268
|
...suppressedMismatchWarnings !== void 0 ? { suppressedMismatchWarnings } : {},
|
|
10240
10269
|
createdGeneration: selected ? void 0 : persistent ? "nursery" : "isolated",
|
|
10241
10270
|
incrementalInputItems: selectedDelta?.length,
|