feat: livrable ticket #91 — notification fin BackgroundTask enrichie
- Backend: enrichissement HeadlessRendezvous avec requester/target/conversationId - Frontend: toast 'Requester -> Target completed/...' explicite - Clic ouvrant viewer de conversation pour visualiser l'échange
This commit is contained in:
@ -127,6 +127,22 @@ fn resolve_background_cwd(
|
||||
ProjectPath::new(path).map_err(|_| AppError::Invalid("invalid background task cwd".to_owned()))
|
||||
}
|
||||
|
||||
fn rendezvous_context_for_task(task: &BackgroundTask) -> Option<domain::RendezvousContext> {
|
||||
match &task.kind {
|
||||
BackgroundTaskKind::HeadlessRendezvous {
|
||||
requester_agent_id,
|
||||
target_agent_id,
|
||||
conversation_id,
|
||||
..
|
||||
} => Some(domain::RendezvousContext {
|
||||
requester_agent_id: *requester_agent_id,
|
||||
target_agent_id: *target_agent_id,
|
||||
conversation_id: *conversation_id,
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_path_no_parent(path: &Path) -> Result<PathBuf, AppError> {
|
||||
let mut out = PathBuf::new();
|
||||
for component in path.components() {
|
||||
@ -847,22 +863,26 @@ impl OrchestratorService {
|
||||
if task.is_terminal() {
|
||||
return Ok(());
|
||||
}
|
||||
let rendezvous = rendezvous_context_for_task(&task);
|
||||
let event = match &result {
|
||||
BackgroundTaskResult::Success { .. } => DomainEvent::BackgroundTaskCompleted {
|
||||
project_id: project.id,
|
||||
task_id,
|
||||
owner_agent_id,
|
||||
rendezvous,
|
||||
},
|
||||
BackgroundTaskResult::Failure { .. } => DomainEvent::BackgroundTaskFailed {
|
||||
project_id: project.id,
|
||||
task_id,
|
||||
owner_agent_id,
|
||||
rendezvous,
|
||||
},
|
||||
BackgroundTaskResult::Cancelled { .. } | BackgroundTaskResult::Expired { .. } => {
|
||||
DomainEvent::BackgroundTaskCancelled {
|
||||
project_id: project.id,
|
||||
task_id,
|
||||
owner_agent_id,
|
||||
rendezvous,
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -2967,6 +2987,52 @@ mod tests {
|
||||
assert_eq!(submit.delay_ms, Some(CODEX_SUBMIT_DELAY_MS));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rendezvous_context_is_extracted_from_headless_background_task_kind() {
|
||||
let requester = aid(1);
|
||||
let target = aid(2);
|
||||
let conversation_id = domain::ConversationId::from_uuid(uuid::Uuid::from_u128(3));
|
||||
let task = BackgroundTask::new(
|
||||
TaskId::from_uuid(uuid::Uuid::from_u128(4)),
|
||||
domain::ProjectId::from_uuid(uuid::Uuid::from_u128(5)),
|
||||
target,
|
||||
BackgroundTaskKind::HeadlessRendezvous {
|
||||
requester_agent_id: Some(requester),
|
||||
target_agent_id: target,
|
||||
ticket_id: TicketId::from_uuid(uuid::Uuid::from_u128(6)),
|
||||
conversation_id,
|
||||
},
|
||||
BackgroundTaskWakePolicy::RecordOnly,
|
||||
100,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let context = rendezvous_context_for_task(&task).expect("rendezvous context");
|
||||
|
||||
assert_eq!(context.requester_agent_id, Some(requester));
|
||||
assert_eq!(context.target_agent_id, target);
|
||||
assert_eq!(context.conversation_id, conversation_id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rendezvous_context_is_absent_for_command_background_task() {
|
||||
let task = BackgroundTask::new(
|
||||
TaskId::from_uuid(uuid::Uuid::from_u128(7)),
|
||||
domain::ProjectId::from_uuid(uuid::Uuid::from_u128(8)),
|
||||
aid(9),
|
||||
BackgroundTaskKind::Command {
|
||||
label: "cargo test".to_owned(),
|
||||
},
|
||||
BackgroundTaskWakePolicy::RecordOnly,
|
||||
100,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(rendezvous_context_for_task(&task), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explicit_profile_submit_delay_is_preserved() {
|
||||
let p = profile(3, "OpenAI Codex CLI", "codex")
|
||||
|
||||
Reference in New Issue
Block a user