1- use std:: borrow:: Cow ;
2-
3- use anyhow:: Result ;
4- use async_trait:: async_trait;
5- use schemars:: schema:: SchemaObject ;
6- use serde:: { Deserialize , Serialize } ;
1+ use crate :: prelude:: * ;
72
83use crate :: base:: json_schema:: ToJsonSchemaOptions ;
4+ use schemars:: schema:: SchemaObject ;
5+ use std:: borrow:: Cow ;
96
10- #[ derive( Debug , Clone , Serialize , Deserialize ) ]
7+ #[ derive( Debug , Clone , Copy , Serialize , Deserialize ) ]
118pub enum LlmApiType {
129 Ollama ,
1310 OpenAi ,
@@ -46,7 +43,7 @@ pub struct LlmGenerateResponse {
4643}
4744
4845#[ async_trait]
49- pub trait LlmClient : Send + Sync {
46+ pub trait LlmGenerationClient : Send + Sync {
5047 async fn generate < ' req > (
5148 & self ,
5249 request : LlmGenerateRequest < ' req > ,
@@ -55,6 +52,28 @@ pub trait LlmClient: Send + Sync {
5552 fn json_schema_options ( & self ) -> ToJsonSchemaOptions ;
5653}
5754
55+ #[ derive( Debug ) ]
56+ pub struct LlmEmbeddingRequest < ' a > {
57+ pub model : & ' a str ,
58+ pub text : Cow < ' a , str > ,
59+ pub output_dimension : u32 ,
60+ pub task_type : Option < Cow < ' a , str > > ,
61+ }
62+
63+ pub struct LlmEmbeddingResponse {
64+ pub embedding : Vec < f32 > ,
65+ }
66+
67+ #[ async_trait]
68+ pub trait LlmEmbeddingClient : Send + Sync {
69+ async fn embed_text < ' req > (
70+ & self ,
71+ request : LlmEmbeddingRequest < ' req > ,
72+ ) -> Result < LlmEmbeddingResponse > ;
73+
74+ fn get_default_embedding_dimension ( & self , model : & str ) -> Option < u32 > ;
75+ }
76+
5877mod anthropic;
5978mod gemini;
6079mod litellm;
@@ -65,20 +84,41 @@ mod openrouter;
6584pub async fn new_llm_generation_client (
6685 api_type : LlmApiType ,
6786 address : Option < String > ,
68- ) -> Result < Box < dyn LlmClient > > {
87+ ) -> Result < Box < dyn LlmGenerationClient > > {
6988 let client = match api_type {
70- LlmApiType :: Ollama => Box :: new ( ollama:: Client :: new ( address) . await ?) as Box < dyn LlmClient > ,
71- LlmApiType :: OpenAi => Box :: new ( openai:: Client :: new ( address) . await ?) as Box < dyn LlmClient > ,
72- LlmApiType :: Gemini => Box :: new ( gemini:: Client :: new ( address) . await ?) as Box < dyn LlmClient > ,
89+ LlmApiType :: Ollama => {
90+ Box :: new ( ollama:: Client :: new ( address) . await ?) as Box < dyn LlmGenerationClient >
91+ }
92+ LlmApiType :: OpenAi => {
93+ Box :: new ( openai:: Client :: new ( address) ?) as Box < dyn LlmGenerationClient >
94+ }
95+ LlmApiType :: Gemini => {
96+ Box :: new ( gemini:: Client :: new ( address) ?) as Box < dyn LlmGenerationClient >
97+ }
7398 LlmApiType :: Anthropic => {
74- Box :: new ( anthropic:: Client :: new ( address) . await ?) as Box < dyn LlmClient >
99+ Box :: new ( anthropic:: Client :: new ( address) . await ?) as Box < dyn LlmGenerationClient >
75100 }
76101 LlmApiType :: LiteLlm => {
77- Box :: new ( litellm:: Client :: new_litellm ( address) . await ?) as Box < dyn LlmClient >
102+ Box :: new ( litellm:: Client :: new_litellm ( address) . await ?) as Box < dyn LlmGenerationClient >
103+ }
104+ LlmApiType :: OpenRouter => Box :: new ( openrouter:: Client :: new_openrouter ( address) . await ?)
105+ as Box < dyn LlmGenerationClient > ,
106+ } ;
107+ Ok ( client)
108+ }
109+
110+ pub fn new_llm_embedding_client (
111+ api_type : LlmApiType ,
112+ address : Option < String > ,
113+ ) -> Result < Box < dyn LlmEmbeddingClient > > {
114+ let client = match api_type {
115+ LlmApiType :: Gemini => {
116+ Box :: new ( gemini:: Client :: new ( address) ?) as Box < dyn LlmEmbeddingClient >
78117 }
79- LlmApiType :: OpenRouter => {
80- Box :: new ( openrouter :: Client :: new_openrouter ( address) . await ?) as Box < dyn LlmClient >
118+ LlmApiType :: OpenAi => {
119+ Box :: new ( openai :: Client :: new ( address) ?) as Box < dyn LlmEmbeddingClient >
81120 }
121+ _ => api_bail ! ( "Embedding is not supported for API type {:?}" , api_type) ,
82122 } ;
83123 Ok ( client)
84124}
0 commit comments