use super::Fact;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RunStatus {
Created,
Planning,
Executing,
Verifying,
Completed,
Failed,
Cancelled,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RunLifecycleEvent {
pub run_id: String,
pub session_id: String,
pub status: RunStatus,
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub result_summary: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub started_at: Option<String>,
pub updated_at: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ArtifactRef {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub uri: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub path: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mime_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sha256: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub size_bytes: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub summary: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EvidenceRef {
pub kind: String,
pub summary: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub artifact: Option<ArtifactRef>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TaskStatus {
Pending,
InProgress,
Completed,
Failed,
Skipped,
Cancelled,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskItem {
pub id: String,
pub title: String,
pub status: TaskStatus,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub depends_on: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub evidence: Vec<EvidenceRef>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub artifacts: Vec<ArtifactRef>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskListEvent {
pub run_id: String,
pub session_id: String,
pub tasks: Vec<TaskItem>,
pub updated_at: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum VerificationStatus {
Pending,
Running,
Passed,
Failed,
Skipped,
NeedsReview,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VerificationCheck {
pub id: String,
pub subject: String,
pub status: VerificationStatus,
#[serde(skip_serializing_if = "Option::is_none")]
pub command: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub evidence: Vec<EvidenceRef>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub artifacts: Vec<ArtifactRef>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VerificationEvent {
pub run_id: String,
pub session_id: String,
pub status: VerificationStatus,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub checks: Vec<VerificationCheck>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub residual_risks: Vec<String>,
pub updated_at: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryRecallEvent {
pub session_id: String,
pub query: String,
pub memory_type: String,
pub max_results: usize,
pub working_directory: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "decision", rename_all = "lowercase")]
pub enum MemoryRecallDecision {
Allow {
injected_facts: Vec<Fact>,
#[serde(skip_serializing_if = "Option::is_none")]
metadata: Option<HashMap<String, serde_json::Value>>,
},
Block {
reason: String,
#[serde(skip_serializing_if = "Option::is_none")]
metadata: Option<HashMap<String, serde_json::Value>>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PlanningStrategy {
None,
StepByStep,
TreeOfThoughts,
GraphPlanning,
Custom(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PlanningEvent {
pub session_id: String,
pub task_description: String,
pub available_strategies: Vec<PlanningStrategy>,
#[serde(skip_serializing_if = "Option::is_none")]
pub constraints: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "decision", rename_all = "lowercase")]
pub enum PlanningDecision {
Allow {
selected_strategy: PlanningStrategy,
#[serde(skip_serializing_if = "Option::is_none")]
planning_template: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
metadata: Option<HashMap<String, serde_json::Value>>,
},
Block {
reason: String,
#[serde(skip_serializing_if = "Option::is_none")]
metadata: Option<HashMap<String, serde_json::Value>>,
},
Modify {
modified_task: String,
#[serde(skip_serializing_if = "Option::is_none")]
hints: Option<Vec<String>>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ReasoningType {
ChainOfThought,
TreeOfThoughts,
ReAct,
Reflexion,
Other(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReasoningEvent {
pub session_id: String,
pub reasoning_type: ReasoningType,
pub problem_statement: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub hints: Option<Vec<String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "decision", rename_all = "lowercase")]
pub enum ReasoningDecision {
Allow {
#[serde(skip_serializing_if = "Option::is_none")]
hints: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
metadata: Option<HashMap<String, serde_json::Value>>,
},
Block {
reason: String,
#[serde(skip_serializing_if = "Option::is_none")]
metadata: Option<HashMap<String, serde_json::Value>>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SuccessEvent {
pub session_id: String,
pub action_type: String,
pub action_summary: String,
pub duration_ms: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RateLimitType {
LlmTokenLimit,
LlmRequestLimit,
ApiRequestLimit,
ToolExecutionLimit,
Custom(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RateLimitEvent {
pub session_id: String,
pub limit_type: RateLimitType,
pub retry_after_ms: u64,
pub current_usage: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "decision", rename_all = "lowercase")]
pub enum RateLimitDecision {
Retry {
retry_after_ms: u64,
#[serde(skip_serializing_if = "Option::is_none")]
metadata: Option<HashMap<String, serde_json::Value>>,
},
Queue,
Skip { reason: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ConfirmationType {
SafetyConfirm,
UserConfirm,
CostConfirm,
Custom(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfirmationEvent {
pub session_id: String,
pub confirmation_type: ConfirmationType,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub options: Option<Vec<String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "decision", rename_all = "lowercase")]
pub enum ConfirmationDecision {
Escalate,
Approve,
Reject { reason: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IntentDetectionEvent {
pub session_id: String,
pub prompt: String,
pub workspace: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub language_hint: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TargetHints {
#[serde(skip_serializing_if = "Option::is_none")]
pub target_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub target_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub domain: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "decision", rename_all = "lowercase")]
pub enum IntentDetectionDecision {
Allow {
detected_intent: String,
confidence: f32,
#[serde(skip_serializing_if = "Option::is_none")]
target_hints: Option<TargetHints>,
},
Block { reason: String },
}