跳到主要内容
    ↑↓ 选择↵ 打开esc 关闭
    中文English
    KONFeature

    Compaction User Prefix

    v0.1.0其他
    opencode-compaction-user-prefix

    opencode plugin that prepends a synthetic user message when a compacted conversation would otherwise start with an assistant tool-call, avoiding the Anthropic `tool_use` without `tool_result` error.

    GitHub 星标

    0

    月装机量

    19

    近 7 天 5

    综合评分SCORE

    23.4

    生态多维模型

    最近提交

    2 个月前

    2026-05-23

    快速安装与配置

    opencode.json

    写入当前项目的 opencode.json,只对这个仓库生效。

    opencode.json

    {
      "$schema": "https://opencode.ai/config.json",
      "plugin": ["opencode-compaction-user-prefix@0.1.0"]
    }

    opencode 启动时会通过内嵌运行时自动加载 npm 依赖并缓存至本地目录,无需手动在全局环境执行安装。

    npm license

    An opencode plugin that works around a compaction bug where a freshly compacted conversation can start with an assistant tool-call message, causing Anthropic to reject the request with:

    messages.N: `tool_use` ids were found without `tool_result` blocks immediately after.
    

    The plugin prepends a synthetic user text message at the experimental.chat.messages.transform boundary so the body sent to the model always begins with a user turn.

    The bug

    When manual or auto compaction runs after a previous compaction whose tail_start_id landed mid-turn on an assistant tool-call, compaction.process builds selected.head as a chain of consecutive assistant tool-call messages with no user message at the start.

    MessageV2.toModelMessagesEffect then faithfully converts that to a model message array whose first entry is assistant tool_use, which Anthropic rejects.

    Upstream reference: opencode session message msg_e5550bcfb001EjDfz6hFE3lpHB (compaction failure on session ses_1ae999d1dffeOLwEseaIFPDg0V).

    How it works

    The plugin hooks experimental.chat.messages.transform, which receives the same WithParts[] opencode is about to pass into toModelMessages. If the first message is an assistant, it prepends a synthetic user text part. opencode recognises text parts in user messages, so the prepended turn survives the conversion and the resulting request body starts with a user message.

    This is safe on the normal chat path because real chat already begins with a user message, in which case the !== "assistant" check short-circuits and nothing is prepended.

    Use

    Register the plugin in your opencode config (opencode.json or ~/.config/opencode/opencode.json):

    {
      "$schema": "https://opencode.ai/config.json",
      "plugin": ["opencode-compaction-user-prefix"]
    }
    

    License

    MIT © Quentin Nivelais