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
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
# OpenRouter (multi-provider gateway)
# OPENROUTER_API_KEY=sk-or-...

# NEAR AI Cloud (TEE inference)
# NEARAI_API_KEY=...

# Together AI
# TOGETHER_API_KEY=...

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -357,11 +357,11 @@ For production workloads, use the [WhatsApp Cloud API](https://developers.facebo

---

## 27 LLM Providers, 123+ Models
## LLM Providers, 128+ Models

3 native drivers (Anthropic, Gemini, OpenAI-compatible) route to 27 providers:
3 native drivers (Anthropic, Gemini, OpenAI-compatible) route to providers including:

Anthropic, Gemini, OpenAI, Groq, DeepSeek, OpenRouter, Together, Mistral, Fireworks, Cohere, Perplexity, xAI, AI21, Cerebras, SambaNova, HuggingFace, Replicate, Ollama, vLLM, LM Studio, Qwen, MiniMax, Zhipu, Moonshot, Qianfan, Bedrock, and more.
Anthropic, Gemini, OpenAI, Groq, DeepSeek, OpenRouter, NEAR AI Cloud, Together, Mistral, Fireworks, Cohere, Perplexity, xAI, AI21, Cerebras, SambaNova, HuggingFace, Replicate, Ollama, vLLM, LM Studio, Qwen, MiniMax, Zhipu, Moonshot, Qianfan, Bedrock, and more.

Intelligent routing with task complexity scoring, automatic fallback, cost tracking, and per-model pricing.

Expand Down
76 changes: 68 additions & 8 deletions crates/openfang-runtime/src/drivers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! Contains drivers for Anthropic Claude, Google Gemini, OpenAI-compatible APIs, and more.
//! Supports: Anthropic, Gemini, OpenAI, Groq, OpenRouter, DeepSeek, Together,
//! Mistral, Fireworks, Ollama, vLLM, Chutes.ai, and any OpenAI-compatible endpoint.
//! Mistral, Fireworks, NEAR AI Cloud, Ollama, vLLM, Chutes.ai, and any OpenAI-compatible endpoint.

pub mod anthropic;
pub mod bedrock;
Expand All @@ -19,11 +19,12 @@ use openfang_types::model_catalog::{
AI21_BASE_URL, ANTHROPIC_BASE_URL, AZURE_OPENAI_BASE_URL, CEREBRAS_BASE_URL, CHUTES_BASE_URL,
COHERE_BASE_URL, DEEPSEEK_BASE_URL, FIREWORKS_BASE_URL, GEMINI_BASE_URL, GROQ_BASE_URL,
HUGGINGFACE_BASE_URL, KIMI_CODING_BASE_URL, LEMONADE_BASE_URL, LMSTUDIO_BASE_URL,
MINIMAX_BASE_URL, MISTRAL_BASE_URL, MOONSHOT_BASE_URL, NOVITA_BASE_URL, NVIDIA_NIM_BASE_URL,
OLLAMA_BASE_URL, OPENAI_BASE_URL, OPENROUTER_BASE_URL, PERPLEXITY_BASE_URL, QIANFAN_BASE_URL,
QWEN_BASE_URL, REPLICATE_BASE_URL, REQUESTY_BASE_URL, SAMBANOVA_BASE_URL, TOGETHER_BASE_URL,
VENICE_BASE_URL, VLLM_BASE_URL, VOLCENGINE_BASE_URL, VOLCENGINE_CODING_BASE_URL, XAI_BASE_URL,
ZAI_BASE_URL, ZAI_CODING_BASE_URL, ZHIPU_BASE_URL, ZHIPU_CODING_BASE_URL,
MINIMAX_BASE_URL, MISTRAL_BASE_URL, MOONSHOT_BASE_URL, NEARAI_BASE_URL, NOVITA_BASE_URL,
NVIDIA_NIM_BASE_URL, OLLAMA_BASE_URL, OPENAI_BASE_URL, OPENROUTER_BASE_URL,
PERPLEXITY_BASE_URL, QIANFAN_BASE_URL, QWEN_BASE_URL, REPLICATE_BASE_URL, REQUESTY_BASE_URL,
SAMBANOVA_BASE_URL, TOGETHER_BASE_URL, VENICE_BASE_URL, VLLM_BASE_URL, VOLCENGINE_BASE_URL,
VOLCENGINE_CODING_BASE_URL, XAI_BASE_URL, ZAI_BASE_URL, ZAI_CODING_BASE_URL, ZHIPU_BASE_URL,
ZHIPU_CODING_BASE_URL,
};
use std::sync::Arc;

Expand Down Expand Up @@ -276,6 +277,11 @@ fn provider_defaults(provider: &str) -> Option<ProviderDefaults> {
api_key_env: "CHUTES_API_KEY",
key_required: true,
}),
"nearai" | "near-ai" => Some(ProviderDefaults {
base_url: NEARAI_BASE_URL,
api_key_env: "NEARAI_API_KEY",
key_required: true,
}),
"venice" => Some(ProviderDefaults {
base_url: VENICE_BASE_URL,
api_key_env: "VENICE_API_KEY",
Expand Down Expand Up @@ -329,6 +335,7 @@ fn provider_defaults(provider: &str) -> Option<ProviderDefaults> {
/// - `xai` — xAI (Grok)
/// - `replicate` — Replicate
/// - `chutes` — Chutes.ai (serverless open-source model inference)
/// - `nearai` — NEAR AI Cloud TEE inference
/// - Any custom provider with `base_url` set uses OpenAI-compatible format
pub fn create_driver(config: &DriverConfig) -> Result<Arc<dyn LlmDriver>, LlmError> {
let provider = config.provider.as_str();
Expand Down Expand Up @@ -589,7 +596,7 @@ pub fn create_driver(config: &DriverConfig) -> Result<Arc<dyn LlmDriver>, LlmErr
"Unknown provider '{}'. Supported: anthropic, gemini, openai, azure, bedrock, groq, \
openrouter, deepseek, together, mistral, fireworks, ollama, vllm, lmstudio, \
perplexity, cohere, ai21, cerebras, sambanova, huggingface, xai, replicate, \
github-copilot, chutes, venice, nvidia, codex, claude-code. \
github-copilot, chutes, nearai, venice, nvidia, codex, claude-code. \
Or set base_url for a custom OpenAI-compatible endpoint.",
provider
),
Expand Down Expand Up @@ -631,6 +638,7 @@ pub fn detect_available_provider() -> Option<(&'static str, &'static str, &'stat
"PERPLEXITY_API_KEY",
),
("cohere", "command-r-plus", "COHERE_API_KEY"),
("nearai", "zai-org/GLM-5.1-FP8", "NEARAI_API_KEY"),
("novita", "moonshotai/kimi-k2.5", "NOVITA_API_KEY"),
];
for &(provider, model, env_var) in PROBE_ORDER {
Expand Down Expand Up @@ -687,6 +695,7 @@ pub fn known_providers() -> &'static [&'static str] {
"qianfan",
"volcengine",
"chutes",
"nearai",
"venice",
"nvidia",
"novita",
Expand Down Expand Up @@ -839,13 +848,14 @@ mod tests {
assert!(providers.contains(&"qianfan"));
assert!(providers.contains(&"volcengine"));
assert!(providers.contains(&"chutes"));
assert!(providers.contains(&"nearai"));
assert!(providers.contains(&"nvidia"));
assert!(providers.contains(&"novita"));
assert!(providers.contains(&"codex"));
assert!(providers.contains(&"claude-code"));
assert!(providers.contains(&"qwen-code"));
assert!(providers.contains(&"azure"));
assert_eq!(providers.len(), 38);
assert_eq!(providers.len(), 39);
}

#[test]
Expand Down Expand Up @@ -902,6 +912,56 @@ mod tests {
assert!(d.key_required);
}

#[test]
fn test_provider_defaults_nearai() {
let d = provider_defaults("nearai").unwrap();
assert_eq!(d.base_url, "https://cloud-api.near.ai/v1");
assert_eq!(d.api_key_env, "NEARAI_API_KEY");
assert!(d.key_required);
}

#[test]
fn test_provider_defaults_near_ai_alias() {
let d = provider_defaults("near-ai").unwrap();
assert_eq!(d.base_url, "https://cloud-api.near.ai/v1");
assert_eq!(d.api_key_env, "NEARAI_API_KEY");
assert!(d.key_required);
}

#[test]
fn test_nearai_provider_with_env_key() {
let _env_lock = ENV_LOCK.lock().unwrap();
let unique_key = "test-nearai-key-12345";
let _env = EnvVarGuard::set("NEARAI_API_KEY", unique_key);
let config = DriverConfig {
provider: "nearai".to_string(),
api_key: None,
base_url: None,
skip_permissions: true,
subprocess_timeout_secs: None,
};
let driver = create_driver(&config);
assert!(
driver.is_ok(),
"NEAR AI provider with env var should succeed"
);
}

#[test]
fn test_nearai_provider_no_key_errors() {
let _env_lock = ENV_LOCK.lock().unwrap();
let _env = EnvVarGuard::remove("NEARAI_API_KEY");
let config = DriverConfig {
provider: "nearai".to_string(),
api_key: None,
base_url: None,
skip_permissions: true,
subprocess_timeout_secs: None,
};
let driver = create_driver(&config);
assert!(driver.is_err());
}

#[test]
fn test_novita_provider_with_env_key() {
let _env_lock = ENV_LOCK.lock().unwrap();
Expand Down
132 changes: 125 additions & 7 deletions crates/openfang-runtime/src/model_catalog.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
//! Model catalog — registry of known models with metadata, pricing, and auth detection.
//!
//! Provides a comprehensive catalog of 130+ builtin models across 28 providers,
//! Provides a comprehensive catalog of 130+ builtin models across 43 providers,
//! with alias resolution, auth status detection, and pricing lookups.

use openfang_types::model_catalog::{
AuthStatus, ModelCatalogEntry, ModelTier, ProviderInfo, AI21_BASE_URL, ANTHROPIC_BASE_URL,
AZURE_OPENAI_BASE_URL, BEDROCK_BASE_URL, CEREBRAS_BASE_URL, CHUTES_BASE_URL, COHERE_BASE_URL,
DEEPSEEK_BASE_URL, FIREWORKS_BASE_URL, GEMINI_BASE_URL, GITHUB_COPILOT_BASE_URL, GROQ_BASE_URL,
HUGGINGFACE_BASE_URL, KIMI_CODING_BASE_URL, LEMONADE_BASE_URL, LMSTUDIO_BASE_URL,
MINIMAX_BASE_URL, MISTRAL_BASE_URL, MOONSHOT_BASE_URL, NVIDIA_NIM_BASE_URL, OLLAMA_BASE_URL,
OPENAI_BASE_URL, OPENROUTER_BASE_URL, PERPLEXITY_BASE_URL, QIANFAN_BASE_URL, QWEN_BASE_URL,
REPLICATE_BASE_URL, REQUESTY_BASE_URL, SAMBANOVA_BASE_URL, TOGETHER_BASE_URL, VENICE_BASE_URL,
VLLM_BASE_URL, VOLCENGINE_BASE_URL, VOLCENGINE_CODING_BASE_URL, XAI_BASE_URL, ZAI_BASE_URL,
ZAI_CODING_BASE_URL, ZHIPU_BASE_URL, ZHIPU_CODING_BASE_URL,
MINIMAX_BASE_URL, MISTRAL_BASE_URL, MOONSHOT_BASE_URL, NEARAI_BASE_URL, NVIDIA_NIM_BASE_URL,
OLLAMA_BASE_URL, OPENAI_BASE_URL, OPENROUTER_BASE_URL, PERPLEXITY_BASE_URL, QIANFAN_BASE_URL,
QWEN_BASE_URL, REPLICATE_BASE_URL, REQUESTY_BASE_URL, SAMBANOVA_BASE_URL, TOGETHER_BASE_URL,
VENICE_BASE_URL, VLLM_BASE_URL, VOLCENGINE_BASE_URL, VOLCENGINE_CODING_BASE_URL, XAI_BASE_URL,
ZAI_BASE_URL, ZAI_CODING_BASE_URL, ZHIPU_BASE_URL, ZHIPU_CODING_BASE_URL,
};
use std::collections::HashMap;

Expand Down Expand Up @@ -790,6 +790,16 @@ fn builtin_providers() -> Vec<ProviderInfo> {
auth_status: AuthStatus::Missing,
model_count: 0,
},
// ── NEAR AI Cloud ───────────────────────────────────────────
ProviderInfo {
id: "nearai".into(),
display_name: "NEAR AI Cloud".into(),
api_key_env: "NEARAI_API_KEY".into(),
base_url: NEARAI_BASE_URL.into(),
key_required: true,
auth_status: AuthStatus::Missing,
model_count: 0,
},
// ── Venice.ai ────────────────────────────────────────────────
ProviderInfo {
id: "venice".into(),
Expand Down Expand Up @@ -1030,6 +1040,9 @@ fn builtin_aliases() -> HashMap<String, String> {
("codex-o4", "codex/o4-mini"),
// NVIDIA NIM aliases
("nemotron", "nvidia/llama-3.1-nemotron-70b-instruct"),
// NEAR AI Cloud aliases
("nearai", "zai-org/GLM-5.1-FP8"),
("nearai-glm", "zai-org/GLM-5.1-FP8"),
// Venice aliases
("venice", "venice-uncensored"),
// Claude Code aliases
Expand Down Expand Up @@ -4023,6 +4036,83 @@ fn builtin_models() -> Vec<ModelCatalogEntry> {
aliases: vec!["chutes-llama-70b".into()],
},
// ══════════════════════════════════════════════════════════════
// NEAR AI Cloud TEE inference (5)
// ══════════════════════════════════════════════════════════════
ModelCatalogEntry {
id: "zai-org/GLM-5.1-FP8".into(),
display_name: "GLM 5.1 (NEAR AI TEE)".into(),
provider: "nearai".into(),
tier: ModelTier::Smart,
context_window: 202_752,
max_output_tokens: 8_192,
input_cost_per_m: 0.85,
output_cost_per_m: 3.3,
supports_tools: true,
supports_vision: false,
supports_streaming: true,
aliases: vec![
"nearai".into(),
"nearai-glm".into(),
"nearai-glm-5.1".into(),
],
},
ModelCatalogEntry {
id: "Qwen/Qwen3.5-122B-A10B".into(),
display_name: "Qwen3.5 122B A10B (NEAR AI TEE)".into(),
provider: "nearai".into(),
tier: ModelTier::Smart,
context_window: 131_072,
max_output_tokens: 8_192,
input_cost_per_m: 0.4,
output_cost_per_m: 3.2,
supports_tools: true,
supports_vision: false,
supports_streaming: true,
aliases: vec!["nearai-qwen3.5".into(), "nearai-qwen3.5-122b".into()],
},
ModelCatalogEntry {
id: "Qwen/Qwen3.6-35B-A3B-FP8".into(),
display_name: "Qwen 3.6 35B A3B FP8 (NEAR AI TEE)".into(),
provider: "nearai".into(),
tier: ModelTier::Balanced,
context_window: 262_144,
max_output_tokens: 8_192,
input_cost_per_m: 0.17,
output_cost_per_m: 1.1,
supports_tools: true,
supports_vision: false,
supports_streaming: true,
aliases: vec!["nearai-qwen3.6".into(), "nearai-qwen3.6-35b".into()],
},
ModelCatalogEntry {
id: "Qwen/Qwen3-VL-30B-A3B-Instruct".into(),
display_name: "Qwen3 VL 30B A3B Instruct (NEAR AI TEE)".into(),
provider: "nearai".into(),
tier: ModelTier::Balanced,
context_window: 256_000,
max_output_tokens: 8_192,
input_cost_per_m: 0.15,
output_cost_per_m: 0.55,
supports_tools: true,
supports_vision: true,
supports_streaming: true,
aliases: vec!["nearai-qwen-vl".into(), "nearai-qwen3-vl".into()],
},
ModelCatalogEntry {
id: "google/gemma-4-31B-it".into(),
display_name: "Gemma 4 31B Instruct (NEAR AI TEE)".into(),
provider: "nearai".into(),
tier: ModelTier::Fast,
context_window: 262_144,
max_output_tokens: 8_192,
input_cost_per_m: 0.13,
output_cost_per_m: 0.4,
supports_tools: true,
supports_vision: false,
supports_streaming: true,
aliases: vec!["nearai-gemma".into(), "nearai-gemma-4".into()],
},
// ══════════════════════════════════════════════════════════════
// Venice.ai (3)
// ══════════════════════════════════════════════════════════════
ModelCatalogEntry {
Expand Down Expand Up @@ -4083,7 +4173,7 @@ mod tests {
#[test]
fn test_catalog_has_providers() {
let catalog = ModelCatalog::new();
assert_eq!(catalog.list_providers().len(), 42);
assert_eq!(catalog.list_providers().len(), 43);
}

#[test]
Expand Down Expand Up @@ -4231,6 +4321,34 @@ mod tests {
assert!(catalog.get_provider("huggingface").is_some());
assert!(catalog.get_provider("xai").is_some());
assert!(catalog.get_provider("replicate").is_some());
assert!(catalog.get_provider("nearai").is_some());
}

#[test]
fn test_nearai_provider_and_models() {
let catalog = ModelCatalog::new();
let provider = catalog.get_provider("nearai").unwrap();
assert_eq!(provider.display_name, "NEAR AI Cloud");
assert_eq!(provider.api_key_env, "NEARAI_API_KEY");
assert_eq!(provider.base_url, "https://cloud-api.near.ai/v1");
assert!(provider.key_required);
assert_eq!(provider.model_count, 5);

let models = catalog.models_by_provider("nearai");
assert!(models.iter().all(|m| m.supports_streaming));
assert!(models.iter().any(|m| m.id == "zai-org/GLM-5.1-FP8"));
assert!(models
.iter()
.any(|m| m.id == "Qwen/Qwen3-VL-30B-A3B-Instruct" && m.supports_vision));
}

#[test]
fn test_nearai_aliases() {
let catalog = ModelCatalog::new();
let entry = catalog.find_model("nearai").unwrap();
assert_eq!(entry.id, "zai-org/GLM-5.1-FP8");
assert_eq!(entry.provider, "nearai");
assert!(catalog.find_model("nearai-qwen3.6").is_some());
}

#[test]
Expand Down
1 change: 1 addition & 0 deletions crates/openfang-types/src/model_catalog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub const SAMBANOVA_BASE_URL: &str = "https://api.sambanova.ai/v1";
pub const HUGGINGFACE_BASE_URL: &str = "https://api-inference.huggingface.co/v1";
pub const XAI_BASE_URL: &str = "https://api.x.ai/v1";
pub const REPLICATE_BASE_URL: &str = "https://api.replicate.com/v1";
pub const NEARAI_BASE_URL: &str = "https://cloud-api.near.ai/v1";
pub const VENICE_BASE_URL: &str = "https://api.venice.ai/api/v1";
pub const NVIDIA_NIM_BASE_URL: &str = "https://integrate.api.nvidia.com/v1";

Expand Down
11 changes: 6 additions & 5 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# OpenFang Documentation

Welcome to the OpenFang documentation. OpenFang is the open-source Agent Operating System -- 14 Rust crates, 40 channels, 60 skills, 20 LLM providers, 76 API endpoints, and 16 security systems in a single binary.
Welcome to the OpenFang documentation. OpenFang is the open-source Agent Operating System -- 14 Rust crates, 40 channels, 60 skills, many LLM providers, 76 API endpoints, and 16 security systems in a single binary.

---

Expand All @@ -27,7 +27,7 @@ Welcome to the OpenFang documentation. OpenFang is the open-source Agent Operati
| Guide | Description |
|-------|-------------|
| [Channel Adapters](channel-adapters.md) | 40 messaging channels -- setup, configuration, custom adapters |
| [LLM Providers](providers.md) | 20 providers, 51 models, 23 aliases -- setup and model routing |
| [LLM Providers](providers.md) | Provider setup, model catalog, aliases, and routing |
| [Skills](skill-development.md) | 60 bundled skills, custom skill development, FangHub marketplace |
| [MCP & A2A](mcp-a2a.md) | Model Context Protocol and Agent-to-Agent protocol integration |

Expand Down Expand Up @@ -74,9 +74,9 @@ openfang init && openfang start
| Messaging channels | 40 |
| Bundled skills | 60 |
| Built-in tools | 38 |
| LLM providers | 20 |
| Models in catalog | 51 |
| Model aliases | 23 |
| LLM providers | Many cloud and local providers |
| Models in catalog | Builtin plus runtime-discovered models |
| Model aliases | Builtin aliases |
| API endpoints | 76 |
| Security systems | 16 |
| Tests | 967 |
Expand All @@ -100,6 +100,7 @@ openfang init && openfang start
| `GEMINI_API_KEY` | Google Gemini |
| `GROQ_API_KEY` | Groq (fast Llama/Mixtral) |
| `DEEPSEEK_API_KEY` | DeepSeek |
| `NEARAI_API_KEY` | NEAR AI Cloud TEE inference |
| `XAI_API_KEY` | xAI (Grok) |

Only one provider key is needed to get started. Groq offers a free tier.
Loading