fix(ai): read the assistant model from the account data - #4886
Merged
Conversation
paultranvan
force-pushed
the
fix/assistant-model-update
branch
from
July 29, 2026 16:16
1f9c777 to
2280bd1
Compare
paultranvan
marked this pull request as ready for review
July 29, 2026 16:16
Member
|
Does it make sense not to store a model in auth.login at all? |
Member
|
And how we update the model in the account info? |
Contributor
Author
actually yes, it makes more sense. I change it, so it is now on |
Contributor
Author
On user-side, we can edit an external LLM provider account with a new model name (gpt-4, opus5, mistral-large, ...) |
paultranvan
force-pushed
the
fix/assistant-model-update
branch
from
August 26, 2026 09:39
2280bd1 to
0764e1b
Compare
Changing an AI assistant's model had no effect unless the API key was retyped at the same time: the conversation kept running on the model the assistant was created with. The provider account stored the model in `auth.login` and the API key in `auth.password`, and `encryptMap` bundles that pair into `auth.credentials_encrypted`. The blob is only rebuilt when a password is present in the incoming document, so editing only the model left it encrypting the previous model — and `buildLLMOverride` preferred the blob. Rather than picking the fresher of two copies, stop duplicating the model. It is configuration, not a credential, so it now lives in `data.model` next to `data.baseUrl`, out of reach of the encryptor. `llmModel` and `llmAPIKey` split the two concerns, and the encrypted blob is never consulted for the model: its copy is the one that goes stale. Accounts written before the move still carry the model in `auth.login`, which is always up to date, so `llmModel` falls back to it and no migration is required. That fallback can be dropped once cozy-client writes `data.model` and existing accounts have been rewritten.
paultranvan
force-pushed
the
fix/assistant-model-update
branch
from
August 26, 2026 09:43
0764e1b to
3dcceb0
Compare
shepilov
approved these changes
Aug 26, 2026
paultranvan
added a commit
to linagora/cozy-client
that referenced
this pull request
Aug 26, 2026
The stack bundles `auth.login` and `auth.password` into
`auth.credentials_encrypted`, and only rebuilds that blob when a
password is sent. Keeping the model in `auth.login` therefore
duplicated it into an encrypted copy that went stale as soon as the
model was edited without retyping the API key — and that copy was the
one forwarded to the LLM.
The model is configuration, not a credential, so it moves to
`data.model` next to `data.baseUrl`. `auth` is now what the stack
encrypts (the API key), `data` is the rest, and the triplet maps onto
the stack's `llm_override` = `{model, api_key, base_url}`.
`editAssistant` drops a leftover `auth.login`, so accounts created
before the move migrate as soon as they are edited. The encrypted blob
is left alone: the stack reads the API key from it and never the model.
Requires cozy-stack reading `data.model` (linagora/cozy-stack#4886).
paultranvan
added a commit
to linagora/cozy-client
that referenced
this pull request
Aug 26, 2026
The stack bundles `auth.login` and `auth.password` into
`auth.credentials_encrypted` and only rebuilds that blob when a password
is sent. Keeping the model in `auth.login` duplicated it into an
encrypted copy that went stale as soon as the model was edited without
retyping the API key — and that copy was the one forwarded to the LLM.
The model is configuration, not a credential, so it moves to
`data.model` next to `data.baseUrl`. The triplet then maps onto the
stack's `llm_override` = `{model, api_key, base_url}`.
Dropping a leftover `auth.login` migrates accounts created before the
move as soon as they are edited. The encrypted blob is left alone: the
stack reads the API key from it and never the model.
Requires cozy-stack reading `data.model` (linagora/cozy-stack#4886).
paultranvan
added a commit
to linagora/cozy-client
that referenced
this pull request
Aug 27, 2026
The stack bundles `auth.login` and `auth.password` into
`auth.credentials_encrypted` and only rebuilds that blob when a password
is sent. Keeping the model in `auth.login` duplicated it into an
encrypted copy that went stale as soon as the model was edited without
retyping the API key — and that copy was the one forwarded to the LLM.
The model is configuration, not a credential, so it moves to
`data.model` next to `data.baseUrl`. The triplet then maps onto the
stack's `llm_override` = `{model, api_key, base_url}`.
Dropping a leftover `auth.login` migrates accounts created before the
move as soon as they are edited. The encrypted blob is left alone: the
stack reads the API key from it and never the model.
Requires cozy-stack reading `data.model` (linagora/cozy-stack#4886).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Changing an AI assistant's model has no effect unless the API key is retyped at the same time: the conversation keeps running on the model the assistant was created with.
The provider account stores the model in
auth.loginand the API key inauth.password, and the stack bundles the two intoauth.credentials_encrypted(encryptMap,model/account/credentials.go). That blob is only rebuilt when apasswordis present in the incoming document, so editing only the model leaves it encrypting the previous model — andbuildLLMOverrideread the blob in preference to the plain fields.The model therefore exists in two places that drift apart, and the stale one won.
Fix
Rather than picking the fresher of the two copies, stop duplicating the model.
The model is configuration, not a credential, so it moves to
data.model, next to thedata.baseUrlthat was already there — out of reach of the encryptor, which only ever touchesauth. The two concerns are split intollmModelandllmAPIKey:auth.login, duplicated into the encrypted blobdata.modelauth.password→ encrypted blobdata.baseUrlauthnow holds what must be encrypted,dataholds the rest, and the resulting triplet maps one-to-one onto OpenRAG'sllm_override={model, api_key, base_url}.The encrypted blob is deliberately never consulted for the model: its copy is precisely the one that goes stale, and resurrecting it would turn a missing field into a silently wrong value.
Impact
No migration required. Accounts written before the move still carry the model in
auth.login, which is never encrypted and therefore always up to date, sollmModelfalls back to it. Every existing assistant is fixed as soon as this is deployed, and the stack can ship independently of the client.The fallback is marked as transitional: it can be dropped once cozy-client writes
data.modeland existing accounts have been rewritten.Follow-up on the client side
cozy-client must write
data.modeland stop writingauth.login. Note the ordering constraint: an account's display label is derived fromauth[account.identifier], falling back toauth.login(cozy-harvest-libgetLabel, cozy-doctypesAccount.getAccountName). Onceauth.loginis gone, that falls through toaccount._id, so the client change that setsidentifier: 'accountName'andauth.accountNamemust land first.That naming is a separate symptom of the same root cause — with the model sitting in
auth.login,ComputeNamelabelled these accountsgemini-2.5-flashinstead ofGoogle— and is handled in its own client-side PR.Tests
TestLLMModelandTestLLMAPIKeycover the data/login precedence, the legacy fallback, the encrypted-key paths, and one case that explicitly locks in that a stale encrypted model is never resurrected.