opencode-acp 1.18.2-pr.447.191 → 1.18.2-pr.448.192

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 CHANGED
@@ -6384,32 +6384,24 @@ function computeStats(plan) {
6384
6384
  const retentionPct = originalTokens > 0 ? (summaryChars / (originalTokens * 4) * 100).toFixed(2) : "?";
6385
6385
  return { originalTokens, summaryChars, ratio, retentionPct };
6386
6386
  }
6387
- function coreReason(reason) {
6388
- if (!reason) return "unknown";
6389
- const candidates = [reason.indexOf(":"), reason.indexOf("(")].filter((i) => i >= 0);
6390
- const cut = Math.min(...candidates);
6391
- return (cut > 0 ? reason.slice(0, cut) : reason).trim() || "unknown";
6392
- }
6393
- function buildQualityRejectionError(plan, result, logger) {
6387
+ function buildQualityRejectionError(plan, result) {
6394
6388
  const stats = computeStats(plan);
6395
- logger?.warn("quality gate rejected compression", {
6396
- range: `${plan.startId}\u2013${plan.endId}`,
6397
- reason: result.reason || "unknown",
6398
- layer: result.layer ?? "unknown",
6399
- originalTokens: stats.originalTokens,
6400
- summaryChars: stats.summaryChars,
6401
- ratio: stats.ratio,
6402
- retentionPct: stats.retentionPct,
6403
- rougeF1: formatMetric(result, "rougeF1"),
6404
- top20Recall: formatMetric(result, "top20Recall")
6405
- });
6389
+ const metrics = [
6390
+ `Reason: ${result.reason || "unknown"}`,
6391
+ `Original: ~${stats.originalTokens} tokens`,
6392
+ `Summary: ${stats.summaryChars} chars`,
6393
+ `Ratio: ${stats.ratio}:1`,
6394
+ `Retention: ${stats.retentionPct}%`,
6395
+ `Gate layer: ${result.layer ?? "unknown"}`,
6396
+ `rougeF1: ${formatMetric(result, "rougeF1")}`,
6397
+ `top20Recall: ${formatMetric(result, "top20Recall")}`
6398
+ ];
6406
6399
  const message = `\u26A0\uFE0F COMPRESSION REJECTED \u2014 QUALITY GATE FAILURE
6407
6400
 
6408
6401
  Range: ${plan.startId}\u2013${plan.endId}
6409
- Reason: ${coreReason(result.reason)}
6410
- Original: ~${stats.originalTokens} tokens \xB7 Summary: ${stats.summaryChars} chars \xB7 Retention: ${stats.retentionPct}%
6402
+ ${metrics.join("\n")}
6411
6403
 
6412
- Retry: write a more complete summary preserving critical details (file paths, decisions, exact values, errors), then call compress again on the same range. If you are confident the summary is adequate despite the metrics, pass "acknowledgeRisk": true.`;
6404
+ Retry: rewrite a more complete summary that preserves critical details (file paths, decisions, exact values, errors) and call compress again on the same range \u2014 the gate re-evaluates automatically. Full compression rules are already in your system prompt. If you are confident the summary is correct despite the metrics, add "acknowledgeRisk": true to bypass the quality gate on your next compress call.`;
6413
6405
  return new Error(message);
6414
6406
  }
6415
6407
 
@@ -8071,8 +8063,7 @@ function createCompressRangeTool(factoryCtx) {
8071
8063
  messageIds: plan.selection.messageIds,
8072
8064
  messageTokenById: plan.selection.messageTokenById
8073
8065
  },
8074
- result,
8075
- ctx.logger
8066
+ result
8076
8067
  );
8077
8068
  }
8078
8069
  }
@@ -10040,14 +10031,31 @@ function buildSchema2() {
10040
10031
  };
10041
10032
  }
10042
10033
  function extractMessageId(m) {
10043
- return m.id ?? m.messageId ?? "";
10034
+ return m?.info?.id ?? "";
10035
+ }
10036
+ function serializeMessagePart(part) {
10037
+ if (!part || typeof part !== "object") return null;
10038
+ if (part.type === "text") {
10039
+ return typeof part.text === "string" && part.text.length > 0 ? part.text : null;
10040
+ }
10041
+ if (part.type === "tool") {
10042
+ const contents = extractToolContent(part);
10043
+ if (contents.length === 0) return null;
10044
+ const toolName = "tool" in part && typeof part.tool === "string" && part.tool.length > 0 ? part.tool : "tool";
10045
+ return `[${toolName}] ${contents.join("\n")}`;
10046
+ }
10047
+ return null;
10044
10048
  }
10045
10049
  function extractMessageText2(m) {
10046
- const msg = m;
10047
- const role = msg.role || msg.type || "unknown";
10048
- const content = typeof msg.content === "string" ? msg.content : typeof msg.text === "string" ? msg.text : JSON.stringify(msg.content || msg.text || "");
10050
+ const role = m?.info?.role ?? "unknown";
10051
+ const parts = Array.isArray(m.parts) ? m.parts : [];
10052
+ const segments = [];
10053
+ for (const part of parts) {
10054
+ const serialized = serializeMessagePart(part);
10055
+ if (serialized !== null) segments.push(serialized);
10056
+ }
10049
10057
  return `[${role}]
10050
- ${content}`;
10058
+ ${segments.join("\n\n")}`;
10051
10059
  }
10052
10060
  function createDecompressTool(factoryCtx) {
10053
10061
  return tool3({
@@ -10099,10 +10107,18 @@ function createDecompressTool(factoryCtx) {
10099
10107
  const blockMessages = rawMessages.filter((m) => msgIdSet.has(extractMessageId(m)));
10100
10108
  const lines2 = blockMessages.map(extractMessageText2);
10101
10109
  const { writeFile: writeFile4 } = await import("fs/promises");
10102
- const fileContent = lines2.length > 0 ? lines2.join("\n\n---\n\n") : targets[0]?.blocks[0]?.summary ?? "(no content available)";
10110
+ let fileContent;
10111
+ let sourceNote;
10112
+ if (lines2.length > 0) {
10113
+ fileContent = lines2.join("\n\n---\n\n");
10114
+ sourceNote = `${blockMessages.length} original message${blockMessages.length === 1 ? "" : "s"}`;
10115
+ } else {
10116
+ fileContent = targets[0]?.blocks[0]?.summary ?? "(no content available)";
10117
+ sourceNote = `no original messages found; wrote block summary (${targets.length} block${targets.length === 1 ? "" : "s"})`;
10118
+ }
10103
10119
  await writeFile4(targetPath, fileContent, "utf-8");
10104
10120
  const displayIds2 = targets.map((t) => `b${t.displayId}`).join(", ");
10105
- return `Block(s) ${displayIds2} content (${blockMessages.length} messages, ${fileContent.length} chars) written to ${targetPath}. Block(s) stay compressed \u2014 context unchanged. Use read tool to access specific parts.`;
10121
+ return `Block(s) ${displayIds2} content (${sourceNote}, ${fileContent.length} chars) written to ${targetPath}. Block(s) stay compressed \u2014 context unchanged. Use read tool to access specific parts.`;
10106
10122
  }
10107
10123
  const activeMessagesBefore = snapshotActiveMessages(messagesState);
10108
10124
  const activeBlockIdsBefore = new Set(messagesState.activeBlockIds);
@@ -10915,7 +10931,7 @@ import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
10915
10931
  import { join as join4 } from "path";
10916
10932
  import { existsSync as existsSync4 } from "fs";
10917
10933
  import { homedir as homedir3 } from "os";
10918
- var LOG_VERSION = true ? "1.18.2-pr.447.191" : "dev";
10934
+ var LOG_VERSION = true ? "1.18.2-pr.448.192" : "dev";
10919
10935
  var LEVEL_RANK = {
10920
10936
  debug: 10,
10921
10937
  info: 20,
@@ -13633,7 +13649,7 @@ var server = (async (ctx) => {
13633
13649
  }
13634
13650
  const logger = new Logger(config.debug, config.debug ? "debug" : config.logLevel);
13635
13651
  logger.info("ACP plugin initialized", {
13636
- version: true ? "1.18.2-pr.447.191" : "dev",
13652
+ version: true ? "1.18.2-pr.448.192" : "dev",
13637
13653
  workspace: ctx.directory,
13638
13654
  logLevel: logger.level,
13639
13655
  debug: config.debug,