use std::time::Duration;
use swink_agent::Usage;
use super::types::PipelineId;
#[non_exhaustive]
#[derive(Clone, Debug)]
pub struct StepResult {
pub agent_name: String,
pub response: String,
pub duration: Duration,
pub usage: Usage,
}
impl StepResult {
#[must_use]
pub fn new(
agent_name: impl Into<String>,
response: impl Into<String>,
duration: Duration,
usage: Usage,
) -> Self {
Self {
agent_name: agent_name.into(),
response: response.into(),
duration,
usage,
}
}
}
#[non_exhaustive]
#[derive(Clone, Debug)]
pub struct PipelineOutput {
pub pipeline_id: PipelineId,
pub final_response: String,
pub steps: Vec<StepResult>,
pub total_duration: Duration,
pub total_usage: Usage,
}
impl PipelineOutput {
#[must_use]
pub fn new(pipeline_id: PipelineId, final_response: impl Into<String>) -> Self {
Self {
pipeline_id,
final_response: final_response.into(),
steps: Vec::new(),
total_duration: Duration::ZERO,
total_usage: Usage::default(),
}
}
#[must_use]
pub fn with_steps(mut self, steps: Vec<StepResult>) -> Self {
self.steps = steps;
self
}
#[must_use]
pub fn with_total_duration(mut self, total_duration: Duration) -> Self {
self.total_duration = total_duration;
self
}
#[must_use]
pub fn with_total_usage(mut self, total_usage: Usage) -> Self {
self.total_usage = total_usage;
self
}
}
#[non_exhaustive]
#[derive(Debug, thiserror::Error)]
pub enum PipelineError {
#[error("agent not found: {name}")]
AgentNotFound { name: String },
#[error("pipeline not found: {id}")]
PipelineNotFound { id: PipelineId },
#[error("step {step_index} ({agent_name}) failed: {source}")]
StepFailed {
step_index: usize,
agent_name: String,
source: Box<dyn std::error::Error + Send + Sync>,
},
#[error("max iterations reached: {iterations}")]
MaxIterationsReached { iterations: usize },
#[error("pipeline cancelled")]
Cancelled,
#[error("invalid exit condition: {message}")]
InvalidExitCondition { message: String },
}