feat: implémentation et QA ticket99 - agent model configuration v2
- backend A-C: VO Codex/Claude, renderers/projecteurs modèle, SecretRef/env, catalogues/use cases/Tauri commands - frontend D: profils Codex/Claude provider->model->secret, validations, conservation SecretRef - fix: app-tauri embedded_server isolant IDEA_WEB_ROOT QA: backend 57/57 tests, frontend 74/74 tests OK
This commit is contained in:
@ -9,6 +9,8 @@ import type {
|
||||
AgentDrift,
|
||||
AppExitWorkGuardState,
|
||||
AgentProfile,
|
||||
ClaudeProviderCatalogEntry,
|
||||
CodexProviderCatalogEntry,
|
||||
DiagnosticWarning,
|
||||
DomainEvent,
|
||||
EmbedderEngines,
|
||||
@ -103,6 +105,8 @@ import type {
|
||||
ReattachResult,
|
||||
RemoteGateway,
|
||||
ReviewPluginPackageInput,
|
||||
SaveClaudeProviderProfileInput,
|
||||
SaveCodexProviderProfileInput,
|
||||
SaveOpenCodeProviderProfileInput,
|
||||
SkillGateway,
|
||||
StoppedLiveAgent,
|
||||
@ -1250,6 +1254,7 @@ export const MOCK_REFERENCE_PROFILES: AgentProfile[] = [
|
||||
contextInjection: { strategy: "conventionFile", target: "CLAUDE.md" },
|
||||
detect: "claude --version",
|
||||
cwdTemplate: "{projectRoot}",
|
||||
structuredAdapter: "claude",
|
||||
},
|
||||
{
|
||||
id: "mock-codex",
|
||||
@ -1259,6 +1264,7 @@ export const MOCK_REFERENCE_PROFILES: AgentProfile[] = [
|
||||
contextInjection: { strategy: "conventionFile", target: "AGENTS.md" },
|
||||
detect: "codex --version",
|
||||
cwdTemplate: "{projectRoot}",
|
||||
structuredAdapter: "codex",
|
||||
},
|
||||
{
|
||||
id: "mock-opencode",
|
||||
@ -1291,6 +1297,25 @@ const MOCK_OPENCODE_PROVIDERS: OpenCodeProviderCatalogEntry[] = [
|
||||
},
|
||||
];
|
||||
|
||||
/** Static mock catalogue mirroring the backend Codex provider list. */
|
||||
const MOCK_CODEX_PROVIDERS: CodexProviderCatalogEntry[] = [
|
||||
{
|
||||
providerId: "openai",
|
||||
displayName: "OpenAI",
|
||||
models: ["gpt-5", "gpt-5-mini", "gpt-5-codex", "o3"],
|
||||
customSupported: true,
|
||||
},
|
||||
];
|
||||
|
||||
/** Static mock catalogue mirroring the backend Claude provider list. */
|
||||
const MOCK_CLAUDE_PROVIDERS: ClaudeProviderCatalogEntry[] = [
|
||||
{
|
||||
providerId: "anthropic",
|
||||
displayName: "Anthropic",
|
||||
models: ["claude-sonnet-4-5", "claude-opus-4-1", "claude-haiku-3-5"],
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -1386,6 +1411,53 @@ export class MockProfileGateway implements ProfileGateway {
|
||||
this.configured = true;
|
||||
return structuredClone(saved);
|
||||
}
|
||||
|
||||
async listCodexProviders(): Promise<CodexProviderCatalogEntry[]> {
|
||||
return structuredClone(MOCK_CODEX_PROVIDERS);
|
||||
}
|
||||
|
||||
async saveCodexProviderProfile(
|
||||
input: SaveCodexProviderProfileInput,
|
||||
): Promise<AgentProfile> {
|
||||
const saved: AgentProfile = {
|
||||
...structuredClone(input.profile),
|
||||
codexProvider: {
|
||||
providerId: input.providerId,
|
||||
model: input.model,
|
||||
apiKeyRef:
|
||||
input.profile.codexProvider?.apiKeyRef ?? `mock-secret-${input.profile.id}`,
|
||||
custom: input.custom,
|
||||
},
|
||||
};
|
||||
const i = this.profiles.findIndex((p) => p.id === saved.id);
|
||||
if (i >= 0) this.profiles[i] = saved;
|
||||
else this.profiles.push(saved);
|
||||
this.configured = true;
|
||||
return structuredClone(saved);
|
||||
}
|
||||
|
||||
async listClaudeProviders(): Promise<ClaudeProviderCatalogEntry[]> {
|
||||
return structuredClone(MOCK_CLAUDE_PROVIDERS);
|
||||
}
|
||||
|
||||
async saveClaudeProviderProfile(
|
||||
input: SaveClaudeProviderProfileInput,
|
||||
): Promise<AgentProfile> {
|
||||
const saved: AgentProfile = {
|
||||
...structuredClone(input.profile),
|
||||
claudeProvider: {
|
||||
providerId: input.providerId,
|
||||
model: input.model,
|
||||
apiKeyRef:
|
||||
input.profile.claudeProvider?.apiKeyRef ?? `mock-secret-${input.profile.id}`,
|
||||
},
|
||||
};
|
||||
const i = this.profiles.findIndex((p) => p.id === saved.id);
|
||||
if (i >= 0) this.profiles[i] = saved;
|
||||
else this.profiles.push(saved);
|
||||
this.configured = true;
|
||||
return structuredClone(saved);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user