use std::sync::Arc;
use serde_json::Value;
use crate::attachment::Attachment;
use crate::chat::Chat;
use crate::config::Config;
use crate::embedding::{EmbedInput, EmbedOptions, Embedding};
use crate::error::Result;
use crate::files::{DownloadedFile, FileOptions, UploadOptions, UploadedFile};
use crate::image::{Images, PaintOptions};
use crate::judge::{Judge, JudgeOptions, Judgment};
use crate::moderation::{ModerateOptions, Moderation, ModerationInput};
use crate::ocr::{Ocr, OcrOptions};
use crate::rerank::{Rerank, RerankOptions};
use crate::speech::{SpeakOptions, Speech, SpeechChunk};
use crate::tokenization::{Tokenization, TokenizeOptions};
use crate::video::{AnimateOptions, Video, VideoJob};
#[derive(Debug, Clone)]
pub struct Context {
config: Arc<Config>,
}
pub fn context(f: impl FnOnce(&mut Config)) -> Context {
let mut config = (*crate::config()).clone();
f(&mut config);
Context::new(config)
}
impl Context {
pub fn new(config: Config) -> Context {
Context {
config: Arc::new(config),
}
}
pub fn config(&self) -> &Arc<Config> {
&self.config
}
pub fn chat(&self, model: Option<&str>, provider: Option<&str>) -> Result<Chat> {
Chat::with_config(self.config.clone(), model, provider, false)
}
pub async fn count_tokens(
&self,
text: &str,
model: Option<&str>,
provider: Option<&str>,
) -> Result<i64> {
self.chat(model, provider)?.count_tokens(Some(text)).await
}
pub async fn tokenize(&self, text: &str, options: TokenizeOptions<'_>) -> Result<Tokenization> {
crate::tokenization::tokenize(
text,
TokenizeOptions {
config: Some(self.config.clone()),
..options
},
)
.await
}
pub async fn embed(
&self,
input: impl Into<EmbedInput>,
options: EmbedOptions<'_>,
) -> Result<Embedding> {
crate::embedding::embed(
input,
EmbedOptions {
config: Some(self.config.clone()),
..options
},
)
.await
}
pub fn embed_later(
&self,
text: impl Into<EmbedInput>,
options: EmbedOptions<'_>,
) -> Result<crate::batch::EmbeddingRequest> {
crate::batch::EmbeddingRequest::new(
text,
EmbedOptions {
config: Some(self.config.clone()),
..options
},
)
}
pub fn mcp(&self, builder: crate::mcp::McpBuilder) -> crate::mcp::McpBuilder {
builder.config(self.config.clone())
}
pub async fn paint(&self, prompt: &str, options: PaintOptions<'_>) -> Result<Images> {
crate::image::paint(
prompt,
PaintOptions {
config: Some(self.config.clone()),
..options
},
)
.await
}
pub async fn animate(
&self,
prompt: Option<&str>,
options: AnimateOptions<'_>,
) -> Result<Video> {
crate::video::animate(
prompt,
AnimateOptions {
config: Some(self.config.clone()),
..options
},
)
.await
}
pub async fn animate_later(
&self,
prompt: Option<&str>,
options: AnimateOptions<'_>,
) -> Result<VideoJob> {
crate::video::animate_later(
prompt,
AnimateOptions {
config: Some(self.config.clone()),
..options
},
)
.await
}
pub async fn speak(&self, input: &str, options: SpeakOptions<'_>) -> Result<Speech> {
crate::speech::speak(
input,
SpeakOptions {
config: Some(self.config.clone()),
..options
},
)
.await
}
pub async fn speak_stream(
&self,
input: &str,
options: SpeakOptions<'_>,
on_chunk: impl FnMut(&SpeechChunk) + Send,
) -> Result<Speech> {
crate::speech::speak_stream(
input,
SpeakOptions {
config: Some(self.config.clone()),
..options
},
on_chunk,
)
.await
}
pub async fn moderate(
&self,
input: impl Into<ModerationInput>,
options: ModerateOptions<'_>,
) -> Result<Moderation> {
crate::moderation::moderate(
input,
ModerateOptions {
config: Some(self.config.clone()),
..options
},
)
.await
}
pub async fn judge(
&self,
input: impl Into<Value>,
questions: Value,
options: JudgeOptions,
) -> Result<Judgment> {
let Value::Object(questions) = questions else {
return Err(crate::Error::Argument("Questions must be a Hash".into()));
};
Judge::new()
.with_config(self.config.clone())
.judge_with(
input,
JudgeOptions {
questions,
..options
},
)
.await
}
pub async fn ocr(&self, file: impl Into<Attachment>, options: OcrOptions<'_>) -> Result<Ocr> {
crate::ocr::ocr(
file,
OcrOptions {
config: Some(self.config.clone()),
..options
},
)
.await
}
pub async fn rerank(
&self,
query: &str,
documents: &[&str],
model: &str,
options: RerankOptions<'_>,
) -> Result<Rerank> {
crate::rerank::rerank(
query,
documents,
model,
RerankOptions {
config: Some(self.config.clone()),
..options
},
)
.await
}
pub async fn upload(
&self,
file: impl Into<Attachment>,
options: UploadOptions<'_>,
) -> Result<UploadedFile> {
UploadedFile::upload(
file,
UploadOptions {
config: Some(self.config.clone()),
..options
},
)
.await
}
pub async fn download(&self, id: &str, options: FileOptions<'_>) -> Result<DownloadedFile> {
UploadedFile::download(
id,
FileOptions {
config: Some(self.config.clone()),
..options
},
)
.await
}
}