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:
@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user