feat: finalise multi-profil Codex/Claude avec catalogue de modèles

- Backend : clone_profile_from_seed généralisé (non OpenCode)
- Backend : catalogue static Claude/Codex (3 modèles chacun, 1 recommandé)
- Backend : commandes Tauri list_claude_models/list_codex_models
- Frontend : ProfilesSettings refonte en onglets Codex/Claude + create/duplicate/edit/delete
- Frontend : ModelSelect searchable partagé + fallback saisie manuelle
- Frontend : assignation agent nom · modèle
- Tests QA : 4 profils modèles distincts (2 Claude, 2 Codex) assignés à agents
This commit is contained in:
2026-07-26 14:56:26 +02:00
parent c807a70fea
commit ea7ea71230
21 changed files with 1298 additions and 109 deletions

View File

@ -35,6 +35,7 @@ import type {
McpToolCatalogue,
McpToolPolicy,
OpenCodeProviderCatalogEntry,
ProfileModelCatalogEntry,
EffectivePermissions,
PairedDevice,
PairingCode,
@ -80,6 +81,7 @@ import type {
ConversationGateway,
ConversationPageRequest,
ConversationDetails,
CloneProfileFromSeedInput,
CloneOpenCodeProfileFromSeedInput,
CreateAgentInput,
CreateMemoryInput,
@ -1293,6 +1295,54 @@ const MOCK_OPENCODE_PROVIDERS: OpenCodeProviderCatalogEntry[] = [
},
];
const MOCK_CLAUDE_MODELS: ProfileModelCatalogEntry[] = [
{
adapter: "claude",
modelId: "claude-sonnet-5",
displayName: "Claude Sonnet 5",
aliases: ["sonnet"],
recommended: true,
},
{
adapter: "claude",
modelId: "claude-opus-4-8",
displayName: "Claude Opus 4.8",
aliases: ["opus"],
recommended: false,
},
{
adapter: "claude",
modelId: "claude-haiku-4-5-20251001",
displayName: "Claude Haiku 4.5",
aliases: ["haiku"],
recommended: false,
},
];
const MOCK_CODEX_MODELS: ProfileModelCatalogEntry[] = [
{
adapter: "codex",
modelId: "gpt-5-codex",
displayName: "GPT-5 Codex",
aliases: ["codex"],
recommended: true,
},
{
adapter: "codex",
modelId: "gpt-5",
displayName: "GPT-5",
aliases: ["general"],
recommended: false,
},
{
adapter: "codex",
modelId: "gpt-5-mini",
displayName: "GPT-5 mini",
aliases: ["mini", "fast"],
recommended: false,
},
];
/**
* In-memory profiles gateway. Tracks configured profiles and a first-run flag so
* the wizard can be driven and tested fully offline. By default it reports the
@ -1348,6 +1398,36 @@ export class MockProfileGateway implements ProfileGateway {
return structuredClone(profiles);
}
async cloneProfileFromSeed(
input: CloneProfileFromSeedInput,
): Promise<AgentProfile> {
const seed = [...this.profiles, ...MOCK_REFERENCE_PROFILES].find(
(p) => p.id === input.seedProfileId,
);
if (!seed) throw new Error(`unknown profile seed: ${input.seedProfileId}`);
this.cloneCounter += 1;
const cloned: AgentProfile = {
...structuredClone(seed),
id: `mock-profile-clone-${this.cloneCounter}`,
name: input.name ?? `${seed.name} copy`,
model:
input.model !== undefined && input.model.trim() !== ""
? input.model
: seed.model,
};
this.profiles.push(cloned);
this.configured = true;
return structuredClone(cloned);
}
async listClaudeModels(): Promise<ProfileModelCatalogEntry[]> {
return structuredClone(MOCK_CLAUDE_MODELS);
}
async listCodexModels(): Promise<ProfileModelCatalogEntry[]> {
return structuredClone(MOCK_CODEX_MODELS);
}
async cloneOpenCodeProfileFromSeed(
input: CloneOpenCodeProfileFromSeedInput = {},
): Promise<AgentProfile> {