Merge branch 'feature/117-opencode-headless-recovery' into develop

This commit is contained in:
2026-07-31 15:05:14 +02:00
9 changed files with 433 additions and 39 deletions

View File

@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
use thiserror::Error;
use crate::conversation::ConversationId;
use crate::ids::{AgentId, ProjectId, ScheduleId, TaskId};
use crate::ids::{AgentId, ProjectId, RendezvousId, ScheduleId, TaskId};
use crate::mailbox::TicketId;
/// Maximum length for human-facing task labels.
@ -59,6 +59,22 @@ pub enum BackgroundTaskWakePolicy {
RecordOnly,
}
/// Structural link from a background task to a composite inter-agent rendezvous.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BackgroundTaskRendezvousLink {
/// Stable business rendezvous id, independent from any task id.
pub rendezvous_id: RendezvousId,
/// Mailbox ticket that must receive the eventual business `Final`.
pub ticket_id: TicketId,
/// Agent that requested the rendezvous, when known.
pub requester_agent_id: Option<AgentId>,
/// Target agent doing the work.
pub target_agent_id: AgentId,
/// Conversation entered by the target turn.
pub conversation_id: ConversationId,
}
/// Kind-specific payload of a background task.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", tag = "kind")]
@ -107,6 +123,9 @@ pub struct BackgroundTask {
pub owner_agent_id: AgentId,
/// Kind-specific payload.
pub kind: BackgroundTaskKind,
/// Optional composite rendezvous this task participates in.
#[serde(default)]
pub rendezvous: Option<BackgroundTaskRendezvousLink>,
/// Current lifecycle state.
pub state: BackgroundTaskState,
/// Completion wake policy.
@ -143,6 +162,7 @@ impl BackgroundTask {
project_id,
owner_agent_id,
kind,
rendezvous: None,
state: BackgroundTaskState::Queued,
wake_policy,
created_at_ms: now_ms,
@ -155,6 +175,13 @@ impl BackgroundTask {
Ok(task)
}
/// Returns a copy linked to a composite inter-agent rendezvous.
#[must_use]
pub fn with_rendezvous(mut self, link: BackgroundTaskRendezvousLink) -> Self {
self.rendezvous = Some(link);
self
}
/// Returns a copy moved to a non-terminal state.
///
/// Terminal transitions must use [`Self::complete`] so the result/state

View File

@ -115,6 +115,10 @@ typed_id!(
/// Identifies a first-class background task.
TaskId
);
typed_id!(
/// Identifies one composite inter-agent business rendezvous.
RendezvousId
);
/// Runtime-only key for an agent scoped by its project.
///

View File

@ -79,8 +79,8 @@ pub use error::DomainError;
pub use events::RendezvousContext;
pub use ids::{
AgentId, IssueId, LayoutId, LocalModelServerId, NodeId, ProfileId, ProjectId, RuntimeAgentKey,
ScheduleId, SessionId, SkillId, SprintId, TabId, TaskId, TemplateId, WindowId,
AgentId, IssueId, LayoutId, LocalModelServerId, NodeId, ProfileId, ProjectId, RendezvousId,
RuntimeAgentKey, ScheduleId, SessionId, SkillId, SprintId, TabId, TaskId, TemplateId, WindowId,
};
pub use project::{Project, ProjectPath};
@ -95,9 +95,10 @@ pub use mcp_tool_permissions::{
};
pub use background_task::{
BackgroundTask, BackgroundTaskError, BackgroundTaskKind, BackgroundTaskResult,
BackgroundTaskState, BackgroundTaskWakePolicy, BACKGROUND_TASK_LABEL_MAX_CHARS,
BACKGROUND_TASK_OUTPUT_TAIL_MAX_BYTES, BACKGROUND_TASK_TEXT_MAX_BYTES,
BackgroundTask, BackgroundTaskError, BackgroundTaskKind, BackgroundTaskRendezvousLink,
BackgroundTaskResult, BackgroundTaskState, BackgroundTaskWakePolicy,
BACKGROUND_TASK_LABEL_MAX_CHARS, BACKGROUND_TASK_OUTPUT_TAIL_MAX_BYTES,
BACKGROUND_TASK_TEXT_MAX_BYTES,
};
pub use skill::{Skill, SkillRef, SkillScope};