opencode-acp 1.4.1 → 1.4.2

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
@@ -389,7 +389,7 @@ ACP auto-migrates config from `dcp.jsonc` to `acp.jsonc` and prompts from `dcp-p
389
389
  ---
390
390
 
391
391
  <details>
392
- <summary><strong>Bug Fixes (37 total)</strong> -- applied on top of DCP v3.1.11</summary>
392
+ <summary><strong>Bug Fixes (38 total)</strong> -- applied on top of DCP v3.1.11</summary>
393
393
 
394
394
  | # | Severity | Summary |
395
395
  |---|----------|---------|
@@ -419,6 +419,7 @@ ACP auto-migrates config from `dcp.jsonc` to `acp.jsonc` and prompts from `dcp-p
419
419
  | 35 | HIGH | Aging warnings shown at low context usage (<50%) -- triggers unnecessary compress, wastes tokens |
420
420
  | 36 | HIGH | Compression summary emitted as a standalone user message before the user's real turn -- model reads its own prior assistant output as user input, causing dialog role confusion / self-Q&A loops |
421
421
  | 37 | HIGH | Message-transform pipeline runs on OpenCode's hidden title/summary/compaction agent requests -- corrupts the request and shared session state, breaking session title generation |
422
+ | 38 | CRITICAL | pruneToolOutputs/pruneToolInputs/pruneToolErrors mutate existing messages in-place -- invalidates LLM prefix cache, causing 89% of fresh input tokens to be wasted on cache-invalidating re-sends |
422
423
 
423
424
  For the complete list with root cause analysis, see the [bug tracker](https://github.com/ranxianglei/opencode-acp/issues).
424
425
 
package/dist/index.js CHANGED
@@ -4958,89 +4958,8 @@ var stripHallucinations = (messages) => {
4958
4958
  };
4959
4959
 
4960
4960
  // lib/messages/prune.ts
4961
- var PRUNED_TOOL_OUTPUT_REPLACEMENT = "[Output removed to save context - information superseded or no longer needed]";
4962
- var PRUNED_TOOL_ERROR_INPUT_REPLACEMENT = "[input removed due to failed tool call]";
4963
- var PRUNED_QUESTION_INPUT_REPLACEMENT = "[questions removed - see output for user's answers]";
4964
4961
  var prune = (state, logger, config, messages) => {
4965
4962
  filterCompressedRanges(state, logger, config, messages);
4966
- pruneToolOutputs(state, logger, messages);
4967
- pruneToolInputs(state, logger, messages);
4968
- pruneToolErrors(state, logger, messages);
4969
- };
4970
- var pruneToolOutputs = (state, logger, messages) => {
4971
- for (const msg of messages) {
4972
- if (isMessageCompacted(state, msg)) {
4973
- continue;
4974
- }
4975
- const parts = Array.isArray(msg.parts) ? msg.parts : [];
4976
- for (const part of parts) {
4977
- if (part.type !== "tool") {
4978
- continue;
4979
- }
4980
- if (!state.prune.tools.has(part.callID)) {
4981
- continue;
4982
- }
4983
- if (part.state.status !== "completed") {
4984
- continue;
4985
- }
4986
- if (part.tool === "question" || part.tool === "edit" || part.tool === "write") {
4987
- continue;
4988
- }
4989
- part.state.output = PRUNED_TOOL_OUTPUT_REPLACEMENT;
4990
- }
4991
- }
4992
- };
4993
- var pruneToolInputs = (state, logger, messages) => {
4994
- for (const msg of messages) {
4995
- if (isMessageCompacted(state, msg)) {
4996
- continue;
4997
- }
4998
- const parts = Array.isArray(msg.parts) ? msg.parts : [];
4999
- for (const part of parts) {
5000
- if (part.type !== "tool") {
5001
- continue;
5002
- }
5003
- if (!state.prune.tools.has(part.callID)) {
5004
- continue;
5005
- }
5006
- if (part.state.status !== "completed") {
5007
- continue;
5008
- }
5009
- if (part.tool !== "question") {
5010
- continue;
5011
- }
5012
- if (part.state.input?.questions !== void 0) {
5013
- part.state.input.questions = PRUNED_QUESTION_INPUT_REPLACEMENT;
5014
- }
5015
- }
5016
- }
5017
- };
5018
- var pruneToolErrors = (state, logger, messages) => {
5019
- for (const msg of messages) {
5020
- if (isMessageCompacted(state, msg)) {
5021
- continue;
5022
- }
5023
- const parts = Array.isArray(msg.parts) ? msg.parts : [];
5024
- for (const part of parts) {
5025
- if (part.type !== "tool") {
5026
- continue;
5027
- }
5028
- if (!state.prune.tools.has(part.callID)) {
5029
- continue;
5030
- }
5031
- if (part.state.status !== "error") {
5032
- continue;
5033
- }
5034
- const input = part.state.input;
5035
- if (input && typeof input === "object") {
5036
- for (const key of Object.keys(input)) {
5037
- if (typeof input[key] === "string") {
5038
- input[key] = PRUNED_TOOL_ERROR_INPUT_REPLACEMENT;
5039
- }
5040
- }
5041
- }
5042
- }
5043
- }
5044
4963
  };
5045
4964
  var filterCompressedRanges = (state, logger, config, messages) => {
5046
4965
  if (state.prune.messages.byMessageId.size === 0 && state.prune.messages.activeByAnchorMessageId.size === 0) {