lc_core/language_models/
chat.rs1use super::BaseLanguageModel;
5use crate::tools::ToolDefinition;
6use crate::RunnableConfig;
7use async_trait::async_trait;
8use futures_util::Stream;
9use lc_schema::Message;
10use lc_shared::tools::ToolCall;
11use serde::{Deserialize, Serialize};
12use std::pin::Pin;
13
14#[derive(Debug, Clone, Serialize, Deserialize, Default)]
16pub struct LLMResult {
17 #[serde(default)]
18 pub content: String,
19 #[serde(default)]
20 pub model: String,
21 #[serde(default)]
22 pub token_usage: Option<TokenUsage>,
23 #[serde(default)]
24 pub tool_calls: Option<Vec<ToolCall>>,
25 #[serde(default, skip_serializing_if = "Option::is_none")]
26 pub thinking_content: Option<String>,
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct TokenUsage {
32 pub prompt_tokens: usize,
34
35 pub completion_tokens: usize,
37
38 pub total_tokens: usize,
40}
41
42#[async_trait]
47pub trait BaseChatModel: BaseLanguageModel<Vec<Message>, LLMResult> {
48 async fn chat(
57 &self,
58 messages: Vec<Message>,
59 config: Option<RunnableConfig>,
60 ) -> Result<LLMResult, Self::Error>;
61
62 async fn stream_chat(
71 &self,
72 messages: Vec<Message>,
73 config: Option<RunnableConfig>,
74 ) -> Result<Pin<Box<dyn Stream<Item = Result<String, Self::Error>> + Send>>, Self::Error>;
75
76 async fn chat_with_system(
85 &self,
86 system: String,
87 messages: Vec<Message>,
88 ) -> Result<LLMResult, Self::Error> {
89 let full_messages = vec![Message::system(system)]
90 .into_iter()
91 .chain(messages)
92 .collect();
93
94 self.chat(full_messages, None).await
95 }
96
97 fn bind_tools(
103 &self,
104 _tools: Vec<ToolDefinition>,
105 ) -> Option<Box<dyn BaseChatModel<Error = Self::Error> + Send + Sync>> {
106 None
107 }
108}