use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Serialize)]
pub(crate) struct MessagesRequest {
pub model: String,
pub messages: Vec<WireMessage>,
pub max_tokens: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub system: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub temperature: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stop_sequences: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tools: Option<Vec<WireTool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_choice: Option<Value>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub stream: bool,
}
#[derive(Debug, Serialize)]
pub(crate) struct WireMessage {
pub role: String,
pub content: Vec<WireBlock>,
}
#[derive(Debug, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub(crate) enum WireBlock {
Text {
text: String,
},
ToolUse {
id: String,
name: String,
input: Value,
},
ToolResult {
tool_use_id: String,
content: String,
},
}
#[derive(Debug, Serialize)]
pub(crate) struct WireTool {
pub name: String,
pub description: String,
pub input_schema: Value,
}
#[derive(Debug, Deserialize)]
pub(crate) struct MessagesResponse {
pub id: String,
#[serde(default)]
pub model: String,
#[serde(default)]
pub content: Vec<RespBlock>,
#[serde(default)]
pub stop_reason: Option<String>,
#[serde(default)]
pub usage: Option<Usage>,
}
#[derive(Debug, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub(crate) enum RespBlock {
Text {
text: String,
},
ToolUse {
id: String,
name: String,
input: Value,
},
#[serde(other)]
Unknown,
}
#[derive(Debug, Clone, Copy, Default, Deserialize)]
pub(crate) struct Usage {
#[serde(default)]
pub input_tokens: u32,
#[serde(default)]
pub output_tokens: u32,
}
#[derive(Debug, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub(crate) enum StreamEvent {
MessageStart {
message: StreamMessageStart,
},
ContentBlockStart {
#[allow(dead_code)]
index: u32,
content_block: StreamContentBlock,
},
ContentBlockDelta {
#[allow(dead_code)]
index: u32,
delta: StreamDeltaBlock,
},
ContentBlockStop {
#[allow(dead_code)]
index: u32,
},
MessageDelta {
#[serde(default)]
usage: Option<Usage>,
},
MessageStop,
Ping,
Error {
error: StreamError,
},
#[serde(other)]
Unknown,
}
#[derive(Debug, Deserialize)]
pub(crate) struct StreamMessageStart {
#[serde(default)]
pub usage: Option<Usage>,
}
#[derive(Debug, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub(crate) enum StreamContentBlock {
Text {
#[allow(dead_code)]
text: String,
},
ToolUse {
id: String,
name: String,
},
#[serde(other)]
Unknown,
}
#[derive(Debug, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub(crate) enum StreamDeltaBlock {
TextDelta {
text: String,
},
InputJsonDelta {
partial_json: String,
},
#[serde(other)]
Unknown,
}
#[derive(Debug, Deserialize)]
pub(crate) struct StreamError {
#[serde(default)]
pub message: String,
}
#[derive(Debug, Deserialize)]
pub(crate) struct ApiError {
pub error: ApiErrorBody,
}
#[derive(Debug, Deserialize)]
pub(crate) struct ApiErrorBody {
#[serde(default)]
pub message: String,
}