Repository navigation
Description
What problem does this solve?
Ensemble delivers teammate messages to the lead via OpenCode promptAsync.
When the receiving lead session is using a non-Build agent, such as Plan,
the injected message can start the next prompt loop using OpenCode's Build
agent and default model instead.
This defeats Plan mode's safety boundary: a lead that was intentionally in
Plan mode can automatically continue in Build mode after a teammate message,
before the user has an opportunity to send another message or restore Plan
mode.
Example correspondance:
- “[Original user request]” — agent:
plan - “[System: New team message from writer-exceptions]” — agent:
build - “[System: New team message from field-contracts]” — agent:
build
Here, my original content was with plan, but it ended up being build - and then the session proceeded to modify files & do commits. That was unfortunate. :)
Environment:
- OpenCode: 1.18.25
- Ensemble: 0.17.0
- OS: Windows
What would you like to see?
Preserve the receiving lead's active agent and model when Ensemble injects a
teammate notification.
Specifically, when calling client.session.promptAsync to deliver a message
to the lead, Ensemble should determine the lead's current agent and model at
delivery time and pass them explicitly in the request.
For example, if the lead is currently using plan, the injected teammate
message should use agent: "plan" rather than falling back to Build. The
same should apply to the active model when it is known.
Desired behavior:
- A Plan lead remains a Plan lead after teammate messages.
- An Explore lead remains an Explore lead after teammate messages.
- Notifications do not silently select Build or change models.
- If Ensemble cannot determine the current recipient agent/model, it should
fall back to existing behavior and log that fallback clearly.
This appears feasible because OpenCode's promptAsync API accepts explicit
agent and model fields.
Alternatives considered
- Change OpenCode's global default agent. This is not a reliable fix and would affect unrelated sessions.
The current README documents the behavior as a limitation, but preserving the
agent/model in Ensemble's promptAsync call would avoid the unsafe fallback. But it seems that this limitation is gone, at least as of OC 1.18.x.. :)
Activity
LordMike commentedon Sep 5, 2026
I see now a potential conflict here.
.. That sucks, thats the issue. But a fix here would probably track the original model A in the teammember, (or team), so in this scenario, the user would switch to A.. Its better, because A is likely closer to what the user wanted, but its still not C.
The proper fix is likely in OpenCode itself, to have PromptAsync not switch the model of the target session, if the parameter is unspecified.
LordMike commentedon Sep 5, 2026
I put an agent on it. Its discovered that Ensemble probably does nothing wrong here - it calls promptasync with no model nor agent specified. But OpenCode has an unfortunate behaviour, where it will use the default agent if not specified, and if an agent is specified, it will use the default model for that agent.
Issues in OC's tracker:
LordMike commentedon Sep 5, 2026
I workarounded this in a local copy, by having ensemble scan the target session for the last non-ensemble user message, and copying the agent/model from that. It currently works here locally.
I've made a bunch of other changes too, because gpt-6-astra found bugs. Truth be told, I have no idea how correct it is, so I'm not making a PR for them. But if others need anything, my fork is here: https://github.com/LordMike/opencode-ensemble
LordMike commentedon Sep 13, 2026
This was merged:anomalyco/opencode#46106 .. update: not merged, I misread a different PR.