opencode-acp 1.17.0-pr.385.132 → 1.17.0-pr.386.133

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
@@ -581,6 +581,14 @@ Full release history moved to [CHANGELOG.md](./CHANGELOG.md).
581
581
 
582
582
  ---
583
583
 
584
+ ## Community
585
+
586
+ Discussion, help, and updates on QQ — one group covers all three projects (`billion-context`, `billion-context-pi`, `opencode-acp`):
587
+
588
+ **QQ Group: 1056132097**
589
+
590
+ ---
591
+
584
592
  ## License
585
593
 
586
594
  AGPL-3.0-or-later -- This project is a fork of [@tarquinen/opencode-dcp](https://github.com/Tarquinen/opencode-dynamic-context-pruning). Original copyright belongs to the original author. Modifications and bug fixes by ranxianglei.
package/README.zh-CN.md CHANGED
@@ -531,6 +531,14 @@ ACP 是 DCP 的直接替代品。迁移步骤:
531
531
 
532
532
  ---
533
533
 
534
+ ## 社区
535
+
536
+ 交流、求助与更新都在 QQ——同一个群覆盖三个项目(`billion-context`、`billion-context-pi`、`opencode-acp`):
537
+
538
+ **QQ 群:1056132097**
539
+
540
+ ---
541
+
534
542
  ## 许可证
535
543
 
536
544
  AGPL-3.0-or-later — 本项目是 [@tarquinen/opencode-dcp](https://github.com/Tarquinen/opencode-dynamic-context-pruning) 的分支。原始版权归原始作者所有。修改和错误修复由 ranxianglei 完成。
package/dist/index.js CHANGED
@@ -2442,9 +2442,6 @@ function countMessageCharacters(msg) {
2442
2442
  }
2443
2443
  return total;
2444
2444
  }
2445
- function estimateAllMessageTokensFast(msg) {
2446
- return Math.round(countMessageCharacters(msg) / 4);
2447
- }
2448
2445
 
2449
2446
  // lib/prompts/extensions/tool.ts
2450
2447
  var RANGE_FORMAT_EXTENSION = `
@@ -2494,9 +2491,6 @@ var isMessageCompacted = (state, msg) => {
2494
2491
  }
2495
2492
  return false;
2496
2493
  };
2497
- function bumpPruneStructureVersion(messagesState) {
2498
- messagesState.structureVersion = (messagesState.structureVersion ?? 0) + 1;
2499
- }
2500
2494
  function serializePruneMessagesState(messagesState) {
2501
2495
  return {
2502
2496
  byMessageId: Object.fromEntries(messagesState.byMessageId),
@@ -2814,13 +2808,9 @@ async function writePersistedSessionState(sessionId, state, logger, storageDir)
2814
2808
  totalTokensSaved: state.stats.totalPruneTokens
2815
2809
  });
2816
2810
  }
2817
- var saveQueues = /* @__PURE__ */ new Map();
2818
- function saveQueueKey(sessionId, storageDir) {
2819
- return `${sessionId}\0${storageDir ?? ""}`;
2820
- }
2821
- function saveSessionState(sessionState, logger, sessionName) {
2811
+ async function saveSessionState(sessionState, logger, sessionName) {
2822
2812
  if (!sessionState.sessionId) {
2823
- return Promise.resolve();
2813
+ return;
2824
2814
  }
2825
2815
  const state = {
2826
2816
  sessionName,
@@ -2851,53 +2841,7 @@ function saveSessionState(sessionState, logger, sessionName) {
2851
2841
  modelProviderID: sessionState.modelProviderID,
2852
2842
  modelID: sessionState.modelID
2853
2843
  };
2854
- const key = saveQueueKey(sessionState.sessionId, sessionState.storageDir);
2855
- let queue = saveQueues.get(key);
2856
- if (!queue) {
2857
- queue = { pending: [], waiters: [], draining: false };
2858
- saveQueues.set(key, queue);
2859
- }
2860
- const promise = new Promise((resolve2, reject) => {
2861
- queue.waiters.push({ resolve: resolve2, reject });
2862
- });
2863
- queue.pending.push({
2864
- sessionId: sessionState.sessionId,
2865
- state,
2866
- storageDir: sessionState.storageDir,
2867
- logger
2868
- });
2869
- if (!queue.draining) {
2870
- queue.draining = true;
2871
- setImmediate(() => drainSaveQueue(key));
2872
- }
2873
- return promise;
2874
- }
2875
- function drainSaveQueue(key) {
2876
- const queue = saveQueues.get(key);
2877
- if (!queue || queue.pending.length === 0) {
2878
- if (queue) {
2879
- queue.draining = false;
2880
- if (queue.waiters.length === 0) saveQueues.delete(key);
2881
- }
2882
- return;
2883
- }
2884
- const batch = queue.pending.splice(0, queue.pending.length);
2885
- const waiters = queue.waiters.splice(0, batch.length);
2886
- const latest = batch[batch.length - 1];
2887
- writePersistedSessionState(latest.sessionId, latest.state, latest.logger, latest.storageDir).then(() => {
2888
- for (const waiter of waiters) waiter.resolve();
2889
- }).catch((err) => {
2890
- for (const waiter of waiters) waiter.reject(err);
2891
- }).finally(() => {
2892
- const q = saveQueues.get(key);
2893
- if (!q) return;
2894
- if (q.pending.length > 0) {
2895
- drainSaveQueue(key);
2896
- } else {
2897
- q.draining = false;
2898
- if (q.waiters.length === 0) saveQueues.delete(key);
2899
- }
2900
- });
2844
+ await writePersistedSessionState(sessionState.sessionId, state, logger, sessionState.storageDir);
2901
2845
  }
2902
2846
  async function loadSessionState(sessionId, logger, storageDir) {
2903
2847
  try {
@@ -3391,7 +3335,6 @@ function applyCompressionState(state, input, selection, anchorMessageId, blockId
3391
3335
  state.stats.pruneTokenCounter += compressedTokens;
3392
3336
  state.stats.totalPruneTokens += state.stats.pruneTokenCounter;
3393
3337
  state.stats.pruneTokenCounter = 0;
3394
- bumpPruneStructureVersion(messagesState);
3395
3338
  return {
3396
3339
  compressedTokens,
3397
3340
  messageIds: selection.messageIds,
@@ -3505,17 +3448,15 @@ function buildSearchContext(state, rawMessages) {
3505
3448
  }
3506
3449
  summaryByBlockId.set(blockId, block);
3507
3450
  }
3508
- const context = {
3451
+ return {
3509
3452
  rawMessages,
3510
3453
  rawMessagesById,
3511
3454
  rawIndexById,
3512
3455
  summaryByBlockId
3513
3456
  };
3514
- context.boundaryLookup = buildBoundaryLookup(context, state);
3515
- return context;
3516
3457
  }
3517
3458
  function resolveBoundaryIds(context, state, startId, endId, logger) {
3518
- const lookup = context.boundaryLookup ?? (context.boundaryLookup = buildBoundaryLookup(context, state));
3459
+ const lookup = buildBoundaryLookup(context, state);
3519
3460
  const issues = [];
3520
3461
  const parsedStartId = parseBoundaryId(startId);
3521
3462
  const parsedEndId = parseBoundaryId(endId);
@@ -3715,7 +3656,7 @@ function resolveSelection(context, startReference, endReference) {
3715
3656
  messageIds.push(messageId);
3716
3657
  }
3717
3658
  if (!messageTokenById.has(messageId)) {
3718
- messageTokenById.set(messageId, estimateAllMessageTokensFast(rawMessage));
3659
+ messageTokenById.set(messageId, countAllMessageTokens(rawMessage));
3719
3660
  }
3720
3661
  const parts = Array.isArray(rawMessage.parts) ? rawMessage.parts : [];
3721
3662
  for (const part of parts) {
@@ -7922,23 +7863,6 @@ var syncCompressionBlocks = (state, logger, messages) => {
7922
7863
  return;
7923
7864
  }
7924
7865
  const messageIds = new Set(messages.map((msg) => msg.info.id));
7925
- const structureVersion = messagesState.structureVersion ?? 0;
7926
- if (messagesState.lastSyncedStructureVersion === structureVersion) {
7927
- const activeBlocks = [...messagesState.activeBlockIds].map((id) => messagesState.blocksById.get(id)).filter((b) => b !== void 0).sort(sortBlocksByCreation);
7928
- const nextAnchorMap = /* @__PURE__ */ new Map();
7929
- for (const block of activeBlocks) {
7930
- if (!messageIds.has(block.anchorMessageId)) continue;
7931
- nextAnchorMap.set(block.anchorMessageId, block.blockId);
7932
- }
7933
- const previous = messagesState.activeByAnchorMessageId;
7934
- if (previous.size !== nextAnchorMap.size || ![...nextAnchorMap.entries()].every(([anchor, id]) => previous.get(anchor) === id)) {
7935
- previous.clear();
7936
- for (const [anchor, id] of nextAnchorMap) {
7937
- previous.set(anchor, id);
7938
- }
7939
- }
7940
- return;
7941
- }
7942
7866
  const previousActiveBlockIds = new Set(
7943
7867
  Array.from(messagesState.blocksById.values()).filter((block) => block.active).map((block) => block.blockId)
7944
7868
  );
@@ -8005,7 +7929,6 @@ var syncCompressionBlocks = (state, logger, messages) => {
8005
7929
  reactivatedCount
8006
7930
  });
8007
7931
  }
8008
- messagesState.lastSyncedStructureVersion = structureVersion;
8009
7932
  };
8010
7933
 
8011
7934
  // lib/host-permissions.ts
@@ -8259,23 +8182,20 @@ var injectCompressNudges = (state, config, logger, messages, prompts, compressio
8259
8182
  state.nudges.lastPerMessageNudgeTokens = currentTokens;
8260
8183
  baselineReEstablished = true;
8261
8184
  }
8262
- const tierUsageEarly = getTierTokenUsage(state);
8263
- const tierTriggerPossible = !!suffixMessage && (tierUsageEarly.tier1Tokens >= nudgeGrowthTokens || tierUsageEarly.tier2Tokens >= nudgeGrowthTokens);
8264
- const needsNudgeAnalysis = nudgeAllowed || emergencyOverride || tierTriggerPossible;
8265
- const composition = needsNudgeAnalysis ? estimateContextComposition(
8185
+ const composition = estimateContextComposition(
8266
8186
  messages,
8267
8187
  state,
8268
8188
  config.compress.protectedTools,
8269
8189
  config.protectedFilePatterns
8270
- ) : null;
8271
- const protectedRefs = needsNudgeAnalysis ? computeProtectedRefs(messages, state, config.compress) : /* @__PURE__ */ new Set();
8272
- const contextRanges = needsNudgeAnalysis ? buildCompressibleRanges(
8190
+ );
8191
+ const protectedRefs = computeProtectedRefs(messages, state, config.compress);
8192
+ const contextRanges = buildCompressibleRanges(
8273
8193
  messages,
8274
8194
  state,
8275
8195
  config.compress.protectedTools,
8276
8196
  config.protectedFilePatterns,
8277
8197
  protectedRefs
8278
- ) : { compressible: [], protected: [] };
8198
+ );
8279
8199
  const unprotectedCompressible = excludeProtectedRanges(contextRanges.compressible, protectedRefs);
8280
8200
  const recommendedRanges = filterRecommendedRanges(
8281
8201
  unprotectedCompressible,
@@ -8300,7 +8220,7 @@ var injectCompressNudges = (state, config, logger, messages, prompts, compressio
8300
8220
  baselineReEstablished = true;
8301
8221
  }
8302
8222
  if (suffixMessage && !shouldInject) {
8303
- const tierUsage = tierUsageEarly;
8223
+ const tierUsage = getTierTokenUsage(state);
8304
8224
  const tierChecks = [
8305
8225
  { triggerTier: 2, targetTier: 1, tokens: tierUsage.tier1Tokens, lastNudge: state.nudges.lastTier2NudgeTokens },
8306
8226
  { triggerTier: 3, targetTier: 2, tokens: tierUsage.tier2Tokens, lastNudge: state.nudges.lastTier3NudgeTokens }
@@ -8427,7 +8347,7 @@ ${rules}`;
8427
8347
  }
8428
8348
  let tipsText = null;
8429
8349
  if (shouldInject) {
8430
- if (suffixMessage && composition !== null && composition.total > 0) {
8350
+ if (suffixMessage && composition.total > 0) {
8431
8351
  const fmt = (n) => n >= 1e3 ? `${(n / 1e3).toFixed(1)}K` : String(n);
8432
8352
  const pct2 = (n) => n > 0 ? Math.max(1, Math.round(n / composition.total * 100)) : 0;
8433
8353
  const growth = currentTokens !== void 0 && (state.nudges.lastNudgeShownTokens ?? state.nudges.lastPerMessageNudgeTokens) !== void 0 ? currentTokens - (state.nudges.lastNudgeShownTokens ?? state.nudges.lastPerMessageNudgeTokens) : 0;
@@ -8802,9 +8722,6 @@ function deactivateCompressionTarget(messagesState, target, options) {
8802
8722
  }
8803
8723
  }
8804
8724
  }
8805
- if (target.blocks.length > 0) {
8806
- bumpPruneStructureVersion(messagesState);
8807
- }
8808
8725
  }
8809
8726
  function computeRestoredMessages(messagesState, activeMessagesBefore) {
8810
8727
  let restoredMessageCount = 0;
@@ -9186,29 +9103,21 @@ function rewriteCompressInput(part, liveKeys) {
9186
9103
  };
9187
9104
  }
9188
9105
  function hideConsumedCompressCalls(state, messages) {
9189
- const messagesState = state.prune.messages;
9190
- const version = messagesState.structureVersion ?? 0;
9191
- let cached = messagesState.hideConsumedIndex;
9192
- if (!cached || cached.version !== version) {
9193
- const allBlockCallIds2 = /* @__PURE__ */ new Set();
9194
- const liveRangeKeysByCallId2 = /* @__PURE__ */ new Map();
9195
- const activeCallIds2 = /* @__PURE__ */ new Set();
9196
- for (const block of messagesState.blocksById.values()) {
9197
- if (!block.compressCallId) continue;
9198
- allBlockCallIds2.add(block.compressCallId);
9199
- if (!isLiveBlock(block)) continue;
9200
- activeCallIds2.add(block.compressCallId);
9201
- let keys = liveRangeKeysByCallId2.get(block.compressCallId);
9202
- if (!keys) {
9203
- keys = /* @__PURE__ */ new Set();
9204
- liveRangeKeysByCallId2.set(block.compressCallId, keys);
9205
- }
9206
- keys.add(rangeKey(block.startId, block.endId));
9207
- }
9208
- cached = { version, allBlockCallIds: allBlockCallIds2, liveRangeKeysByCallId: liveRangeKeysByCallId2, activeCallIds: activeCallIds2 };
9209
- messagesState.hideConsumedIndex = cached;
9210
- }
9211
- const { allBlockCallIds, liveRangeKeysByCallId, activeCallIds } = cached;
9106
+ const allBlockCallIds = /* @__PURE__ */ new Set();
9107
+ const liveRangeKeysByCallId = /* @__PURE__ */ new Map();
9108
+ const activeCallIds = /* @__PURE__ */ new Set();
9109
+ for (const block of state.prune.messages.blocksById.values()) {
9110
+ if (!block.compressCallId) continue;
9111
+ allBlockCallIds.add(block.compressCallId);
9112
+ if (!isLiveBlock(block)) continue;
9113
+ activeCallIds.add(block.compressCallId);
9114
+ let keys = liveRangeKeysByCallId.get(block.compressCallId);
9115
+ if (!keys) {
9116
+ keys = /* @__PURE__ */ new Set();
9117
+ liveRangeKeysByCallId.set(block.compressCallId, keys);
9118
+ }
9119
+ keys.add(rangeKey(block.startId, block.endId));
9120
+ }
9212
9121
  const lastOrphanedCallIds = [];
9213
9122
  for (let i = messages.length - 1; i >= 0 && lastOrphanedCallIds.length < KEEP_LAST_ORPHANED; i--) {
9214
9123
  const parts = Array.isArray(messages[i]?.parts) ? messages[i].parts : [];
@@ -9782,7 +9691,7 @@ import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
9782
9691
  import { join as join4 } from "path";
9783
9692
  import { existsSync as existsSync4 } from "fs";
9784
9693
  import { homedir as homedir3 } from "os";
9785
- var LOG_VERSION = true ? "1.17.0-pr.385.132" : "dev";
9694
+ var LOG_VERSION = true ? "1.17.0-pr.386.133" : "dev";
9786
9695
  var LEVEL_RANK = {
9787
9696
  debug: 10,
9788
9697
  info: 20,
@@ -11782,7 +11691,6 @@ function mergeMarkedBlocks(state, markedIds, maxMergedLength) {
11782
11691
  0
11783
11692
  );
11784
11693
  const savedTokens = Math.max(0, sourceTokens - newSummaryTokens);
11785
- bumpPruneStructureVersion(messagesState);
11786
11694
  return { mergedCount: sourceBlocks.length, savedTokens };
11787
11695
  }
11788
11696
  function runBatchCleanup(state, config, logger, messages) {
@@ -12478,7 +12386,7 @@ var server = (async (ctx) => {
12478
12386
  }
12479
12387
  const logger = new Logger(config.debug, config.debug ? "debug" : config.logLevel);
12480
12388
  logger.info("ACP plugin initialized", {
12481
- version: true ? "1.17.0-pr.385.132" : "dev",
12389
+ version: true ? "1.17.0-pr.386.133" : "dev",
12482
12390
  workspace: ctx.directory,
12483
12391
  logLevel: logger.level,
12484
12392
  debug: config.debug,