omni_llm_kit/model/
request.rs

1use serde::{Deserialize, Serialize};
2use crate::common::SharedString;
3use crate::model::types::{CompletionIntent, CompletionMode, LanguageModelRequestTool, LanguageModelToolChoice, LanguageModelToolResult, LanguageModelToolUse};
4
5#[derive(Clone, Copy, Serialize, Deserialize, Debug, Eq, PartialEq, Hash)]
6#[serde(rename_all = "lowercase")]
7pub enum Role {
8    User,
9    Assistant,
10    System,
11}
12#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
13pub enum MessageContent {
14    Text(String),
15    Thinking {
16        text: String,
17        signature: Option<String>,
18    },
19    RedactedThinking(String),
20    Image(LanguageModelImage),
21    ToolUse(LanguageModelToolUse),
22    ToolResult(LanguageModelToolResult),
23}
24
25impl MessageContent {
26    pub fn to_str(&self) -> Option<&str> {
27        match self {
28            MessageContent::Text(text) => Some(text.as_str()),
29            MessageContent::Thinking { text, .. } => Some(text.as_str()),
30            MessageContent::RedactedThinking(_) => None,
31            MessageContent::ToolResult(tool_result) => tool_result.content.to_str(),
32            MessageContent::ToolUse(_) | MessageContent::Image(_) => None,
33        }
34    }
35
36    pub fn is_empty(&self) -> bool {
37        match self {
38            MessageContent::Text(text) => text.chars().all(|c| c.is_whitespace()),
39            MessageContent::Thinking { text, .. } => text.chars().all(|c| c.is_whitespace()),
40            MessageContent::ToolResult(tool_result) => tool_result.content.is_empty(),
41            MessageContent::RedactedThinking(_)
42            | MessageContent::ToolUse(_)
43            | MessageContent::Image(_) => false,
44        }
45    }
46}
47#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Hash, Debug)]
48pub struct LanguageModelImage {
49    /// A base64-encoded PNG image.
50    pub source: SharedString,
51    // pub size: Size<DevicePixels>,
52}
53impl LanguageModelImage {
54    pub fn len(&self) -> usize {
55        0
56    }
57}
58impl LanguageModelImage {
59    pub fn to_base64_url(&self) -> String {
60        format!("data:image/png;base64,{}", self.source)
61    }
62    pub fn is_empty(&self) -> bool {
63        false
64    }
65}
66
67
68#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Hash)]
69pub struct LanguageModelRequestMessage {
70    pub role: Role,
71    pub content: Vec<MessageContent>,
72    pub cache: bool,
73}
74impl LanguageModelRequestMessage {
75    pub fn string_contents(&self) -> String {
76        let mut buffer = String::new();
77        for string in self.content.iter().filter_map(|content| content.to_str()) {
78            buffer.push_str(string);
79        }
80
81        buffer
82    }
83
84    pub fn contents_empty(&self) -> bool {
85        self.content.iter().all(|content| content.is_empty())
86    }
87}
88#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
89pub struct LanguageModelRequest {
90    pub thread_id: Option<String>,
91    pub prompt_id: Option<String>,
92    pub intent: Option<CompletionIntent>,
93    pub mode: Option<CompletionMode>,
94    pub messages: Vec<LanguageModelRequestMessage>,
95    pub tools: Vec<LanguageModelRequestTool>,
96    pub tool_choice: Option<LanguageModelToolChoice>,
97    pub stop: Vec<String>,
98    pub temperature: Option<f32>,
99    pub thinking_allowed: bool,
100}