[FEATURE]: Config-driven agent system — no hardcoded agents, all behavior defined in global config #8723

Open
opened 2026-02-16 18:10:40 -05:00 by yindo · 3 comments
Owner

Originally created by @markokraemer on GitHub (Feb 6, 2026).

Originally assigned to: @thdxr on GitHub.

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

Currently, all 7 built-in agents are a mix of config and hardcoded logic. general, explore, compaction, title, and summary are fully defined via config (permissions, prompts, mode). But build and plan have significant behavior hardcoded in prompt.ts — the insertReminders function string-matches agent.name === "plan" / agent.name === "build" to inject system-reminder blocks, plan file management, mode transition prompts, and the 5-phase planning workflow.

This means the agent system isn't truly modular. You can create custom agents, but you can't fully replace or extend the two most important ones.

Proposal: Fully config-driven agent system

Refactor so that zero agents are hardcoded. The agent runtime should be agnostic — it doesn't know or care about "build" or "plan" by name. Instead:

  1. All agent behavior defined in global config — ship the current build/plan/general/explore/compaction/title/summary as default config entries (in ~/.config/opencode/ or bundled defaults). The runtime loads and executes them generically.

  2. Mode transitions as config — instead of hardcoding "when switching from plan to build, inject this reminder", define transition prompts as part of the agent config. Something like:

    {
      "plan": {
        "on_exit": "{file:./prompts/build-switch.txt}",
        "on_enter": "{file:./prompts/plan-reminder.txt}"
      }
    }
    
  3. Dynamic injection via plugin system — use experimental.chat.messages.transform for things like plan file path injection, rather than hardcoding it in prompt.ts. Ship this as a built-in plugin that users can override or extend.

  4. Template variables for dynamic content — plan file paths, session IDs, etc. could use variables like {plan_file}, {session_id} in prompt templates instead of being assembled in TypeScript.

What this enables

  • Full control — users can customize every aspect of every agent without forking
  • Custom workflows — build your own planning flow, review flow, or multi-phase agent choreography entirely through config
  • More programmatic use — agent behavior becomes data, not code. Easier to generate, compose, and share agent configs
  • Cleaner codebase — the runtime becomes a generic agent executor. Agent-specific logic lives in config where it belongs
  • Default behavior unchanged — new installs ship with the same defaults, just loaded from config instead of hardcoded

Happy to take this on if the team is interested.

Originally created by @markokraemer on GitHub (Feb 6, 2026). Originally assigned to: @thdxr on GitHub. ### Feature hasn't been suggested before. - [x] I have verified this feature I'm about to request hasn't been suggested before. ### Describe the enhancement you want to request Currently, all 7 built-in agents are a mix of config and hardcoded logic. `general`, `explore`, `compaction`, `title`, and `summary` are fully defined via config (permissions, prompts, mode). But `build` and `plan` have significant behavior hardcoded in `prompt.ts` — the `insertReminders` function string-matches `agent.name === "plan"` / `agent.name === "build"` to inject system-reminder blocks, plan file management, mode transition prompts, and the 5-phase planning workflow. This means the agent system isn't truly modular. You can create custom agents, but you can't fully replace or extend the two most important ones. ### Proposal: Fully config-driven agent system Refactor so that **zero agents are hardcoded**. The agent runtime should be agnostic — it doesn't know or care about "build" or "plan" by name. Instead: 1. **All agent behavior defined in global config** — ship the current build/plan/general/explore/compaction/title/summary as default config entries (in `~/.config/opencode/` or bundled defaults). The runtime loads and executes them generically. 2. **Mode transitions as config** — instead of hardcoding "when switching from plan to build, inject this reminder", define transition prompts as part of the agent config. Something like: ```jsonc { "plan": { "on_exit": "{file:./prompts/build-switch.txt}", "on_enter": "{file:./prompts/plan-reminder.txt}" } } ``` 3. **Dynamic injection via plugin system** — use `experimental.chat.messages.transform` for things like plan file path injection, rather than hardcoding it in `prompt.ts`. Ship this as a built-in plugin that users can override or extend. 4. **Template variables for dynamic content** — plan file paths, session IDs, etc. could use variables like `{plan_file}`, `{session_id}` in prompt templates instead of being assembled in TypeScript. ### What this enables - **Full control** — users can customize every aspect of every agent without forking - **Custom workflows** — build your own planning flow, review flow, or multi-phase agent choreography entirely through config - **More programmatic use** — agent behavior becomes data, not code. Easier to generate, compose, and share agent configs - **Cleaner codebase** — the runtime becomes a generic agent executor. Agent-specific logic lives in config where it belongs - **Default behavior unchanged** — new installs ship with the same defaults, just loaded from config instead of hardcoded Happy to take this on if the team is interested.
Author
Owner

@github-actions[bot] commented on GitHub (Feb 6, 2026):

This issue might be a duplicate of existing issues. Please check:

  • #5005: unexpected system prompt parts despite disabling default agent(s)

This related issue documents the exact problem being addressed here — system prompt parts are leaking despite disabling default agents, which is caused by the hardcoded insertReminders function you've identified.

Feel free to ignore if this doesn't fully capture your use case.

@github-actions[bot] commented on GitHub (Feb 6, 2026): This issue might be a duplicate of existing issues. Please check: - #5005: unexpected system prompt parts despite disabling default agent(s) This related issue documents the exact problem being addressed here — system prompt parts are leaking despite disabling default agents, which is caused by the hardcoded `insertReminders` function you've identified. Feel free to ignore if this doesn't fully capture your use case.
Author
Owner

@markokraemer commented on GitHub (Feb 6, 2026):

btw was just opencode generated issue ofc, but should describe it well

@markokraemer commented on GitHub (Feb 6, 2026): btw was just opencode generated issue ofc, but should describe it well
Author
Owner

@NateAGeek commented on GitHub (Feb 11, 2026):

I do agree with this, as it would allow better maintenance imo. Currently I only see logic for Plan mode to switch to Build mode. But that doesn't seem to be used.

@NateAGeek commented on GitHub (Feb 11, 2026): I do agree with this, as it would allow better maintenance imo. Currently I only see logic for Plan mode to switch to Build mode. But that doesn't seem to be used.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#8723