use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PluginReadiness {
pub plugin_name: String,
pub available_stages: Vec<String>,
pub degraded_stages: Vec<String>,
pub lsp_status: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AgentEvent {
TaskStatusChanged { node_id: String, status: NodeStatus },
PlanGenerated(crate::types::TaskPlan),
EnergyUpdated { node_id: String, energy: f32 },
Log(String),
NodeCompleted { node_id: String, goal: String },
ApprovalRequest {
request_id: String,
node_id: String,
action_type: ActionType,
description: String,
diff: Option<String>,
},
Complete { success: bool, message: String },
Error(String),
PlanReady {
nodes: usize,
plugins: Vec<String>,
execution_mode: String,
},
NodeSelected {
node_id: String,
goal: String,
node_class: String,
},
FallbackPlanner { reason: String },
VerificationComplete {
node_id: String,
syntax_ok: bool,
build_ok: bool,
tests_ok: bool,
lint_ok: bool,
diagnostics_count: usize,
tests_passed: usize,
tests_failed: usize,
energy: f32,
energy_components: crate::types::EnergyComponents,
stage_outcomes: Vec<crate::types::StageOutcome>,
degraded: bool,
degraded_reasons: Vec<String>,
summary: String,
node_class: String,
},
BundleApplied {
node_id: String,
files_created: Vec<String>,
files_modified: Vec<String>,
writes_count: usize,
diffs_count: usize,
node_class: String,
},
SensorFallback {
node_id: String,
stage: String,
primary: String,
actual: String,
reason: String,
},
DegradedVerification {
node_id: String,
degraded_stages: Vec<String>,
stability_blocked: bool,
},
EscalationClassified {
node_id: String,
category: String,
action: String,
},
SheafValidationComplete {
node_id: String,
validators_run: usize,
failures: usize,
v_sheaf: f32,
},
GraphRewriteApplied {
trigger_node: String,
action: String,
nodes_affected: usize,
},
BranchCreated {
branch_id: String,
node_id: String,
parent_node_id: String,
},
InterfaceSealed {
node_id: String,
sealed_paths: Vec<String>,
seal_hash: String,
},
BranchFlushed {
parent_node_id: String,
flushed_branch_ids: Vec<String>,
reason: String,
},
DependentUnblocked {
child_node_id: String,
parent_node_id: String,
},
BranchMerged { branch_id: String, node_id: String },
ContextDegraded {
node_id: String,
budget_exceeded: bool,
missing_owned_files: Vec<String>,
included_file_count: usize,
total_bytes: usize,
reason: String,
},
ContextBlocked {
node_id: String,
missing_owned_files: Vec<String>,
reason: String,
},
StructuralDependencyMissing {
node_id: String,
dependency_node_id: String,
reason: String,
},
ModelFallback {
node_id: String,
tier: String,
primary_model: String,
fallback_model: String,
reason: String,
},
ProvenanceDrift {
node_id: String,
missing_files: Vec<String>,
reason: String,
},
ToolReadiness {
plugins: Vec<PluginReadiness>,
strictness: String,
},
BudgetUpdated {
steps_used: u32,
max_steps: Option<u32>,
cost_used_usd: f64,
max_cost_usd: Option<f64>,
revisions_used: u32,
max_revisions: Option<u32>,
},
PlanRevised {
revision_id: String,
sequence: u32,
reason: String,
node_count: usize,
},
FileDeleted { node_id: String, path: String },
FileMoved {
node_id: String,
from: String,
to: String,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum NodeStatus {
Queued,
Planning,
Pending,
Coding,
Running,
Verifying,
Retrying,
SheafCheck,
Committing,
Completed,
Failed,
Escalated,
Aborted,
}
impl From<crate::types::NodeState> for NodeStatus {
fn from(state: crate::types::NodeState) -> Self {
use crate::types::NodeState;
match state {
NodeState::TaskQueued => NodeStatus::Queued,
NodeState::Planning => NodeStatus::Planning,
NodeState::Coding => NodeStatus::Coding,
NodeState::Verifying => NodeStatus::Verifying,
NodeState::Retry => NodeStatus::Retrying,
NodeState::SheafCheck => NodeStatus::SheafCheck,
NodeState::Committing => NodeStatus::Committing,
NodeState::Escalated => NodeStatus::Escalated,
NodeState::Completed => NodeStatus::Completed,
NodeState::Failed => NodeStatus::Failed,
NodeState::Aborted => NodeStatus::Aborted,
NodeState::Superseded => NodeStatus::Completed,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ActionType {
FileWrite { path: String },
Command { command: String },
SubGraph { node_count: usize },
ProjectInit {
command: String,
suggested_name: String,
},
BundleWrite {
node_id: String,
files: Vec<String>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AgentAction {
Approve { request_id: String },
ApproveWithEdit {
request_id: String,
edited_value: String,
},
Reject {
request_id: String,
reason: Option<String>,
},
Pause,
Resume,
Abort,
RequestCorrection {
request_id: String,
feedback: String,
},
}
pub mod channel {
use super::{AgentAction, AgentEvent};
use tokio::sync::mpsc;
pub type EventSender = mpsc::UnboundedSender<AgentEvent>;
pub type EventReceiver = mpsc::UnboundedReceiver<AgentEvent>;
pub type ActionSender = mpsc::UnboundedSender<AgentAction>;
pub type ActionReceiver = mpsc::UnboundedReceiver<AgentAction>;
pub fn event_channel() -> (EventSender, EventReceiver) {
mpsc::unbounded_channel()
}
pub fn action_channel() -> (ActionSender, ActionReceiver) {
mpsc::unbounded_channel()
}
}