opencode-acp 1.18.4-pr.483.216 → 1.18.4-pr.484.217
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 +6 -0
- package/README.zh-CN.md +5 -0
- package/dist/index.js +67 -51
- package/dist/index.js.map +1 -1
- package/dist/lib/config-validation.d.ts.map +1 -1
- package/dist/lib/config.d.ts +11 -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 +1 -2
- package/dist/lib/messages/index.d.ts.map +1 -1
- package/dist/lib/messages/reasoning-strip.d.ts +41 -0
- package/dist/lib/messages/reasoning-strip.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/README.md
CHANGED
|
@@ -431,9 +431,15 @@ Each level overrides the previous, so project settings take priority over global
|
|
|
431
431
|
// compression, so their thinking rides along every request as an
|
|
432
432
|
// unreclaimable floor. Closed turns only; the active round is never
|
|
433
433
|
// touched. Small thinkings under the threshold are kept.
|
|
434
|
+
// [#482] Pin the wire form of historical thinking: fold each assistant
|
|
435
|
+
// message's reasoning parts into one <thinking>-marked text part at
|
|
436
|
+
// request time, so serialized bytes stay deterministic across host
|
|
437
|
+
// metadata-table refreshes. On by default; set normalize:false for
|
|
438
|
+
// direct providers needing structured thinking replay.
|
|
434
439
|
"reasoning": {
|
|
435
440
|
"drop": true,
|
|
436
441
|
"threshold": 2048,
|
|
442
|
+
"normalize": true
|
|
437
443
|
},
|
|
438
444
|
// [#478] Image archive: spill data-URL images to disk when they enter
|
|
439
445
|
// the session so folded ranges keep re-readable pointers instead of
|
package/README.zh-CN.md
CHANGED
|
@@ -376,9 +376,14 @@ ACP 使用自己的配置文件,按以下顺序搜索:
|
|
|
376
376
|
// compress 调用被硬排除在压缩之外,其思考内容会随每次请求原样重发,
|
|
377
377
|
// 形成无法回收的上下文底座。仅作用于已关闭的轮次,活跃轮永不触碰;
|
|
378
378
|
// 低于阈值的小思考保留。
|
|
379
|
+
// [#482] 钉死历史思考的 wire 形态:请求时把每个 assistant 消息的
|
|
380
|
+
// reasoning 部分折叠为一个带 <thinking> 标记的 text 部分,使序列化字节
|
|
381
|
+
// 在宿主元数据表刷新后保持确定。默认开启;直连需要结构化 thinking
|
|
382
|
+
// 回放的 provider 设 normalize:false。
|
|
379
383
|
"reasoning": {
|
|
380
384
|
"drop": true,
|
|
381
385
|
"threshold": 2048,
|
|
386
|
+
"normalize": true
|
|
382
387
|
},
|
|
383
388
|
// [#478] 图片归档:图片(data-URL)进入会话时即落盘,折叠后摘要里保留
|
|
384
389
|
// 可重读的路径指针,而不是把像素悄悄丢掉。文件落在
|
package/dist/index.js
CHANGED
|
@@ -916,6 +916,7 @@ var VALID_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
|
916
916
|
"compress.reasoning",
|
|
917
917
|
"compress.reasoning.drop",
|
|
918
918
|
"compress.reasoning.threshold",
|
|
919
|
+
"compress.reasoning.normalize",
|
|
919
920
|
"compress.images",
|
|
920
921
|
"compress.images.enabled",
|
|
921
922
|
"compress.images.minBytes",
|
|
@@ -1292,7 +1293,7 @@ function validateConfigTypes(config) {
|
|
|
1292
1293
|
if (typeof compress.reasoning !== "object" || compress.reasoning === null || Array.isArray(compress.reasoning)) {
|
|
1293
1294
|
errors.push({
|
|
1294
1295
|
key: "compress.reasoning",
|
|
1295
|
-
expected: "object { drop?: boolean; threshold?: integer (>= 0) }",
|
|
1296
|
+
expected: "object { drop?: boolean; threshold?: integer (>= 0); normalize?: boolean }",
|
|
1296
1297
|
actual: JSON.stringify(compress.reasoning)
|
|
1297
1298
|
});
|
|
1298
1299
|
} else {
|
|
@@ -1310,6 +1311,13 @@ function validateConfigTypes(config) {
|
|
|
1310
1311
|
actual: JSON.stringify(compress.reasoning.threshold)
|
|
1311
1312
|
});
|
|
1312
1313
|
}
|
|
1314
|
+
if (compress.reasoning.normalize !== void 0 && typeof compress.reasoning.normalize !== "boolean") {
|
|
1315
|
+
errors.push({
|
|
1316
|
+
key: "compress.reasoning.normalize",
|
|
1317
|
+
expected: "boolean",
|
|
1318
|
+
actual: typeof compress.reasoning.normalize
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1313
1321
|
}
|
|
1314
1322
|
}
|
|
1315
1323
|
if (compress.images !== void 0) {
|
|
@@ -1496,7 +1504,7 @@ function validateConfigTypes(config) {
|
|
|
1496
1504
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
1497
1505
|
errors.push({
|
|
1498
1506
|
key,
|
|
1499
|
-
expected: "object { drop?: boolean; threshold?: integer (>= 0) }",
|
|
1507
|
+
expected: "object { drop?: boolean; threshold?: integer (>= 0); normalize?: boolean }",
|
|
1500
1508
|
actual: JSON.stringify(value)
|
|
1501
1509
|
});
|
|
1502
1510
|
break;
|
|
@@ -1516,6 +1524,13 @@ function validateConfigTypes(config) {
|
|
|
1516
1524
|
actual: JSON.stringify(reasoning.threshold)
|
|
1517
1525
|
});
|
|
1518
1526
|
}
|
|
1527
|
+
if (reasoning.normalize !== void 0 && typeof reasoning.normalize !== "boolean") {
|
|
1528
|
+
errors.push({
|
|
1529
|
+
key: `${key}.normalize`,
|
|
1530
|
+
expected: "boolean",
|
|
1531
|
+
actual: typeof reasoning.normalize
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1519
1534
|
break;
|
|
1520
1535
|
}
|
|
1521
1536
|
};
|
|
@@ -1976,6 +1991,7 @@ function mergeCompress(base, override) {
|
|
|
1976
1991
|
if (!override) {
|
|
1977
1992
|
return base;
|
|
1978
1993
|
}
|
|
1994
|
+
const normalizeResolved = override.reasoning?.normalize ?? base.reasoning?.normalize;
|
|
1979
1995
|
return {
|
|
1980
1996
|
permission: override.permission ?? base.permission,
|
|
1981
1997
|
showCompression: override.showCompression ?? base.showCompression,
|
|
@@ -2010,7 +2026,8 @@ function mergeCompress(base, override) {
|
|
|
2010
2026
|
preserveLastUserMessage: override.preserveLastUserMessage ?? base.preserveLastUserMessage,
|
|
2011
2027
|
reasoning: {
|
|
2012
2028
|
drop: override.reasoning?.drop ?? base.reasoning?.drop ?? DEFAULT_COMPRESS_REASONING.drop,
|
|
2013
|
-
threshold: override.reasoning?.threshold ?? base.reasoning?.threshold ?? DEFAULT_COMPRESS_REASONING.threshold
|
|
2029
|
+
threshold: override.reasoning?.threshold ?? base.reasoning?.threshold ?? DEFAULT_COMPRESS_REASONING.threshold,
|
|
2030
|
+
...normalizeResolved !== void 0 ? { normalize: normalizeResolved } : {}
|
|
2014
2031
|
},
|
|
2015
2032
|
images: {
|
|
2016
2033
|
enabled: override.images?.enabled ?? base.images?.enabled ?? DEFAULT_COMPRESS_IMAGES.enabled,
|
|
@@ -9884,6 +9901,8 @@ var injectMessageIds = (state, config, messages, compressionPriorities) => {
|
|
|
9884
9901
|
};
|
|
9885
9902
|
|
|
9886
9903
|
// lib/messages/reasoning-strip.ts
|
|
9904
|
+
var isReasoningWithText = (part) => part.type === "reasoning" && typeof part.text === "string";
|
|
9905
|
+
var isTextWithText = (part) => part.type === "text" && typeof part.text === "string";
|
|
9887
9906
|
function stripStaleMetadata(messages) {
|
|
9888
9907
|
const lastUserMessage = getLastUserMessage(messages);
|
|
9889
9908
|
if (lastUserMessage?.info.role !== "user") {
|
|
@@ -9952,62 +9971,57 @@ function dropCompressReasoning(messages, threshold) {
|
|
|
9952
9971
|
}
|
|
9953
9972
|
return removed;
|
|
9954
9973
|
}
|
|
9955
|
-
|
|
9956
|
-
// lib/messages/reasoning-canonicalize.ts
|
|
9957
|
-
var CANONICAL_OPEN = "<thinking>\n";
|
|
9958
|
-
var CANONICAL_CLOSE = "\n</thinking>";
|
|
9959
|
-
function canonicalizeReasoningShape(messages) {
|
|
9974
|
+
function normalizeThinkingForm(messages) {
|
|
9960
9975
|
let normalized = 0;
|
|
9961
9976
|
for (const message of messages) {
|
|
9962
9977
|
if (!message || message.info.role !== "assistant") {
|
|
9963
9978
|
continue;
|
|
9964
9979
|
}
|
|
9965
9980
|
const parts = Array.isArray(message.parts) ? message.parts : [];
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
if (part.type === "reasoning") {
|
|
9969
|
-
allReasoning += part.text;
|
|
9970
|
-
}
|
|
9971
|
-
}
|
|
9972
|
-
if (allReasoning.length === 0) {
|
|
9981
|
+
const reasoningParts = parts.filter(isReasoningWithText);
|
|
9982
|
+
if (reasoningParts.length === 0) {
|
|
9973
9983
|
continue;
|
|
9974
9984
|
}
|
|
9975
|
-
|
|
9985
|
+
const R = reasoningParts.map((part) => part.text).join("");
|
|
9986
|
+
const textParts = parts.filter(isTextWithText);
|
|
9987
|
+
const T = textParts.map((part) => part.text).join("");
|
|
9988
|
+
const mergedText = `<thinking>
|
|
9989
|
+
${R}
|
|
9990
|
+
</thinking>` + (T.length > 0 ? `
|
|
9991
|
+
${T}` : "");
|
|
9992
|
+
const donor = textParts[0];
|
|
9993
|
+
const newParts = [];
|
|
9994
|
+
let inserted = false;
|
|
9976
9995
|
for (const part of parts) {
|
|
9977
|
-
if (part.type === "text") {
|
|
9978
|
-
|
|
9996
|
+
if (part.type === "reasoning" || part.type === "text") {
|
|
9997
|
+
if (!inserted) {
|
|
9998
|
+
if (donor) {
|
|
9999
|
+
newParts.push({ ...donor, text: mergedText });
|
|
10000
|
+
} else {
|
|
10001
|
+
newParts.push({
|
|
10002
|
+
id: `${message.info.id}-acp-think`,
|
|
10003
|
+
sessionID: message.info.sessionID,
|
|
10004
|
+
messageID: message.info.id,
|
|
10005
|
+
type: "text",
|
|
10006
|
+
text: mergedText
|
|
10007
|
+
});
|
|
10008
|
+
}
|
|
10009
|
+
inserted = true;
|
|
10010
|
+
}
|
|
10011
|
+
continue;
|
|
9979
10012
|
}
|
|
10013
|
+
newParts.push(part);
|
|
9980
10014
|
}
|
|
9981
|
-
|
|
9982
|
-
|
|
9983
|
-
|
|
9984
|
-
let placed = false;
|
|
9985
|
-
const placeMerged = (carrier) => {
|
|
9986
|
-
if (placed) {
|
|
9987
|
-
return;
|
|
9988
|
-
}
|
|
9989
|
-
placed = true;
|
|
9990
|
-
const part = {
|
|
9991
|
-
id: carrier.id,
|
|
10015
|
+
if (!inserted) {
|
|
10016
|
+
newParts.unshift({
|
|
10017
|
+
id: `${message.info.id}-acp-think`,
|
|
9992
10018
|
sessionID: message.info.sessionID,
|
|
9993
10019
|
messageID: message.info.id,
|
|
9994
10020
|
type: "text",
|
|
9995
|
-
text:
|
|
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);
|
|
10021
|
+
text: mergedText
|
|
10022
|
+
});
|
|
10009
10023
|
}
|
|
10010
|
-
message.parts =
|
|
10024
|
+
message.parts = newParts;
|
|
10011
10025
|
normalized++;
|
|
10012
10026
|
}
|
|
10013
10027
|
return normalized;
|
|
@@ -11389,7 +11403,7 @@ import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
|
11389
11403
|
import { join as join5 } from "path";
|
|
11390
11404
|
import { existsSync as existsSync5 } from "fs";
|
|
11391
11405
|
import { homedir as homedir3 } from "os";
|
|
11392
|
-
var LOG_VERSION = true ? "1.18.4-pr.
|
|
11406
|
+
var LOG_VERSION = true ? "1.18.4-pr.484.217" : "dev";
|
|
11393
11407
|
var LEVEL_RANK = {
|
|
11394
11408
|
debug: 10,
|
|
11395
11409
|
info: 20,
|
|
@@ -13588,11 +13602,13 @@ function createChatMessageTransformHandler(client, registry4, logger, config, pr
|
|
|
13588
13602
|
});
|
|
13589
13603
|
}
|
|
13590
13604
|
}
|
|
13591
|
-
|
|
13592
|
-
|
|
13593
|
-
|
|
13594
|
-
|
|
13595
|
-
|
|
13605
|
+
if (reasoningConfig?.normalize !== false) {
|
|
13606
|
+
const normalizedThinking = normalizeThinkingForm(output.messages);
|
|
13607
|
+
if (normalizedThinking > 0) {
|
|
13608
|
+
logger.debug("compress.reasoning: pinned thinking wire form", {
|
|
13609
|
+
normalizedMessages: normalizedThinking
|
|
13610
|
+
});
|
|
13611
|
+
}
|
|
13596
13612
|
}
|
|
13597
13613
|
ensureBuiltinFiltersRegistered();
|
|
13598
13614
|
const effectiveLimit = resolveEffectiveContextLimit(state, config);
|
|
@@ -14105,7 +14121,7 @@ var server = (async (ctx) => {
|
|
|
14105
14121
|
}
|
|
14106
14122
|
const logger = new Logger(config.debug, config.debug ? "debug" : config.logLevel);
|
|
14107
14123
|
logger.info("ACP plugin initialized", {
|
|
14108
|
-
version: true ? "1.18.4-pr.
|
|
14124
|
+
version: true ? "1.18.4-pr.484.217" : "dev",
|
|
14109
14125
|
workspace: ctx.directory,
|
|
14110
14126
|
logLevel: logger.level,
|
|
14111
14127
|
debug: config.debug,
|