use std::{error::Error, fmt::Debug};
use crate::{
options::Options,
output::Output,
prompt::Prompt,
schema::{Document, EmptyMetadata},
tokens::{PromptTokensError, TokenCount, Tokenizer, TokenizerError},
};
use async_trait::async_trait;
#[derive(thiserror::Error, Debug)]
#[error("unable to create executor")]
pub enum ExecutorCreationError {
#[error("unable to create executor: {0}")]
InnerError(#[from] Box<dyn Error + Send + Sync>),
#[error("Field must be set: {0}")]
FieldRequiredError(String),
}
#[derive(thiserror::Error, Debug)]
pub enum ExecutorError {
#[error("Unable to run model: {0}")]
InnerError(#[from] Box<dyn Error + Send + Sync>),
#[error("Invalid options when calling the executor")]
InvalidOptions,
#[error(transparent)]
PromptTokens(PromptTokensError),
#[error("the context was to small to fit your input")]
ContextTooSmall,
}
#[async_trait]
pub trait Executor: Sized {
type StepTokenizer<'a>: Tokenizer
where
Self: 'a;
fn new_with_options(options: Options) -> Result<Self, ExecutorCreationError>;
fn new() -> Result<Self, ExecutorCreationError> {
Self::new_with_options(Options::empty().clone())
}
async fn execute(&self, options: &Options, prompt: &Prompt) -> Result<Output, ExecutorError>;
fn tokens_used(
&self,
options: &Options,
prompt: &Prompt,
) -> Result<TokenCount, PromptTokensError>;
fn max_tokens_allowed(&self, options: &Options) -> i32;
fn answer_prefix(&self, prompt: &Prompt) -> Option<String>;
fn get_tokenizer(&self, options: &Options) -> Result<Self::StepTokenizer<'_>, TokenizerError>;
}
pub trait EmbeddingsError {}
#[async_trait]
pub trait Embeddings {
type Error: Send + Debug + Error + EmbeddingsError;
async fn embed_texts(&self, texts: Vec<String>) -> Result<Vec<Vec<f32>>, Self::Error>;
async fn embed_query(&self, query: String) -> Result<Vec<f32>, Self::Error>;
}
pub trait VectorStoreError {}
#[async_trait]
pub trait VectorStore<E, M = EmptyMetadata>
where
E: Embeddings,
M: serde::Serialize + serde::de::DeserializeOwned,
{
type Error: Debug + Error + VectorStoreError;
async fn add_texts(&self, texts: Vec<String>) -> Result<Vec<String>, Self::Error>;
async fn add_documents(&self, documents: Vec<Document<M>>) -> Result<Vec<String>, Self::Error>;
async fn similarity_search(
&self,
query: String,
limit: u32,
) -> Result<Vec<Document<M>>, Self::Error>;
}