fix: track agent config changes and health-check selected models only

This commit is contained in:
lzt404 committed 2026-08-04 18:07:34 +08:00
1 parent 4d32f58ee2
commit 02c6fac72a
8 files changed
+180 -59

No files matched your search

+68
View File
@@ -0,0 +1,68 @@
export type AgentConfigurationClientId =
| 'claude-code'
| 'claude-desktop'
| 'codex'
| 'opencode'
| 'openclaw'
| 'hermes'
| 'pi';
export type AgentConfigurationModificationState = 'unconfigured' | 'applied' | 'invalid';
export type AgentConfigurationAction = 'apply' | 'update' | 'close';
export type AgentModelMappings = {
opus: string;
sonnet: string;
haiku: string;
};
type ResolveAgentConfigurationActionOptions = {
client: AgentConfigurationClientId;
modificationState: AgentConfigurationModificationState;
selectedModel: string;
appliedModel: string;
oauthConfiguration: boolean;
appliedOauthConfiguration: boolean;
modelMappings: AgentModelMappings;
appliedModelMappings: AgentModelMappings;
};
const normalizedModel = (value: string) => value.trim().toLocaleLowerCase();
export const sameAgentModel = (left: string, right: string) => (
normalizedModel(left) === normalizedModel(right)
);
export const sameAgentModelMappings = (
left: AgentModelMappings,
right: AgentModelMappings,
) => sameAgentModel(left.opus, right.opus)
&& sameAgentModel(left.sonnet, right.sonnet)
&& sameAgentModel(left.haiku, right.haiku);
export function resolveAgentConfigurationAction({
client,
modificationState,
selectedModel,
appliedModel,
oauthConfiguration,
appliedOauthConfiguration,
modelMappings,
appliedModelMappings,
}: ResolveAgentConfigurationActionOptions): AgentConfigurationAction {
if (modificationState !== 'applied') return 'apply';
if (client === 'pi') return 'close';
const modelChanged = client === 'claude-code' || client === 'claude-desktop'
? !sameAgentModelMappings(modelMappings, appliedModelMappings)
: Boolean(
selectedModel.trim()
&& appliedModel.trim()
&& !sameAgentModel(selectedModel, appliedModel),
);
const oauthChanged = client === 'codex'
&& oauthConfiguration !== appliedOauthConfiguration;
return modelChanged || oauthChanged ? 'update' : 'close';
}
+10 -9
View File
@@ -65,20 +65,21 @@ export function primaryProviderHealthCredential(apiKeys: string[]): string {
export function mergeProviderHealthModels(
discoveredModels: ModelOption[],
configuredModels: ModelOption[],
testModel = '',
): ModelOption[] {
const models = new Map<string, ModelOption>();
[...discoveredModels, ...configuredModels].forEach((model) => {
const configured = new Map<string, ModelOption>();
configuredModels.forEach((model) => {
const name = model.name.trim();
if (!name) return;
const key = name.toLowerCase();
models.set(key, { ...models.get(key), ...model, name });
configured.set(key, { ...configured.get(key), ...model, name });
});
const normalizedTestModel = testModel.trim();
if (normalizedTestModel && !models.has(normalizedTestModel.toLowerCase())) {
models.set(normalizedTestModel.toLowerCase(), { name: normalizedTestModel });
}
return Array.from(models.values()).sort((left, right) =>
discoveredModels.forEach((model) => {
const key = model.name.trim().toLowerCase();
const selected = configured.get(key);
if (!selected) return;
configured.set(key, { ...model, ...selected });
});
return Array.from(configured.values()).sort((left, right) =>
left.name.localeCompare(right.name, undefined, { sensitivity: 'base' }),
);
}