genai_types/
messages.rs

1use crate::models::ModelInfo;
2use crate::tool_choice::ToolChoice;
3use mcp_protocol::tool::{Tool, ToolContent};
4use serde::{Deserialize, Serialize};
5
6/// Different types of content that can be in a message
7#[derive(Serialize, Deserialize, Debug, Clone)]
8#[serde(tag = "type", rename_all = "snake_case")]
9pub enum MessageContent {
10    Text {
11        text: String,
12    },
13
14    ToolUse {
15        id: String,
16        name: String,
17        input: serde_json::Value,
18    },
19
20    ToolResult {
21        tool_use_id: String,
22        content: Vec<ToolContent>,
23        is_error: Option<bool>,
24    },
25}
26
27/// A single message in a conversation with Claude
28#[derive(Serialize, Deserialize, Debug, Clone)]
29pub struct Message {
30    /// Role of the message sender (user, assistant, system)
31    pub role: Role,
32
33    /// Content of the message as vector of MessageContent objects
34    pub content: Vec<MessageContent>,
35}
36
37/// Role of the message sender
38#[derive(Serialize, Deserialize, Debug, Clone)]
39pub enum Role {
40    #[serde(rename = "user")]
41    User,
42
43    #[serde(rename = "assistant")]
44    Assistant,
45
46    #[serde(rename = "system")]
47    System,
48}
49
50impl Message {
51    /// Create a new message with structured content
52    pub fn new_structured(role: impl Into<String>, content: Vec<MessageContent>) -> Self {
53        Self {
54            role: match role.into().as_str() {
55                "user" => Role::User,
56                "assistant" => Role::Assistant,
57                "system" => Role::System,
58                _ => panic!("Invalid role"),
59            },
60            content,
61        }
62    }
63}
64
65/// Request to generate a completion from Claude
66#[derive(Serialize, Deserialize, Debug, Clone)]
67pub struct CompletionRequest {
68    /// The model to use
69    pub model: String,
70
71    /// List of messages in the conversation
72    pub messages: Vec<Message>,
73
74    /// Maximum number of tokens to generate
75    pub max_tokens: u32,
76
77    /// Temperature parameter (0.0 to 1.0)
78    pub temperature: Option<f32>,
79
80    /// System prompt to use
81    pub system: Option<String>,
82
83    /// Tools to make available to the model
84    pub tools: Option<Vec<Tool>>,
85
86    /// Tool choice configuration
87    pub tool_choice: Option<ToolChoice>,
88
89    /// Whether to disable parallel tool use
90    pub disable_parallel_tool_use: Option<bool>,
91}
92
93/// Information about token usage
94#[derive(Serialize, Deserialize, Debug, Clone)]
95pub struct Usage {
96    pub input_tokens: u32,
97
98    pub output_tokens: u32,
99}
100
101/// Response from a completion request
102#[derive(Serialize, Deserialize, Debug, Clone)]
103pub struct CompletionResponse {
104    /// Generated content blocks
105    pub content: Vec<MessageContent>,
106
107    /// ID of the message
108    pub id: String,
109
110    /// Model used for generation
111    pub model: String,
112
113    // always "assistant"
114    pub role: Role,
115
116    pub stop_reason: StopReason,
117
118    pub stop_sequence: Option<String>,
119
120    /// Message type
121    #[serde(rename = "type")]
122    pub message_type: String,
123
124    /// Token usage information
125    pub usage: Usage,
126}
127
128impl From<CompletionResponse> for Message {
129    fn from(request: CompletionResponse) -> Self {
130        Self {
131            role: request.role,
132            content: request.content,
133        }
134    }
135}
136
137/// Reason why generation stopped
138#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
139pub enum StopReason {
140    /// Generation stopped because the end of a turn was reached
141    #[serde(rename = "end_turn")]
142    EndTurn,
143
144    /// Generation stopped because the maximum token limit was reached
145    #[serde(rename = "max_tokens")]
146    MaxTokens,
147
148    /// Generation stopped because a stop sequence was encountered
149    #[serde(rename = "stop_sequence")]
150    StopSequence,
151
152    /// Generation stopped because a tool was used
153    #[serde(rename = "tool_use")]
154    ToolUse,
155
156    /// Other reason
157    #[serde(rename = "other")]
158    Other(String),
159}
160
161/// Request format for the anthropic-proxy actor
162#[derive(Serialize, Deserialize, Debug, Clone)]
163pub enum ProxyRequest {
164    ListModels,
165
166    GenerateCompletion { request: CompletionRequest },
167}
168
169/// Response format from the anthropic-proxy actor
170#[derive(Serialize, Deserialize, Debug, Clone)]
171pub enum ProxyResponse {
172    /// List of available models
173    ListModels { models: Vec<ModelInfo> },
174
175    /// Generated completion
176    Completion { completion: CompletionResponse },
177
178    /// Error response
179    Error { error: String },
180}