Skip to content

fix(opencode): use instructions array, not agent.build.prompt#60

Merged
chubes4 merged 1 commit intomainfrom
fix/opencode-instructions-not-agent-prompt
Apr 22, 2026
Merged

fix(opencode): use instructions array, not agent.build.prompt#60
chubes4 merged 1 commit intomainfrom
fix/opencode-instructions-not-agent-prompt

Conversation

@chubes4
Copy link
Copy Markdown
Member

@chubes4 chubes4 commented Apr 22, 2026

Summary

Switch runtimes/opencode.sh away from emitting agent.build.prompt / agent.plan.prompt with a {file:}-bundle, and over to a top-level instructions: [...] array.

Root cause

Setting agent.build.prompt in opencode.json puts our custom prompt at the very top of system[1] in the outgoing Anthropic request, which pushes OpenCode's canonical <environment>…Skills provide specialized instructions… opening down.

Anthropic's third-party-app detector fingerprints the first bytes of system[1] on Claude Max OAuth requests. When the canonical opening isn't the first thing, the request is routed through extra-usage billing and returns HTTP 400:

{"error":{"type":"invalid_request_error",
 "message":"Third-party apps now draw from your extra usage,
            not your plan limits. Add more at
            claude.ai/settings/usage and keep going."}}

This bricks every Opus-tier Claude Max request the moment any memory file is attached via agent.build.prompt, even a tiny one (repro: 251-byte USER.md is enough).

Tied to remorses/kimaki#99 — Kimaki 0.4.101 fixed the system-prompt sanitization for its request path, but wp-coding-agents' hand-written agent.build.prompt bypasses the sanitizer's anchor and re-breaks it.

Fix

runtime_generate_config() now emits "instructions": ["./path1", "./path2", ...] from $DM_AGENT_FILES. OpenCode loads each path through Instruction.system() in packages/opencode/src/session/instruction.ts and appends them with the Instructions from: <path> prefix after the canonical opening — the same mechanism that auto-discovers AGENTS.md. OAuth flow stays intact; memory is preserved end-to-end.

Also drops the now-unused OPENCODE_PROMPT builder in runtime_discover_dm_paths (AGENTS.md auto-discovery covers the root file; memory files ride the instructions array).

Test plan

  • Reproduce 400 on Opus-4-7 with agent.build.prompt = "{file:./AGENTS.md}\n{file:...}" on live intelligence-chubes4 (Kimaki 0.6.0, opencode 1.14.20)
  • Apply the equivalent manual fix to opencode.json on the live site → 200 OK, full memory in context (AGENTS.md + SITE.md + RULES.md + SOUL.md + USER.md + MEMORY.md all present in system[])
  • bash -n runtimes/opencode.sh
  • Fresh setup on a clean site: setup.sh produces opencode.json with instructions array, no agent block
  • Kimaki + Opus-4-7 flow works end-to-end on the regenerated config

🤖 Generated with Claude Code

Setting agent.build.prompt/agent.plan.prompt in opencode.json puts the
custom prompt at the top of system[1], pushing OpenCode's canonical
`<environment>…Skills provide specialized instructions…` opening down.

Anthropic's third-party-app detector fingerprints the first bytes of
system[1] on Claude Max OAuth requests. When the canonical opening is
missing, it routes the request to extra-usage billing and returns 400:

  {"error":{"type":"invalid_request_error",
    "message":"Third-party apps now draw from your extra usage,
               not your plan limits. Add more at
               claude.ai/settings/usage and keep going."}}

This blocks every Opus-tier Claude Max request the moment the user
attaches any memory file via agent.build.prompt, even if the file is
tiny (repro: 251-byte USER.md still breaks).

Fix: emit a top-level `instructions` array instead. OpenCode loads each
path through Instruction.system() (packages/opencode/src/session/
instruction.ts), appending them with the `Instructions from: <path>`
prefix *after* the canonical opening — the same mechanism that
auto-discovers AGENTS.md. The OAuth flow stays intact and memory is
preserved end-to-end.

Also drops the now-unused OPENCODE_PROMPT builder in
runtime_discover_dm_paths (AGENTS.md auto-discovery covers the root
file; memory files ride the instructions array).

Verified on intelligence-chubes4 (Kimaki 0.6.0 + opencode 1.14.20):
- agent.build.prompt with {file:} includes → 400 on opus-4-7
- instructions array with same paths → 200 OK, full memory in context
@chubes4 chubes4 merged commit ece0656 into main Apr 22, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant