opencode-acp 1.2.0 → 1.3.1

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
@@ -5523,18 +5523,39 @@ function applyMessageModeAnchoredNudge(anchorMessageIds, messages, baseNudgeText
5523
5523
  injectAnchoredNudge(message, nudgeText);
5524
5524
  }
5525
5525
  }
5526
- function buildContextUsageInfo(currentTokens, modelContextLimit) {
5526
+ function resolveThresholdPercent(threshold, modelContextLimit) {
5527
+ if (threshold === void 0) return void 0;
5528
+ if (typeof threshold === "number") {
5529
+ if (!modelContextLimit) return void 0;
5530
+ return threshold / modelContextLimit * 100;
5531
+ }
5532
+ const parsed = parseFloat(threshold);
5533
+ return isNaN(parsed) ? void 0 : parsed;
5534
+ }
5535
+ function buildContextUsageGuidance(config, currentTokens, modelContextLimit) {
5527
5536
  if (currentTokens === void 0 || modelContextLimit === void 0 || modelContextLimit === 0) {
5528
5537
  return "";
5529
5538
  }
5530
- const percentage = (currentTokens / modelContextLimit * 100).toFixed(1);
5539
+ const pct = currentTokens / modelContextLimit * 100;
5540
+ const percentage = pct.toFixed(1);
5531
5541
  const formatK = (n) => n >= 1e3 ? `${(n / 1e3).toFixed(1)}K` : String(n);
5542
+ const minPct = resolveThresholdPercent(config.compress.minContextLimit, modelContextLimit) ?? 45;
5543
+ const maxPct = resolveThresholdPercent(config.compress.maxContextLimit, modelContextLimit) ?? 55;
5544
+ const base = `Context usage: ${formatK(currentTokens)} / ${formatK(modelContextLimit)} tokens (${percentage}%). ACP threshold: ${maxPct.toFixed(0)}%.`;
5545
+ let guidance;
5546
+ if (pct < minPct) {
5547
+ guidance = " Context is ample \u2014 focus on your task. Only compress obvious waste (large terminal outputs, duplicated content).";
5548
+ } else if (pct < maxPct) {
5549
+ guidance = " Context is moderate \u2014 compress completed sections and high-token waste. Preserve key details.";
5550
+ } else {
5551
+ guidance = " Context is high \u2014 compress aggressively but selectively. Preserve only what is essential.";
5552
+ }
5532
5553
  return `
5533
5554
 
5534
- Context usage: ${formatK(currentTokens)} / ${formatK(modelContextLimit)} tokens (${percentage}%). ACP (Active Context Pruning) threshold: 55%. You ARE the ACP agent \u2014 use the compress tool proactively to manage context quality.`;
5555
+ ${base}${guidance}`;
5535
5556
  }
5536
5557
  function applyAnchoredNudges(state, config, messages, prompts, compressionPriorities, currentTokens, modelContextLimit, suffixMessage) {
5537
- const contextUsageInfo = buildContextUsageInfo(currentTokens, modelContextLimit);
5558
+ const contextUsageInfo = buildContextUsageGuidance(config, currentTokens, modelContextLimit);
5538
5559
  const contextLimitNudgeWithUsage = prompts.contextLimitNudge + contextUsageInfo;
5539
5560
  const turnNudgeAnchors = collectTurnNudgeAnchors2(state, config, messages);
5540
5561
  if (suffixMessage) {
@@ -5709,7 +5730,7 @@ var injectCompressNudges = (state, config, logger, messages, prompts, compressio
5709
5730
  }
5710
5731
  const suffixMessage = createSuffixMessage(messages);
5711
5732
  applyAnchoredNudges(state, config, messages, prompts, compressionPriorities, currentTokens, modelContextLimit, suffixMessage);
5712
- injectContextUsage(suffixMessage, currentTokens, modelContextLimit);
5733
+ injectContextUsage(suffixMessage, config, currentTokens, modelContextLimit);
5713
5734
  if (config.compress.mode !== "message") {
5714
5735
  const blockGuidance = buildCompressedBlockGuidance(state, config.gc, { currentTokens, modelContextLimit });
5715
5736
  if (blockGuidance.trim() && suffixMessage) {
@@ -5721,16 +5742,10 @@ var injectCompressNudges = (state, config, logger, messages, prompts, compressio
5721
5742
  void saveSessionState(state, logger);
5722
5743
  }
5723
5744
  };
5724
- function injectContextUsage(target, currentTokens, modelContextLimit) {
5745
+ function injectContextUsage(target, config, currentTokens, modelContextLimit) {
5725
5746
  if (!target) return;
5726
- if (currentTokens === void 0 || modelContextLimit === void 0 || modelContextLimit === 0) {
5727
- return;
5728
- }
5729
- const percentage = (currentTokens / modelContextLimit * 100).toFixed(1);
5730
- const formatK = (n) => n >= 1e3 ? `${(n / 1e3).toFixed(1)}K` : String(n);
5731
- const usageTag = `
5732
-
5733
- Context usage: ${formatK(currentTokens)} / ${formatK(modelContextLimit)} tokens (${percentage}%). ACP (Active Context Pruning) threshold: 55%. You ARE the ACP agent \u2014 use the compress tool proactively to manage context quality.`;
5747
+ const usageTag = buildContextUsageGuidance(config, currentTokens, modelContextLimit);
5748
+ if (!usageTag) return;
5734
5749
  for (const part of target.parts) {
5735
5750
  if (part.type === "text") {
5736
5751
  appendToTextPart(part, usageTag);
@@ -6465,37 +6480,74 @@ import { homedir as homedir4 } from "os";
6465
6480
 
6466
6481
  // lib/prompts/system.ts
6467
6482
  var SYSTEM = `
6468
- You operate in a context-constrained environment. Manage context continuously to avoid buildup and preserve retrieval quality. Efficient context management is paramount for your agentic performance.
6483
+
6484
+ You operate in a context-constrained environment. Context management helps preserve retrieval quality, but your primary goal is completing the task at hand. Do not let context management distract from the actual work.
6469
6485
 
6470
6486
  The tools you have for context management are \`compress\` and \`decompress\`. \`compress\` replaces older conversation content with technical summaries you produce. \`decompress\` restores previously compressed content when you need exact details.
6471
6487
 
6472
6488
  \`<dcp-message-id>\` and \`<dcp-system-reminder>\` tags are environment-injected metadata. Do not output them.
6473
6489
 
6474
- THE PHILOSOPHY OF COMPRESS
6475
- \`compress\` transforms conversation content into dense, high-fidelity summaries. This is not cleanup - it is crystallization. Your summary becomes the authoritative record of what transpired.
6490
+ COMPRESSION PHILOSOPHY
6491
+
6492
+ Compression replaces raw conversation content with dense summaries. When used correctly, it keeps your context sharp and focused. When used carelessly, it destroys information you need.
6493
+
6494
+ The key principle: compress based on context pressure, not habit. When context is ample, compress rarely or not at all. When context is tight, compress aggressively but selectively. The runtime context usage indicator tells you the current pressure level.
6495
+
6496
+ Target the largest UNCOMPRESSED content first. Savings scale with original size \u2014 compressing a 5000-token tool output frees far more than re-shrinking an already-summarized 300-token block.
6497
+
6498
+ CONTEXT PRESSURE LEVELS
6499
+
6500
+ - Ample: Context is well below the threshold. Do NOT compress unless there is obvious waste (huge terminal dumps, duplicated content). Focus entirely on your task.
6501
+ - Moderate: Context is approaching the threshold. Compress completed sections proactively. Prioritize high-token waste over minor cleanup.
6502
+ - High: Context has exceeded the threshold. Compress aggressively. Every compression should free meaningful tokens. Preserve only what is essential for the current task.
6503
+
6504
+ WHAT TO COMPRESS FIRST (high value, low risk)
6505
+
6506
+ - Agent/subagent review and consultation results: Prime compression targets when context pressure rises \u2014 the surrounding reasoning and tool-call chatter is typically the largest block of uncompressed content. Note: if the agent tool is in your protected list, its output is auto-preserved in the summary, so the savings come from the surrounding conversation, not the agent output itself. Compress once you have fully consumed the results (all recommended actions applied or recorded in files). Recover via \`decompress\` while the block is still active. Re-invoking the agent is a last resort \u2014 it is a fresh run, not a cache hit.
6507
+ - Verbose command output (build/test runs, git diff/log/status, publish logs, directory listings): Once you have read the result, compress. Keep only the verdict \u2014 pass/fail status, commit hash, version number, or count. For failures, keep the specific error messages and file/line references needed to act on them. The full output is reproducible by re-running the command.
6508
+ - Exploration that led nowhere (failed approaches, dead-end searches): Compress to a one-line note about what was tried and why it failed.
6509
+ - Redundant tool results (reading the same file multiple times, repeated status checks, exhausted search results): Keep only the most recent result.
6510
+ - Intermediate steps of completed multi-step tasks: Once the task is done, compress the process. Keep only the final outcome.
6511
+ - Resolved discussion threads (clarification rounds, negotiated requirements, design debate that reached a decision): Once a conclusion is recorded, compress the back-and-forth. Keep the decision and its rationale.
6512
+ - Large file contents that have already been used and are no longer needed: Compress to a summary of key functions, types, or patterns.
6513
+
6514
+ DO NOT RE-COMPRESS (low value, diminishing returns)
6515
+
6516
+ - Already-compressed block summaries: Re-compressing a summary into a shorter summary saves negligible tokens. If a block needs better detail, use \`decompress\` to restore it, then compress the original content properly. Exception: if a block-aging warning flags specific block IDs as facing GC truncation, re-summarize exactly those flagged blocks into a fresh range \u2014 this preserves detail that GC would otherwise destroy.
6517
+ - Short messages (1-3 sentences): The compression overhead (block metadata, summary structure) may exceed the tokens saved.
6518
+ - Content whose immediate use is complete \u2014 the task it supported is done and no open todo/plan references it. If still in active use, let it stay.
6519
+ - User instructions and requirements: These must remain visible until the task is complete.
6520
+ - Tool calls that are still pending or in-progress: Wait until the result is returned and consumed.
6476
6521
 
6477
- Think of compression as phase transitions: raw exploration becomes refined understanding. The original context served its purpose; your summary now carries that understanding forward.
6522
+ WHAT TO COMPRESS CAREFULLY (high risk - verify before compressing)
6478
6523
 
6479
- COMPRESS WHEN
6524
+ - Temporary secrets/keys/tokens needed later: Do NOT compress unless recorded elsewhere
6525
+ - File paths and directory structures: Keep in summary - losing these wastes tokens rediscovering them
6526
+ - Key function/method signatures and APIs: Summarize with exact names and signatures
6527
+ - Critical error messages and stack traces: Keep the error type and key detail in summary
6528
+ - User preferences and requirements: These must survive compression intact
6529
+ - Architectural decisions and rationale: Summarize the decision, not just the conclusion
6480
6530
 
6481
- A section is genuinely closed and the raw conversation has served its purpose:
6531
+ BEFORE COMPRESSING IMPORTANT CONTENT
6482
6532
 
6483
- - Research concluded and findings are clear
6484
- - Implementation finished and verified
6485
- - Exploration exhausted and patterns understood
6486
- - Dead-end noise can be discarded without waiting for a whole chapter to close
6533
+ Verify the information is persisted in one of:
6534
+ - A file you have written or edited
6535
+ - An issue, PR, or devlog entry
6536
+ - The compression summary itself (include the critical bits explicitly)
6487
6537
 
6488
- DO NOT COMPRESS IF
6538
+ If it is not persisted anywhere, either persist it first or include it explicitly in your compression summary.
6489
6539
 
6490
- - Raw context is still relevant and needed for edits or precise references
6491
- - The target content is still actively in progress
6492
- - You may need exact code, error messages, or file contents in the immediate next steps
6540
+ AFTER COMPRESSING
6493
6541
 
6494
- Before compressing, ask: _"Is this section closed enough to become summary-only right now?"_
6542
+ Generate recovery breadcrumbs in your summary so future-you can reconstruct the context:
6543
+ - Reference specific files by path
6544
+ - Include key variable names, function signatures, or configuration values
6545
+ - Note what was decided and why, not just what was done
6546
+ - Example: "Implemented auth check in src/middleware.ts using validateToken() from auth.ts - user table is users not user"
6495
6547
 
6496
- Evaluate conversation signal-to-noise REGULARLY. Use \`compress\` deliberately with quality-first summaries. Prioritize stale content intelligently to maintain a high-signal context window that supports your agency.
6548
+ If you later realize you need the original details from a compressed block, use \`decompress\` to restore them. You can decompress, read the content, then re-compress if needed.
6497
6549
 
6498
- It is of your responsibility to keep a sharp, high-quality context window for optimal performance.
6550
+ Use \`compress\` and \`decompress\` deliberately with quality-first summaries. Prioritize stale content intelligently to maintain a high-signal context window.
6499
6551
  `;
6500
6552
 
6501
6553
  // lib/prompts/compress-range.ts