use crate::primitives::{Address, Timestamp};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TaskStatus {
Open,
Assigned,
InProgress,
Completed,
Cancelled,
Expired,
Disputed,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TaskType {
Inference,
CodeReview,
DataAnalysis,
ContentGeneration,
AgentExecution,
Translation,
Research,
Custom(String),
}
impl TaskType {
pub fn as_str(&self) -> &str {
match self {
TaskType::Inference => "inference",
TaskType::CodeReview => "code_review",
TaskType::DataAnalysis => "data_analysis",
TaskType::ContentGeneration => "content_generation",
TaskType::AgentExecution => "agent_execution",
TaskType::Translation => "translation",
TaskType::Research => "research",
TaskType::Custom(s) => s.as_str(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[derive(Default)]
pub enum TaskPriority {
Low,
#[default]
Normal,
High,
Urgent,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "kind")]
pub enum ProofRequirement {
ZeroKnowledge {
#[serde(default)]
circuit_id: Option<String>,
#[serde(default)]
model_id: Option<String>,
},
TeeAttestation {
#[serde(default)]
provider_class: Option<String>,
},
Cryptographic,
Oracle,
Merkle {
expected_root: String,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
pub struct AcceptanceCriteria {
#[serde(default)]
pub required_proof: Option<ProofRequirement>,
#[serde(default)]
pub format: Option<String>,
#[serde(default)]
pub min_word_count: Option<u64>,
#[serde(default)]
pub required_sections: Vec<String>,
#[serde(default)]
pub constraints: HashMap<String, String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ReputationProof {
pub agent_id: String,
pub claimed_score: u32,
pub registry_root: String,
pub leaf: String,
pub merkle_path: Vec<String>,
pub leaf_index: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TaskDispute {
pub raised_by: Address,
pub reason: String,
pub raised_at: Timestamp,
#[serde(default)]
pub resolution: Option<DisputeResolution>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum DisputeResolution {
ReleaseToProvider,
RefundToPoster,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TaskInfo {
pub task_id: String,
pub title: String,
pub description: String,
pub task_type: TaskType,
pub poster: Address,
pub assignee: Option<Address>,
pub max_price: u128,
pub quoted_price: Option<u128>,
pub status: TaskStatus,
pub created_at: Timestamp,
pub deadline: Option<u64>,
pub required_model: Option<String>,
pub preferred_model_id: Option<String>,
pub input: String,
pub output: Option<String>,
pub priority: TaskPriority,
pub metadata: HashMap<String, String>,
pub tx_hash: Option<String>,
#[serde(default)]
pub acceptance_criteria: Option<AcceptanceCriteria>,
#[serde(default)]
pub escrow_id: Option<String>,
#[serde(default)]
pub dispute: Option<TaskDispute>,
}
impl TaskInfo {
pub fn new(
title: String,
description: String,
task_type: TaskType,
poster: Address,
max_price: u128,
input: String,
) -> Self {
let task_id = uuid::Uuid::new_v4().to_string();
Self {
task_id,
title,
description,
task_type,
poster,
assignee: None,
max_price,
quoted_price: None,
status: TaskStatus::Open,
created_at: Timestamp(chrono::Utc::now().timestamp()),
deadline: None,
required_model: None,
preferred_model_id: None,
input,
output: None,
priority: TaskPriority::Normal,
metadata: HashMap::new(),
tx_hash: None,
acceptance_criteria: None,
escrow_id: None,
dispute: None,
}
}
pub fn is_available(&self) -> bool {
self.status == TaskStatus::Open
}
pub fn is_terminal(&self) -> bool {
matches!(
self.status,
TaskStatus::Completed | TaskStatus::Cancelled | TaskStatus::Expired
)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TaskQuote {
pub task_id: String,
pub provider: Address,
pub price: u128,
pub estimated_duration_secs: u64,
pub model_id: String,
pub confidence: u8,
pub expires_at: u64,
pub notes: Option<String>,
#[serde(default)]
pub provider_attestation: Option<String>,
#[serde(default)]
pub provider_reputation_proof: Option<ReputationProof>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct TaskFilter {
pub task_type: Option<TaskType>,
pub status: Option<TaskStatus>,
pub poster: Option<String>,
pub assignee: Option<String>,
pub max_price: Option<u128>,
pub required_model: Option<String>,
pub limit: Option<usize>,
pub offset: Option<usize>,
}