claude-code-infinite 1.0.31 → 1.0.33
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 +71 -56
- package/dist/claude-auth-status.d.ts +50 -0
- package/dist/claude-auth-status.d.ts.map +1 -0
- package/dist/claude-auth-status.js +213 -0
- package/dist/claude-auth-status.js.map +1 -0
- package/dist/claude-auth.d.ts +2 -1
- package/dist/claude-auth.d.ts.map +1 -1
- package/dist/claude-auth.js +2 -1
- package/dist/claude-auth.js.map +1 -1
- package/dist/claude-plan-warning.d.ts +13 -40
- package/dist/claude-plan-warning.d.ts.map +1 -1
- package/dist/claude-plan-warning.js +24 -75
- package/dist/claude-plan-warning.js.map +1 -1
- package/dist/cli-args.d.ts +7 -0
- package/dist/cli-args.d.ts.map +1 -1
- package/dist/cli-args.js +19 -0
- package/dist/cli-args.js.map +1 -1
- package/dist/cli-main.js +117 -17
- package/dist/cli-main.js.map +1 -1
- package/dist/count-tokens.d.ts +7 -3
- package/dist/count-tokens.d.ts.map +1 -1
- package/dist/count-tokens.js +6 -2
- package/dist/count-tokens.js.map +1 -1
- package/dist/diagnostics-schema.d.ts +5 -2
- package/dist/diagnostics-schema.d.ts.map +1 -1
- package/dist/diagnostics-schema.js +26 -6
- package/dist/diagnostics-schema.js.map +1 -1
- package/dist/diagnostics.d.ts +5 -1
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +7 -2
- package/dist/diagnostics.js.map +1 -1
- package/dist/hooks.d.ts +18 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +57 -4
- package/dist/hooks.js.map +1 -1
- package/dist/memtree-mcp.d.ts +7 -0
- package/dist/memtree-mcp.d.ts.map +1 -1
- package/dist/memtree-mcp.js +12 -1
- package/dist/memtree-mcp.js.map +1 -1
- package/dist/memtree.d.ts +86 -3
- package/dist/memtree.d.ts.map +1 -1
- package/dist/memtree.js +305 -18
- package/dist/memtree.js.map +1 -1
- package/dist/notices.d.ts +2 -0
- package/dist/notices.d.ts.map +1 -1
- package/dist/notices.js +2 -0
- package/dist/notices.js.map +1 -1
- package/dist/open-url.d.ts +49 -0
- package/dist/open-url.d.ts.map +1 -0
- package/dist/open-url.js +100 -0
- package/dist/open-url.js.map +1 -0
- package/dist/proxy.d.ts +77 -1
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +618 -77
- package/dist/proxy.js.map +1 -1
- package/dist/reqlog.d.ts +21 -2
- package/dist/reqlog.d.ts.map +1 -1
- package/dist/reqlog.js.map +1 -1
- package/dist/request-sizing.d.ts +2 -0
- package/dist/request-sizing.d.ts.map +1 -1
- package/dist/request-sizing.js +5 -0
- package/dist/request-sizing.js.map +1 -1
- package/dist/resume-guidance.d.ts +102 -0
- package/dist/resume-guidance.d.ts.map +1 -0
- package/dist/resume-guidance.js +182 -0
- package/dist/resume-guidance.js.map +1 -0
- package/dist/route-fallback.d.ts +23 -0
- package/dist/route-fallback.d.ts.map +1 -1
- package/dist/route-fallback.js +44 -0
- package/dist/route-fallback.js.map +1 -1
- package/dist/sign-in-notice.d.ts +137 -0
- package/dist/sign-in-notice.d.ts.map +1 -0
- package/dist/sign-in-notice.js +300 -0
- package/dist/sign-in-notice.js.map +1 -0
- package/dist/subagent-hint.d.ts +31 -0
- package/dist/subagent-hint.d.ts.map +1 -0
- package/dist/subagent-hint.js +47 -0
- package/dist/subagent-hint.js.map +1 -0
- package/package.json +1 -1
package/dist/memtree.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memtree.d.ts","sourceRoot":"","sources":["../src/memtree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAwC,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAExE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAO1D,OAAO,EAEL,KAAK,OAAO,EACb,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,kCAA6C,CAAC;AAG1E,eAAO,MAAM,cAAc,EAAE,MAEpB,CAAC;AAOV;;;;;GAKG;AACH,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"memtree.d.ts","sourceRoot":"","sources":["../src/memtree.ts"],"names":[],"mappings":"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"}
|
package/dist/memtree.js
CHANGED
|
@@ -48,8 +48,12 @@ const DEFAULT_COMPRESS_TIMEOUT_MS = 15000;
|
|
|
48
48
|
* body (20+ MB) takes seconds to send on a slow link before the server even
|
|
49
49
|
* starts, so a flat budget times out on size alone (2026-10-23: every tool
|
|
50
50
|
* turn's compress of a 21.5 MB body timed out at 15 s with MemTree healthy).
|
|
51
|
+
* Measured from ccc's request logs, 2026-10-23..30: compress calls of 21-27 MB
|
|
52
|
+
* answered in 10-53 s (median ~19 s); at 1 ms/KiB a 26 MB call had ~41 s and lost
|
|
53
|
+
* to the 53 s ones, refusing a session for ten minutes (2026-10-30). 2.5 ms/KiB
|
|
54
|
+
* gives a 26 MB call ~79 s, 1.5x the slowest seen.
|
|
51
55
|
*/
|
|
52
|
-
export const COMPRESS_TIMEOUT_MS_PER_KIB =
|
|
56
|
+
export const COMPRESS_TIMEOUT_MS_PER_KIB = 2.5;
|
|
53
57
|
/**
|
|
54
58
|
* The budget for a compress with nothing else to send: no compressed prefix to
|
|
55
59
|
* ride and a raw request known not to fit the window (the first turn after
|
|
@@ -60,6 +64,13 @@ export const COMPRESS_TIMEOUT_MS_PER_KIB = 1;
|
|
|
60
64
|
const DEFAULT_LONG_COMPRESS_TIMEOUT_MS = 120_000;
|
|
61
65
|
/** Indexing runs off the response path; give it room. */
|
|
62
66
|
const INDEX_TIMEOUT_MS = 120_000;
|
|
67
|
+
/**
|
|
68
|
+
* New text (characters) a conversation's history must gain over its last index upload
|
|
69
|
+
* before the next one is sent: about the server's 10k-token index minimum
|
|
70
|
+
* (polychat MIN_TOKENS_TO_INDEX) at ~3 characters a token. Under it the server only
|
|
71
|
+
* acknowledges the upload.
|
|
72
|
+
*/
|
|
73
|
+
export const INDEX_MIN_NEW_CHARS = 30_000;
|
|
63
74
|
const DEDUPE_CACHE_MAX = 64;
|
|
64
75
|
/**
|
|
65
76
|
* A main-lane Stop followed by this long without a new request is taken as the
|
|
@@ -774,6 +785,17 @@ export class MemtreeClient {
|
|
|
774
785
|
indexLanesNext = new Map();
|
|
775
786
|
/** Per conversation, the history the exit's final index carries (flushFinalIndexes). */
|
|
776
787
|
finalIndexLanes = new Map();
|
|
788
|
+
indexMinNewChars;
|
|
789
|
+
compressTimeoutMsPerKiB;
|
|
790
|
+
/** Per conversation, the last history an index call was started for (INDEX_MIN_NEW_CHARS). */
|
|
791
|
+
indexLanesSent = new Map();
|
|
792
|
+
/**
|
|
793
|
+
* Per conversation, the newest history held back by INDEX_MIN_NEW_CHARS: sent before a
|
|
794
|
+
* call that does not carry it whole (a rewind, evicted media) replaces it.
|
|
795
|
+
*/
|
|
796
|
+
indexLanesHeld = new Map();
|
|
797
|
+
/** Per conversation, the upload in flight: the baseline until it succeeds or fails. */
|
|
798
|
+
indexLanesPending = new Map();
|
|
777
799
|
/** Once draining begins, no later request may create another log producer. */
|
|
778
800
|
backgroundClosing = false;
|
|
779
801
|
/** drainBackground ran out and is aborting what is left (exit_index_cut, not an error). */
|
|
@@ -867,7 +889,7 @@ export class MemtreeClient {
|
|
|
867
889
|
}
|
|
868
890
|
/** The blocking-compress budget for an upload of `bytes` (COMPRESS_TIMEOUT_MS_PER_KIB). */
|
|
869
891
|
compressBudgetForBytes(bytes) {
|
|
870
|
-
return scaledTimeout(this.compressBudgetMs, bytes);
|
|
892
|
+
return scaledTimeout(this.compressBudgetMs, bytes, this.compressTimeoutMsPerKiB);
|
|
871
893
|
}
|
|
872
894
|
/**
|
|
873
895
|
* When a compress call (not an index-only one) last got a live successful
|
|
@@ -926,6 +948,8 @@ export class MemtreeClient {
|
|
|
926
948
|
this.longCompressTimeoutMs =
|
|
927
949
|
opts.longCompressTimeoutMs ??
|
|
928
950
|
Number(process.env.CCC_COMPRESS_TIMEOUT_MS || DEFAULT_LONG_COMPRESS_TIMEOUT_MS);
|
|
951
|
+
this.indexMinNewChars = opts.indexMinNewChars ?? INDEX_MIN_NEW_CHARS;
|
|
952
|
+
this.compressTimeoutMsPerKiB = opts.compressTimeoutMsPerKiB ?? COMPRESS_TIMEOUT_MS_PER_KIB;
|
|
929
953
|
this.debug = opts.debug ?? false;
|
|
930
954
|
this.reqlog = opts.reqlog;
|
|
931
955
|
this.memtreeTools = opts.memtreeTools || undefined;
|
|
@@ -1087,19 +1111,36 @@ export class MemtreeClient {
|
|
|
1087
1111
|
*/
|
|
1088
1112
|
indexInBackground(hash, messages, modelContextLimit, sessionId, clientMeta,
|
|
1089
1113
|
/** Times for retained original messages, in the positions actually sent. */
|
|
1090
|
-
messageTimesFor
|
|
1114
|
+
messageTimesFor,
|
|
1115
|
+
/**
|
|
1116
|
+
* `force`: send even under INDEX_MIN_NEW_CHARS of new text. `finalIndex` (implies it):
|
|
1117
|
+
* flagged final_index, so the server indexes the tail under its own minimum too; the
|
|
1118
|
+
* server allows one per conversation per 30 minutes, so only at a subagent's end.
|
|
1119
|
+
*/
|
|
1120
|
+
options = {}) {
|
|
1091
1121
|
if (this.backgroundClosing)
|
|
1092
1122
|
return;
|
|
1093
|
-
|
|
1123
|
+
// A final call is its own entry: the same history sent per turn may have left a tail.
|
|
1124
|
+
const final = options.finalIndex === true;
|
|
1125
|
+
const indexKey = JSON.stringify([sessionId ?? null, hash, ...(final ? ["final"] : [])]);
|
|
1094
1126
|
if (this.indexedHashes.has(indexKey))
|
|
1095
1127
|
return;
|
|
1128
|
+
const lane = indexLaneKey(sessionId, messages);
|
|
1129
|
+
const job = { messages, modelContextLimit,
|
|
1130
|
+
opts: { sessionId, clientMeta, messageTimesFor, ...(final ? { finalIndex: true } : {}) } };
|
|
1131
|
+
this.releaseHeldIndex(lane, job);
|
|
1132
|
+
// Held back is not sent: a later (or forced) call of the same history still goes.
|
|
1133
|
+
if (!options.force && !final && this.tooLittleNewText(lane, job)) {
|
|
1134
|
+
this.holdIndex(lane, job);
|
|
1135
|
+
return;
|
|
1136
|
+
}
|
|
1096
1137
|
this.indexedHashes.add(indexKey);
|
|
1097
1138
|
if (this.indexedHashes.size > DEDUPE_CACHE_MAX) {
|
|
1098
1139
|
const first = this.indexedHashes.values().next().value;
|
|
1099
1140
|
if (first !== undefined)
|
|
1100
1141
|
this.indexedHashes.delete(first);
|
|
1101
1142
|
}
|
|
1102
|
-
this.enqueueIndex(
|
|
1143
|
+
this.enqueueIndex(lane, job);
|
|
1103
1144
|
}
|
|
1104
1145
|
/**
|
|
1105
1146
|
* At most one background index call per conversation. Each call carries the whole
|
|
@@ -1107,6 +1148,9 @@ export class MemtreeClient {
|
|
|
1107
1148
|
* session's tool rounds otherwise stacked 25 MB uploads, up to 16 at once, and starved
|
|
1108
1149
|
* the compress calls that share the link (long-session test, staging 2026-10-24). A
|
|
1109
1150
|
* waiting call is replaced only by one whose history extends it; otherwise it goes now.
|
|
1151
|
+
* A call whose history extends the last one sent by less than INDEX_MIN_NEW_CHARS of
|
|
1152
|
+
* text is not sent at all: the server only acknowledges it (2026-10-30: 3 in 4 of a
|
|
1153
|
+
* 23 MB session's index uploads, ~1 GB per 40 minutes).
|
|
1110
1154
|
*/
|
|
1111
1155
|
enqueueIndex(lane, job) {
|
|
1112
1156
|
if (!this.indexLanesBusy.has(lane)) {
|
|
@@ -1114,14 +1158,85 @@ export class MemtreeClient {
|
|
|
1114
1158
|
return;
|
|
1115
1159
|
}
|
|
1116
1160
|
const waiting = this.indexLanesNext.get(lane);
|
|
1117
|
-
|
|
1118
|
-
|
|
1161
|
+
// Not replaced when the new one does not carry it whole: another branch, media Claude
|
|
1162
|
+
// Code evicted since (never uploaded otherwise), or a final call.
|
|
1163
|
+
if (waiting && (!extendsHistory(job.messages, waiting.messages) ||
|
|
1164
|
+
losesMedia(waiting.messages, job.messages) ||
|
|
1165
|
+
(waiting.opts.finalIndex && !job.opts.finalIndex))) {
|
|
1166
|
+
void this.sendLaneIndex(lane, waiting);
|
|
1119
1167
|
}
|
|
1120
1168
|
this.indexLanesNext.set(lane, job);
|
|
1121
1169
|
}
|
|
1170
|
+
/**
|
|
1171
|
+
* Send `job` as its conversation's newest upload: the INDEX_MIN_NEW_CHARS baseline while
|
|
1172
|
+
* it is in flight, and once it succeeded. A failed one is never a baseline, so the next
|
|
1173
|
+
* turn is not held back by an upload the server never got.
|
|
1174
|
+
*/
|
|
1175
|
+
sendLaneIndex(lane, job) {
|
|
1176
|
+
const sent = { messages: job.messages, chars: messagesTextChars(job.messages) };
|
|
1177
|
+
this.indexLanesPending.set(lane, sent);
|
|
1178
|
+
return this.submitIndexOnly(job.messages, job.modelContextLimit, job.opts).then((ok) => {
|
|
1179
|
+
if (this.indexLanesPending.get(lane) === sent)
|
|
1180
|
+
this.indexLanesPending.delete(lane);
|
|
1181
|
+
if (ok)
|
|
1182
|
+
this.noteIndexSent(lane, sent);
|
|
1183
|
+
return ok;
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1186
|
+
/**
|
|
1187
|
+
* Before `job` goes or is held: the lane's held-back history is sent if `job` does not
|
|
1188
|
+
* carry it whole (origin/main sent every turn, so a rewind must not lose a branch), and
|
|
1189
|
+
* dropped otherwise (`job` carries it).
|
|
1190
|
+
*/
|
|
1191
|
+
releaseHeldIndex(lane, job) {
|
|
1192
|
+
const held = this.indexLanesHeld.get(lane);
|
|
1193
|
+
if (!held)
|
|
1194
|
+
return;
|
|
1195
|
+
this.indexLanesHeld.delete(lane);
|
|
1196
|
+
if (!extendsHistory(job.messages, held.messages) || losesMedia(held.messages, job.messages)) {
|
|
1197
|
+
this.enqueueIndex(lane, held);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
holdIndex(lane, job) {
|
|
1201
|
+
this.indexLanesHeld.set(lane, job);
|
|
1202
|
+
if (this.indexLanesHeld.size > DEDUPE_CACHE_MAX) {
|
|
1203
|
+
// Over capacity the oldest held history is sent, not dropped (origin/main sent it).
|
|
1204
|
+
const [first, evicted] = this.indexLanesHeld.entries().next().value;
|
|
1205
|
+
this.indexLanesHeld.delete(first);
|
|
1206
|
+
this.enqueueIndex(first, evicted);
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
/**
|
|
1210
|
+
* Whether `job` adds under INDEX_MIN_NEW_CHARS of text to the history its conversation
|
|
1211
|
+
* last sent (or has waiting to send): the server's index minimum would only ack it.
|
|
1212
|
+
*/
|
|
1213
|
+
tooLittleNewText(lane, job) {
|
|
1214
|
+
// A waiting call is replaced by this one anyway: it is never held back.
|
|
1215
|
+
if (this.indexLanesNext.has(lane))
|
|
1216
|
+
return false;
|
|
1217
|
+
const sent = this.indexLanesPending.get(lane) ?? this.indexLanesSent.get(lane);
|
|
1218
|
+
if (this.indexMinNewChars <= 0 || !sent || !extendsHistory(job.messages, sent.messages)) {
|
|
1219
|
+
return false;
|
|
1220
|
+
}
|
|
1221
|
+
// An image or document carries no text but may be evicted by Claude Code before a
|
|
1222
|
+
// later upload: never held back.
|
|
1223
|
+
if (carriesMedia(job.messages.slice(sent.messages.length)))
|
|
1224
|
+
return false;
|
|
1225
|
+
return messagesTextChars(job.messages) - sent.chars < this.indexMinNewChars;
|
|
1226
|
+
}
|
|
1227
|
+
/** Record the history an index call of `lane` delivered. */
|
|
1228
|
+
noteIndexSent(lane, sent) {
|
|
1229
|
+
this.indexLanesSent.delete(lane);
|
|
1230
|
+
this.indexLanesSent.set(lane, sent);
|
|
1231
|
+
if (this.indexLanesSent.size > DEDUPE_CACHE_MAX) {
|
|
1232
|
+
const first = this.indexLanesSent.keys().next().value;
|
|
1233
|
+
if (first !== undefined)
|
|
1234
|
+
this.indexLanesSent.delete(first);
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1122
1237
|
startLaneIndex(lane, job) {
|
|
1123
1238
|
this.indexLanesBusy.add(lane);
|
|
1124
|
-
void this.
|
|
1239
|
+
void this.sendLaneIndex(lane, job).finally(() => {
|
|
1125
1240
|
this.indexLanesBusy.delete(lane);
|
|
1126
1241
|
const next = this.indexLanesNext.get(lane);
|
|
1127
1242
|
this.indexLanesNext.delete(lane);
|
|
@@ -1135,9 +1250,20 @@ export class MemtreeClient {
|
|
|
1135
1250
|
* the final index carries (a main session's, unless it was rewound since).
|
|
1136
1251
|
*/
|
|
1137
1252
|
sendWaitingIndexes() {
|
|
1253
|
+
// A history held back by the text minimum goes too (origin/main sent every turn),
|
|
1254
|
+
// unless a waiting call or the final index carries it.
|
|
1255
|
+
// A carrier must hold the media too: extendsHistory tolerates media Claude Code evicted,
|
|
1256
|
+
// which no later upload would carry (Codex r1 P0, release 1.0.33).
|
|
1257
|
+
const carries = (carrier, messages) => carrier !== undefined && extendsHistory(carrier, messages) && !losesMedia(messages, carrier);
|
|
1258
|
+
for (const [lane, held] of this.indexLanesHeld) {
|
|
1259
|
+
const carriers = [this.indexLanesNext.get(lane)?.messages, this.finalIndexLanes.get(lane)];
|
|
1260
|
+
if (!carriers.some((messages) => carries(messages, held.messages))) {
|
|
1261
|
+
void this.submitIndexOnly(held.messages, held.modelContextLimit, held.opts);
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
this.indexLanesHeld.clear();
|
|
1138
1265
|
for (const [lane, job] of this.indexLanesNext) {
|
|
1139
|
-
|
|
1140
|
-
if (!final || !extendsHistory(final, job.messages)) {
|
|
1266
|
+
if (!carries(this.finalIndexLanes.get(lane), job.messages)) {
|
|
1141
1267
|
void this.submitIndexOnly(job.messages, job.modelContextLimit, job.opts);
|
|
1142
1268
|
}
|
|
1143
1269
|
}
|
|
@@ -1263,8 +1389,9 @@ export class MemtreeClient {
|
|
|
1263
1389
|
sessionId: opts.sessionId,
|
|
1264
1390
|
clientMeta: opts.clientMeta,
|
|
1265
1391
|
})
|
|
1266
|
-
.then(() =>
|
|
1392
|
+
.then(() => true, (err) => {
|
|
1267
1393
|
this.log(`background indexing failed (ignored): ${err?.message ?? err}`);
|
|
1394
|
+
return false;
|
|
1268
1395
|
})
|
|
1269
1396
|
.finally(() => {
|
|
1270
1397
|
this.backgroundIndexes.delete(operation);
|
|
@@ -1473,14 +1600,15 @@ export class MemtreeClient {
|
|
|
1473
1600
|
// A default compress budget grows with what it uploads; an index call's,
|
|
1474
1601
|
// and any budget a caller set, is fixed.
|
|
1475
1602
|
const timeoutMs = opts.scaleTimeout && !opts.indexOnly
|
|
1476
|
-
? scaledTimeout(opts.timeoutMs, Buffer.byteLength(payload, "utf-8")
|
|
1603
|
+
? scaledTimeout(opts.timeoutMs, Buffer.byteLength(payload, "utf-8"), this.compressTimeoutMsPerKiB)
|
|
1604
|
+
: opts.timeoutMs;
|
|
1477
1605
|
const timeout = setTimeout(abort, timeoutMs);
|
|
1478
1606
|
timeout.unref();
|
|
1479
1607
|
opts.signal?.addEventListener("abort", abort, { once: true });
|
|
1480
1608
|
if (opts.signal?.aborted)
|
|
1481
1609
|
abort();
|
|
1482
1610
|
try {
|
|
1483
|
-
const response = await this.
|
|
1611
|
+
const response = await this.postRetryingDrop(payload, opts, controller.signal);
|
|
1484
1612
|
status = response.status;
|
|
1485
1613
|
if (planned.refs.length && !response.ok) {
|
|
1486
1614
|
refusalText = await readUnlessAborted(response, controller.signal);
|
|
@@ -1590,13 +1718,49 @@ export class MemtreeClient {
|
|
|
1590
1718
|
});
|
|
1591
1719
|
}
|
|
1592
1720
|
}
|
|
1593
|
-
/**
|
|
1594
|
-
|
|
1721
|
+
/**
|
|
1722
|
+
* A compress or prepare call's POST, sent once more (within the same budget) when its
|
|
1723
|
+
* connection dropped while the body was still uploading: a Wi-Fi switch cut a 24 MB
|
|
1724
|
+
* upload with EHOSTUNREACH after 89 s, ~1 MB sent (2026-10-28), and the turn went without
|
|
1725
|
+
* memory. Only before the whole body was handed over: after that MemTree may already be
|
|
1726
|
+
* compressing (and billing) it, and a second call would be a second compression.
|
|
1727
|
+
* Index-only calls are not retried: the next turn sends their history again.
|
|
1728
|
+
*/
|
|
1729
|
+
async postRetryingDrop(payload, opts, signal) {
|
|
1730
|
+
const upload = { done: false };
|
|
1731
|
+
try {
|
|
1732
|
+
return await this.postContextMemory(payload, opts, signal, opts.indexOnly ? undefined : upload);
|
|
1733
|
+
}
|
|
1734
|
+
catch (err) {
|
|
1735
|
+
if (opts.indexOnly || signal.aborted)
|
|
1736
|
+
throw err;
|
|
1737
|
+
// A 401 to a streamed body: fetch reports a network error, not the status. A 401
|
|
1738
|
+
// compresses nothing (nothing billed): sent again whole, its status is seen.
|
|
1739
|
+
if (isStreamedBodyAuthChallenge(err)) {
|
|
1740
|
+
return await this.postContextMemory(payload, opts, signal);
|
|
1741
|
+
}
|
|
1742
|
+
if (upload.done || !isDroppedConnection(err))
|
|
1743
|
+
throw err;
|
|
1744
|
+
this.log(`context_memory upload dropped (${droppedCode(err)}); retrying once`);
|
|
1745
|
+
return await this.postContextMemory(payload, opts, signal);
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
/**
|
|
1749
|
+
* One POST of a MemTree call's body. With `upload`, a body of STREAMED_UPLOAD_MIN_BYTES
|
|
1750
|
+
* or more goes as a stream and `upload.done` turns true once its last byte was handed
|
|
1751
|
+
* over (a smaller one counts as handed over at once).
|
|
1752
|
+
*/
|
|
1753
|
+
postContextMemory(payload, opts, signal, upload) {
|
|
1754
|
+
const bytes = Buffer.from(payload, "utf-8");
|
|
1755
|
+
const streamed = upload !== undefined && bytes.length >= STREAMED_UPLOAD_MIN_BYTES;
|
|
1756
|
+
if (upload && !streamed)
|
|
1757
|
+
upload.done = true;
|
|
1595
1758
|
return fetch(`${this.baseUrl}/v1/context_memory`, {
|
|
1596
1759
|
method: "POST",
|
|
1597
1760
|
headers: {
|
|
1598
1761
|
authorization: `Bearer ${this.apiKey}`,
|
|
1599
1762
|
"content-type": "application/json",
|
|
1763
|
+
...(streamed ? { "content-length": String(bytes.length) } : {}),
|
|
1600
1764
|
"x-client": CLIENT_NAME,
|
|
1601
1765
|
"x-client-version": CLIENT_VERSION,
|
|
1602
1766
|
"x-client-features": CLIENT_FEATURES,
|
|
@@ -1609,7 +1773,8 @@ export class MemtreeClient {
|
|
|
1609
1773
|
? { "x-memtree-tools": this.memtreeTools }
|
|
1610
1774
|
: {}),
|
|
1611
1775
|
},
|
|
1612
|
-
body: payload,
|
|
1776
|
+
body: streamed ? uploadStream(bytes, upload) : payload,
|
|
1777
|
+
...(streamed ? { duplex: "half" } : {}),
|
|
1613
1778
|
signal,
|
|
1614
1779
|
});
|
|
1615
1780
|
}
|
|
@@ -1685,11 +1850,133 @@ export function withFinalReply(messages, reply) {
|
|
|
1685
1850
|
function callerCut(status) {
|
|
1686
1851
|
return status === undefined || (status >= 200 && status < 300);
|
|
1687
1852
|
}
|
|
1853
|
+
/** Connection-level failures a compress call is retried once after (postRetryingDrop). */
|
|
1854
|
+
const DROPPED_CONNECTION_CODES = new Set([
|
|
1855
|
+
"ECONNRESET", "EHOSTUNREACH", "ENETUNREACH", "ENETDOWN", "EPIPE", "ECONNABORTED",
|
|
1856
|
+
"ETIMEDOUT", "EAI_AGAIN", "UND_ERR_SOCKET", "ECONNREFUSED",
|
|
1857
|
+
]);
|
|
1858
|
+
/** Bodies from this size are streamed, so a drop can be told to come before their end. */
|
|
1859
|
+
const STREAMED_UPLOAD_MIN_BYTES = 1024 * 1024;
|
|
1860
|
+
const UPLOAD_CHUNK_BYTES = 256 * 1024;
|
|
1861
|
+
/** undici's message for a 401/407 answer to a body it cannot send again. */
|
|
1862
|
+
const STREAMED_BODY_AUTH_ERROR = /non-null body source/;
|
|
1863
|
+
/** `bytes` as a stream that sets `upload.done` once its last chunk was taken. */
|
|
1864
|
+
function uploadStream(bytes, upload) {
|
|
1865
|
+
let offset = 0;
|
|
1866
|
+
return new ReadableStream({
|
|
1867
|
+
pull(controller) {
|
|
1868
|
+
if (offset >= bytes.length) {
|
|
1869
|
+
upload.done = true;
|
|
1870
|
+
controller.close();
|
|
1871
|
+
return;
|
|
1872
|
+
}
|
|
1873
|
+
const end = Math.min(bytes.length, offset + UPLOAD_CHUNK_BYTES);
|
|
1874
|
+
controller.enqueue(bytes.subarray(offset, end));
|
|
1875
|
+
offset = end;
|
|
1876
|
+
if (offset >= bytes.length)
|
|
1877
|
+
upload.done = true;
|
|
1878
|
+
},
|
|
1879
|
+
});
|
|
1880
|
+
}
|
|
1881
|
+
/** Whether a failed fetch lost its connection (the error's or its cause's code). */
|
|
1882
|
+
export function isDroppedConnection(err) {
|
|
1883
|
+
const code = droppedCode(err);
|
|
1884
|
+
return code !== undefined && DROPPED_CONNECTION_CODES.has(code);
|
|
1885
|
+
}
|
|
1886
|
+
/**
|
|
1887
|
+
* Whether fetch failed a streamed body on a 401 (or 407) answer: the fetch standard turns
|
|
1888
|
+
* those into a network error ("expected non-null body source") when the body cannot be
|
|
1889
|
+
* replayed, so a revoked key would otherwise read as a lost connection.
|
|
1890
|
+
*/
|
|
1891
|
+
function isStreamedBodyAuthChallenge(err) {
|
|
1892
|
+
const cause = err?.cause;
|
|
1893
|
+
return cause?.code === undefined && typeof cause?.message === "string" &&
|
|
1894
|
+
STREAMED_BODY_AUTH_ERROR.test(cause.message);
|
|
1895
|
+
}
|
|
1896
|
+
function droppedCode(err) {
|
|
1897
|
+
const own = err?.code;
|
|
1898
|
+
if (typeof own === "string")
|
|
1899
|
+
return own;
|
|
1900
|
+
const cause = err?.cause?.code;
|
|
1901
|
+
return typeof cause === "string" ? cause : undefined;
|
|
1902
|
+
}
|
|
1903
|
+
/**
|
|
1904
|
+
* The text a history carries, in characters: strings and text blocks, tool inputs and
|
|
1905
|
+
* results; images and documents (base64) count nothing. For INDEX_MIN_NEW_CHARS only.
|
|
1906
|
+
*/
|
|
1907
|
+
export function messagesTextChars(messages) {
|
|
1908
|
+
let chars = 0;
|
|
1909
|
+
for (const message of messages)
|
|
1910
|
+
chars += contentTextChars(message.content);
|
|
1911
|
+
return chars;
|
|
1912
|
+
}
|
|
1913
|
+
/** Whether `messages` hold an image or document block (at any depth). */
|
|
1914
|
+
function carriesMedia(value) {
|
|
1915
|
+
return mediaKeys(value).size > 0;
|
|
1916
|
+
}
|
|
1917
|
+
/**
|
|
1918
|
+
* Whether `older` holds an image or document `newer` does not (Claude Code evicted it):
|
|
1919
|
+
* replacing `older` by `newer` would leave it never uploaded.
|
|
1920
|
+
*/
|
|
1921
|
+
export function losesMedia(older, newer) {
|
|
1922
|
+
const kept = mediaKeys(older);
|
|
1923
|
+
if (kept.size === 0)
|
|
1924
|
+
return false;
|
|
1925
|
+
const now = mediaKeys(newer);
|
|
1926
|
+
for (const key of kept)
|
|
1927
|
+
if (!now.has(key))
|
|
1928
|
+
return true;
|
|
1929
|
+
return false;
|
|
1930
|
+
}
|
|
1931
|
+
/** A digest of each image and document block's source in `value`, at any depth. */
|
|
1932
|
+
function mediaKeys(value, keys = new Set()) {
|
|
1933
|
+
if (Array.isArray(value)) {
|
|
1934
|
+
for (const item of value)
|
|
1935
|
+
mediaKeys(item, keys);
|
|
1936
|
+
return keys;
|
|
1937
|
+
}
|
|
1938
|
+
if (!value || typeof value !== "object")
|
|
1939
|
+
return keys;
|
|
1940
|
+
const block = value;
|
|
1941
|
+
if (block.type === "image" || block.type === "document") {
|
|
1942
|
+
keys.add(createHash("sha256").update(JSON.stringify(block.source ?? block)).digest("hex"));
|
|
1943
|
+
}
|
|
1944
|
+
else if (Array.isArray(block.content)) {
|
|
1945
|
+
mediaKeys(block.content, keys);
|
|
1946
|
+
}
|
|
1947
|
+
return keys;
|
|
1948
|
+
}
|
|
1949
|
+
function contentTextChars(value) {
|
|
1950
|
+
if (typeof value === "string")
|
|
1951
|
+
return value.length;
|
|
1952
|
+
if (Array.isArray(value)) {
|
|
1953
|
+
let chars = 0;
|
|
1954
|
+
for (const item of value)
|
|
1955
|
+
chars += contentTextChars(item);
|
|
1956
|
+
return chars;
|
|
1957
|
+
}
|
|
1958
|
+
if (!value || typeof value !== "object")
|
|
1959
|
+
return 0;
|
|
1960
|
+
const block = value;
|
|
1961
|
+
if (block.type === "image" || block.type === "document")
|
|
1962
|
+
return 0;
|
|
1963
|
+
if (typeof block.text === "string")
|
|
1964
|
+
return block.text.length;
|
|
1965
|
+
if (typeof block.thinking === "string")
|
|
1966
|
+
return block.thinking.length;
|
|
1967
|
+
if (block.content !== undefined)
|
|
1968
|
+
return contentTextChars(block.content);
|
|
1969
|
+
if (block.input !== undefined)
|
|
1970
|
+
return JSON.stringify(block.input)?.length ?? 0;
|
|
1971
|
+
return 0;
|
|
1972
|
+
}
|
|
1688
1973
|
/** `baseMs` plus COMPRESS_TIMEOUT_MS_PER_KIB per KiB of `bytes`. */
|
|
1689
|
-
function scaledTimeout(baseMs, bytes) {
|
|
1974
|
+
function scaledTimeout(baseMs, bytes, perKiB) {
|
|
1690
1975
|
if (!Number.isFinite(baseMs))
|
|
1691
1976
|
return baseMs;
|
|
1692
|
-
|
|
1977
|
+
// Whole milliseconds: timers truncate a fractional delay, and a call that ran its whole
|
|
1978
|
+
// budget must not measure as shorter than it (the proxy's timedOut check).
|
|
1979
|
+
return baseMs + Math.ceil(Math.ceil(Math.max(0, bytes) / 1024) * perKiB);
|
|
1693
1980
|
}
|
|
1694
1981
|
/**
|
|
1695
1982
|
* One conversation for background indexing: its session and its first message after the
|