trae_agent_rs_core/llm/
client.rs1use crate::error::{ LlmError, Result };
4use crate::tools::ToolCall;
5use async_trait::async_trait;
6use serde::{ Deserialize, Serialize };
7use std::collections::HashMap;
8
9use super::message::LlmMessage;
10
11#[async_trait]
13pub trait LlmClient: Send + Sync {
14 async fn chat_completion(
16 &self,
17 messages: Vec<LlmMessage>,
18 tools: Option<Vec<ToolDefinition>>,
19 options: Option<ChatOptions>
20 ) -> Result<LlmResponse>;
21
22 fn model_name(&self) -> &str;
24
25 fn provider_name(&self) -> &str;
27
28 fn supports_streaming(&self) -> bool {
30 false
31 }
32
33 async fn chat_completion_stream(
35 &self,
36 _messages: Vec<LlmMessage>,
37 _tools: Option<Vec<ToolDefinition>>,
38 _options: Option<ChatOptions>
39 ) -> Result<Box<dyn futures::Stream<Item = Result<LlmStreamChunk>> + Send + Unpin + '_>> {
40 Err(
41 (LlmError::InvalidRequest {
42 message: "Streaming not supported by this client".to_string(),
43 }).into()
44 )
45 }
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct LlmResponse {
51 pub message: LlmMessage,
53
54 pub usage: Option<Usage>,
56
57 pub model: String,
59
60 pub finish_reason: Option<FinishReason>,
62
63 pub metadata: Option<HashMap<String, serde_json::Value>>,
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct LlmStreamChunk {
70 pub delta: Option<String>,
72
73 pub tool_calls: Option<Vec<ToolCall>>,
75
76 pub finish_reason: Option<FinishReason>,
78
79 pub usage: Option<Usage>,
81}
82
83#[derive(Debug, Clone, Serialize, Deserialize)]
85pub struct Usage {
86 pub prompt_tokens: u32,
88
89 pub completion_tokens: u32,
91
92 pub total_tokens: u32,
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
98#[serde(rename_all = "snake_case")]
99pub enum FinishReason {
100 Stop,
102
103 Length,
105
106 ToolCalls,
108
109 ContentFilter,
111
112 Other(String),
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
118pub struct ToolDefinition {
119 #[serde(rename = "type")]
121 pub tool_type: String,
122
123 pub function: FunctionDefinition,
125}
126
127#[derive(Debug, Clone, Serialize, Deserialize)]
129pub struct FunctionDefinition {
130 pub name: String,
132
133 pub description: String,
135
136 pub parameters: serde_json::Value,
138}
139
140#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct ChatOptions {
143 pub max_tokens: Option<u32>,
145
146 pub temperature: Option<f32>,
148
149 pub top_p: Option<f32>,
151
152 pub top_k: Option<u32>,
154
155 pub stop: Option<Vec<String>>,
157
158 pub stream: Option<bool>,
160
161 pub tool_choice: Option<ToolChoice>,
163}
164
165#[derive(Debug, Clone, Serialize, Deserialize)]
167#[serde(untagged)]
168pub enum ToolChoice {
169 Auto,
171
172 None,
174
175 Required {
177 name: String,
178 },
179}
180
181impl Default for ChatOptions {
182 fn default() -> Self {
183 Self {
184 max_tokens: Some(8192),
185 temperature: Some(0.7),
186 top_p: Some(1.0),
187 top_k: None,
188 stop: None,
189 stream: Some(false),
190 tool_choice: Some(ToolChoice::Auto),
191 }
192 }
193}