model_gateway_rs/model/
vision.rs

1use serde::{Deserialize, Serialize};
2
3use crate::model::doubao_vision::{DoubaoVisionMessage, DoubaoVisionResponse};
4
5/// Input structure for vision models
6#[derive(Debug, Clone, Serialize)]
7pub struct VisionInput {
8    pub messages: Vec<DoubaoVisionMessage>,
9}
10
11impl VisionInput {
12    pub fn new(messages: Vec<DoubaoVisionMessage>) -> Self {
13        Self { messages }
14    }
15
16    pub fn single_image(text: impl Into<String>, image_url: impl Into<String>) -> Self {
17        Self {
18            messages: vec![DoubaoVisionMessage::with_image(text, image_url)],
19        }
20    }
21}
22
23/// Output structure for vision models
24#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct VisionOutput {
26    pub content: String,
27    pub reasoning_content: Option<String>,
28    pub usage: Option<VisionUsage>,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct VisionUsage {
33    pub prompt_tokens: u32,
34    pub completion_tokens: u32,
35    pub total_tokens: u32,
36    pub reasoning_tokens: Option<u32>,
37}
38
39impl From<DoubaoVisionResponse> for VisionOutput {
40    fn from(response: DoubaoVisionResponse) -> Self {
41        let content = response.first_content().unwrap_or("").to_string();
42        let reasoning_content = response.reasoning_content().map(String::from);
43
44        let usage = response.usage.as_ref().map(|u| VisionUsage {
45            prompt_tokens: u.prompt_tokens,
46            completion_tokens: u.completion_tokens,
47            total_tokens: u.total_tokens,
48            reasoning_tokens: u.reasoning_tokens,
49        });
50
51        Self {
52            content,
53            reasoning_content,
54            usage,
55        }
56    }
57}