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:
2026-07-26 11:56:25 +02:00
parent 13fb538880
commit dae07d35bb
27 changed files with 2358 additions and 143 deletions

View File

@ -69,23 +69,25 @@ use backend::dto::{
parse_sprint_id_dto, parse_sprint_status_dto, parse_task_id, parse_template_id,
sort_ticket_rows, sprint_version_dto, update_input, version_dto, AgentDriftListDto, AgentDto,
AgentListDto, AssignSkillRequestDto, AttachLiveAgentRequestDto, AttachLiveAgentResponseDto,
BackgroundTaskDto, ChangeAgentProfileDto, ChangeAgentProfileRequestDto,
CloneOpenCodeProfileFromSeedRequestDto, ConfigureProfilesRequestDto, ConversationDetailsDto,
CreateAgentFromTemplateRequestDto, CreateAgentRequestDto, CreateMemoryRequestDto,
CreateSkillRequestDto, CreateTemplateRequestDto, DetectProfilesRequestDto,
DetectProfilesResponseDto, EffectivePermissionsDto, EmbedderEnginesDto, EmbedderProfileDto,
EmbedderProfileListDto, ErrorDto, FirstRunStateDto, GitBranchesDto, GitCheckoutRequestDto,
GitCommitDto, GitCommitListDto, GitCommitRequestDto, GitStageRequestDto, GitStatusListDto,
GraphCommitListDto, HealthRequestDto, HealthResponseDto, InspectConversationRequestDto,
LaunchAgentRequestDto, LiveAgentListDto, MemoryDto, MemoryIndexDto, MemoryLinksDto,
MemoryListDto, OpenTerminalRequestDto, ProfileDto, ProfileListDto, ProjectDto, ProjectListDto,
ProjectMcpToolPermissionsDto, ProjectPermissionsDto, ProjectSystemPermissionsDto,
ProjectWorkStateDto, ReadAgentContextResponseDto, ReadConversationPageRequestDto,
RecallMemoryRequestDto, ResolveAgentPermissionsRequestDto,
ResolveAgentSystemPermissionsRequestDto, ResolvedAgentSystemPermissionsDto,
ResumableAgentListDto, SaveEmbedderProfileRequestDto, SaveProfileRequestDto, SkillDto,
SkillListDto, SprintCreateRequestDto, SprintDeleteRequestDto, SprintDto, SprintListDto,
SprintListRequestDto, SprintRenameRequestDto, SprintReorderRequestDto, StopLiveAgentRequestDto,
BackgroundTaskDto, ChangeAgentProfileDto, ChangeAgentProfileRequestDto, ClaudeProviderListDto,
CloneOpenCodeProfileFromSeedRequestDto, CodexProviderListDto, ConfigureProfilesRequestDto,
ConversationDetailsDto, CreateAgentFromTemplateRequestDto, CreateAgentRequestDto,
CreateMemoryRequestDto, CreateSkillRequestDto, CreateTemplateRequestDto,
DetectProfilesRequestDto, DetectProfilesResponseDto, EffectivePermissionsDto,
EmbedderEnginesDto, EmbedderProfileDto, EmbedderProfileListDto, ErrorDto, FirstRunStateDto,
GitBranchesDto, GitCheckoutRequestDto, GitCommitDto, GitCommitListDto, GitCommitRequestDto,
GitStageRequestDto, GitStatusListDto, GraphCommitListDto, HealthRequestDto, HealthResponseDto,
InspectConversationRequestDto, LaunchAgentRequestDto, LiveAgentListDto, MemoryDto,
MemoryIndexDto, MemoryLinksDto, MemoryListDto, OpenCodeProviderListDto, OpenTerminalRequestDto,
ProfileDto, ProfileListDto, ProjectDto, ProjectListDto, ProjectMcpToolPermissionsDto,
ProjectPermissionsDto, ProjectSystemPermissionsDto, ProjectWorkStateDto,
ReadAgentContextResponseDto, ReadConversationPageRequestDto, RecallMemoryRequestDto,
ResolveAgentPermissionsRequestDto, ResolveAgentSystemPermissionsRequestDto,
ResolvedAgentSystemPermissionsDto, ResumableAgentListDto, SaveClaudeProviderProfileRequestDto,
SaveCodexProviderProfileRequestDto, SaveEmbedderProfileRequestDto,
SaveOpenCodeProviderProfileRequestDto, SaveProfileRequestDto, SkillDto, SkillListDto,
SprintCreateRequestDto, SprintDeleteRequestDto, SprintDto, SprintListDto, SprintListRequestDto,
SprintRenameRequestDto, SprintReorderRequestDto, StopLiveAgentRequestDto,
StopLiveAgentResponseDto, SyncAgentWithTemplateRequestDto, SyncResultDto, TemplateDto,
TemplateListDto, TerminalSessionDto, TicketAssignRequestDto, TicketCarnetDto,
TicketCreateRequestDto, TicketDeleteRequestDto, TicketDto, TicketLinkCommandRequestDto,
@ -2351,6 +2353,18 @@ async fn invoke(
"detect_profiles" => invoke_detect_profiles(&request.args, &state.app).await,
"list_profiles" => invoke_list_profiles(&state.app).await,
"save_profile" => invoke_save_profile(&request.args, &state.app).await,
"list_opencode_providers" => invoke_list_opencode_providers(&state.app),
"save_opencode_provider_profile" => {
invoke_save_opencode_provider_profile(&request.args, &state.app).await
}
"list_codex_providers" => invoke_list_codex_providers(&state.app),
"save_codex_provider_profile" => {
invoke_save_codex_provider_profile(&request.args, &state.app).await
}
"list_claude_providers" => invoke_list_claude_providers(&state.app),
"save_claude_provider_profile" => {
invoke_save_claude_provider_profile(&request.args, &state.app).await
}
"delete_profile" => invoke_delete_profile(&request.args, &state.app).await,
"configure_profiles" => invoke_configure_profiles(&request.args, &state.app).await,
"clone_opencode_profile_from_seed" => {
@ -2596,6 +2610,72 @@ async fn invoke_save_profile(args: &Value, state: &BackendCore) -> Result<Value,
serde_json::to_value(output).map_err(serialization_error)
}
fn invoke_list_opencode_providers(state: &BackendCore) -> Result<Value, ErrorDto> {
let output: OpenCodeProviderListDto = state.list_opencode_providers.execute().into();
serde_json::to_value(output).map_err(serialization_error)
}
async fn invoke_save_opencode_provider_profile(
args: &Value,
state: &BackendCore,
) -> Result<Value, ErrorDto> {
let request = required_request::<SaveOpenCodeProviderProfileRequestDto>(
"save_opencode_provider_profile",
args,
)?;
let output = state
.save_opencode_provider_profile
.execute(request.into())
.await
.map(ProfileDto::from)
.map_err(ErrorDto::from)?;
serde_json::to_value(output).map_err(serialization_error)
}
fn invoke_list_codex_providers(state: &BackendCore) -> Result<Value, ErrorDto> {
let output: CodexProviderListDto = state.list_codex_providers.execute().into();
serde_json::to_value(output).map_err(serialization_error)
}
async fn invoke_save_codex_provider_profile(
args: &Value,
state: &BackendCore,
) -> Result<Value, ErrorDto> {
let request = required_request::<SaveCodexProviderProfileRequestDto>(
"save_codex_provider_profile",
args,
)?;
let output = state
.save_codex_provider_profile
.execute(request.into())
.await
.map(ProfileDto::from)
.map_err(ErrorDto::from)?;
serde_json::to_value(output).map_err(serialization_error)
}
fn invoke_list_claude_providers(state: &BackendCore) -> Result<Value, ErrorDto> {
let output: ClaudeProviderListDto = state.list_claude_providers.execute().into();
serde_json::to_value(output).map_err(serialization_error)
}
async fn invoke_save_claude_provider_profile(
args: &Value,
state: &BackendCore,
) -> Result<Value, ErrorDto> {
let request = required_request::<SaveClaudeProviderProfileRequestDto>(
"save_claude_provider_profile",
args,
)?;
let output = state
.save_claude_provider_profile
.execute(request.into())
.await
.map(ProfileDto::from)
.map_err(ErrorDto::from)?;
serde_json::to_value(output).map_err(serialization_error)
}
async fn invoke_delete_profile(args: &Value, state: &BackendCore) -> Result<Value, ErrorDto> {
let profile_id = string_arg(args, "profileId", "delete_profile")?;
let input = backend::dto::parse_delete_profile(profile_id)?;
@ -7625,6 +7705,12 @@ mod tests {
"detect_profiles",
"list_profiles",
"save_profile",
"list_opencode_providers",
"save_opencode_provider_profile",
"list_codex_providers",
"save_codex_provider_profile",
"list_claude_providers",
"save_claude_provider_profile",
"delete_profile",
"configure_profiles",
"clone_opencode_profile_from_seed",