opencode-acp 1.14.27 → 1.15.0-pr.378.113

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 CHANGED
@@ -381,6 +381,15 @@ Each level overrides the previous, so project settings take priority over global
381
381
  // Preserve your messages during compression.
382
382
  // Warning: large copy-pasted prompts will never be compressed away
383
383
  "protectUserMessages": false,
384
+ // [#368] Drop oversized reasoning (thinking) from historical compress
385
+ // tool calls at request time. compress calls are hard-exempt from
386
+ // compression, so their thinking rides along every request as an
387
+ // unreclaimable floor. Closed turns only; the active round is never
388
+ // touched. Small thinkings under the threshold are kept.
389
+ "reasoning": {
390
+ "drop": true,
391
+ "threshold": 2048
392
+ },
384
393
  },
385
394
  // Garbage collection — hardcoded 100% fallback only
386
395
  "gc": {
package/README.zh-CN.md CHANGED
@@ -334,6 +334,14 @@ ACP 使用自己的配置文件,按以下顺序搜索:
334
334
  // Preserve your messages during compression.
335
335
  // Warning: large copy-pasted prompts will never be compressed away
336
336
  "protectUserMessages": false,
337
+ // [#368] 请求时丢弃历史 compress 工具调用中超大的 reasoning(思考)。
338
+ // compress 调用被硬排除在压缩之外,其思考内容会随每次请求原样重发,
339
+ // 形成无法回收的上下文底座。仅作用于已关闭的轮次,活跃轮永不触碰;
340
+ // 低于阈值的小思考保留。
341
+ "reasoning": {
342
+ "drop": true,
343
+ "threshold": 2048
344
+ },
337
345
  },
338
346
  // 垃圾回收与批量清理
339
347
  "gc": {
package/dist/index.js CHANGED
@@ -909,6 +909,9 @@ var VALID_CONFIG_KEYS = /* @__PURE__ */ new Set([
909
909
  "compress.preserveRecentMessages",
910
910
  "compress.preserveRecentTokens",
911
911
  "compress.preserveLastUserMessage",
912
+ "compress.reasoning",
913
+ "compress.reasoning.drop",
914
+ "compress.reasoning.threshold",
912
915
  "gc",
913
916
  "gc.algorithm",
914
917
  "gc.promotionThreshold",
@@ -1262,6 +1265,30 @@ function validateConfigTypes(config) {
1262
1265
  actual: typeof compress.preserveLastUserMessage
1263
1266
  });
1264
1267
  }
1268
+ if (compress.reasoning !== void 0) {
1269
+ if (typeof compress.reasoning !== "object" || compress.reasoning === null || Array.isArray(compress.reasoning)) {
1270
+ errors.push({
1271
+ key: "compress.reasoning",
1272
+ expected: "object { drop?: boolean; threshold?: integer (>= 0) }",
1273
+ actual: JSON.stringify(compress.reasoning)
1274
+ });
1275
+ } else {
1276
+ if (compress.reasoning.drop !== void 0 && typeof compress.reasoning.drop !== "boolean") {
1277
+ errors.push({
1278
+ key: "compress.reasoning.drop",
1279
+ expected: "boolean",
1280
+ actual: typeof compress.reasoning.drop
1281
+ });
1282
+ }
1283
+ if (compress.reasoning.threshold !== void 0 && (typeof compress.reasoning.threshold !== "number" || !Number.isInteger(compress.reasoning.threshold) || compress.reasoning.threshold < 0)) {
1284
+ errors.push({
1285
+ key: "compress.reasoning.threshold",
1286
+ expected: "integer (>= 0)",
1287
+ actual: JSON.stringify(compress.reasoning.threshold)
1288
+ });
1289
+ }
1290
+ }
1291
+ }
1265
1292
  if (typeof compress.iterationNudgeThreshold === "number" && compress.iterationNudgeThreshold < 1) {
1266
1293
  errors.push({
1267
1294
  key: "compress.iterationNudgeThreshold",
@@ -1347,7 +1374,8 @@ function validateConfigTypes(config) {
1347
1374
  maxVisibleSegments: "positiveNumber",
1348
1375
  keepEmbedMaxChars: "nonNegativeNumber",
1349
1376
  preserveRecentMessages: "nonNegativeNumber",
1350
- preserveRecentTokens: "nonNegativeNumber"
1377
+ preserveRecentTokens: "nonNegativeNumber",
1378
+ reasoning: "reasoningConfig"
1351
1379
  };
1352
1380
  const validateOverrideField = (key, type, value) => {
1353
1381
  if (value === void 0) {
@@ -1387,6 +1415,31 @@ function validateConfigTypes(config) {
1387
1415
  errors.push({ key, expected: "string[]", actual: JSON.stringify(value) });
1388
1416
  }
1389
1417
  break;
1418
+ case "reasoningConfig":
1419
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
1420
+ errors.push({
1421
+ key,
1422
+ expected: "object { drop?: boolean; threshold?: integer (>= 0) }",
1423
+ actual: JSON.stringify(value)
1424
+ });
1425
+ break;
1426
+ }
1427
+ const reasoning = value;
1428
+ if (reasoning.drop !== void 0 && typeof reasoning.drop !== "boolean") {
1429
+ errors.push({
1430
+ key: `${key}.drop`,
1431
+ expected: "boolean",
1432
+ actual: typeof reasoning.drop
1433
+ });
1434
+ }
1435
+ if (reasoning.threshold !== void 0 && (typeof reasoning.threshold !== "number" || !Number.isInteger(reasoning.threshold) || reasoning.threshold < 0)) {
1436
+ errors.push({
1437
+ key: `${key}.threshold`,
1438
+ expected: "integer (>= 0)",
1439
+ actual: JSON.stringify(reasoning.threshold)
1440
+ });
1441
+ }
1442
+ break;
1390
1443
  }
1391
1444
  };
1392
1445
  const validateOverrideObject = (prefix, overrides) => {
@@ -1565,6 +1618,10 @@ function validateConfigTypes(config) {
1565
1618
  }
1566
1619
 
1567
1620
  // lib/config.ts
1621
+ var DEFAULT_COMPRESS_REASONING = {
1622
+ drop: true,
1623
+ threshold: 2048
1624
+ };
1568
1625
  var DEFAULT_PROTECTED_TOOLS = [
1569
1626
  "task",
1570
1627
  "skill",
@@ -1659,7 +1716,8 @@ var defaultConfig = {
1659
1716
  lastSegmentSoftBlock: true,
1660
1717
  preserveRecentMessages: 5,
1661
1718
  preserveRecentTokens: 5e3,
1662
- preserveLastUserMessage: true
1719
+ preserveLastUserMessage: true,
1720
+ reasoning: { ...DEFAULT_COMPRESS_REASONING }
1663
1721
  },
1664
1722
  gc: {
1665
1723
  algorithm: "truncate",
@@ -1829,7 +1887,11 @@ function mergeCompress(base, override) {
1829
1887
  lastSegmentSoftBlock: override.lastSegmentSoftBlock ?? base.lastSegmentSoftBlock,
1830
1888
  preserveRecentMessages: override.preserveRecentMessages ?? base.preserveRecentMessages,
1831
1889
  preserveRecentTokens: override.preserveRecentTokens ?? base.preserveRecentTokens,
1832
- preserveLastUserMessage: override.preserveLastUserMessage ?? base.preserveLastUserMessage
1890
+ preserveLastUserMessage: override.preserveLastUserMessage ?? base.preserveLastUserMessage,
1891
+ reasoning: {
1892
+ drop: override.reasoning?.drop ?? base.reasoning?.drop ?? DEFAULT_COMPRESS_REASONING.drop,
1893
+ threshold: override.reasoning?.threshold ?? base.reasoning?.threshold ?? DEFAULT_COMPRESS_REASONING.threshold
1894
+ }
1833
1895
  };
1834
1896
  }
1835
1897
  function mergeCommands(base, override) {
@@ -6647,10 +6709,11 @@ function resolveCompressOverrides(config, providerId, modelId) {
6647
6709
  }
6648
6710
  const { models: _models, ...providerFields } = providerEntry;
6649
6711
  const modelEntry = modelId !== void 0 ? providerEntry.models?.[modelId] : void 0;
6650
- if (modelEntry) {
6651
- return { ...providerFields, ...modelEntry };
6712
+ const merged = modelEntry ? { ...providerFields, ...modelEntry } : providerFields;
6713
+ if (providerFields.reasoning !== void 0 || modelEntry?.reasoning !== void 0) {
6714
+ merged.reasoning = { ...providerFields.reasoning, ...modelEntry?.reasoning };
6652
6715
  }
6653
- return providerFields;
6716
+ return merged;
6654
6717
  }
6655
6718
  function resolveMinNudgeContextPercent(config, providerId, modelId) {
6656
6719
  const overrides = resolveCompressOverrides(config, providerId, modelId);
@@ -6667,19 +6730,26 @@ function resolveMinNudgeFloorTokens(config, modelContextLimit, providerId, model
6667
6730
  const clamped = Math.min(100, Math.max(0, percent));
6668
6731
  return Math.round(clamped / 100 * modelContextLimit);
6669
6732
  }
6670
- var OVERRIDE_BLANKET_APPLY_EXCLUDE = /* @__PURE__ */ new Set(["maxContextLimit"]);
6733
+ var OVERRIDE_BLANKET_APPLY_EXCLUDE = /* @__PURE__ */ new Set([
6734
+ "maxContextLimit",
6735
+ "reasoning"
6736
+ ]);
6671
6737
  function applyCompressOverrides(config, providerId, modelId) {
6672
6738
  const overrides = resolveCompressOverrides(config, providerId, modelId);
6673
6739
  const applied = Object.keys(overrides).filter(
6674
6740
  (key) => !OVERRIDE_BLANKET_APPLY_EXCLUDE.has(key)
6675
6741
  );
6676
- if (applied.length === 0 || !config.compress) {
6742
+ const reasoningOverride = overrides.reasoning;
6743
+ if (applied.length === 0 && reasoningOverride === void 0 || !config.compress) {
6677
6744
  return config;
6678
6745
  }
6679
6746
  const effectiveCompress = { ...config.compress };
6680
6747
  for (const key of applied) {
6681
6748
  effectiveCompress[key] = overrides[key];
6682
6749
  }
6750
+ if (reasoningOverride !== void 0) {
6751
+ effectiveCompress.reasoning = { ...config.compress.reasoning, ...reasoningOverride };
6752
+ }
6683
6753
  return { ...config, compress: effectiveCompress };
6684
6754
  }
6685
6755
  function addAnchor(anchorMessageIds, anchorMessageId, anchorMessageIndex, messages, interval) {
@@ -8262,6 +8332,46 @@ function stripStaleMetadata(messages) {
8262
8332
  });
8263
8333
  });
8264
8334
  }
8335
+ function dropCompressReasoning(messages, threshold) {
8336
+ const lastUserMessage = getLastUserMessage(messages);
8337
+ if (!lastUserMessage || lastUserMessage.info.role !== "user") {
8338
+ return 0;
8339
+ }
8340
+ const lastUserIndex = messages.lastIndexOf(lastUserMessage);
8341
+ if (lastUserIndex <= 0) {
8342
+ return 0;
8343
+ }
8344
+ let removed = 0;
8345
+ for (let i = 0; i < lastUserIndex; i++) {
8346
+ const message = messages[i];
8347
+ if (!message || message.info.role !== "assistant") {
8348
+ continue;
8349
+ }
8350
+ const parts = Array.isArray(message.parts) ? message.parts : [];
8351
+ let hasCompressTool = false;
8352
+ let reasoningLength = 0;
8353
+ for (const part of parts) {
8354
+ if (part.type === "tool" && part.tool === "compress") {
8355
+ hasCompressTool = true;
8356
+ } else if (part.type === "reasoning") {
8357
+ reasoningLength += part.text.length;
8358
+ }
8359
+ }
8360
+ if (!hasCompressTool) {
8361
+ continue;
8362
+ }
8363
+ if (reasoningLength <= threshold) {
8364
+ continue;
8365
+ }
8366
+ const filtered = parts.filter((part) => part.type !== "reasoning");
8367
+ if (filtered.length === parts.length) {
8368
+ continue;
8369
+ }
8370
+ message.parts = filtered;
8371
+ removed += parts.length - filtered.length;
8372
+ }
8373
+ return removed;
8374
+ }
8265
8375
 
8266
8376
  // lib/messages/priority.ts
8267
8377
  function buildPriorityMap(_config, _state, _messages) {
@@ -9378,7 +9488,7 @@ import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
9378
9488
  import { join as join3 } from "path";
9379
9489
  import { existsSync as existsSync3 } from "fs";
9380
9490
  import { homedir as homedir3 } from "os";
9381
- var LOG_VERSION = true ? "1.14.27" : "dev";
9491
+ var LOG_VERSION = true ? "1.15.0-pr.378.113" : "dev";
9382
9492
  var LEVEL_RANK = {
9383
9493
  debug: 10,
9384
9494
  info: 20,
@@ -11370,6 +11480,24 @@ function createChatMessageTransformHandler(client, registry4, logger, config, pr
11370
11480
  return;
11371
11481
  }
11372
11482
  stripHallucinations(output.messages);
11483
+ const dropReasoningModel = lastUserMessage?.info?.model;
11484
+ const reasoningConfig = applyCompressOverrides(
11485
+ config,
11486
+ dropReasoningModel?.providerID ?? state.modelProviderID,
11487
+ dropReasoningModel?.modelID ?? state.modelID
11488
+ ).compress.reasoning;
11489
+ if (reasoningConfig?.drop !== false) {
11490
+ const droppedReasoning = dropCompressReasoning(
11491
+ output.messages,
11492
+ reasoningConfig?.threshold ?? DEFAULT_COMPRESS_REASONING.threshold
11493
+ );
11494
+ if (droppedReasoning > 0) {
11495
+ logger.debug("compress.reasoning: dropped oversized reasoning parts", {
11496
+ dropped: droppedReasoning,
11497
+ threshold: reasoningConfig?.threshold ?? DEFAULT_COMPRESS_REASONING.threshold
11498
+ });
11499
+ }
11500
+ }
11373
11501
  ensureBuiltinFiltersRegistered();
11374
11502
  applyMessageFilters(output.messages, config.messageFilters, logger, {
11375
11503
  sessionId: state.sessionId ?? "",
@@ -11851,7 +11979,7 @@ var server = (async (ctx) => {
11851
11979
  }
11852
11980
  const logger = new Logger(config.debug, config.debug ? "debug" : config.logLevel);
11853
11981
  logger.info("ACP plugin initialized", {
11854
- version: true ? "1.14.27" : "dev",
11982
+ version: true ? "1.15.0-pr.378.113" : "dev",
11855
11983
  workspace: ctx.directory,
11856
11984
  logLevel: logger.level,
11857
11985
  debug: config.debug,