Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions crates/jp_config/src/model/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,9 @@ pub enum ProviderId {
/// Openrouter provider.
/// See: <https://openrouter.io>.
Openrouter,
/// vLLM provider: a self-hosted vLLM server with an OpenAI-compatible API.
/// See: <https://docs.vllm.ai>.
Vllm,
/// xAI provider.
/// See: <https://x.ai/api>.
/// UNIMPLEMENTED.
Expand All @@ -619,6 +622,7 @@ impl ProviderId {
Self::Ollama => "ollama",
Self::Openai => "openai",
Self::Openrouter => "openrouter",
Self::Vllm => "vllm",
Self::Xai => "xai",

Self::Test => "test",
Expand Down
1 change: 1 addition & 0 deletions crates/jp_config/src/model/id_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ fn the_variant_list_leaves_out_the_test_provider() {
"ollama",
"openai",
"openrouter",
"vllm",
"xai"
]);
}
Expand Down
11 changes: 11 additions & 0 deletions crates/jp_config/src/providers/llm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod llamacpp;
pub mod ollama;
pub mod openai;
pub mod openrouter;
pub mod vllm;

use indexmap::IndexMap;
use schematic::{Config, ConfigError};
Expand All @@ -27,6 +28,7 @@ use crate::{
ollama::{OllamaConfig, PartialOllamaConfig},
openai::{OpenaiConfig, PartialOpenaiConfig},
openrouter::{OpenrouterConfig, PartialOpenrouterConfig},
vllm::{PartialVllmConfig, VllmConfig},
},
util::merge_nested_indexmap,
validate::Validator,
Expand Down Expand Up @@ -83,6 +85,10 @@ pub struct LlmProviderConfig {
/// Openrouter API configuration.
#[setting(nested)]
pub openrouter: OpenrouterConfig,

/// vLLM API configuration.
#[setting(nested)]
pub vllm: VllmConfig,
}

impl Validator for LlmProviderConfig {
Expand All @@ -104,6 +110,7 @@ impl AssignKeyValue for PartialLlmProviderConfig {
_ if kv.p("ollama") => self.ollama.assign(kv)?,
_ if kv.p("openai") => self.openai.assign(kv)?,
_ if kv.p("openrouter") => self.openrouter.assign(kv)?,
_ if kv.p("vllm") => self.vllm.assign(kv)?,
_ => return missing_key(&kv),
}

Expand All @@ -126,6 +133,7 @@ impl PartialConfigDelta for PartialLlmProviderConfig {
ollama: self.ollama.delta(next.ollama),
openai: self.openai.delta(next.openai),
openrouter: self.openrouter.delta(next.openrouter),
vllm: self.vllm.delta(next.vllm),
}
}

Expand All @@ -148,6 +156,7 @@ impl PartialConfigDelta for PartialLlmProviderConfig {
&path(prefix, "openrouter"),
unsets,
),
vllm: self.vllm.delta(next.vllm),
}
}
}
Expand All @@ -164,6 +173,7 @@ impl FillDefaults for PartialLlmProviderConfig {
ollama: self.ollama.fill_from(defaults.ollama),
openai: self.openai.fill_from(defaults.openai),
openrouter: self.openrouter.fill_from(defaults.openrouter),
vllm: self.vllm.fill_from(defaults.vllm),
}
}
}
Expand All @@ -184,6 +194,7 @@ impl ToPartial for LlmProviderConfig {
ollama: self.ollama.to_partial(),
openai: self.openai.to_partial(),
openrouter: self.openrouter.to_partial(),
vllm: self.vllm.to_partial(),
}
}
}
Expand Down
77 changes: 77 additions & 0 deletions crates/jp_config/src/providers/llm/vllm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//! vLLM API configuration.
//!
//! A vLLM server speaks the OpenAI-compatible `/v1/chat/completions` dialect
//! and checks the Bearer token given to it with `--api-key`.
//!
//! ```toml
//! [providers.llm.vllm]
//! api_key_env = "VLLM_API_KEY"
//! base_url = "http://127.0.0.1:8000"
//! ```

use schematic::Config;

use crate::{
assignment::{AssignKeyValue, AssignResult, KvAssignment, missing_key},
delta::{PartialConfigDelta, delta_opt},
fill::FillDefaults,
partial::{ToPartial, partial_opt},
};

/// vLLM API configuration.
#[derive(Debug, Clone, PartialEq, Config)]
#[config(rename_all = "snake_case")]
pub struct VllmConfig {
/// Environment variable that contains the API key.
#[setting(default = "VLLM_API_KEY")]
pub api_key_env: String,

/// The base URL to use for API requests.
///
/// The default is `http://127.0.0.1:8000`, which is the default URL for a
/// vLLM server.
#[setting(default = "http://127.0.0.1:8000")]
pub base_url: String,
}

impl AssignKeyValue for PartialVllmConfig {
fn assign(&mut self, kv: KvAssignment) -> AssignResult {
match kv.key_string().as_str() {
"" => kv.try_merge_object(self)?,
"api_key_env" => self.api_key_env = kv.try_some_string()?,
"base_url" => self.base_url = kv.try_some_string()?,
_ => return missing_key(&kv),
}

Ok(())
}
}

impl PartialConfigDelta for PartialVllmConfig {
fn delta(&self, next: Self) -> Self {
Self {
api_key_env: delta_opt(self.api_key_env.as_ref(), next.api_key_env),
base_url: delta_opt(self.base_url.as_ref(), next.base_url),
}
}
}

impl FillDefaults for PartialVllmConfig {
fn fill_from(self, defaults: Self) -> Self {
Self {
api_key_env: self.api_key_env.or(defaults.api_key_env),
base_url: self.base_url.or(defaults.base_url),
}
}
}

impl ToPartial for VllmConfig {
fn to_partial(&self) -> Self::Partial {
let defaults = Self::Partial::default();

Self::Partial {
api_key_env: partial_opt(&self.api_key_env, defaults.api_key_env),
base_url: partial_opt(&self.base_url, defaults.base_url),
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ expression: "AppConfig::fields()"
"style.code.line_numbers",
"providers.mcp",
"providers.llm.aliases",
"providers.llm.vllm.api_key_env",
"providers.llm.vllm.base_url",
"providers.llm.openrouter.api_key_env",
"providers.llm.openrouter.app_name",
"providers.llm.openrouter.app_referrer",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ assistant: AssistantConfig
id: ModelIdOrAliasConfig
|: ModelIdConfig
name: string
provider: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "xai"
provider: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "vllm" | "xai"
|: string
parameters: ParametersConfig
max_tokens: int | null
Expand Down Expand Up @@ -136,7 +136,7 @@ conversation: ConversationConfig
id: ModelIdOrAliasConfig
|: ModelIdConfig
name: string
provider: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "xai"
provider: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "vllm" | "xai"
|: string
parameters: ParametersConfig
max_tokens: int | null
Expand Down Expand Up @@ -189,7 +189,7 @@ conversation: ConversationConfig
id: ModelIdOrAliasConfig
|: ModelIdConfig
name: string
provider: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "xai"
provider: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "vllm" | "xai"
|: string
parameters: ParametersConfig
max_tokens: int | null
Expand Down Expand Up @@ -256,7 +256,7 @@ conversation: ConversationConfig
id: ModelIdOrAliasConfig
|: ModelIdConfig
name: string
provider: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "xai"
provider: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "vllm" | "xai"
|: string
parameters: ParametersConfig
max_tokens: int | null
Expand Down Expand Up @@ -363,7 +363,7 @@ conversation: ConversationConfig
id: ModelIdOrAliasConfig
|: ModelIdConfig
name: string
provider: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "xai"
provider: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "vllm" | "xai"
|: string
parameters: ParametersConfig
max_tokens: int | null
Expand Down Expand Up @@ -584,7 +584,7 @@ conversation: ConversationConfig
|: PartialModelIdOrAliasConfig
|: PartialModelIdConfig
name?: string | null
provider?: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "xai" | null
provider?: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "vllm" | "xai" | null
|: string
|: null
parameters?:
Expand Down Expand Up @@ -723,7 +723,7 @@ providers: ProviderConfig
*: ModelIdOrAliasConfig
|: ModelIdConfig
name: string
provider: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "xai"
provider: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "vllm" | "xai"
|: string
anthropic: AnthropicConfig
api_key_env?: string
Expand Down Expand Up @@ -753,6 +753,9 @@ providers: ProviderConfig
app_name?: string
app_referrer: string | null
base_url?: string
vllm: VllmConfig
api_key_env?: string
base_url?: string
mcp:
*: McpProviderConfig
|: StdioConfig
Expand Down Expand Up @@ -800,7 +803,7 @@ style: StyleConfig
id: ModelIdOrAliasConfig
|: ModelIdConfig
name: string
provider: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "xai"
provider: "anthropic" | "cerebras" | "deepseek" | "google" | "llamacpp" | "ollama" | "openai" | "openrouter" | "vllm" | "xai"
|: string
parameters: ParametersConfig
max_tokens: int | null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ PartialAppConfig {
app_referrer: None,
base_url: None,
},
vllm: PartialVllmConfig {
api_key_env: None,
base_url: None,
},
},
mcp: {},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,14 @@ Ok(
"https://openrouter.ai",
),
},
vllm: PartialVllmConfig {
api_key_env: Some(
"VLLM_API_KEY",
),
base_url: Some(
"http://127.0.0.1:8000",
),
},
},
mcp: {},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ PartialAppConfig {
app_referrer: None,
base_url: None,
},
vllm: PartialVllmConfig {
api_key_env: None,
base_url: None,
},
},
mcp: {},
},
Expand Down
4 changes: 4 additions & 0 deletions crates/jp_llm/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod ollama;
pub mod openai;
pub(crate) mod openai_compat;
pub mod openrouter;
pub mod vllm;

use std::sync::atomic::{AtomicU64, Ordering};

Expand All @@ -24,6 +25,7 @@ use llamacpp::Llamacpp;
use ollama::Ollama;
use openai::Openai;
use openrouter::Openrouter;
use vllm::Vllm;

use crate::{
error::Result, model::ModelDetails, provider::mock::MockProvider, query::ChatQuery,
Expand Down Expand Up @@ -56,6 +58,7 @@ pub fn get_provider(id: ProviderId, config: &LlmProviderConfig) -> Result<Box<dy
ProviderId::Ollama => Box::new(Ollama::try_from(&config.ollama)?),
ProviderId::Openai => Box::new(Openai::try_from(&config.openai)?),
ProviderId::Openrouter => Box::new(Openrouter::try_from(&config.openrouter)?),
ProviderId::Vllm => Box::new(Vllm::try_from(&config.vllm)?),

ProviderId::Deepseek => todo!(),
ProviderId::Xai => todo!(),
Expand Down Expand Up @@ -113,6 +116,7 @@ pub(crate) fn build_request_value(
ProviderId::Openrouter => {
Openrouter::try_from(&config.openrouter)?.request_value(model, query)
}
ProviderId::Vllm => Vllm::try_from(&config.vllm)?.request_value(model, query),
ProviderId::Test | ProviderId::Deepseek | ProviderId::Xai => {
unreachable!("{id:?} is not part of the request snapshot suite")
}
Expand Down
Loading
Loading