Description
When using duo-workflow-* models, there are two issues that hurt the experience.
1. "I am GitLab Duo, not OpenCode"
Right now OpenCode sends its system prompt as a standard { role: "system" } message through the AI SDK. The problem is that DWS also injects its own system prompt on the server side. The two conflict, and the DWS one wins.
If you start a conversation and ask "who are you?", the model answers "I am GitLab Duo, not OpenCode".
2. Plan mode shows up as a giant user message
The plan mode instructions are injected as a synthetic: true text part on the last user message (prompt.ts:1410-1493). From DWS's perspective, this is just part of the user's message — not a system instruction.
If you open the conversation on a self-hosted GitLab instance, you'll see the user's actual message followed by a wall of text with the system reminder:
This confuses the model (it treats plan instructions as user input) and clutters the conversation history visible on GitLab Duo web interface.
How I fixed this in my plugin
I ran into both issues while building opencode-gitlab-duo-agentic
(https://github.com/gaetan-puleo/opencode-duo-agentic) and found that the DWS startRequest WebSocket message already supports the right parameters to fix this properly:
{
"startRequest": {
"additional_context": [
{ "category": "os_information", "content": "...", "id": "os_information" },
{ "category": "user_rule", "content": "...", "id": "user_rules" },
{ "category": "agent_context", "content": "...", "id": "agent_reminders" }
],
"flowConfig": {
"prompts": [{
"prompt_template": {
"system": "<sanitized system prompt>"
}
}]
},
"flowConfigSchemaVersion": "v1"
}
}
- flowConfig.prompts[].prompt_template.system overrides DWS's default system prompt with OpenCode's own. This fixes the identity conflict.
- additional_context sends the plan mode reminders, OS info, and rules as structured context — not as user message text.
What needs to happen
- Extract the user's actual goal from the last message, stripping tags
- Extract agent reminders (plan mode, build-switch) separately
- Send the system prompt via flowConfig.prompts[].prompt_template.system
- Send reminders and context via additional_context
- We need to add an identifier for each additional_context (like a timestamp, because Duo only keep one instance of the reminder in the history so In my pluggin i used a timestamp as id in my system reminder tags.
I am happy to help if needed.
(ping @vglafirov )
Plugins
No response
OpenCode version
1.2.30
Steps to reproduce
No response
Screenshot and/or share link
No response
Operating System
No response
Terminal
No response
Description
When using duo-workflow-* models, there are two issues that hurt the experience.
1. "I am GitLab Duo, not OpenCode"
Right now OpenCode sends its system prompt as a standard { role: "system" } message through the AI SDK. The problem is that DWS also injects its own system prompt on the server side. The two conflict, and the DWS one wins.
If you start a conversation and ask "who are you?", the model answers "I am GitLab Duo, not OpenCode".
2. Plan mode shows up as a giant user message
The plan mode instructions are injected as a synthetic: true text part on the last user message (prompt.ts:1410-1493). From DWS's perspective, this is just part of the user's message — not a system instruction.
If you open the conversation on a self-hosted GitLab instance, you'll see the user's actual message followed by a wall of text with the system reminder:
This confuses the model (it treats plan instructions as user input) and clutters the conversation history visible on GitLab Duo web interface.
How I fixed this in my plugin
I ran into both issues while building opencode-gitlab-duo-agentic
(https://github.com/gaetan-puleo/opencode-duo-agentic) and found that the DWS startRequest WebSocket message already supports the right parameters to fix this properly:
What needs to happen
I am happy to help if needed.
(ping @vglafirov )
Plugins
No response
OpenCode version
1.2.30
Steps to reproduce
No response
Screenshot and/or share link
No response
Operating System
No response
Terminal
No response