feat(providers): add Gondola as declarative OpenAI-compatible provider (#11421)
Signed-off-by: Abhijay Jain <Abhijay007j@gmail.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
use super::api_client::{ApiClient, AuthMethod};
|
||||
use super::base::{ConfigKey, ProviderDef, ProviderMetadata};
|
||||
use super::openai_compatible::OpenAiCompatibleProvider;
|
||||
use anyhow::Result;
|
||||
use futures::future::BoxFuture;
|
||||
|
||||
const GONDOLA_PROVIDER_NAME: &str = "gondola";
|
||||
pub const GONDOLA_API_HOST: &str = "https://api.gondola-ai.com/v1";
|
||||
pub const GONDOLA_DEFAULT_MODEL: &str = "deepseek-v4-flash";
|
||||
pub const GONDOLA_KNOWN_MODELS: &[&str] = &[
|
||||
"claude-opus-5",
|
||||
"claude-sonnet-5",
|
||||
"deepseek-v3.2",
|
||||
"deepseek-v4-flash",
|
||||
"deepseek-v4-pro",
|
||||
"e2ee-deepseek-v4-flash",
|
||||
"e2ee-qwen3-6-35b-a3b",
|
||||
"kimi-k2-5",
|
||||
"kimi-k3",
|
||||
"llama-3.3-70b",
|
||||
"qwen3-235b-a22b-instruct-2507",
|
||||
];
|
||||
pub const GONDOLA_DOC_URL: &str = "https://gondola-ai.com/guides";
|
||||
|
||||
pub struct GondolaProvider;
|
||||
|
||||
impl goose_providers::base::ProviderDescriptor for GondolaProvider {
|
||||
fn metadata() -> ProviderMetadata {
|
||||
ProviderMetadata::new(
|
||||
GONDOLA_PROVIDER_NAME,
|
||||
"Gondola",
|
||||
"Pay-per-request inference via Venice AI, settled in USDC. Privacy-preserving with TEE model options.",
|
||||
GONDOLA_DEFAULT_MODEL,
|
||||
GONDOLA_KNOWN_MODELS.to_vec(),
|
||||
GONDOLA_DOC_URL,
|
||||
vec![
|
||||
ConfigKey::new("GONDOLA_API_KEY", true, true, None, true),
|
||||
ConfigKey::new("GONDOLA_HOST", false, false, Some(GONDOLA_API_HOST), false),
|
||||
],
|
||||
)
|
||||
.with_setup(
|
||||
crate::providers::catalog::ProviderSetupMetadata::api_key(
|
||||
crate::providers::catalog::ProviderSetupGroup::Default,
|
||||
)
|
||||
.with_docs_url(GONDOLA_DOC_URL),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ProviderDef for GondolaProvider {
|
||||
type Provider = OpenAiCompatibleProvider;
|
||||
|
||||
fn from_env(
|
||||
_extensions: Vec<crate::config::ExtensionConfig>,
|
||||
tls_config: Option<crate::providers::api_client::TlsConfig>,
|
||||
) -> BoxFuture<'static, Result<OpenAiCompatibleProvider>> {
|
||||
Box::pin(async move {
|
||||
let config = crate::config::Config::global();
|
||||
let api_key: String = config.get_secret("GONDOLA_API_KEY")?;
|
||||
let host: String = config
|
||||
.get_param("GONDOLA_HOST")
|
||||
.unwrap_or_else(|_| GONDOLA_API_HOST.to_string());
|
||||
|
||||
let api_client =
|
||||
ApiClient::new_with_tls(host, AuthMethod::BearerToken(api_key), tls_config)?
|
||||
.with_request_builder(crate::session_context::session_id_request_builder());
|
||||
|
||||
Ok(OpenAiCompatibleProvider::new(
|
||||
GONDOLA_PROVIDER_NAME.to_string(),
|
||||
api_client,
|
||||
String::new(),
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ use super::{
|
||||
gemini_cli::GeminiCliProvider,
|
||||
gemini_oauth::GeminiOAuthProvider,
|
||||
githubcopilot::GithubCopilotProvider,
|
||||
gondola::GondolaProvider,
|
||||
huggingface::HuggingFaceProvider,
|
||||
kimicode::KimiCodeProvider,
|
||||
litellm::LiteLLMProvider,
|
||||
@@ -121,6 +122,7 @@ async fn init_registry() -> RwLock<ProviderRegistry> {
|
||||
false,
|
||||
Some(registrations::refresh_only()),
|
||||
);
|
||||
registry.register::<GondolaProvider>(false);
|
||||
registry.register_with_inventory::<GoogleProviderDef>(
|
||||
true,
|
||||
Some(registrations::google_inventory()),
|
||||
@@ -329,6 +331,21 @@ mod tests {
|
||||
.any(|key| key.name == "HF_TOKEN" && key.secret));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_gondola_provider_registry_wiring() {
|
||||
let gondola = get_from_registry("gondola")
|
||||
.await
|
||||
.expect("gondola provider should be registered");
|
||||
let meta = gondola.metadata();
|
||||
|
||||
assert_eq!(meta.name, "gondola");
|
||||
assert_eq!(meta.default_model, "deepseek-v4-flash");
|
||||
assert!(meta
|
||||
.config_keys
|
||||
.iter()
|
||||
.any(|key| key.name == "GONDOLA_API_KEY" && key.secret));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_openai_compatible_providers_config_keys() {
|
||||
let providers_list = providers().await;
|
||||
|
||||
@@ -42,6 +42,7 @@ pub mod githubcopilot;
|
||||
pub mod google {
|
||||
pub use goose_providers::google::*;
|
||||
}
|
||||
pub mod gondola;
|
||||
pub mod google_def;
|
||||
pub mod http_status {
|
||||
pub use goose_providers::http_status::*;
|
||||
|
||||
@@ -38,6 +38,7 @@ goose is compatible with a wide range of LLM providers, allowing you to choose a
|
||||
| [Gemini](https://ai.google.dev/gemini-api/docs) | Advanced LLMs by Google with multimodal capabilities (text, images). Gemini 3 models support configurable [thinking levels](#gemini-3-thinking-levels). | `GOOGLE_API_KEY`, `GEMINI3_THINKING_LEVEL` (optional) |
|
||||
| [GCP Vertex AI](https://cloud.google.com/vertex-ai) | Google Cloud's Vertex AI platform, supporting Gemini and Claude models. **Credentials must be [configured in advance](https://cloud.google.com/vertex-ai/docs/authentication).** Filters for allowed models by organization policy (if configured). | `GCP_PROJECT_ID`, `GCP_LOCATION` and optionally `GCP_MAX_RATE_LIMIT_RETRIES` (5), `GCP_MAX_OVERLOADED_RETRIES` (5), `GCP_INITIAL_RETRY_INTERVAL_MS` (5000), `GCP_BACKOFF_MULTIPLIER` (2.0), `GCP_MAX_RETRY_INTERVAL_MS` (320_000). |
|
||||
| [GitHub Copilot](https://docs.github.com/en/copilot/using-github-copilot/ai-models) | Access to AI models from OpenAI, Anthropic, Google, and other providers through GitHub's Copilot infrastructure. **GitHub account with Copilot access required.** | No manual key. Uses [device flow authentication](#github-copilot-authentication) for both CLI and Desktop. |
|
||||
| [Gondola](https://gondola-ai.com/guides) | Pay-per-request inference via Venice AI, settled in USDC on Base. No subscription or minimum. Includes privacy-preserving TEE models (`e2ee-*`). OpenAI-compatible. | `GONDOLA_API_KEY`, `GONDOLA_HOST` (optional) |
|
||||
| [Groq](https://groq.com/) | High-performance inference hardware and tools for LLMs. | `GROQ_API_KEY` |
|
||||
| [iFlytek Spark](https://www.xfyun.cn/doc/spark/HTTP%E8%B0%83%E7%94%A8%E6%96%87%E6%A1%A3.html) | iFlytek Spark (讯飞星火) models (4.0Ultra, generalv3.5, max-32k) via the OpenAI-compatible HTTP API. Best for chat: Spark needs `tool_calls_switch=true` (not injectable here) to return OpenAI-style tool calls. | `SPARK_API_PASSWORD` |
|
||||
| [iFlytek Astron MaaS](https://maas.xfyun.cn/) | iFlytek Astron MaaS (讯飞星辰) hosting Spark X2, DeepSeek, GLM, Kimi, MiniMax, Qwen, and Astron coding models via an OpenAI-compatible API. Set `ASTRON_BASE_URL` to switch between the Token Plan and Coding Plan endpoints. | `ASTRON_API_KEY`, `ASTRON_BASE_URL` (optional) |
|
||||
|
||||
@@ -169,6 +169,11 @@ prompt: |
|
||||
4. Verify MaaS requires its bound model and uses /v1/chat/completions.
|
||||
If the source checkout or Rust toolchain is unavailable, mark this validation as skipped rather than failed.
|
||||
|
||||
### Gondola Provider Validation
|
||||
When running from a goose source checkout:
|
||||
1. Run `cargo test -p goose test_gondola_provider_registry_wiring` to verify Gondola is registered with the correct name, default model (`deepseek-v4-flash`), and a secret `GONDOLA_API_KEY` config key.
|
||||
If the source checkout or Rust toolchain is unavailable, mark this validation as skipped rather than failed.
|
||||
|
||||
Log results to: {{ workspace_dir }}/phase1_basic_tools.md
|
||||
{% endif %}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user