[Bug] Active provider/model is dropped and OpenCode falls back to a stale global model
Description
A fresh task can fail immediately with a generic Session error when Accomplish has an active provider/model selected but the user's global OpenCode configuration points to a different provider.
This was observed on macOS with Accomplish 0.5.17 and OpenCode 1.14.18. The task runtime starts successfully and the OpenCode session is created, but the first prompt fails before producing model output.
Steps to Reproduce
- Configure Accomplish with an active Z.AI provider and model
zai/glm-5.1. - Leave a global OpenCode model configured for another provider, for example
google/gemini-2.5-flash. - Start a new task in Accomplish.
- Observe that the task fails with
Session error.
Expected Behavior
The task should use the active Accomplish selection, normalized for OpenCode:
providerID: zai-coding-plan
modelID: glm-5.1The global OpenCode model should not override an explicit Accomplish provider/model selection.
If the model is unavailable, the UI should show the structured provider/model error rather than the generic Session error.
Actual Behavior
The current daemon reads the active model but only copies the model string into TaskConfig; it drops the provider:
apps/daemon/src/task-service.tsreadsgetActiveProviderModel()but assigns onlyselectedModel.model.packages/agent-core/src/internal/classes/OpenCodeAdapter.tsrequires bothconfig.modelIdandconfig.providerbefore sending an SDK model override.- Because the provider is absent, the SDK prompt is sent without an explicit model and OpenCode falls back to the global configuration.
- The generated task config contains
zai-coding-planmodels, while the global model isgoogle/gemini-2.5-flash.
The native OpenCode log confirms the mismatch:
providerID=zai-coding-plan found
ProviderModelNotFoundError:
providerID=google
modelID=gemini-2.5-flashAccomplish also extracts error.message, but OpenCode 1.14.18 stores the useful message under error.data.message. This hides the root cause behind Session error.
Root Cause
- The active internal provider/model selection is not converted into the OpenCode SDK reference and is not passed through for fresh tasks or follow-up tasks.
- OpenCode therefore applies the stale global
modelsetting. - Structured OpenCode session errors are read using the wrong field.
- The task error callback does not preserve the detailed error in the persisted task result, reducing diagnosability.
Proposed Solution
- Introduce one canonical conversion from Accomplish's selected model to the OpenCode SDK reference, reusing the provider mapping and normalization already present in
model-runtime-mapping.ts. - Populate both
TaskConfig.providerandTaskConfig.modelIdfor:- new tasks;
- resumed/follow-up tasks;
- any headless task path that resolves the active provider.
- Ensure the conversion maps values such as:
zai/glm-5.1->zai-coding-plan/glm-5.1;google/gemini-2.5-flash->google/gemini-2.5-flash.
- Keep the explicit SDK model override authoritative over global OpenCode configuration.
- Normalize structured session errors from
error.data.message, retaining the error name and provider/model identifiers when available. - Persist the detailed error message in the task result/database so the debug panel and task history remain useful.
Acceptance Criteria
- With global OpenCode model
google/gemini-2.5-flashand active Accomplish modelzai/glm-5.1, a new task sendsproviderID=zai-coding-planandmodelID=glm-5.1. - The same provider/model behavior works for resumed tasks.
- A provider/model mismatch reports the actual OpenCode error, not only
Session error. - Fresh-task and resume regression tests cover provider mapping, model normalization, and global-config isolation.
- Existing permission/IPC lifecycle behavior remains unchanged.
- No credentials or token contents are logged or persisted.
Environment
- OS: macOS Apple Silicon
- Accomplish: 0.5.17
- OpenCode: 1.14.18
- Active provider/model observed: Z.AI /
zai/glm-5.1
Source: accomplish-ai/coworker