🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@tuanhung303/opencode-acp

Package Overview
Dependencies
Maintainers
1
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tuanhung303/opencode-acp

Reduce LLM token usage by up to 50% through intelligent context pruning. Auto-supersede duplicates, manually discard/distill content, and preserve critical state.

latest
Source
npmnpm
Version
3.0.15
Version published
Weekly downloads
40
5.26%
Maintainers
1
Weekly downloads
 
Created
Source

Agentic Context Pruning (ACP)

npm version CI License: MIT

Agent Context Pruning

Your AI agent wastes half its tokens re-reading old tool outputs, stale file contents, and duplicate results. ACP fixes that — it's a zero-config OpenCode plugin that automatically prunes obsolete context so your agent stays fast, cheap, and focused.

Before / After

 WITHOUT ACP                          WITH ACP
┌──────────────────────────┐        ┌──────────────────────────┐
│ read(config.ts)    3k tk │        │                          │
│ edit(config.ts)    2k tk │        │                          │
│ read(config.ts)    3k tk │  ───►  │ read(config.ts)    3k tk │ ← latest only
│ git status         1k tk │        │ git status         1k tk │ ← latest only
│ git status         1k tk │        │                          │
│ glob(**/*.ts)      4k tk │        │ glob(**/*.ts)      4k tk │
├──────────────────────────┤        ├──────────────────────────┤
│ Total: ~14k tokens       │        │ Total: ~8k tokens  -43%  │
└──────────────────────────┘        └──────────────────────────┘
WorkloadWithout ACPWith ACPSavings
Typical Session~80k tokens~40k tokens50%
Long Session~150k tokens~75k tokens50%
File-Heavy Work~100k tokens~35k tokens65%

Quick Start

Add to your OpenCode config:

// opencode.jsonc
{
    "plugin": ["@tuanhung303/opencode-acp@latest"],
}

That's it. ACP works out of the box — no configuration needed.

What It Does

  • 🔁 Auto-deduplicates — re-reads of the same file, duplicate git status, repeated URL fetches are automatically superseded (details)
  • 📁 One-file-one-view — only the latest read/write/edit of each file stays in context
  • 🧹 Manual pruning — agents can discard, distill, or replace any context block by hash (API reference)
  • 🔖 Todo reminders — nudges agents when tasks are forgotten or stuck
  • 🧠 Thinking mode safe — fully compatible with Anthropic, DeepSeek, and Kimi extended thinking APIs (details)
  • Zero-config — works immediately, with optional presets for fine-tuning

Configuration

ACP works with zero config. For fine-tuning, use presets:

// .opencode/acp.jsonc
{
    "strategies": {
        "aggressivePruning": {
            "preset": "balanced", // "compact" | "balanced" | "verbose"
        },
    },
}
PresetDescriptionBest For
compactMaximum cleanup, all options enabledLong sessions, token-constrained
balancedGood defaults, preserves user codeMost use cases (default)
verboseMinimal cleanup, preserves allDebugging, audit trails

Full configuration reference

Documentation

DocumentDescription
ConfigurationFull config reference, all flags, protected tools
API Referencecontext_prune tool interface, batch ops, pattern replace
Auto-SupersedeAll 8 automatic deduplication strategies
TroubleshootingCommon errors and fixes
ArchitecturePlugin internals and message flow
Validation Guide43 test scenarios
ChangelogVersion history

Provider Compatibility

ProviderThinking ModeCompatibleNotes
AnthropicExtended thinkingStrict validation
DeepSeekDeepThinkSimilar to Anthropic
KimiK1 thinkingSimilar to Anthropic
OpenAINo thinking mode
GoogleNo thinking mode

Contributing

  • Fork → 2. Branch → 3. npm test → 4. PR

CI/CD: PRs run lint + type check + tests automatically. Merges to main auto-publish to npm.

License

MIT © tuanhung303

⚠️ Known Pitfalls for Agents — Critical rules when modifying ACP code

Read this section before modifying ACP code. These are hard-won lessons from debugging production issues.

1. Always Fetch Messages in All Code Paths

❌ WRONG:

async function executeContextToolDiscard(ctx, toolCtx, hashes) {
    const { state, logger } = ctx

    // Validate hashes...

    if (validHashes.length === 0) {
        // Early return without fetching messages
        const currentParams = getCurrentParams(state, [], logger)  // ← BUG: Empty array
        return "No valid hashes"
    }

    // Only fetch messages in success path
    const messages = await client.session.messages(...)
}

✅ CORRECT:

async function executeContextToolDiscard(ctx, toolCtx, hashes) {
    const { client, state, logger } = ctx

    // ALWAYS fetch messages first - required for thinking mode API compatibility
    const messagesResponse = await client.session.messages({
        path: { id: toolCtx.sessionID },
    })
    const messages = messagesResponse.data || messagesResponse

    // ALWAYS initialize session - syncs reasoning_content
    await ensureSessionInitialized(client, state, toolCtx.sessionID, logger, messages)

    // Now validate hashes...

    if (validHashes.length === 0) {
        const currentParams = getCurrentParams(state, messages, logger) // ← Use actual messages
        return "No valid hashes"
    }
}

Why? Anthropic's thinking mode API requires reasoning_content on all assistant messages with tool calls. Skipping ensureSessionInitialized causes 400 errors.

2. Never Skip ensureSessionInitialized

This function syncs reasoning_content from message parts to msg.info. Without it:

error, status code: 400, message: thinking is enabled but reasoning_content is missing
in assistant tool call message at index 2

Rule: Call ensureSessionInitialized at the START of every context_prune tool function, before any early returns.

3. Thinking Mode: Distill, Don't Discard Reasoning

❌ WRONG:

// Completely removing reasoning_content breaks API
state.prune.reasoningPartIds.push(partId)
// No replacement content → field removed → API error

✅ CORRECT:

// Convert discard to distill with minimal placeholder
if (reasoningHashes.length > 0) {
    const minimalSummaries = reasoningHashes.map(() => "—")
    await executeContextReasoningDistill(
        ctx,
        toolCtx,
        reasoningHashes.map((h, i) => [h, minimalSummaries[i]]),
    )
}

Why? The reasoning_content field must exist (even if minimal) for thinking mode providers.

4. Test with Non-Existing Hashes

Always test context_prune tool changes with:

  • Valid existing hashes (success path)
  • Non-existing hashes like "zzzzzz" (no-op path)
  • Mix of valid and invalid hashes

The no-op path is where most bugs hide because it's less tested.

5. Provider-Specific Behavior

ProviderThinking Modereasoning_content RequiredNotes
AnthropicExtended thinking✅ YesStrict validation
DeepSeekDeepThink✅ YesSimilar to Anthropic
KimiK1 thinking✅ YesSimilar to Anthropic
OpenAIN/A❌ NoNo thinking mode
GoogleN/A❌ NoNo thinking mode

Always test with Anthropic when modifying context/pruning logic—it has the strictest API validation.

6. The Transform Hook Timing

User Message → Transform Hook → ensureReasoningContentSync → API Call
                    ↑
            Context tool runs HERE

If context_prune tool returns early (no-op), the transform hook may not have synced reasoning_content yet. That's why each tool function must call ensureSessionInitialized itself.

7. Debug Checklist

When you see reasoning_content is missing errors:

  • Check the error index - "at index 2" means the 3rd message in the array
  • Verify message fetch - Is the function fetching messages before early returns?
  • Verify session init - Is ensureSessionInitialized called in ALL code paths?
  • Check the no-op path - Does the early return path have proper initialization?
  • Test with invalid hash - context_prune({ action: "discard", targets: [["zzzzzz"]] })
🗨️ For LLM Agents — Quick pruning reference and safety guidelines

If you're an AI assistant reading this:

Quick Pruning Reference:

  • Light pressure (<50%): No action
  • Moderate (50-75%): Prune old tool outputs using context_prune({ action: "discard", targets: [[hash]] })
  • High (75-90%): Anchor critical info, then batch prune non-essential items
  • Critical (>90%): Aggressively discard all disposable context

Always Protect: Active todos, current file edits, user requirements

Ask the user: "Would you like me to run a context optimization check?"

Keywords

opencode

FAQs

Package last updated on 18 Feb 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts