rune-chain-core 0.1.1

Core traits and types for the rune-chain LLM orchestration framework
Documentation
use std::pin::Pin;

use async_trait::async_trait;
use futures::Stream;

use crate::{GenerateResult, LlmError, Message, StreamData};

/// An async interface to a large language model.
///
/// Implementors wrap a specific provider (OpenAI, Anthropic, Ollama, …) and
/// translate a slice of [`Message`]s into a [`GenerateResult`]. The `rune-chain`
/// ecosystem builds all chains on top of this trait rather than depending on any
/// concrete LLM type.
///
/// # Example
///
/// ```rust,ignore
/// use rune_chain_core::{Llm, Message};
///
/// let messages = vec![
///     Message::system("You are a helpful assistant."),
///     Message::human("What is the capital of France?"),
/// ];
/// let result = llm.generate(&messages).await?;
/// println!("{}", result.generation);
/// ```
#[async_trait]
pub trait Llm: Sync + Send {
    /// Send a slice of messages and return the model's complete response.
    async fn generate(&self, messages: &[Message]) -> Result<GenerateResult, LlmError>;

    /// Stream tokens from the model as they are produced.
    ///
    /// Providers that do not support streaming return [`LlmError::Other`] by default.
    async fn stream(
        &self,
        _messages: &[Message],
    ) -> Result<Pin<Box<dyn Stream<Item = Result<StreamData, LlmError>> + Send>>, LlmError> {
        Err(LlmError::Other(
            "streaming is not supported by this LLM provider".into(),
        ))
    }
}