fix(cross-project): ask/cancel inter-projets routent par agentId résolu, plus par nom — agents homonymes désambiguïsés par projectId+agentId, tests ask/cancel names_collide — #260/#263 (QA verte)
This commit is contained in:
@ -1400,7 +1400,7 @@ impl OrchestratorService {
|
||||
crate::diag!(
|
||||
"[cross-project] ask correlation={correlation_id} requester={requester_project_id}/{requester_agent_id} target={target_project_id}/{target_agent_id}"
|
||||
);
|
||||
self.ask_agent(&project, target.name, task, Some(requester_agent_id))
|
||||
self.ask_resolved_agent(&project, target, task, Some(requester_agent_id))
|
||||
.await
|
||||
}
|
||||
|
||||
@ -1427,7 +1427,8 @@ impl OrchestratorService {
|
||||
"[cross-project] cancel correlation={correlation_id} requester={requester_project_id}/{requester_agent_id} target={target_project_id}/{target_agent_id}"
|
||||
);
|
||||
let _ = requester_agent_id;
|
||||
self.stop_agent(&project, target.name, None).await
|
||||
self.stop_agent_by_id(&project, target.id, target.name, None)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn run_in_background(
|
||||
@ -1916,6 +1917,18 @@ impl OrchestratorService {
|
||||
.find_agent_by_name(project, &target)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound(format!("agent {target}")))?;
|
||||
self.ask_resolved_agent(project, agent, task, requester)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn ask_resolved_agent(
|
||||
&self,
|
||||
project: &Project,
|
||||
agent: domain::Agent,
|
||||
task: String,
|
||||
requester: Option<AgentId>,
|
||||
) -> Result<OrchestratorOutcome, AppError> {
|
||||
let target = agent.name.clone();
|
||||
let agent_id = agent.id;
|
||||
// Détection de cycle (cadrage C3 §6) : si l'ask vient d'un **agent** A vers la
|
||||
// cible B, refuser AVANT tout enqueue si poser l'arête A→B fermerait un cycle
|
||||
@ -2855,7 +2868,17 @@ impl OrchestratorService {
|
||||
.find_agent_id_by_name(project, &name)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound(format!("agent {name}")))?;
|
||||
self.stop_agent_by_id(project, agent_id, name, requester)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn stop_agent_by_id(
|
||||
&self,
|
||||
project: &Project,
|
||||
agent_id: AgentId,
|
||||
label: String,
|
||||
requester: Option<AgentId>,
|
||||
) -> Result<OrchestratorOutcome, AppError> {
|
||||
if let Some(requester) = requester {
|
||||
let allowed = requester == agent_id
|
||||
|| self
|
||||
@ -2898,7 +2921,7 @@ impl OrchestratorService {
|
||||
.await
|
||||
.map_err(|err| AppError::Process(err.to_string()))?;
|
||||
return Ok(OrchestratorOutcome {
|
||||
detail: format!("cancelled current work for agent {name}"),
|
||||
detail: format!("cancelled current work for agent {label}"),
|
||||
reply: None,
|
||||
});
|
||||
}
|
||||
@ -2909,12 +2932,12 @@ impl OrchestratorService {
|
||||
.is_empty()
|
||||
{
|
||||
return Err(AppError::NotFound(format!(
|
||||
"running session for agent {name}"
|
||||
"running session for agent {label}"
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(OrchestratorOutcome {
|
||||
detail: format!("stopped agent {name}"),
|
||||
detail: format!("stopped agent {label}"),
|
||||
reply: None,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user