feat: ollama cloud support
This commit is contained in:
@@ -63,6 +63,9 @@ pub struct AppArgs {
|
|||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub nvidia_nim_api_key: Vec<SecretString>,
|
pub nvidia_nim_api_key: Vec<SecretString>,
|
||||||
|
|
||||||
|
#[arg(long)]
|
||||||
|
pub ollama_cloud_api_key: Vec<SecretString>,
|
||||||
|
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub openrouter_api_key: Vec<SecretString>,
|
pub openrouter_api_key: Vec<SecretString>,
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use crate::CloudflareCredentials;
|
use crate::CloudflareCredentials;
|
||||||
use crate::openai;
|
use crate::openai;
|
||||||
use crate::server::AppState;
|
use crate::server::AppState;
|
||||||
use crate::server::Provider;
|
|
||||||
use crate::server::Upstream;
|
use crate::server::Upstream;
|
||||||
use crate::server::take_random_by_swapping;
|
use crate::server::take_random_by_swapping;
|
||||||
use axum::Json;
|
use axum::Json;
|
||||||
@@ -86,6 +85,22 @@ impl Display for ShortcutAndMaybeReasoning {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
enum Provider {
|
||||||
|
CloudflareWorkersAi,
|
||||||
|
GoogleAiStudio,
|
||||||
|
Groq,
|
||||||
|
HuggingFace,
|
||||||
|
Kilo,
|
||||||
|
Mistral,
|
||||||
|
NovitaAi,
|
||||||
|
NvidiaNim,
|
||||||
|
Ollama,
|
||||||
|
OpenRouter,
|
||||||
|
VercelAiGateway,
|
||||||
|
ZAi,
|
||||||
|
}
|
||||||
|
|
||||||
impl Shortcut {
|
impl Shortcut {
|
||||||
fn suggestions(&self) -> Vec<(Provider, EcoString)> {
|
fn suggestions(&self) -> Vec<(Provider, EcoString)> {
|
||||||
use Provider as P;
|
use Provider as P;
|
||||||
@@ -125,7 +140,9 @@ impl Shortcut {
|
|||||||
P::OpenRouter,
|
P::OpenRouter,
|
||||||
"nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free".into(),
|
"nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free".into(),
|
||||||
),
|
),
|
||||||
|
(P::Ollama, "nemotron-3-nano:30b".into()),
|
||||||
(P::Groq, "openai/gpt-oss-20b".into()),
|
(P::Groq, "openai/gpt-oss-20b".into()),
|
||||||
|
(P::Ollama, "gpt-oss:20b".into()),
|
||||||
(P::NvidiaNim, "openai/gpt-oss-20b".into()),
|
(P::NvidiaNim, "openai/gpt-oss-20b".into()),
|
||||||
(P::CloudflareWorkersAi, "@cf/openai/gpt-oss-20b".into()),
|
(P::CloudflareWorkersAi, "@cf/openai/gpt-oss-20b".into()),
|
||||||
(P::OpenRouter, "openai/gpt-oss-20b:free".into()),
|
(P::OpenRouter, "openai/gpt-oss-20b:free".into()),
|
||||||
@@ -145,6 +162,7 @@ impl Shortcut {
|
|||||||
(P::NvidiaNim, "meta/muse-glimmer-30b".into()),
|
(P::NvidiaNim, "meta/muse-glimmer-30b".into()),
|
||||||
(P::HuggingFace, "meta-models/Muse-Glimmer-30B".into()),
|
(P::HuggingFace, "meta-models/Muse-Glimmer-30B".into()),
|
||||||
(P::GoogleAiStudio, "gemma-4-31b-it".into()),
|
(P::GoogleAiStudio, "gemma-4-31b-it".into()),
|
||||||
|
(P::Ollama, "gemma4:31b".into()),
|
||||||
(P::NvidiaNim, "google/gemma-4-31b-it".into()),
|
(P::NvidiaNim, "google/gemma-4-31b-it".into()),
|
||||||
(P::OpenRouter, "google/gemma-4-31b-it:free".into()),
|
(P::OpenRouter, "google/gemma-4-31b-it:free".into()),
|
||||||
(P::HuggingFace, "google/gemma-4-31B-it".into()),
|
(P::HuggingFace, "google/gemma-4-31B-it".into()),
|
||||||
@@ -185,6 +203,7 @@ impl Shortcut {
|
|||||||
"inclusionai/ling-3.0-flash-sante".into(),
|
"inclusionai/ling-3.0-flash-sante".into(),
|
||||||
),
|
),
|
||||||
(P::VercelAiGateway, "mistral/mistral-large-3".into()),
|
(P::VercelAiGateway, "mistral/mistral-large-3".into()),
|
||||||
|
(P::Ollama, "nemotron-3-super".into()),
|
||||||
(P::NvidiaNim, "nvidia/nemotron-3-super-120b-a12b".into()),
|
(P::NvidiaNim, "nvidia/nemotron-3-super-120b-a12b".into()),
|
||||||
(P::Kilo, "nvidia-nemotron-3-super-120b-a12b-free".into()),
|
(P::Kilo, "nvidia-nemotron-3-super-120b-a12b-free".into()),
|
||||||
(
|
(
|
||||||
@@ -192,6 +211,7 @@ impl Shortcut {
|
|||||||
"nvidia/nemotron-3-super-120b-a12b:free".into(),
|
"nvidia/nemotron-3-super-120b-a12b:free".into(),
|
||||||
),
|
),
|
||||||
(P::Groq, "openai/gpt-oss-120b".into()),
|
(P::Groq, "openai/gpt-oss-120b".into()),
|
||||||
|
(P::Ollama, "gpt-oss:120b".into()),
|
||||||
(P::CloudflareWorkersAi, "@cf/openai/gpt-oss-120b".into()),
|
(P::CloudflareWorkersAi, "@cf/openai/gpt-oss-120b".into()),
|
||||||
(P::OpenRouter, "openai/gpt-oss-120b:free".into()),
|
(P::OpenRouter, "openai/gpt-oss-120b:free".into()),
|
||||||
(P::HuggingFace, "openai/gpt-oss-120b".into()),
|
(P::HuggingFace, "openai/gpt-oss-120b".into()),
|
||||||
@@ -208,10 +228,11 @@ impl Shortcut {
|
|||||||
(P::VercelAiGateway, "openai/gpt-5.2".into()),
|
(P::VercelAiGateway, "openai/gpt-5.2".into()),
|
||||||
(P::NvidiaNim, "deepseek-ai/deepseek-v4.1-flash".into()),
|
(P::NvidiaNim, "deepseek-ai/deepseek-v4.1-flash".into()),
|
||||||
(P::HuggingFace, "deepseek-ai/DeepSeek-V4.1-Flash".into()),
|
(P::HuggingFace, "deepseek-ai/DeepSeek-V4.1-Flash".into()),
|
||||||
(P::VercelAiGateway, "xiaomi/mimo-v2.6-flash".into()),
|
|
||||||
(P::HuggingFace, "XiaomiMiMo/MiMo-V2.6-Flash-RL".into()),
|
|
||||||
(P::VercelAiGateway, "inclusionai/ling-3.1-flash".into()),
|
(P::VercelAiGateway, "inclusionai/ling-3.1-flash".into()),
|
||||||
(P::HuggingFace, "inclusionAI/Ling-3.1-flash".into()),
|
(P::HuggingFace, "inclusionAI/Ling-3.1-flash".into()),
|
||||||
|
(P::Ollama, "beam".into()),
|
||||||
|
(P::VercelAiGateway, "xiaomi/mimo-v2.6-flash".into()),
|
||||||
|
(P::HuggingFace, "XiaomiMiMo/MiMo-V2.6-Flash-RL".into()),
|
||||||
(P::Kilo, "nex-agi-nex-n2-5-pro-free".into()),
|
(P::Kilo, "nex-agi-nex-n2-5-pro-free".into()),
|
||||||
(P::VercelAiGateway, "xiaomi/mimo-v2.5".into()),
|
(P::VercelAiGateway, "xiaomi/mimo-v2.5".into()),
|
||||||
(P::Kilo, "dots-studio-dots-3-note-preview-free".into()),
|
(P::Kilo, "dots-studio-dots-3-note-preview-free".into()),
|
||||||
@@ -223,6 +244,7 @@ impl Shortcut {
|
|||||||
(P::Kilo, "tencent-hy3-preview-free".into()),
|
(P::Kilo, "tencent-hy3-preview-free".into()),
|
||||||
(P::OpenRouter, "thinkingmachines/inkling-small:free".into()),
|
(P::OpenRouter, "thinkingmachines/inkling-small:free".into()),
|
||||||
(P::HuggingFace, "thinkingmachines/Inkling-Small".into()),
|
(P::HuggingFace, "thinkingmachines/Inkling-Small".into()),
|
||||||
|
(P::Ollama, "nemotron-3-ultra".into()),
|
||||||
(P::NvidiaNim, "nvidia/nemotron-3-ultra-550b-a55b".into()),
|
(P::NvidiaNim, "nvidia/nemotron-3-ultra-550b-a55b".into()),
|
||||||
(P::Kilo, "nvidia-nemotron-3-ultra-550b-a55b-free".into()),
|
(P::Kilo, "nvidia-nemotron-3-ultra-550b-a55b-free".into()),
|
||||||
],
|
],
|
||||||
@@ -232,11 +254,11 @@ impl Shortcut {
|
|||||||
(P::HuggingFace, "zai-org/GLM-5.3".into()),
|
(P::HuggingFace, "zai-org/GLM-5.3".into()),
|
||||||
(P::CloudflareWorkersAi, "@cf/zai-org/glm-5.3".into()),
|
(P::CloudflareWorkersAi, "@cf/zai-org/glm-5.3".into()),
|
||||||
(P::Mistral, "zai-glm-5-3".into()),
|
(P::Mistral, "zai-glm-5-3".into()),
|
||||||
|
(P::NvidiaNim, "moonshotai/kimi-k3".into()),
|
||||||
|
(P::HuggingFace, "moonshotai/Kimi-K3".into()),
|
||||||
(P::HuggingFace, "tencent/Hy4-preview".into()),
|
(P::HuggingFace, "tencent/Hy4-preview".into()),
|
||||||
(P::HuggingFace, "XiaomiMiMo/MiMo-V2.6-Pro-RL".into()),
|
(P::HuggingFace, "XiaomiMiMo/MiMo-V2.6-Pro-RL".into()),
|
||||||
(P::Mistral, "mistral-large-4".into()),
|
(P::Mistral, "mistral-large-4".into()),
|
||||||
(P::NvidiaNim, "moonshotai/kimi-k3".into()),
|
|
||||||
(P::HuggingFace, "moonshotai/Kimi-K3".into()),
|
|
||||||
(P::HuggingFace, "Qwen/Qwen3.8-2.4T-A95B".into()),
|
(P::HuggingFace, "Qwen/Qwen3.8-2.4T-A95B".into()),
|
||||||
(P::VercelAiGateway, "xiaomi/mimo-v2.5-pro".into()),
|
(P::VercelAiGateway, "xiaomi/mimo-v2.5-pro".into()),
|
||||||
(P::OpenRouter, "thinkingmachines/inkling:free".into()),
|
(P::OpenRouter, "thinkingmachines/inkling:free".into()),
|
||||||
@@ -397,7 +419,6 @@ pub async fn create_chat_completion(
|
|||||||
.build()
|
.build()
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
Provider::LiquidAi => unreachable!(),
|
|
||||||
Provider::Mistral => state
|
Provider::Mistral => state
|
||||||
.app_args
|
.app_args
|
||||||
.mistral_api_key
|
.mistral_api_key
|
||||||
@@ -434,6 +455,18 @@ pub async fn create_chat_completion(
|
|||||||
.build()
|
.build()
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
|
Provider::Ollama => state
|
||||||
|
.app_args
|
||||||
|
.ollama_cloud_api_key
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.map(|api_key| {
|
||||||
|
Upstream::builder()
|
||||||
|
.url("https://ollama.com/v1/chat/completions".parse().expect("TODO"))
|
||||||
|
.api_key(api_key)
|
||||||
|
.build()
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
Provider::OpenRouter => state
|
Provider::OpenRouter => state
|
||||||
.app_args
|
.app_args
|
||||||
.openrouter_api_key
|
.openrouter_api_key
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use crate::CloudflareCredentials;
|
use crate::CloudflareCredentials;
|
||||||
use crate::openai;
|
use crate::openai;
|
||||||
use crate::server::AppState;
|
use crate::server::AppState;
|
||||||
use crate::server::Provider;
|
|
||||||
use crate::server::Upstream;
|
use crate::server::Upstream;
|
||||||
use crate::server::take_random_by_swapping;
|
use crate::server::take_random_by_swapping;
|
||||||
use axum::Json;
|
use axum::Json;
|
||||||
@@ -45,6 +44,13 @@ pub enum Shortcut {
|
|||||||
Nemotron3Embed1B,
|
Nemotron3Embed1B,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
enum Provider {
|
||||||
|
Mistral,
|
||||||
|
NvidiaNim,
|
||||||
|
OpenRouter,
|
||||||
|
}
|
||||||
|
|
||||||
impl Shortcut {
|
impl Shortcut {
|
||||||
fn suggestions(&self) -> Vec<(Provider, EcoString)> {
|
fn suggestions(&self) -> Vec<(Provider, EcoString)> {
|
||||||
use Provider as P;
|
use Provider as P;
|
||||||
@@ -96,71 +102,7 @@ pub async fn create_embeddings(
|
|||||||
let mut model_upstreams = VecDeque::new();
|
let mut model_upstreams = VecDeque::new();
|
||||||
|
|
||||||
for (provider, model) in shortcut.suggestions() {
|
for (provider, model) in shortcut.suggestions() {
|
||||||
let upstreams: Vec<Upstream> =
|
let upstreams: Vec<Upstream> = match provider {
|
||||||
match provider {
|
|
||||||
Provider::CloudflareWorkersAi => state
|
|
||||||
.app_args
|
|
||||||
.cloudflare_workers_ai_credentials
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(
|
|
||||||
|CloudflareCredentials {
|
|
||||||
account_id,
|
|
||||||
api_key,
|
|
||||||
}| {
|
|
||||||
Upstream::builder()
|
|
||||||
.url(
|
|
||||||
format!("https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1/embeddings")
|
|
||||||
.parse()
|
|
||||||
.expect("TODO"),
|
|
||||||
)
|
|
||||||
.api_key(api_key)
|
|
||||||
.build()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.collect(),
|
|
||||||
Provider::GoogleAiStudio => state
|
|
||||||
.app_args
|
|
||||||
.google_ai_studio_api_key
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(|api_key| {
|
|
||||||
Upstream::builder()
|
|
||||||
.url(
|
|
||||||
"https://generativelanguage.googleapis.com/v1beta/openai/v1/embeddings"
|
|
||||||
.parse()
|
|
||||||
.expect("TODO"),
|
|
||||||
)
|
|
||||||
.api_key(api_key)
|
|
||||||
.build()
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
Provider::Groq => state
|
|
||||||
.app_args
|
|
||||||
.groq_api_key
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(|api_key| {
|
|
||||||
Upstream::builder()
|
|
||||||
.url("https://api.groq.com/openai/v1/embeddings".parse().expect("TODO"))
|
|
||||||
.api_key(api_key)
|
|
||||||
.build()
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
Provider::HuggingFace => state
|
|
||||||
.app_args
|
|
||||||
.hugging_face_api_key
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(|api_key| {
|
|
||||||
Upstream::builder()
|
|
||||||
.url("https://router.huggingface.co/v1/embeddings".parse().expect("TODO"))
|
|
||||||
.api_key(api_key)
|
|
||||||
.build()
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
Provider::Kilo => unreachable!(),
|
|
||||||
Provider::LiquidAi => unreachable!(),
|
|
||||||
Provider::Mistral => state
|
Provider::Mistral => state
|
||||||
.app_args
|
.app_args
|
||||||
.mistral_api_key
|
.mistral_api_key
|
||||||
@@ -168,7 +110,11 @@ pub async fn create_embeddings(
|
|||||||
.cloned()
|
.cloned()
|
||||||
.map(|api_key| {
|
.map(|api_key| {
|
||||||
Upstream::builder()
|
Upstream::builder()
|
||||||
.url("https://api.mistral.ai/v1/embeddings".parse().expect("TODO"))
|
.url(
|
||||||
|
"https://api.mistral.ai/v1/embeddings"
|
||||||
|
.parse()
|
||||||
|
.expect("TODO"),
|
||||||
|
)
|
||||||
.api_key(api_key)
|
.api_key(api_key)
|
||||||
.build()
|
.build()
|
||||||
})
|
})
|
||||||
@@ -180,12 +126,15 @@ pub async fn create_embeddings(
|
|||||||
.cloned()
|
.cloned()
|
||||||
.map(|api_key| {
|
.map(|api_key| {
|
||||||
Upstream::builder()
|
Upstream::builder()
|
||||||
.url("https://integrate.api.nvidia.com/v1/embeddings".parse().expect("TODO"))
|
.url(
|
||||||
|
"https://integrate.api.nvidia.com/v1/embeddings"
|
||||||
|
.parse()
|
||||||
|
.expect("TODO"),
|
||||||
|
)
|
||||||
.api_key(api_key)
|
.api_key(api_key)
|
||||||
.build()
|
.build()
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
Provider::NovitaAi => unreachable!(),
|
|
||||||
Provider::OpenRouter => state
|
Provider::OpenRouter => state
|
||||||
.app_args
|
.app_args
|
||||||
.openrouter_api_key
|
.openrouter_api_key
|
||||||
@@ -193,13 +142,15 @@ pub async fn create_embeddings(
|
|||||||
.cloned()
|
.cloned()
|
||||||
.map(|api_key| {
|
.map(|api_key| {
|
||||||
Upstream::builder()
|
Upstream::builder()
|
||||||
.url("https://openrouter.ai/api/v1/embeddings".parse().expect("TODO"))
|
.url(
|
||||||
|
"https://openrouter.ai/api/v1/embeddings"
|
||||||
|
.parse()
|
||||||
|
.expect("TODO"),
|
||||||
|
)
|
||||||
.api_key(api_key)
|
.api_key(api_key)
|
||||||
.build()
|
.build()
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
Provider::VercelAiGateway => unreachable!(),
|
|
||||||
Provider::ZAi => unreachable!(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok(upstreams) = Vec1::try_from(upstreams) {
|
if let Ok(upstreams) = Vec1::try_from(upstreams) {
|
||||||
|
|||||||
@@ -19,23 +19,6 @@ mod system_one;
|
|||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
app_args: Arc<AppArgs>,
|
app_args: Arc<AppArgs>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
enum Provider {
|
|
||||||
CloudflareWorkersAi,
|
|
||||||
GoogleAiStudio,
|
|
||||||
Groq,
|
|
||||||
HuggingFace,
|
|
||||||
Kilo,
|
|
||||||
LiquidAi,
|
|
||||||
Mistral,
|
|
||||||
NovitaAi,
|
|
||||||
NvidiaNim,
|
|
||||||
OpenRouter,
|
|
||||||
VercelAiGateway,
|
|
||||||
ZAi,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn take_random_by_swapping<T>(mut vec1: Vec1<T>, mut rng: impl Rng) -> (T, Option<Vec1<T>>) {
|
fn take_random_by_swapping<T>(mut vec1: Vec1<T>, mut rng: impl Rng) -> (T, Option<Vec1<T>>) {
|
||||||
let end = vec1.len().get() - 1;
|
let end = vec1.len().get() - 1;
|
||||||
let index = rng.random_range(0..=end);
|
let index = rng.random_range(0..=end);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use crate::CloudflareCredentials;
|
use crate::CloudflareCredentials;
|
||||||
use crate::openai;
|
use crate::openai;
|
||||||
use crate::server::AppState;
|
use crate::server::AppState;
|
||||||
use crate::server::Provider;
|
|
||||||
use crate::server::Upstream;
|
use crate::server::Upstream;
|
||||||
use crate::server::take_random_by_swapping;
|
use crate::server::take_random_by_swapping;
|
||||||
use axum::Json;
|
use axum::Json;
|
||||||
@@ -36,6 +35,14 @@ pub enum Shortcut {
|
|||||||
M,
|
M,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
enum Provider {
|
||||||
|
CloudflareWorkersAi,
|
||||||
|
LiquidAi,
|
||||||
|
OpenRouter,
|
||||||
|
VercelAiGateway,
|
||||||
|
}
|
||||||
|
|
||||||
impl Shortcut {
|
impl Shortcut {
|
||||||
fn suggestions(&self) -> Vec<(Provider, EcoString)> {
|
fn suggestions(&self) -> Vec<(Provider, EcoString)> {
|
||||||
use Provider as P;
|
use Provider as P;
|
||||||
@@ -53,6 +60,7 @@ impl Shortcut {
|
|||||||
(P::VercelAiGateway, "convaiinnovations/laya".into()),
|
(P::VercelAiGateway, "convaiinnovations/laya".into()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
S::M => {
|
S::M => {
|
||||||
vec![
|
vec![
|
||||||
(P::CloudflareWorkersAi, "clef".into()),
|
(P::CloudflareWorkersAi, "clef".into()),
|
||||||
@@ -118,10 +126,6 @@ pub async fn create_system_one(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.collect(),
|
.collect(),
|
||||||
Provider::GoogleAiStudio => unreachable!(),
|
|
||||||
Provider::Groq => unreachable!(),
|
|
||||||
Provider::HuggingFace => unreachable!(),
|
|
||||||
Provider::Kilo => unreachable!(),
|
|
||||||
Provider::LiquidAi => state
|
Provider::LiquidAi => state
|
||||||
.app_args
|
.app_args
|
||||||
.liquid_ai_api_key
|
.liquid_ai_api_key
|
||||||
@@ -134,9 +138,6 @@ pub async fn create_system_one(
|
|||||||
.build()
|
.build()
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
Provider::Mistral => unreachable!(),
|
|
||||||
Provider::NovitaAi => unreachable!(),
|
|
||||||
Provider::NvidiaNim => unreachable!(),
|
|
||||||
Provider::OpenRouter => state
|
Provider::OpenRouter => state
|
||||||
.app_args
|
.app_args
|
||||||
.openrouter_api_key
|
.openrouter_api_key
|
||||||
@@ -161,7 +162,6 @@ pub async fn create_system_one(
|
|||||||
.build()
|
.build()
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
Provider::ZAi => unreachable!(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok(upstreams) = Vec1::try_from(upstreams) {
|
if let Ok(upstreams) = Vec1::try_from(upstreams) {
|
||||||
|
|||||||
Reference in New Issue
Block a user