opencode-acp 1.1.0 → 1.1.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
@@ -1758,6 +1758,10 @@ function filterMessagesInPlace(messages) {
1758
1758
  }
1759
1759
 
1760
1760
  // lib/messages/query.ts
1761
+ function isSyntheticMessage(message) {
1762
+ const id = message?.info?.id;
1763
+ return typeof id === "string" && (id.startsWith("msg_dcp_summary_") || id.startsWith("msg_dcp_text_"));
1764
+ }
1761
1765
  var getLastUserMessage = (messages, startIndex) => {
1762
1766
  const start = startIndex ?? messages.length - 1;
1763
1767
  for (let i = start; i >= 0; i--) {
@@ -1765,7 +1769,7 @@ var getLastUserMessage = (messages, startIndex) => {
1765
1769
  if (!isMessageWithInfo(msg)) {
1766
1770
  continue;
1767
1771
  }
1768
- if (msg.info.role === "user" && !isIgnoredUserMessage(msg)) {
1772
+ if (msg.info.role === "user" && !isIgnoredUserMessage(msg) && !isSyntheticMessage(msg)) {
1769
1773
  return msg;
1770
1774
  }
1771
1775
  }
@@ -6098,6 +6102,9 @@ function findLastNonIgnoredMessage(messages) {
6098
6102
  if (isIgnoredUserMessage(message)) {
6099
6103
  continue;
6100
6104
  }
6105
+ if (isSyntheticMessage(message)) {
6106
+ continue;
6107
+ }
6101
6108
  return { message, index: i };
6102
6109
  }
6103
6110
  return null;
@@ -6308,10 +6315,48 @@ function buildContextUsageInfo(currentTokens, modelContextLimit) {
6308
6315
 
6309
6316
  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.`;
6310
6317
  }
6311
- function applyAnchoredNudges(state, config, messages, prompts, compressionPriorities, currentTokens, modelContextLimit) {
6318
+ function applyAnchoredNudges(state, config, messages, prompts, compressionPriorities, currentTokens, modelContextLimit, suffixMessage) {
6312
6319
  const contextUsageInfo = buildContextUsageInfo(currentTokens, modelContextLimit);
6313
6320
  const contextLimitNudgeWithUsage = prompts.contextLimitNudge + contextUsageInfo;
6314
6321
  const turnNudgeAnchors = collectTurnNudgeAnchors2(state, config, messages);
6322
+ if (suffixMessage) {
6323
+ const nudgeParts = [];
6324
+ if (config.compress.mode === "message") {
6325
+ if (state.nudges.contextLimitAnchors.size > 0) {
6326
+ for (const { index } of collectAnchoredMessages(state.nudges.contextLimitAnchors, messages)) {
6327
+ const guidance = buildMessagePriorityGuidance(messages, compressionPriorities, index, MESSAGE_MODE_NUDGE_PRIORITY);
6328
+ nudgeParts.push(appendGuidanceToDcpTag(contextLimitNudgeWithUsage, guidance));
6329
+ }
6330
+ }
6331
+ if (turnNudgeAnchors.size > 0) {
6332
+ for (const { index } of collectAnchoredMessages(turnNudgeAnchors, messages)) {
6333
+ const guidance = buildMessagePriorityGuidance(messages, compressionPriorities, index, MESSAGE_MODE_NUDGE_PRIORITY);
6334
+ nudgeParts.push(appendGuidanceToDcpTag(prompts.turnNudge, guidance));
6335
+ }
6336
+ }
6337
+ if (state.nudges.iterationNudgeAnchors.size > 0) {
6338
+ for (const { index } of collectAnchoredMessages(state.nudges.iterationNudgeAnchors, messages)) {
6339
+ const guidance = buildMessagePriorityGuidance(messages, compressionPriorities, index, MESSAGE_MODE_NUDGE_PRIORITY);
6340
+ nudgeParts.push(appendGuidanceToDcpTag(prompts.iterationNudge, guidance));
6341
+ }
6342
+ }
6343
+ } else {
6344
+ if (state.nudges.contextLimitAnchors.size > 0) {
6345
+ nudgeParts.push(contextLimitNudgeWithUsage);
6346
+ }
6347
+ if (turnNudgeAnchors.size > 0) {
6348
+ nudgeParts.push(prompts.turnNudge);
6349
+ }
6350
+ if (state.nudges.iterationNudgeAnchors.size > 0) {
6351
+ nudgeParts.push(prompts.iterationNudge);
6352
+ }
6353
+ }
6354
+ const combined = nudgeParts.join("\n\n");
6355
+ if (combined.trim()) {
6356
+ injectAnchoredNudge(suffixMessage, combined);
6357
+ }
6358
+ return;
6359
+ }
6315
6360
  if (config.compress.mode === "message") {
6316
6361
  applyMessageModeAnchoredNudge(
6317
6362
  state.nudges.contextLimitAnchors,
@@ -6354,6 +6399,14 @@ function applyAnchoredNudges(state, config, messages, prompts, compressionPriori
6354
6399
  }
6355
6400
 
6356
6401
  // lib/messages/inject/inject.ts
6402
+ var ACP_SUFFIX_SEED = "acp-dynamic-guidance";
6403
+ function createSuffixMessage(messages) {
6404
+ if (messages.length === 0) return null;
6405
+ const base = messages.find((m) => m.info.role === "user") || messages[messages.length - 1];
6406
+ const synthetic = createSyntheticUserMessage(base, "", ACP_SUFFIX_SEED);
6407
+ messages.push(synthetic);
6408
+ return synthetic;
6409
+ }
6357
6410
  var injectCompressNudges = (state, config, logger, messages, prompts, compressionPriorities) => {
6358
6411
  if (compressPermission(state, config) === "deny") {
6359
6412
  return;
@@ -6436,40 +6489,40 @@ var injectCompressNudges = (state, config, logger, messages, prompts, compressio
6436
6489
  }
6437
6490
  }
6438
6491
  }
6439
- applyAnchoredNudges(state, config, messages, prompts, compressionPriorities, currentTokens, modelContextLimit);
6440
- injectContextUsage(messages, currentTokens, modelContextLimit);
6492
+ const suffixMessage = createSuffixMessage(messages);
6493
+ applyAnchoredNudges(state, config, messages, prompts, compressionPriorities, currentTokens, modelContextLimit, suffixMessage);
6494
+ injectContextUsage(suffixMessage, currentTokens, modelContextLimit);
6441
6495
  if (config.compress.mode !== "message") {
6442
6496
  const blockGuidance = buildCompressedBlockGuidance(state, config.gc, { currentTokens, modelContextLimit });
6443
- if (blockGuidance.trim()) {
6444
- const lastUser = getLastUserMessage(messages);
6445
- if (lastUser) appendToLastTextPart(lastUser, "\n\n" + blockGuidance);
6497
+ if (blockGuidance.trim() && suffixMessage) {
6498
+ appendToLastTextPart(suffixMessage, "\n\n" + blockGuidance);
6446
6499
  }
6447
6500
  }
6448
- injectVisibleIdRange(state, messages);
6501
+ injectVisibleIdRange(state, messages, suffixMessage);
6449
6502
  if (anchorsChanged) {
6450
6503
  void saveSessionState(state, logger);
6451
6504
  }
6452
6505
  };
6453
- function injectContextUsage(messages, currentTokens, modelContextLimit) {
6506
+ function injectContextUsage(target, currentTokens, modelContextLimit) {
6507
+ if (!target) return;
6454
6508
  if (currentTokens === void 0 || modelContextLimit === void 0 || modelContextLimit === 0) {
6455
6509
  return;
6456
6510
  }
6457
- const lastUser = getLastUserMessage(messages);
6458
- if (!lastUser) return;
6459
6511
  const percentage = (currentTokens / modelContextLimit * 100).toFixed(1);
6460
6512
  const formatK = (n) => n >= 1e3 ? `${(n / 1e3).toFixed(1)}K` : String(n);
6461
6513
  const usageTag = `
6462
6514
 
6463
6515
  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.`;
6464
- for (const part of lastUser.parts) {
6516
+ for (const part of target.parts) {
6465
6517
  if (part.type === "text") {
6466
6518
  appendToTextPart(part, usageTag);
6467
6519
  return;
6468
6520
  }
6469
6521
  }
6470
- lastUser.parts.push(createSyntheticTextPart(lastUser, usageTag));
6522
+ target.parts.push(createSyntheticTextPart(target, usageTag));
6471
6523
  }
6472
- function injectVisibleIdRange(state, messages) {
6524
+ function injectVisibleIdRange(state, messages, target) {
6525
+ if (!target) return;
6473
6526
  const visibleRefs = [];
6474
6527
  for (const message of messages) {
6475
6528
  const ref = state.messageIds.byRawId.get(message.info.id);
@@ -6484,15 +6537,13 @@ function injectVisibleIdRange(state, messages) {
6484
6537
  const rangeTag = `
6485
6538
 
6486
6539
  [Visible message IDs: ${first} to ${last} (${visibleRefs.length} messages). Only use IDs in this range for compress.]`;
6487
- const lastUser = getLastUserMessage(messages);
6488
- if (!lastUser) return;
6489
- for (const part of lastUser.parts) {
6540
+ for (const part of target.parts) {
6490
6541
  if (part.type === "text") {
6491
6542
  appendToTextPart(part, rangeTag);
6492
6543
  return;
6493
6544
  }
6494
6545
  }
6495
- lastUser.parts.push(createSyntheticTextPart(lastUser, rangeTag));
6546
+ target.parts.push(createSyntheticTextPart(target, rangeTag));
6496
6547
  }
6497
6548
  var injectMessageIds = (state, config, messages, compressionPriorities) => {
6498
6549
  if (compressPermission(state, config) === "deny") {
@@ -8102,7 +8153,7 @@ function configureClientAuth(client) {
8102
8153
  import { readFile as readFile2, rm } from "fs/promises";
8103
8154
  import { basename, dirname as dirname3, join as join5 } from "path";
8104
8155
  import { fileURLToPath } from "url";
8105
- var PACKAGE_NAME = "@tarquinen/opencode-dcp";
8156
+ var PACKAGE_NAME = "opencode-acp";
8106
8157
  function startAutoUpdate(ctx, enabled) {
8107
8158
  if (!enabled) return;
8108
8159
  const controller = new AbortController();