agent_core/client/
models.rs

1#[derive(Debug, Clone, PartialEq)]
2pub enum Role {
3    System,
4    User,
5    Assistant,
6}
7
8/// Image source types supported by LLM providers.
9#[derive(Debug, Clone, PartialEq)]
10pub enum ImageSource {
11    /// Base64-encoded image data with media type (e.g., "image/jpeg", "image/png").
12    Base64 {
13        media_type: String,
14        data: String,
15    },
16    /// URL reference to an image.
17    Url(String),
18}
19
20/// Tool invocation requested by the assistant.
21#[derive(Debug, Clone, PartialEq)]
22pub struct ToolUse {
23    /// Unique identifier for this tool use (used to match with ToolResult).
24    pub id: String,
25    /// Name of the tool to invoke.
26    pub name: String,
27    /// Input arguments as a JSON string.
28    pub input: String,
29}
30
31/// Result of a tool invocation, sent back to the assistant.
32#[derive(Debug, Clone, PartialEq)]
33pub struct ToolResult {
34    /// ID of the tool use this result corresponds to.
35    pub tool_use_id: String,
36    /// Result content (can be text or error message).
37    pub content: String,
38    /// Whether this result represents an error.
39    pub is_error: bool,
40}
41
42/// Content block types that can appear in messages.
43#[derive(Debug, Clone, PartialEq)]
44pub enum Content {
45    /// Plain text content.
46    Text(String),
47    /// Image content with source data.
48    Image(ImageSource),
49    /// Tool invocation from the assistant.
50    ToolUse(ToolUse),
51    /// Tool result from the user.
52    ToolResult(ToolResult),
53}
54
55#[derive(Debug, Clone, PartialEq)]
56pub struct Message {
57    pub role: Role,
58    pub content: Vec<Content>,
59}
60
61impl Message {
62    pub fn new(role: Role, text: impl Into<String>) -> Self {
63        Self {
64            role,
65            content: vec![Content::Text(text.into())],
66        }
67    }
68
69    /// Create a message with multiple content blocks.
70    pub fn with_content(role: Role, content: Vec<Content>) -> Self {
71        Self { role, content }
72    }
73
74    pub fn system(text: impl Into<String>) -> Self {
75        Self::new(Role::System, text)
76    }
77
78    pub fn user(text: impl Into<String>) -> Self {
79        Self::new(Role::User, text)
80    }
81
82    pub fn assistant(text: impl Into<String>) -> Self {
83        Self::new(Role::Assistant, text)
84    }
85
86    /// Create a user message with a tool result.
87    pub fn tool_result(tool_use_id: impl Into<String>, content: impl Into<String>, is_error: bool) -> Self {
88        Self {
89            role: Role::User,
90            content: vec![Content::ToolResult(ToolResult {
91                tool_use_id: tool_use_id.into(),
92                content: content.into(),
93                is_error,
94            })],
95        }
96    }
97}
98
99/// Tool definition for function calling.
100#[derive(Debug, Clone, PartialEq)]
101pub struct Tool {
102    /// Name of the tool.
103    pub name: String,
104    /// Description of what the tool does.
105    pub description: String,
106    /// JSON Schema for the tool's input parameters.
107    pub input_schema: String,
108}
109
110impl Tool {
111    pub fn new(
112        name: impl Into<String>,
113        description: impl Into<String>,
114        input_schema: impl Into<String>,
115    ) -> Self {
116        Self {
117            name: name.into(),
118            description: description.into(),
119            input_schema: input_schema.into(),
120        }
121    }
122}
123
124/// Controls how the model uses tools.
125#[derive(Debug, Clone, PartialEq)]
126pub enum ToolChoice {
127    /// Model decides whether to use tools.
128    Auto,
129    /// Model must use at least one tool.
130    Any,
131    /// Model must use the specified tool.
132    Tool(String),
133    /// Model cannot use any tools.
134    None,
135}
136
137impl Default for ToolChoice {
138    fn default() -> Self {
139        Self::Auto
140    }
141}
142
143/// Metadata for request tracking.
144#[derive(Debug, Clone, PartialEq, Default)]
145pub struct Metadata {
146    /// User identifier for tracking/billing.
147    pub user_id: Option<String>,
148}
149
150#[derive(Debug, Clone, Default)]
151pub struct MessageOptions {
152    /// Sampling temperature (0.0-1.0).
153    pub temperature: Option<f32>,
154    /// Maximum tokens to generate.
155    pub max_tokens: Option<u32>,
156    /// Model to use.
157    pub model: Option<String>,
158    /// Tools available for the model to use.
159    pub tools: Option<Vec<Tool>>,
160    /// How the model should use tools.
161    pub tool_choice: Option<ToolChoice>,
162    /// Custom stop sequences.
163    pub stop_sequences: Option<Vec<String>>,
164    /// Nucleus sampling parameter.
165    pub top_p: Option<f32>,
166    /// Top-K sampling parameter.
167    pub top_k: Option<u32>,
168    /// Request metadata.
169    pub metadata: Option<Metadata>,
170}
171
172// ============================================================================
173// Streaming Types
174// ============================================================================
175
176/// Events emitted during streaming responses.
177#[derive(Debug, Clone, PartialEq)]
178pub enum StreamEvent {
179    /// Stream started, contains message metadata.
180    MessageStart {
181        message_id: String,
182        model: String,
183    },
184    /// A content block is starting.
185    ContentBlockStart {
186        index: usize,
187        block_type: ContentBlockType,
188    },
189    /// Incremental text content.
190    TextDelta {
191        index: usize,
192        text: String,
193    },
194    /// Incremental JSON for tool input.
195    InputJsonDelta {
196        index: usize,
197        json: String,
198    },
199    /// A content block has finished.
200    ContentBlockStop {
201        index: usize,
202    },
203    /// Message-level updates (stop reason, usage).
204    MessageDelta {
205        stop_reason: Option<String>,
206        usage: Option<Usage>,
207    },
208    /// Stream has ended.
209    MessageStop,
210    /// Keep-alive ping.
211    Ping,
212}
213
214/// Type of content block in streaming.
215#[derive(Debug, Clone, PartialEq)]
216pub enum ContentBlockType {
217    Text,
218    ToolUse { id: String, name: String },
219}
220
221/// Token usage statistics.
222#[derive(Debug, Clone, PartialEq, Default)]
223pub struct Usage {
224    /// Input tokens used.
225    pub input_tokens: u32,
226    /// Output tokens generated.
227    pub output_tokens: u32,
228}