Skip to main content

rs_agent/
types.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4/// Tool specification describing how an agent presents a tool to the model
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct ToolSpec {
7    pub name: String,
8    pub description: String,
9    pub input_schema: serde_json::Value,
10    #[serde(skip_serializing_if = "Option::is_none")]
11    pub examples: Option<Vec<serde_json::Value>>,
12}
13
14/// Tool request captures an invocation request
15#[derive(Debug, Clone)]
16pub struct ToolRequest {
17    pub session_id: String,
18    pub arguments: HashMap<String, serde_json::Value>,
19}
20
21/// Tool response represents the structured response from a tool
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct ToolResponse {
24    pub content: String,
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub metadata: Option<HashMap<String, String>>,
27}
28
29/// Message role in a conversation
30#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
31#[serde(rename_all = "lowercase")]
32pub enum Role {
33    System,
34    User,
35    Assistant,
36    Tool,
37}
38
39/// Message in a conversation
40#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct Message {
42    pub role: Role,
43    pub content: String,
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub metadata: Option<HashMap<String, String>>,
46}
47
48/// File attachment
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct File {
51    pub mime_type: String,
52    pub data: Vec<u8>,
53}
54
55/// Generation response from a model
56#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct GenerationResponse {
58    pub content: String,
59    pub metadata: Option<HashMap<String, String>>,
60}
61
62/// Generation chunk from a streaming model response
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct GenerationChunk {
65    pub content: String,
66    // Typically empty for most chunks, but some APIs might send metadata/usage info at the end
67    pub metadata: Option<HashMap<String, String>>,
68}
69
70/// Configuration options for creating an agent
71#[derive(Debug, Clone)]
72pub struct AgentOptions {
73    pub system_prompt: Option<String>,
74    pub context_limit: Option<usize>,
75}
76
77impl Default for AgentOptions {
78    fn default() -> Self {
79        Self {
80            system_prompt: None,
81            context_limit: Some(8192),
82        }
83    }
84}
85
86// ============================================================================
87// SubAgent System (matching go-agent's types.go)
88// ============================================================================
89
90use crate::error::Result;
91use crate::memory::MemoryRecord;
92use async_trait::async_trait;
93use chrono::{DateTime, Utc};
94use std::sync::Arc;
95
96/// SubAgent represents a specialist agent that can be delegated work.
97#[async_trait]
98pub trait SubAgent: Send + Sync {
99    /// Returns the name of the sub-agent
100    fn name(&self) -> String;
101
102    /// Returns the description of what the sub-agent does
103    fn description(&self) -> String;
104
105    /// Runs the sub-agent with the given input and returns the result
106    async fn run(&self, input: String) -> Result<String>;
107}
108
109/// SubAgentDirectory stores sub-agents by name while preserving insertion order.
110pub trait SubAgentDirectory: Send + Sync {
111    /// Register a sub-agent. Duplicate names return an error.
112    fn register(&self, subagent: Arc<dyn SubAgent>) -> Result<()>;
113
114    /// Lookup a sub-agent by name
115    fn lookup(&self, name: &str) -> Option<Arc<dyn SubAgent>>;
116
117    /// Returns all registered sub-agents in registration order
118    fn all(&self) -> Vec<Arc<dyn SubAgent>>;
119}
120
121/// AgentState represents the serializable state of an agent for checkpointing.
122#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct AgentState {
124    pub system_prompt: String,
125    pub short_term: Vec<MemoryRecord>,
126    #[serde(skip_serializing_if = "Option::is_none")]
127    pub joined_spaces: Option<Vec<String>>,
128    pub timestamp: DateTime<Utc>,
129}