langchain_rust/language_models/
llm.rs1use std::pin::Pin;
2
3use async_trait::async_trait;
4use futures::Stream;
5
6use crate::schemas::{Message, StreamData};
7
8use super::{
9 box_llm_events, options::CallOptions, result_events, GenerateResult, LLMError, LLMEventStream,
10};
11
12#[async_trait]
13pub trait LLM: Sync + Send + LLMClone {
14 async fn generate(&self, messages: &[Message]) -> Result<GenerateResult, LLMError>;
15 async fn invoke(&self, prompt: &str) -> Result<String, LLMError> {
16 self.generate(&[Message::new_human_message(prompt)])
17 .await
18 .map(|res| res.generation)
19 }
20 async fn stream(
21 &self,
22 _messages: &[Message],
23 ) -> Result<Pin<Box<dyn Stream<Item = Result<StreamData, LLMError>> + Send>>, LLMError>;
24
25 fn generate_stream<'a>(&'a self, messages: &'a [Message]) -> LLMEventStream<'a> {
43 box_llm_events(async_stream::try_stream! {
44 let result = self.generate(messages).await?;
45 for event in result_events(result) {
46 yield event;
47 }
48 })
49 }
50
51 fn add_options(&mut self, _options: CallOptions) {
54 }
56 fn messages_to_string(&self, messages: &[Message]) -> String {
58 Message::messages_to_string(messages)
59 }
60}
61
62pub trait LLMClone {
63 fn clone_box(&self) -> Box<dyn LLM>;
64}
65
66impl<T> LLMClone for T
67where
68 T: 'static + LLM + Clone,
69{
70 fn clone_box(&self) -> Box<dyn LLM> {
71 Box::new(self.clone())
72 }
73}
74
75impl<L> From<L> for Box<dyn LLM>
76where
77 L: 'static + LLM,
78{
79 fn from(llm: L) -> Self {
80 Box::new(llm)
81 }
82}