agent_core/client/
models.rs

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