opencode-acp 1.18.4-pr.483.218 → 1.18.4-pr.486.219
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/index.js +104 -78
- package/dist/index.js.map +1 -1
- package/dist/lib/config-validation.d.ts.map +1 -1
- package/dist/lib/config.d.ts +13 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/messages/index.d.ts +0 -1
- package/dist/lib/messages/index.d.ts.map +1 -1
- package/dist/lib/messages/sticky-truncation.d.ts +35 -0
- package/dist/lib/messages/sticky-truncation.d.ts.map +1 -0
- package/dist/lib/state/persistence.d.ts +2 -0
- package/dist/lib/state/persistence.d.ts.map +1 -1
- package/dist/lib/state/state.d.ts.map +1 -1
- package/dist/lib/state/types.d.ts +10 -0
- package/dist/lib/state/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/lib/messages/reasoning-canonicalize.d.ts +0 -37
- package/dist/lib/messages/reasoning-canonicalize.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -921,6 +921,7 @@ var VALID_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
|
921
921
|
"compress.images.minBytes",
|
|
922
922
|
"compress.images.ttlDays",
|
|
923
923
|
"compress.completionReserveTokens",
|
|
924
|
+
"compress.emergencyTruncation",
|
|
924
925
|
"gc",
|
|
925
926
|
"gc.algorithm",
|
|
926
927
|
"gc.promotionThreshold",
|
|
@@ -1350,6 +1351,13 @@ function validateConfigTypes(config) {
|
|
|
1350
1351
|
actual: typeof compress.completionReserveTokens
|
|
1351
1352
|
});
|
|
1352
1353
|
}
|
|
1354
|
+
if (compress.emergencyTruncation !== void 0 && typeof compress.emergencyTruncation !== "boolean") {
|
|
1355
|
+
errors.push({
|
|
1356
|
+
key: "compress.emergencyTruncation",
|
|
1357
|
+
expected: "boolean",
|
|
1358
|
+
actual: typeof compress.emergencyTruncation
|
|
1359
|
+
});
|
|
1360
|
+
}
|
|
1353
1361
|
if (typeof compress.completionReserveTokens === "number" && compress.completionReserveTokens < 0) {
|
|
1354
1362
|
errors.push({
|
|
1355
1363
|
key: "compress.completionReserveTokens",
|
|
@@ -1422,6 +1430,7 @@ function validateConfigTypes(config) {
|
|
|
1422
1430
|
const OVERRIDE_FIELD_TYPES = {
|
|
1423
1431
|
showCompression: "boolean",
|
|
1424
1432
|
summaryBuffer: "boolean",
|
|
1433
|
+
emergencyTruncation: "boolean",
|
|
1425
1434
|
protectTags: "boolean",
|
|
1426
1435
|
protectUserMessages: "boolean",
|
|
1427
1436
|
lastSegmentSoftBlock: "boolean",
|
|
@@ -1809,6 +1818,7 @@ var defaultConfig = {
|
|
|
1809
1818
|
permission: "allow",
|
|
1810
1819
|
showCompression: true,
|
|
1811
1820
|
summaryBuffer: true,
|
|
1821
|
+
emergencyTruncation: false,
|
|
1812
1822
|
candidates: false,
|
|
1813
1823
|
maxContextLimit: "80%",
|
|
1814
1824
|
minContextLimit: "80%",
|
|
@@ -2017,7 +2027,8 @@ function mergeCompress(base, override) {
|
|
|
2017
2027
|
minBytes: override.images?.minBytes ?? base.images?.minBytes ?? DEFAULT_COMPRESS_IMAGES.minBytes,
|
|
2018
2028
|
ttlDays: override.images?.ttlDays ?? base.images?.ttlDays ?? DEFAULT_COMPRESS_IMAGES.ttlDays
|
|
2019
2029
|
},
|
|
2020
|
-
completionReserveTokens: override.completionReserveTokens ?? base.completionReserveTokens
|
|
2030
|
+
completionReserveTokens: override.completionReserveTokens ?? base.completionReserveTokens,
|
|
2031
|
+
emergencyTruncation: override.emergencyTruncation ?? base.emergencyTruncation
|
|
2021
2032
|
};
|
|
2022
2033
|
}
|
|
2023
2034
|
function mergeCommands(base, override) {
|
|
@@ -2955,7 +2966,8 @@ function saveSessionState(sessionState, logger, sessionName) {
|
|
|
2955
2966
|
modelContextLimit: sessionState.modelContextLimit,
|
|
2956
2967
|
modelProviderID: sessionState.modelProviderID,
|
|
2957
2968
|
modelID: sessionState.modelID,
|
|
2958
|
-
imageArchive: sessionState.imageArchive
|
|
2969
|
+
imageArchive: sessionState.imageArchive,
|
|
2970
|
+
stickyTruncations: sessionState.stickyTruncations
|
|
2959
2971
|
};
|
|
2960
2972
|
const key = saveQueueKey(sessionState.sessionId, sessionState.storageDir);
|
|
2961
2973
|
let queue = saveQueues.get(key);
|
|
@@ -5124,7 +5136,8 @@ function createSessionState() {
|
|
|
5124
5136
|
qualityGateRetryPending: false,
|
|
5125
5137
|
noContextLimitWarned: false,
|
|
5126
5138
|
imageArchive: {},
|
|
5127
|
-
imagePruneDone: false
|
|
5139
|
+
imagePruneDone: false,
|
|
5140
|
+
stickyTruncations: {}
|
|
5128
5141
|
};
|
|
5129
5142
|
}
|
|
5130
5143
|
function resetSessionState(state) {
|
|
@@ -5170,6 +5183,7 @@ function resetSessionState(state) {
|
|
|
5170
5183
|
state.noContextLimitWarned = false;
|
|
5171
5184
|
state.imageArchive = {};
|
|
5172
5185
|
state.imagePruneDone = false;
|
|
5186
|
+
state.stickyTruncations = {};
|
|
5173
5187
|
}
|
|
5174
5188
|
async function ensureSessionInitialized(client, state, sessionId, logger, messages, config, projectDir) {
|
|
5175
5189
|
if (state.sessionId === sessionId) {
|
|
@@ -5263,6 +5277,14 @@ async function ensureSessionInitialized(client, state, sessionId, logger, messag
|
|
|
5263
5277
|
}
|
|
5264
5278
|
}
|
|
5265
5279
|
}
|
|
5280
|
+
const persistedSticky = persisted.stickyTruncations;
|
|
5281
|
+
if (persistedSticky && typeof persistedSticky === "object") {
|
|
5282
|
+
for (const [callID, output] of Object.entries(persistedSticky)) {
|
|
5283
|
+
if (typeof output === "string") {
|
|
5284
|
+
state.stickyTruncations[callID] = output;
|
|
5285
|
+
}
|
|
5286
|
+
}
|
|
5287
|
+
}
|
|
5266
5288
|
const persistedAny = persisted;
|
|
5267
5289
|
if (persistedAny._persistedMessageIds) {
|
|
5268
5290
|
state.messageIds = {
|
|
@@ -9953,66 +9975,6 @@ function dropCompressReasoning(messages, threshold) {
|
|
|
9953
9975
|
return removed;
|
|
9954
9976
|
}
|
|
9955
9977
|
|
|
9956
|
-
// lib/messages/reasoning-canonicalize.ts
|
|
9957
|
-
var CANONICAL_OPEN = "<thinking>\n";
|
|
9958
|
-
var CANONICAL_CLOSE = "\n</thinking>";
|
|
9959
|
-
function canonicalizeReasoningShape(messages) {
|
|
9960
|
-
let normalized = 0;
|
|
9961
|
-
for (const message of messages) {
|
|
9962
|
-
if (!message || message.info.role !== "assistant") {
|
|
9963
|
-
continue;
|
|
9964
|
-
}
|
|
9965
|
-
const parts = Array.isArray(message.parts) ? message.parts : [];
|
|
9966
|
-
let allReasoning = "";
|
|
9967
|
-
for (const part of parts) {
|
|
9968
|
-
if (part.type === "reasoning") {
|
|
9969
|
-
allReasoning += part.text;
|
|
9970
|
-
}
|
|
9971
|
-
}
|
|
9972
|
-
if (allReasoning.length === 0) {
|
|
9973
|
-
continue;
|
|
9974
|
-
}
|
|
9975
|
-
let allText = "";
|
|
9976
|
-
for (const part of parts) {
|
|
9977
|
-
if (part.type === "text") {
|
|
9978
|
-
allText += part.text;
|
|
9979
|
-
}
|
|
9980
|
-
}
|
|
9981
|
-
const merged = allText.length > 0 ? `${CANONICAL_OPEN}${allReasoning}${CANONICAL_CLOSE}
|
|
9982
|
-
${allText}` : `${CANONICAL_OPEN}${allReasoning}${CANONICAL_CLOSE}`;
|
|
9983
|
-
const rebuilt = [];
|
|
9984
|
-
let placed = false;
|
|
9985
|
-
const placeMerged = (carrier) => {
|
|
9986
|
-
if (placed) {
|
|
9987
|
-
return;
|
|
9988
|
-
}
|
|
9989
|
-
placed = true;
|
|
9990
|
-
const part = {
|
|
9991
|
-
id: carrier.id,
|
|
9992
|
-
sessionID: message.info.sessionID,
|
|
9993
|
-
messageID: message.info.id,
|
|
9994
|
-
type: "text",
|
|
9995
|
-
text: merged
|
|
9996
|
-
};
|
|
9997
|
-
rebuilt.push(part);
|
|
9998
|
-
};
|
|
9999
|
-
for (const part of parts) {
|
|
10000
|
-
if (part.type === "reasoning") {
|
|
10001
|
-
placeMerged(part);
|
|
10002
|
-
continue;
|
|
10003
|
-
}
|
|
10004
|
-
if (part.type === "text") {
|
|
10005
|
-
placeMerged(part);
|
|
10006
|
-
continue;
|
|
10007
|
-
}
|
|
10008
|
-
rebuilt.push(part);
|
|
10009
|
-
}
|
|
10010
|
-
message.parts = rebuilt;
|
|
10011
|
-
normalized++;
|
|
10012
|
-
}
|
|
10013
|
-
return normalized;
|
|
10014
|
-
}
|
|
10015
|
-
|
|
10016
9978
|
// lib/messages/priority.ts
|
|
10017
9979
|
function buildPriorityMap(_config, _state, _messages) {
|
|
10018
9980
|
return /* @__PURE__ */ new Map();
|
|
@@ -11389,7 +11351,7 @@ import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
|
11389
11351
|
import { join as join5 } from "path";
|
|
11390
11352
|
import { existsSync as existsSync5 } from "fs";
|
|
11391
11353
|
import { homedir as homedir3 } from "os";
|
|
11392
|
-
var LOG_VERSION = true ? "1.18.4-pr.
|
|
11354
|
+
var LOG_VERSION = true ? "1.18.4-pr.486.219" : "dev";
|
|
11393
11355
|
var LEVEL_RANK = {
|
|
11394
11356
|
debug: 10,
|
|
11395
11357
|
info: 20,
|
|
@@ -12284,6 +12246,71 @@ function truncateLargeToolOutputs(state, config, logger, messages) {
|
|
|
12284
12246
|
}
|
|
12285
12247
|
}
|
|
12286
12248
|
|
|
12249
|
+
// lib/messages/sticky-truncation.ts
|
|
12250
|
+
function collectToolParts(messages) {
|
|
12251
|
+
const parts = [];
|
|
12252
|
+
for (const message of messages) {
|
|
12253
|
+
const messageParts = Array.isArray(message.parts) ? message.parts : [];
|
|
12254
|
+
for (const part of messageParts) {
|
|
12255
|
+
if (part?.type === "tool") {
|
|
12256
|
+
parts.push(part);
|
|
12257
|
+
}
|
|
12258
|
+
}
|
|
12259
|
+
}
|
|
12260
|
+
return parts;
|
|
12261
|
+
}
|
|
12262
|
+
function applyStickyTruncations(state, messages, logger) {
|
|
12263
|
+
const frozen = state.stickyTruncations;
|
|
12264
|
+
if (Object.keys(frozen).length === 0) return;
|
|
12265
|
+
let replayed = 0;
|
|
12266
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12267
|
+
for (const part of collectToolParts(messages)) {
|
|
12268
|
+
const callID = typeof part.callID === "string" ? part.callID : void 0;
|
|
12269
|
+
if (!callID) continue;
|
|
12270
|
+
seen.add(callID);
|
|
12271
|
+
const recorded = frozen[callID];
|
|
12272
|
+
if (recorded === void 0) continue;
|
|
12273
|
+
if (typeof part.state?.output !== "string" || part.state.output === recorded) continue;
|
|
12274
|
+
part.state.output = recorded;
|
|
12275
|
+
replayed++;
|
|
12276
|
+
}
|
|
12277
|
+
for (const callID of Object.keys(frozen)) {
|
|
12278
|
+
if (!seen.has(callID)) delete frozen[callID];
|
|
12279
|
+
}
|
|
12280
|
+
if (replayed > 0) {
|
|
12281
|
+
logger.debug("Sticky truncation: replayed frozen tool outputs", {
|
|
12282
|
+
replayed,
|
|
12283
|
+
frozen: Object.keys(frozen).length
|
|
12284
|
+
});
|
|
12285
|
+
}
|
|
12286
|
+
}
|
|
12287
|
+
function snapshotToolOutputs(messages) {
|
|
12288
|
+
const snapshot = /* @__PURE__ */ new Map();
|
|
12289
|
+
for (const part of collectToolParts(messages)) {
|
|
12290
|
+
const callID = typeof part.callID === "string" ? part.callID : void 0;
|
|
12291
|
+
if (!callID) continue;
|
|
12292
|
+
if (typeof part.state?.output !== "string") continue;
|
|
12293
|
+
snapshot.set(callID, part.state.output);
|
|
12294
|
+
}
|
|
12295
|
+
return snapshot;
|
|
12296
|
+
}
|
|
12297
|
+
function recordStickyTruncations(state, messages, before, logger) {
|
|
12298
|
+
let recorded = 0;
|
|
12299
|
+
for (const part of collectToolParts(messages)) {
|
|
12300
|
+
const callID = typeof part.callID === "string" ? part.callID : void 0;
|
|
12301
|
+
if (!callID) continue;
|
|
12302
|
+
if (typeof part.state?.output !== "string") continue;
|
|
12303
|
+
const prior = before.get(callID);
|
|
12304
|
+
if (prior === void 0 || prior === part.state.output) continue;
|
|
12305
|
+
if (state.stickyTruncations[callID] === part.state.output) continue;
|
|
12306
|
+
state.stickyTruncations[callID] = part.state.output;
|
|
12307
|
+
recorded++;
|
|
12308
|
+
}
|
|
12309
|
+
if (recorded > 0) {
|
|
12310
|
+
logger.info("Sticky truncation: froze truncated tool outputs", { recorded });
|
|
12311
|
+
}
|
|
12312
|
+
}
|
|
12313
|
+
|
|
12287
12314
|
// lib/messages/enforce-budget.ts
|
|
12288
12315
|
var DEFAULT_COMPLETION_RESERVE_TOKENS = 32768;
|
|
12289
12316
|
var TRUNCATION_MARKER2 = "[truncated for context space";
|
|
@@ -13588,12 +13615,6 @@ function createChatMessageTransformHandler(client, registry4, logger, config, pr
|
|
|
13588
13615
|
});
|
|
13589
13616
|
}
|
|
13590
13617
|
}
|
|
13591
|
-
const canonicalizedReasoning = canonicalizeReasoningShape(output.messages);
|
|
13592
|
-
if (canonicalizedReasoning > 0) {
|
|
13593
|
-
logger.debug("reasoning-canonicalize: pinned historical thinking shape", {
|
|
13594
|
-
messages: canonicalizedReasoning
|
|
13595
|
-
});
|
|
13596
|
-
}
|
|
13597
13618
|
ensureBuiltinFiltersRegistered();
|
|
13598
13619
|
const effectiveLimit = resolveEffectiveContextLimit(state, config);
|
|
13599
13620
|
applyMessageFilters(output.messages, config.messageFilters, logger, {
|
|
@@ -13660,13 +13681,18 @@ ${text}`);
|
|
|
13660
13681
|
prePruneTokens,
|
|
13661
13682
|
candidateMessages
|
|
13662
13683
|
);
|
|
13663
|
-
|
|
13664
|
-
state,
|
|
13665
|
-
|
|
13666
|
-
|
|
13667
|
-
|
|
13668
|
-
|
|
13669
|
-
|
|
13684
|
+
if (config.compress?.emergencyTruncation === true) {
|
|
13685
|
+
applyStickyTruncations(state, output.messages, logger);
|
|
13686
|
+
const toolOutputsBefore = snapshotToolOutputs(output.messages);
|
|
13687
|
+
truncateLargeToolOutputs(
|
|
13688
|
+
state,
|
|
13689
|
+
config,
|
|
13690
|
+
logger,
|
|
13691
|
+
output.messages.filter((message) => !isSyntheticMessage(message))
|
|
13692
|
+
);
|
|
13693
|
+
enforceContextBudget(state, config, logger, output.messages);
|
|
13694
|
+
recordStickyTruncations(state, output.messages, toolOutputsBefore, logger);
|
|
13695
|
+
}
|
|
13670
13696
|
injectMessageIds(state, config, output.messages, compressionPriorities);
|
|
13671
13697
|
hideFailedCompressCalls(output.messages);
|
|
13672
13698
|
stripStaleMetadata(output.messages);
|
|
@@ -14105,7 +14131,7 @@ var server = (async (ctx) => {
|
|
|
14105
14131
|
}
|
|
14106
14132
|
const logger = new Logger(config.debug, config.debug ? "debug" : config.logLevel);
|
|
14107
14133
|
logger.info("ACP plugin initialized", {
|
|
14108
|
-
version: true ? "1.18.4-pr.
|
|
14134
|
+
version: true ? "1.18.4-pr.486.219" : "dev",
|
|
14109
14135
|
workspace: ctx.directory,
|
|
14110
14136
|
logLevel: logger.level,
|
|
14111
14137
|
debug: config.debug,
|