feat: more
This commit is contained in:
@@ -16,7 +16,7 @@ struct AppArgs {
|
||||
port: u16,
|
||||
|
||||
#[arg(long)]
|
||||
cloudflare_workers_api_key: Vec<SecretString>,
|
||||
cloudflare_workers_ai_api_key: Vec<SecretString>,
|
||||
|
||||
#[arg(long)]
|
||||
google_ai_studio_api_key: Vec<SecretString>,
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
use schemars::Schema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Message {
|
||||
role: String,
|
||||
content: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct ResponseFormatJsonSchema {
|
||||
pub strict: bool,
|
||||
pub name: String,
|
||||
pub schema: Schema,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum ResponseFormat {
|
||||
JsonSchema {
|
||||
json_schema: ResponseFormatJsonSchema,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct ChatCompletionsRequest<Model> {
|
||||
pub model: Model,
|
||||
|
||||
pub messages: Vec<Message>,
|
||||
|
||||
pub response_format: ResponseFormat,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Choice {
|
||||
pub finish_reason: String, // I don't care
|
||||
|
||||
pub message: Message,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct ChatCompletionsResponse {
|
||||
pub choices: Vec<Choice>,
|
||||
}
|
||||
1492
src/openai/chat/completion.rs
Normal file
1492
src/openai/chat/completion.rs
Normal file
File diff suppressed because it is too large
Load Diff
1
src/openai/chat/mod.rs
Normal file
1
src/openai/chat/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod completion;
|
||||
1
src/openai/mod.rs
Normal file
1
src/openai/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod chat;
|
||||
102
src/server.rs
102
src/server.rs
@@ -17,28 +17,110 @@ pub struct AppState {
|
||||
}
|
||||
|
||||
#[derive(Deserialize, TypedPath)]
|
||||
#[typed_path("/v1/chat/completions")]
|
||||
struct V1ChatCompletions;
|
||||
#[typed_path("/chat/completions")]
|
||||
struct ChatCompletionsPath;
|
||||
|
||||
enum Provider {
|
||||
CloudflareWorkersAi,
|
||||
GoogleAiStudio,
|
||||
Groq,
|
||||
HuggingFace,
|
||||
Mistral,
|
||||
OpenRouter,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
enum Shortcut {
|
||||
Xs,
|
||||
XS,
|
||||
S,
|
||||
M,
|
||||
L,
|
||||
XL
|
||||
XL,
|
||||
}
|
||||
|
||||
async fn post_v1_chat_completions(
|
||||
_: V1ChatCompletions,
|
||||
impl Shortcut {
|
||||
fn suggestions(&self) -> Vec<(Provider, String)> {
|
||||
use Provider as P;
|
||||
use Shortcut as S;
|
||||
|
||||
match self {
|
||||
S::XS => vec![
|
||||
(P::GoogleAiStudio, "gemini-3.5-flash-lite".into()),
|
||||
(P::OpenRouter, "poolside/laguna-xs-2.1:free".into()),
|
||||
(P::OpenRouter, "nex-agi/nex-n2.5-mini:free".into()),
|
||||
(P::OpenRouter, "cohere/north-mini-code:free".into()),
|
||||
(P::OpenRouter, "nvidia/nemotron-3.5-lightning:free".into()),
|
||||
(P::OpenRouter, "google/gemma-4-26b-a4b-it:free".into()),
|
||||
(P::OpenRouter, "poolside/laguna-xs.2:free".into()),
|
||||
(P::OpenRouter, "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free".into()),
|
||||
(P::CloudflareWorkersAi, "@cf/openai/gpt-oss-20b".into()),
|
||||
(P::OpenRouter, "openai/gpt-oss-20b:free".into()),
|
||||
(P::Groq, "openai/gpt-oss-20b".into()),
|
||||
(P::OpenRouter, "liquid/lfm-2.5-2.6b:free".into()),
|
||||
(P::Groq, "groq/compound-mini".into()),
|
||||
(P::OpenRouter, "openrouter/free".into()),
|
||||
],
|
||||
S::S => vec![
|
||||
(P::CloudflareWorkersAi, "@cf/qwen/qwen3.8-27b".into()),
|
||||
(P::OpenRouter, "qwen/qwen3.8-27b:free".into()),
|
||||
(P::Groq, "qwen/qwen3.8-27b".into()),
|
||||
(P::HuggingFace, "Qwen/Qwen3.8-27B".into()),
|
||||
(P::HuggingFace, "meta-models/Muse-Glimmer-30B".into()),
|
||||
(P::OpenRouter, "google/gemma-4-31b-it:free".into()),
|
||||
(P::Mistral, "mistral-small-2603".into()),
|
||||
(P::Groq, "groq/compound".into()),
|
||||
(P::OpenRouter, "openrouter/fusion".into()),
|
||||
],
|
||||
S::M => vec![
|
||||
(P::GoogleAiStudio, "gemini-3.8-flash".into()),
|
||||
(P::GoogleAiStudio, "gemini-3.7-flash".into()),
|
||||
(P::Mistral, "mistral-medium-3.5".into()),
|
||||
(P::OpenRouter, "inclusionai/ling-3.0-flash-vl:free".into()),
|
||||
(P::OpenRouter, "poolside/laguna-s-2.1:free".into()),
|
||||
(P::OpenRouter, "nvidia/nemotron-3-super-120b-a12b:free".into()),
|
||||
(P::CloudflareWorkersAi, "@cf/openai/gpt-oss-120b".into()),
|
||||
(P::OpenRouter, "openai/gpt-oss-120b:free".into()),
|
||||
(P::Groq, "openai/gpt-oss-120b".into()),
|
||||
],
|
||||
S::L => vec![
|
||||
(P::CloudflareWorkersAi, "@cf/zai-org/glm-5.3-flash".into()),
|
||||
(P::HuggingFace, "zai-org/GLM-5.3-Flash".into()),
|
||||
(P::HuggingFace, "deepseek-ai/DeepSeek-V4.1-Flash".into()),
|
||||
(P::OpenRouter, "nex-agi/nex-n2.5-pro:free".into()),
|
||||
(P::OpenRouter, "thinkingmachines/inkling-small:free".into()),
|
||||
(P::HuggingFace, "thinkingmachines/Inkling-Small".into())
|
||||
],
|
||||
S::XL => vec![
|
||||
(P::CloudflareWorkersAi, "@cf/zai-org/glm-5.3".into()),
|
||||
(P::HuggingFace, "zai-org/GLM-5.3".into()),
|
||||
(P::Mistral, "zai-glm-5-3".into()),
|
||||
(P::HuggingFace, "moonshotai/Kimi-K3".into()),
|
||||
(P::HuggingFace, "Qwen/Qwen3.8-2.4T-A95B".into()),
|
||||
(P::HuggingFace, "MiniMaxAI/MiniMax-M3".into()),
|
||||
(P::OpenRouter, "thinkingmachines/inkling:free".into()),
|
||||
(P::HuggingFace, "thinkingmachines/Inkling".into()),
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ChatCompletionResponse {
|
||||
Immediate(openai::chat::completion::ChatCompletion),
|
||||
Stream(()),
|
||||
}
|
||||
|
||||
async fn create_chat_completion(
|
||||
_: ChatCompletionsPath,
|
||||
State(state): State<AppState>,
|
||||
Json(request): Json<openai::ChatCompletionsRequest<Shortcut>>,
|
||||
) -> Result<Json<openai::ChatCompletionsResponse>, ()> {
|
||||
todo!();
|
||||
Json(request): Json<openai::chat::completion::CreateChatCompletionRequest<Shortcut>>,
|
||||
) -> Result<ChatCompletionResponse, ()> {
|
||||
if request.stream.unwrap_or(false) {
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_router() -> Router<AppState> {
|
||||
Router::new().typed_post(post_v1_chat_completions)
|
||||
Router::new().typed_post(create_chat_completion)
|
||||
}
|
||||
|
||||
pub fn create_app(state: AppState) -> Router<()> {
|
||||
|
||||
Reference in New Issue
Block a user