Skip to main content

car_multi/
types.rs

1//! Core types for multi-agent coordination.
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6use std::collections::HashMap;
7
8/// Blueprint for an agent in a multi-agent system.
9///
10/// The runtime doesn't own the model — `metadata` carries provider/model info
11/// that the caller's `AgentRunner` implementation uses to select the right model.
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct AgentSpec {
14    pub name: String,
15    pub system_prompt: String,
16    /// Tool names this agent is allowed to use.
17    pub tools: Vec<String>,
18    pub max_turns: u32,
19    /// Opaque metadata (provider, model, temperature, etc.).
20    pub metadata: HashMap<String, Value>,
21}
22
23impl AgentSpec {
24    pub fn new(name: &str, system_prompt: &str) -> Self {
25        Self {
26            name: name.to_string(),
27            system_prompt: system_prompt.to_string(),
28            tools: Vec::new(),
29            max_turns: 10,
30            metadata: HashMap::new(),
31        }
32    }
33
34    pub fn with_tools(mut self, tools: Vec<String>) -> Self {
35        self.tools = tools;
36        self
37    }
38
39    pub fn with_max_turns(mut self, max_turns: u32) -> Self {
40        self.max_turns = max_turns;
41        self
42    }
43
44    pub fn with_metadata(mut self, key: &str, value: Value) -> Self {
45        self.metadata.insert(key.to_string(), value);
46        self
47    }
48}
49
50/// Output from one agent's execution.
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct AgentOutput {
53    pub name: String,
54    pub answer: String,
55    pub turns: u32,
56    pub tool_calls: u32,
57    pub duration_ms: f64,
58    pub error: Option<String>,
59}
60
61impl AgentOutput {
62    pub fn succeeded(&self) -> bool {
63        self.error.is_none() && !self.answer.is_empty()
64    }
65}
66
67/// A message between agents in a multi-agent system.
68#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct Message {
70    pub from: String,
71    pub to: String,
72    pub kind: MessageKind,
73    pub payload: Value,
74    pub timestamp: DateTime<Utc>,
75}
76
77impl Message {
78    pub fn new(from: &str, to: &str, kind: MessageKind, payload: Value) -> Self {
79        Self {
80            from: from.to_string(),
81            to: to.to_string(),
82            kind,
83            payload,
84            timestamp: Utc::now(),
85        }
86    }
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
90#[serde(rename_all = "snake_case")]
91pub enum MessageKind {
92    /// Task assignment from orchestrator.
93    TaskAssignment,
94    /// Agent's completed result.
95    Result,
96    /// Feedback from supervisor.
97    Feedback,
98    /// Delegation request.
99    DelegateRequest,
100    /// Delegation response.
101    DelegateResponse,
102    /// Custom inter-agent message.
103    Custom,
104}