Fix missing market/usage helpers on Rotation & Autoselect handlers; bump to 0.99.69

Add _record_dashboard_proxy_event, _settle_market_result,
_get_market_source_details, _market_request_id and
_extract_usage_from_sse_chunk to RotationHandler, and the market
settlement cluster to AutoselectHandler. These were defined only on
RequestHandler, so rotation/autoselect requests raised AttributeError
(crash on the dashboard event path, silently swallowed elsewhere),
dropping market settlement and streaming usage capture.
Co-Authored-By: 's avatarClaude Opus 4.8 <noreply@anthropic.com>
parent f78ec200
......@@ -55,7 +55,7 @@ from .auth.qwen import QwenOAuth2
from .handlers import RequestHandler, RotationHandler, AutoselectHandler
from .utils import count_messages_tokens, split_messages_into_chunks, get_max_request_tokens_for_model
__version__ = "0.99.66"
__version__ = "0.99.69"
__all__ = [
# Config
"config",
......
......@@ -104,7 +104,7 @@ def _feature_mode_default(mode: str) -> FeatureModeConfig:
class ProviderConfig(BaseModel):
id: str
name: str
endpoint: str
endpoint: str = "" # May be empty for pre-configured handler types that supply their own default
type: str
api_key_required: bool
rate_limit: float = 0.0
......
......@@ -997,10 +997,17 @@ class DatabaseManager:
''', (inactivity_days,))
user_ids = [row[0] for row in cursor.fetchall()]
for user_id in user_ids:
# Delete outside the SELECT's connection; each delete_user runs in its
# own transaction, so one failing user can't abort the whole batch.
deleted = 0
for user_id in user_ids:
try:
self.delete_user(user_id)
deleted += 1
except Exception as exc:
logger.warning(f"Failed to delete stale signup user {user_id}: {exc}")
return len(user_ids)
return deleted
def get_user_by_email(self, email: str) -> Optional[Dict]:
"""
......@@ -1656,9 +1663,58 @@ class DatabaseManager:
'total': total
}
# Child tables referencing users(id), ordered so that dependents are
# deleted before the rows they point at (FK-safe on MySQL/InnoDB, where
# constraints are enforced per-statement). Each entry is (table, column).
# Tables missing from a given deployment are skipped gracefully.
_USER_CHILD_TABLES = [
# Level A: leaf dependents (reference other child tables and/or users)
('wallet_transactions', 'user_id'),
('crypto_transactions', 'user_id'),
('market_import_references', 'user_id'),
('market_imports', 'user_id'),
('market_usage_transactions', 'consumer_user_id'),
('market_usage_transactions', 'provider_user_id'),
('market_votes', 'voter_user_id'),
('payment_transactions', 'user_id'),
('payment_retry_queue', 'user_id'),
('user_token_usage', 'user_id'),
('email_notification_queue', 'user_id'),
('api_requests', 'user_id'),
('studio_assets', 'user_id'),
('studio_pipelines', 'user_id'),
('user_providers', 'user_id'),
('user_rotations', 'user_id'),
('user_autoselects', 'user_id'),
('user_notifications', 'user_id'),
('user_oauth', 'user_id'),
('user_prompts', 'user_id'),
('user_cache_settings', 'user_id'),
('user_auth_files', 'user_id'),
# Level B: referenced by level A, themselves reference level C
('user_wallets', 'user_id'),
('subscriptions', 'user_id'),
('user_subscriptions', 'user_id'),
('user_crypto_addresses', 'user_id'),
('user_crypto_addresses_new', 'user_id'),
('user_crypto_wallets', 'user_id'),
('market_listings', 'owner_user_id'),
('user_api_tokens', 'user_id'),
# Level C: referenced by level B
('payment_methods', 'user_id'),
]
@staticmethod
def _is_missing_table_error(exc: Exception) -> bool:
"""True if the exception is a 'table does not exist' error (MySQL 1146 / SQLite)."""
if getattr(exc, 'errno', None) == 1146:
return True
msg = str(exc).lower()
return 'no such table' in msg or "doesn't exist" in msg
def delete_user(self, user_id: int):
"""
Delete a user and all their configurations.
Delete a user and all their related rows across every child table.
Args:
user_id: User ID to delete
......@@ -1666,14 +1722,18 @@ class DatabaseManager:
with self._get_connection() as conn:
cursor = conn.cursor()
placeholder = '?' if self.db_type == 'sqlite' else '%s'
# Delete user configurations first (due to foreign key constraints)
cursor.execute(f'DELETE FROM user_providers WHERE user_id = {placeholder}', (user_id,))
cursor.execute(f'DELETE FROM user_rotations WHERE user_id = {placeholder}', (user_id,))
cursor.execute(f'DELETE FROM user_autoselects WHERE user_id = {placeholder}', (user_id,))
cursor.execute(f'DELETE FROM user_api_tokens WHERE user_id = {placeholder}', (user_id,))
cursor.execute(f'DELETE FROM user_token_usage WHERE user_id = {placeholder}', (user_id,))
cursor.execute(f'DELETE FROM user_notifications WHERE user_id = {placeholder}', (user_id,))
# Delete the user
# Delete all child rows first (FK constraints are enforced on MySQL).
for table, column in self._USER_CHILD_TABLES:
try:
cursor.execute(
f'DELETE FROM {table} WHERE {column} = {placeholder}',
(user_id,),
)
except Exception as exc:
if self._is_missing_table_error(exc):
continue
raise
# Finally delete the user itself.
cursor.execute(f'DELETE FROM users WHERE id = {placeholder}', (user_id,))
conn.commit()
......@@ -4365,6 +4425,72 @@ class DatabaseManager:
conn.commit()
return cursor.lastrowid
def create_market_import_reference(self, user_id: int, listing_id: int, reference_type: str,
display_name: str, owner_username: str, source_type: str,
source_id: str) -> int:
with self._get_connection() as conn:
cursor = conn.cursor()
placeholder = self.placeholder
cursor.execute(
f'''
INSERT INTO market_import_references
(user_id, listing_id, reference_type, display_name, owner_username, source_type, source_id,
is_active, created_at, updated_at)
VALUES ({placeholder}, {placeholder}, {placeholder}, {placeholder}, {placeholder},
{placeholder}, {placeholder}, 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
''',
(user_id, listing_id, reference_type, display_name, owner_username, source_type, source_id)
)
conn.commit()
return cursor.lastrowid
def get_market_import_reference(self, reference_id: int) -> Optional[Dict[str, Any]]:
with self._get_connection() as conn:
cursor = conn.cursor()
placeholder = self.placeholder
cursor.execute(
f'''
SELECT id, user_id, listing_id, reference_type, display_name, owner_username,
source_type, source_id, is_active, created_at, updated_at
FROM market_import_references
WHERE id = {placeholder}
''',
(reference_id,)
)
row = cursor.fetchone()
if not row:
return None
return {
'id': row[0], 'user_id': row[1], 'listing_id': row[2],
'reference_type': row[3], 'display_name': row[4], 'name': row[4],
'owner_username': row[5], 'source_type': row[6], 'source_id': row[7],
'is_active': bool(row[8]), 'created_at': row[9], 'updated_at': row[10],
}
def list_market_import_references(self, user_id: int) -> List[Dict[str, Any]]:
with self._get_connection() as conn:
cursor = conn.cursor()
placeholder = self.placeholder
cursor.execute(
f'''
SELECT id, user_id, listing_id, reference_type, display_name, owner_username,
source_type, source_id, is_active, created_at, updated_at
FROM market_import_references
WHERE user_id = {placeholder}
ORDER BY created_at DESC
''',
(user_id,)
)
return [
{
'id': row[0], 'user_id': row[1], 'listing_id': row[2],
'reference_type': row[3], 'display_name': row[4], 'name': row[4],
'owner_username': row[5], 'source_type': row[6], 'source_id': row[7],
'is_active': bool(row[8]), 'created_at': row[9], 'updated_at': row[10],
}
for row in cursor.fetchall()
]
def get_market_listing_for_share(self, owner_username: str, resource_type: str, resource_id: str) -> Optional[Dict[str, Any]]:
with self._get_connection() as conn:
cursor = conn.cursor()
......
......@@ -2470,6 +2470,110 @@ class RotationHandler:
for rotation in self.user_rotations:
self.rotations[rotation['rotation_id']] = rotation['config']
def _record_dashboard_proxy_event(self, request, provider_id: str, model_name: str, success: bool, latency_ms: float, metadata: Dict | None = None):
try:
from aisbf.database import DatabaseRegistry
db = DatabaseRegistry.get_config_database()
status_code = (metadata or {}).get('status_code')
if status_code is None:
status_code = 200 if success else 500
db.record_dashboard_event(
event_type='request_proxied',
path=request.url.path,
user_id=getattr(request.state, 'user_id', None),
username=request.session.get('username') if hasattr(request, 'session') else None,
method=request.method,
status_code=status_code,
provider_id=provider_id,
rotation_id=(metadata or {}).get('rotation_id'),
autoselect_id=(metadata or {}).get('autoselect_id'),
metadata={
'model_name': model_name,
'latency_ms': round(float(latency_ms or 0), 2),
'stream': bool((metadata or {}).get('stream')),
**(metadata or {}),
},
)
except Exception:
logger.debug("Failed to record proxied request dashboard event", exc_info=True)
def _get_market_source_details(self, provider_id: str):
provider_config = None
if self.user_id and provider_id in getattr(self, 'user_providers', {}):
provider_config = self.user_providers.get(provider_id)
elif provider_id in getattr(self.config, 'providers', {}):
cfg = self.config.get_provider(provider_id)
provider_config = cfg.model_dump() if hasattr(cfg, 'model_dump') else cfg
if isinstance(provider_config, dict):
return provider_config.get('market_source')
return None
@staticmethod
def _market_request_id(request_data: Optional[Dict], fallback_provider_id: str) -> str:
payload = {
'provider_id': fallback_provider_id,
'model': (request_data or {}).get('model'),
'messages': (request_data or {}).get('messages'),
'input': (request_data or {}).get('input'),
'prompt': (request_data or {}).get('prompt'),
'voice': (request_data or {}).get('voice'),
'endpoint_path': (request_data or {}).get('_market_endpoint_path'),
}
serialized = json.dumps(payload, sort_keys=True, default=str)
return hashlib.sha256(serialized.encode('utf-8')).hexdigest()
def _settle_market_result(self, provider_id: str, usage: Optional[Dict], requests_count: int = 1, metadata: Optional[Dict] = None, request_data: Optional[Dict] = None):
market_source = self._get_market_source_details(provider_id)
if not self.user_id or not market_source:
return None
listing_id = market_source.get('listing_id')
if not listing_id:
return None
db = DatabaseRegistry.get_config_database()
settlement_metadata = {
'provider_id': provider_id,
'market_imported': True,
'market_request_id': self._market_request_id(request_data, provider_id),
}
if metadata:
settlement_metadata.update(metadata)
return db.settle_market_usage(
consumer_user_id=self.user_id,
listing_id=int(listing_id),
prompt_tokens=(usage or {}).get('prompt_tokens', 0),
completion_tokens=(usage or {}).get('completion_tokens', 0),
requests_count=requests_count,
metadata=settlement_metadata,
)
def _extract_usage_from_sse_chunk(self, chunk_payload) -> Optional[Dict[str, int]]:
try:
if isinstance(chunk_payload, bytes):
chunk_payload = chunk_payload.decode('utf-8', errors='ignore')
if isinstance(chunk_payload, str):
for line in chunk_payload.splitlines():
line = line.strip()
if not line.startswith('data: '):
continue
raw = line[6:].strip()
if not raw or raw == '[DONE]':
continue
try:
parsed = json.loads(raw)
except Exception:
continue
if isinstance(parsed, dict) and isinstance(parsed.get('usage'), dict):
usage = parsed.get('usage') or {}
if usage.get('total_tokens') is not None or usage.get('prompt_tokens') is not None or usage.get('completion_tokens') is not None:
return usage
elif isinstance(chunk_payload, dict):
usage = chunk_payload.get('usage')
if isinstance(usage, dict):
return usage
except Exception:
return None
return None
def _get_provider_type(self, provider_id: str) -> str:
"""Get the provider type from configuration"""
provider_config = self.config.get_provider(provider_id)
......@@ -4460,6 +4564,55 @@ class AutoselectHandler:
self.user_autoselects = {}
self.autoselects = self.config.autoselect if hasattr(self.config, 'autoselect') else {}
def _get_market_source_details(self, provider_id: str):
provider_config = None
if self.user_id and provider_id in getattr(self, 'user_providers', {}):
provider_config = self.user_providers.get(provider_id)
elif provider_id in getattr(self.config, 'providers', {}):
cfg = self.config.get_provider(provider_id)
provider_config = cfg.model_dump() if hasattr(cfg, 'model_dump') else cfg
if isinstance(provider_config, dict):
return provider_config.get('market_source')
return None
@staticmethod
def _market_request_id(request_data: Optional[Dict], fallback_provider_id: str) -> str:
payload = {
'provider_id': fallback_provider_id,
'model': (request_data or {}).get('model'),
'messages': (request_data or {}).get('messages'),
'input': (request_data or {}).get('input'),
'prompt': (request_data or {}).get('prompt'),
'voice': (request_data or {}).get('voice'),
'endpoint_path': (request_data or {}).get('_market_endpoint_path'),
}
serialized = json.dumps(payload, sort_keys=True, default=str)
return hashlib.sha256(serialized.encode('utf-8')).hexdigest()
def _settle_market_result(self, provider_id: str, usage: Optional[Dict], requests_count: int = 1, metadata: Optional[Dict] = None, request_data: Optional[Dict] = None):
market_source = self._get_market_source_details(provider_id)
if not self.user_id or not market_source:
return None
listing_id = market_source.get('listing_id')
if not listing_id:
return None
db = DatabaseRegistry.get_config_database()
settlement_metadata = {
'provider_id': provider_id,
'market_imported': True,
'market_request_id': self._market_request_id(request_data, provider_id),
}
if metadata:
settlement_metadata.update(metadata)
return db.settle_market_usage(
consumer_user_id=self.user_id,
listing_id=int(listing_id),
prompt_tokens=(usage or {}).get('prompt_tokens', 0),
completion_tokens=(usage or {}).get('completion_tokens', 0),
requests_count=requests_count,
metadata=settlement_metadata,
)
def _get_response_cache_backend(self):
aisbf_config = self.config.get_aisbf_config()
if not (aisbf_config and aisbf_config.response_cache and aisbf_config.response_cache.enabled):
......
......@@ -44,10 +44,93 @@ from .codex import CodexProviderHandler
from .coderai import CoderAIProviderHandler
from .qwen import QwenProviderHandler
from .runpod import RunpodProviderHandler
from .preconfigured_openai import (
# Major inference API providers
GroqProviderHandler,
TogetherAIProviderHandler,
FireworksAIProviderHandler,
MistralProviderHandler,
CodestralProviderHandler,
DeepSeekProviderHandler,
PerplexityProviderHandler,
DeepInfraProviderHandler,
CerebrasProviderHandler,
SambaNovaProviderHandler,
XAIProviderHandler,
MoonshotProviderHandler,
DashScopeProviderHandler,
NvidiaNIMProviderHandler,
NScaleProviderHandler,
FeatherlessAIProviderHandler,
OpenRouterProviderHandler,
ScalewayProviderHandler,
VolcEngineProviderHandler,
FriendliAIProviderHandler,
HyperbolicProviderHandler,
NebiusProviderHandler,
NovitaProviderHandler,
LambdaAIProviderHandler,
OVHCloudProviderHandler,
AIMLAPIProviderHandler,
CometAPIProviderHandler,
GaladrielProviderHandler,
MorphProviderHandler,
GitHubModelsProviderHandler,
AI21ProviderHandler,
NLPCloudProviderHandler,
ClarifaiProviderHandler,
EmpowerProviderHandler,
GradientAIProviderHandler,
CompactifAIProviderHandler,
MariTalkProviderHandler,
MetaLlamaProviderHandler,
PredibaseProviderHandler,
ZAIProviderHandler,
VoyageAIProviderHandler,
WandBInferenceProviderHandler,
CohereProviderHandler,
MiniMaxProviderHandler,
PublicAIProviderHandler,
HeliconeProviderHandler,
VeniceAIProviderHandler,
AIHubMixProviderHandler,
CharityEngineProviderHandler,
PoeProviderHandler,
ChutesProviderHandler,
SyntheticProviderHandler,
AssemblyAILLMProviderHandler,
GMIProviderHandler,
SarvamProviderHandler,
NanoGPTProviderHandler,
LlamaGateProviderHandler,
AbliterationProviderHandler,
CrusoeProviderHandler,
XiaomiMimoProviderHandler,
ApertisProviderHandler,
VercelAIGatewayProviderHandler,
BasetenProviderHandler,
JinaAIProviderHandler,
HuggingFaceProviderHandler,
# Local / self-hosted runtimes
LMStudioProviderHandler,
LlamafileProviderHandler,
VLLMProviderHandler,
XinferenceProviderHandler,
InfinityProviderHandler,
OobaboogaProviderHandler,
DockerModelRunnerProviderHandler,
TabbyAPIProviderHandler,
# Cloud providers with user-configured endpoints
AzureOpenAIProviderHandler,
DatabricksProviderHandler,
SnowflakeProviderHandler,
HerokuProviderHandler,
)
from ..config import config
PROVIDER_HANDLERS = {
# --- existing special-protocol handlers ---
'google': GoogleProviderHandler,
'openai': OpenAIProviderHandler,
'anthropic': AnthropicProviderHandler,
......@@ -55,11 +138,92 @@ PROVIDER_HANDLERS = {
'kiro': KiroProviderHandler,
'claude': ClaudeProviderHandler,
'kilo': KiloProviderHandler,
'kilocode': KiloProviderHandler, # Kilocode provider with OAuth2 support
'codex': CodexProviderHandler, # Codex provider with OAuth2 support (OpenAI protocol)
'coderai': CoderAIProviderHandler, # CoderAI provider with HTTP/WebSocket bridge support
'qwen': QwenProviderHandler, # Qwen provider with OAuth2 support (OpenAI-compatible)
'kilocode': KiloProviderHandler,
'codex': CodexProviderHandler,
'coderai': CoderAIProviderHandler,
'qwen': QwenProviderHandler,
'runpod': RunpodProviderHandler,
# --- pre-configured OpenAI-compatible providers ---
'groq': GroqProviderHandler,
'together_ai': TogetherAIProviderHandler,
'fireworks_ai': FireworksAIProviderHandler,
'mistral': MistralProviderHandler,
'codestral': CodestralProviderHandler,
'deepseek': DeepSeekProviderHandler,
'perplexity': PerplexityProviderHandler,
'deepinfra': DeepInfraProviderHandler,
'cerebras': CerebrasProviderHandler,
'sambanova': SambaNovaProviderHandler,
'xai': XAIProviderHandler,
'moonshot': MoonshotProviderHandler,
'dashscope': DashScopeProviderHandler,
'nvidia_nim': NvidiaNIMProviderHandler,
'nscale': NScaleProviderHandler,
'featherless_ai': FeatherlessAIProviderHandler,
'openrouter': OpenRouterProviderHandler,
'scaleway': ScalewayProviderHandler,
'volcengine': VolcEngineProviderHandler,
'friendliai': FriendliAIProviderHandler,
'hyperbolic': HyperbolicProviderHandler,
'nebius': NebiusProviderHandler,
'novita': NovitaProviderHandler,
'lambda_ai': LambdaAIProviderHandler,
'ovhcloud': OVHCloudProviderHandler,
'aiml': AIMLAPIProviderHandler,
'cometapi': CometAPIProviderHandler,
'galadriel': GaladrielProviderHandler,
'morph': MorphProviderHandler,
'github_models': GitHubModelsProviderHandler,
'ai21': AI21ProviderHandler,
'nlp_cloud': NLPCloudProviderHandler,
'clarifai': ClarifaiProviderHandler,
'empower': EmpowerProviderHandler,
'gradient_ai': GradientAIProviderHandler,
'compactifai': CompactifAIProviderHandler,
'maritalk': MariTalkProviderHandler,
'meta_llama': MetaLlamaProviderHandler,
'predibase': PredibaseProviderHandler,
'zai': ZAIProviderHandler,
'voyage': VoyageAIProviderHandler,
'wandb_inference': WandBInferenceProviderHandler,
'cohere': CohereProviderHandler,
'minimax': MiniMaxProviderHandler,
'publicai': PublicAIProviderHandler,
'helicone': HeliconeProviderHandler,
'veniceai': VeniceAIProviderHandler,
'aihubmix': AIHubMixProviderHandler,
'charity_engine': CharityEngineProviderHandler,
'poe': PoeProviderHandler,
'chutes': ChutesProviderHandler,
'synthetic': SyntheticProviderHandler,
'assemblyai_llm': AssemblyAILLMProviderHandler,
'gmi': GMIProviderHandler,
'sarvam': SarvamProviderHandler,
'nano_gpt': NanoGPTProviderHandler,
'llamagate': LlamaGateProviderHandler,
'abliteration': AbliterationProviderHandler,
'crusoe': CrusoeProviderHandler,
'xiaomi_mimo': XiaomiMimoProviderHandler,
'apertis': ApertisProviderHandler,
'vercel_ai_gateway': VercelAIGatewayProviderHandler,
'baseten': BasetenProviderHandler,
'jina_ai': JinaAIProviderHandler,
'huggingface': HuggingFaceProviderHandler,
# local runtimes
'lm_studio': LMStudioProviderHandler,
'llamafile': LlamafileProviderHandler,
'vllm': VLLMProviderHandler,
'xinference': XinferenceProviderHandler,
'infinity': InfinityProviderHandler,
'oobabooga': OobaboogaProviderHandler,
'docker_model_runner': DockerModelRunnerProviderHandler,
'tabbyapi': TabbyAPIProviderHandler,
# cloud providers with user-configured endpoints
'azure_openai': AzureOpenAIProviderHandler,
'databricks': DatabricksProviderHandler,
'snowflake': SnowflakeProviderHandler,
'heroku': HerokuProviderHandler,
}
......
......@@ -822,7 +822,12 @@ class BaseProviderHandler:
"disabled_until": None
}
else:
self.error_tracking = config.error_tracking[provider_id]
# Fall back to defaults for pre-configured handler types not in providers.json
self.error_tracking = config.error_tracking.get(provider_id, {
"failures": 0,
"last_failure": None,
"disabled_until": None,
})
self.last_request_time = 0
......@@ -834,7 +839,8 @@ class BaseProviderHandler:
# Default rate limit for user providers
self.rate_limit = 60
else:
self.rate_limit = config.providers[provider_id].rate_limit
_pcfg = config.providers.get(provider_id)
self.rate_limit = _pcfg.rate_limit if _pcfg else 0
# Add model-level rate limit tracking
self.model_last_request_time = {} # {model_name: timestamp}
# Token usage tracking for rate limits
......
"""
Copyleft (C) 2026 Stefy Lanza <stefy@nexlab.net>
AISBF - AI Service Broker Framework || AI Should Be Free
Pre-configured provider handlers for OpenAI-compatible APIs.
Each class is a thin subclass of OpenAIProviderHandler that ships with
a known default endpoint so users only need to supply an API key (and
optionally override the endpoint in their provider config).
Endpoint data sourced from the LiteLLM provider registry.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
"""
from typing import Any, Optional
from .openai import OpenAIProviderHandler
class _OpenAICompatBase(OpenAIProviderHandler):
"""
Base for pre-configured OpenAI-compatible providers.
Subclasses set DEFAULT_ENDPOINT and optionally DEFAULT_API_KEY_REQUIRED.
If the provider config supplies no endpoint (or an empty one), the class
default is used instead. This lets users configure e.g. type="groq"
without knowing or caring about the API base URL.
"""
DEFAULT_ENDPOINT: str = ""
DEFAULT_API_KEY_REQUIRED: bool = True
def __init__(
self,
provider_id: str,
api_key: Optional[str] = None,
user_id: Optional[int] = None,
provider_config: Optional[Any] = None,
):
if provider_config is None:
from ..config import config as _cfg
provider_config = _cfg.providers.get(provider_id)
# Inject default endpoint when the config has none
if isinstance(provider_config, dict):
if not provider_config.get("endpoint"):
provider_config = {**provider_config, "endpoint": self.DEFAULT_ENDPOINT}
elif provider_config is not None:
ep = getattr(provider_config, "endpoint", None)
if not ep:
d = (
provider_config.model_dump()
if hasattr(provider_config, "model_dump")
else provider_config.dict()
)
d["endpoint"] = self.DEFAULT_ENDPOINT
provider_config = d
else:
# No config at all — build a minimal dict so the parent can init
provider_config = {
"id": provider_id,
"name": provider_id,
"endpoint": self.DEFAULT_ENDPOINT,
"type": provider_id,
"api_key_required": self.DEFAULT_API_KEY_REQUIRED,
"rate_limit": 0,
}
super().__init__(provider_id, api_key, user_id=user_id, provider_config=provider_config)
# ---------------------------------------------------------------------------
# Major inference API providers
# ---------------------------------------------------------------------------
class GroqProviderHandler(_OpenAICompatBase):
"""Groq — ultra-fast inference on custom LPU hardware."""
DEFAULT_ENDPOINT = "https://api.groq.com/openai/v1"
class TogetherAIProviderHandler(_OpenAICompatBase):
"""Together AI — open-model inference and fine-tuning platform."""
DEFAULT_ENDPOINT = "https://api.together.xyz/v1"
class FireworksAIProviderHandler(_OpenAICompatBase):
"""Fireworks AI — fast open-model inference."""
DEFAULT_ENDPOINT = "https://api.fireworks.ai/inference/v1"
class MistralProviderHandler(_OpenAICompatBase):
"""Mistral AI — proprietary and open models."""
DEFAULT_ENDPOINT = "https://api.mistral.ai/v1"
class CodestralProviderHandler(_OpenAICompatBase):
"""Codestral — Mistral's code-specialised model endpoint."""
DEFAULT_ENDPOINT = "https://codestral.mistral.ai/v1"
class DeepSeekProviderHandler(_OpenAICompatBase):
"""DeepSeek — high-performance reasoning and coding models."""
DEFAULT_ENDPOINT = "https://api.deepseek.com/v1"
class PerplexityProviderHandler(_OpenAICompatBase):
"""Perplexity AI — search-augmented language models."""
DEFAULT_ENDPOINT = "https://api.perplexity.ai"
class DeepInfraProviderHandler(_OpenAICompatBase):
"""DeepInfra — serverless GPU inference for open models."""
DEFAULT_ENDPOINT = "https://api.deepinfra.com/v1/openai"
class CerebrasProviderHandler(_OpenAICompatBase):
"""Cerebras — wafer-scale chip inference."""
DEFAULT_ENDPOINT = "https://api.cerebras.ai/v1"
class SambaNovaProviderHandler(_OpenAICompatBase):
"""SambaNova — RDU-accelerated inference."""
DEFAULT_ENDPOINT = "https://api.sambanova.ai/v1"
class XAIProviderHandler(_OpenAICompatBase):
"""xAI — Grok models from X (Twitter)."""
DEFAULT_ENDPOINT = "https://api.x.ai/v1"
class MoonshotProviderHandler(_OpenAICompatBase):
"""Moonshot AI — Kimi long-context models."""
DEFAULT_ENDPOINT = "https://api.moonshot.ai/v1"
class DashScopeProviderHandler(_OpenAICompatBase):
"""Alibaba DashScope — Qwen and other Alibaba models."""
DEFAULT_ENDPOINT = "https://dashscope.aliyuncs.com/compatible-mode/v1"
class NvidiaNIMProviderHandler(_OpenAICompatBase):
"""NVIDIA NIM — NVIDIA-hosted inference microservices."""
DEFAULT_ENDPOINT = "https://integrate.api.nvidia.com/v1"
class NScaleProviderHandler(_OpenAICompatBase):
"""NScale — GPU cloud inference."""
DEFAULT_ENDPOINT = "https://inference.api.nscale.com/v1"
class FeatherlessAIProviderHandler(_OpenAICompatBase):
"""Featherless AI — serverless open-model inference."""
DEFAULT_ENDPOINT = "https://api.featherless.ai/v1"
class OpenRouterProviderHandler(_OpenAICompatBase):
"""OpenRouter — unified gateway to 200+ models from all major providers."""
DEFAULT_ENDPOINT = "https://openrouter.ai/api/v1"
class ScalewayProviderHandler(_OpenAICompatBase):
"""Scaleway Generative APIs — European cloud AI."""
DEFAULT_ENDPOINT = "https://api.scaleway.ai/v1"
class VolcEngineProviderHandler(_OpenAICompatBase):
"""VolcEngine Ark — ByteDance's model inference platform."""
DEFAULT_ENDPOINT = "https://ark.cn-beijing.volces.com/api/v3"
class FriendliAIProviderHandler(_OpenAICompatBase):
"""FriendliAI — serverless and dedicated inference."""
DEFAULT_ENDPOINT = "https://api.friendli.ai/serverless/v1"
class HyperbolicProviderHandler(_OpenAICompatBase):
"""Hyperbolic — GPU cloud inference."""
DEFAULT_ENDPOINT = "https://api.hyperbolic.xyz/v1"
class NebiusProviderHandler(_OpenAICompatBase):
"""Nebius AI Studio — European GPU cloud."""
DEFAULT_ENDPOINT = "https://api.studio.nebius.ai/v1"
class NovitaProviderHandler(_OpenAICompatBase):
"""Novita AI — open-model inference."""
DEFAULT_ENDPOINT = "https://api.novita.ai/v3/openai"
class LambdaAIProviderHandler(_OpenAICompatBase):
"""Lambda AI — GPU cloud inference."""
DEFAULT_ENDPOINT = "https://api.lambda.ai/v1"
class OVHCloudProviderHandler(_OpenAICompatBase):
"""OVHcloud AI Endpoints — European sovereign AI."""
DEFAULT_ENDPOINT = "https://oai.endpoints.kepler.ai.cloud.ovh.net/v1"
class AIMLAPIProviderHandler(_OpenAICompatBase):
"""AI/ML API — multi-provider unified gateway."""
DEFAULT_ENDPOINT = "https://api.aimlapi.com/v1"
class CometAPIProviderHandler(_OpenAICompatBase):
"""CometAPI — OpenAI-compatible model gateway."""
DEFAULT_ENDPOINT = "https://api.cometapi.com/v1"
class GaladrielProviderHandler(_OpenAICompatBase):
"""Galadriel — decentralised AI inference."""
DEFAULT_ENDPOINT = "https://api.galadriel.com/v1"
class MorphProviderHandler(_OpenAICompatBase):
"""Morph — fast code completion inference."""
DEFAULT_ENDPOINT = "https://api.morphllm.com/v1"
class GitHubModelsProviderHandler(_OpenAICompatBase):
"""GitHub Models — Azure AI Inference endpoint behind a GitHub PAT."""
DEFAULT_ENDPOINT = "https://models.inference.ai.azure.com"
class AI21ProviderHandler(_OpenAICompatBase):
"""AI21 Labs — Jamba and Jurassic series models."""
DEFAULT_ENDPOINT = "https://api.ai21.com/studio/v1"
class NLPCloudProviderHandler(_OpenAICompatBase):
"""NLP Cloud — hosted open-source NLP models."""
DEFAULT_ENDPOINT = "https://api.nlpcloud.io/v1"
class ClarifaiProviderHandler(_OpenAICompatBase):
"""Clarifai — AI platform with OpenAI-compatible inference."""
DEFAULT_ENDPOINT = "https://api.clarifai.com/v2/ext/openai/v1"
class EmpowerProviderHandler(_OpenAICompatBase):
"""Empower — privacy-focused inference."""
DEFAULT_ENDPOINT = "https://app.empower.dev/api/v1"
class GradientAIProviderHandler(_OpenAICompatBase):
"""Gradient AI — fine-tuning and inference."""
DEFAULT_ENDPOINT = "https://inference.do-ai.run/v1"
class CompactifAIProviderHandler(_OpenAICompatBase):
"""CompactifAI — model compression and inference."""
DEFAULT_ENDPOINT = "https://api.compactif.ai/v1"
class MariTalkProviderHandler(_OpenAICompatBase):
"""MariTalk (Maritaca AI) — Brazilian Portuguese language models."""
DEFAULT_ENDPOINT = "https://api.maritalk.com/v1"
class MetaLlamaProviderHandler(_OpenAICompatBase):
"""Meta Llama API — official Meta inference endpoint."""
DEFAULT_ENDPOINT = "https://api.llama.com/compat/v1"
class PredibaseProviderHandler(_OpenAICompatBase):
"""Predibase — fine-tuned LoRA adapter serving."""
DEFAULT_ENDPOINT = "https://serving.app.predibase.com/v1"
class ZAIProviderHandler(_OpenAICompatBase):
"""ZAI / 01.AI — Yi series models."""
DEFAULT_ENDPOINT = "https://api.z.ai/api/paas/v4"
class VoyageAIProviderHandler(_OpenAICompatBase):
"""VoyageAI — embedding and reranking models."""
DEFAULT_ENDPOINT = "https://api.voyageai.com/v1"
class WandBInferenceProviderHandler(_OpenAICompatBase):
"""Weights & Biases Inference — W&B hosted model serving."""
DEFAULT_ENDPOINT = "https://api.inference.wandb.ai/v1"
class CohereProviderHandler(_OpenAICompatBase):
"""Cohere — Command and Embed models via OpenAI compatibility layer."""
DEFAULT_ENDPOINT = "https://api.cohere.ai/compatibility/v1"
class MiniMaxProviderHandler(_OpenAICompatBase):
"""MiniMax — long-context Chinese and multilingual models."""
DEFAULT_ENDPOINT = "https://api.minimax.io/v1"
class PublicAIProviderHandler(_OpenAICompatBase):
"""PublicAI — public model inference."""
DEFAULT_ENDPOINT = "https://api.publicai.co/v1"
class HeliconeProviderHandler(_OpenAICompatBase):
"""Helicone AI Gateway — observability proxy in front of OpenAI-compatible APIs."""
DEFAULT_ENDPOINT = "https://ai-gateway.helicone.ai"
class VeniceAIProviderHandler(_OpenAICompatBase):
"""Venice AI — privacy-preserving inference."""
DEFAULT_ENDPOINT = "https://api.venice.ai/api/v1"
class AIHubMixProviderHandler(_OpenAICompatBase):
"""AIHubMix — model aggregation gateway."""
DEFAULT_ENDPOINT = "https://aihubmix.com/v1"
class CharityEngineProviderHandler(_OpenAICompatBase):
"""Charity Engine — distributed volunteer compute."""
DEFAULT_ENDPOINT = "https://api.charityengine.services/remotejobs/v2/inference"
class PoeProviderHandler(_OpenAICompatBase):
"""Poe API — Quora's multi-model platform."""
DEFAULT_ENDPOINT = "https://api.poe.com/v1"
class ChutesProviderHandler(_OpenAICompatBase):
"""Chutes AI — decentralised GPU inference."""
DEFAULT_ENDPOINT = "https://llm.chutes.ai/v1"
class SyntheticProviderHandler(_OpenAICompatBase):
"""Synthetic AI — open-model inference."""
DEFAULT_ENDPOINT = "https://api.synthetic.new/openai/v1"
class AssemblyAILLMProviderHandler(_OpenAICompatBase):
"""AssemblyAI LLM Gateway — AI speech and language platform."""
DEFAULT_ENDPOINT = "https://llm-gateway.assemblyai.com/v1"
class GMIProviderHandler(_OpenAICompatBase):
"""GMI Serving — GPU model inference."""
DEFAULT_ENDPOINT = "https://api.gmi-serving.com/v1"
class SarvamProviderHandler(_OpenAICompatBase):
"""Sarvam AI — Indian language models."""
DEFAULT_ENDPOINT = "https://api.sarvam.ai/v1"
class NanoGPTProviderHandler(_OpenAICompatBase):
"""Nano-GPT — pay-per-token inference."""
DEFAULT_ENDPOINT = "https://nano-gpt.com/api/v1"
class LlamaGateProviderHandler(_OpenAICompatBase):
"""LlamaGate — open-model inference gateway."""
DEFAULT_ENDPOINT = "https://api.llamagate.dev/v1"
class AbliterationProviderHandler(_OpenAICompatBase):
"""Abliteration AI — uncensored model inference."""
DEFAULT_ENDPOINT = "https://api.abliteration.ai/v1"
class CrusoeProviderHandler(_OpenAICompatBase):
"""Crusoe Cloud — sustainable GPU inference."""
DEFAULT_ENDPOINT = "https://managed-inference-api-proxy.crusoecloud.com/v1"
class XiaomiMimoProviderHandler(_OpenAICompatBase):
"""Xiaomi MiMo — Xiaomi's reasoning model API."""
DEFAULT_ENDPOINT = "https://api.xiaomimimo.com/v1"
class ApertisProviderHandler(_OpenAICompatBase):
"""Apertis / Stima — OpenAI-compatible inference."""
DEFAULT_ENDPOINT = "https://api.stima.tech/v1"
class VercelAIGatewayProviderHandler(_OpenAICompatBase):
"""Vercel AI Gateway — edge-deployed model routing."""
DEFAULT_ENDPOINT = "https://ai-gateway.vercel.sh/v1"
class BasetenProviderHandler(_OpenAICompatBase):
"""Baseten — custom model deployment and inference."""
DEFAULT_ENDPOINT = "https://inference.baseten.co/v1"
class JinaAIProviderHandler(_OpenAICompatBase):
"""Jina AI — embedding, reranking, and reader models."""
DEFAULT_ENDPOINT = "https://api.jina.ai/v1"
class HuggingFaceProviderHandler(_OpenAICompatBase):
"""HuggingFace Inference API — hosted open-source models."""
DEFAULT_ENDPOINT = "https://api-inference.huggingface.co/v1"
# ---------------------------------------------------------------------------
# Local / self-hosted runtimes (no API key required by default)
# ---------------------------------------------------------------------------
class LMStudioProviderHandler(_OpenAICompatBase):
"""LM Studio — local model inference server."""
DEFAULT_ENDPOINT = "http://localhost:1234/v1"
DEFAULT_API_KEY_REQUIRED = False
class LlamafileProviderHandler(_OpenAICompatBase):
"""Llamafile — single-file local model server."""
DEFAULT_ENDPOINT = "http://localhost:8080/v1"
DEFAULT_API_KEY_REQUIRED = False
class VLLMProviderHandler(_OpenAICompatBase):
"""vLLM — high-throughput local/self-hosted inference engine."""
DEFAULT_ENDPOINT = "http://localhost:8000/v1"
DEFAULT_API_KEY_REQUIRED = False
class XinferenceProviderHandler(_OpenAICompatBase):
"""Xorbits Inference — local model serving framework."""
DEFAULT_ENDPOINT = "http://localhost:9997/v1"
DEFAULT_API_KEY_REQUIRED = False
class InfinityProviderHandler(_OpenAICompatBase):
"""Infinity — local embedding and reranking server."""
DEFAULT_ENDPOINT = "http://localhost:8000/v1"
DEFAULT_API_KEY_REQUIRED = False
class OobaboogaProviderHandler(_OpenAICompatBase):
"""Text Generation WebUI (oobabooga) — local model server with OpenAI extension."""
DEFAULT_ENDPOINT = "http://localhost:5000/v1"
DEFAULT_API_KEY_REQUIRED = False
class DockerModelRunnerProviderHandler(_OpenAICompatBase):
"""Docker Model Runner — Docker Desktop built-in model serving."""
DEFAULT_ENDPOINT = "http://localhost:12434/engines/llama.cpp/v1"
DEFAULT_API_KEY_REQUIRED = False
class TabbyAPIProviderHandler(_OpenAICompatBase):
"""TabbyAPI — exllamav2-based local inference server."""
DEFAULT_ENDPOINT = "http://localhost:5000/v1"
DEFAULT_API_KEY_REQUIRED = False
# ---------------------------------------------------------------------------
# Cloud providers with user-configured endpoints
# (endpoint MUST be set in config — no sensible universal default exists)
# ---------------------------------------------------------------------------
class AzureOpenAIProviderHandler(_OpenAICompatBase):
"""
Azure OpenAI Service.
Set endpoint to your deployment URL:
https://<resource>.openai.azure.com/openai/deployments/<deployment>
"""
DEFAULT_ENDPOINT = ""
class DatabricksProviderHandler(_OpenAICompatBase):
"""
Databricks Model Serving.
Set endpoint to your workspace serving endpoint:
https://<workspace>.databricks.com/serving-endpoints
"""
DEFAULT_ENDPOINT = ""
class SnowflakeProviderHandler(_OpenAICompatBase):
"""
Snowflake Cortex.
Set endpoint to your account URL:
https://<account>.snowflakecomputing.com/api/v2
"""
DEFAULT_ENDPOINT = ""
class HerokuProviderHandler(_OpenAICompatBase):
"""
Heroku AI (Managed Inference).
Set endpoint to your Heroku app inference URL.
"""
DEFAULT_ENDPOINT = ""
......@@ -32,12 +32,20 @@ logger = logging.getLogger(__name__)
def cleanup_stale_signup_users() -> int:
"""Delete self-registered users who never logged in within 14 days."""
db = DatabaseRegistry.get_config_database()
deleted_count = db.delete_stale_unverified_signup_users(inactivity_days=14)
if deleted_count:
logger.info(f"Deleted {deleted_count} stale self-registered user(s) with no login activity")
return deleted_count
"""Delete self-registered users who never logged in within 14 days.
Best-effort housekeeping: never propagate errors to the caller, since this
runs on the login path and must not be able to break authentication.
"""
try:
db = DatabaseRegistry.get_config_database()
deleted_count = db.delete_stale_unverified_signup_users(inactivity_days=14)
if deleted_count:
logger.info(f"Deleted {deleted_count} stale self-registered user(s) with no login activity")
return deleted_count
except Exception as exc:
logger.warning(f"Stale signup user cleanup failed (ignored): {exc}", exc_info=True)
return 0
@router.get("/dashboard/profile-pic")
......
......@@ -61,16 +61,16 @@ def count_messages_tokens(messages: List[Dict], model: str) -> int:
content = msg.get('content', '')
if content:
if isinstance(content, str):
total_tokens += len(encoding.encode(content))
total_tokens += len(encoding.encode(content, disallowed_special=()))
elif isinstance(content, list):
# Handle complex content (e.g., with images)
for item in content:
if isinstance(item, dict):
text = item.get('text', '')
if text:
total_tokens += len(encoding.encode(text))
total_tokens += len(encoding.encode(text, disallowed_special=()))
elif isinstance(item, str):
total_tokens += len(encoding.encode(item))
total_tokens += len(encoding.encode(item, disallowed_special=()))
logger.debug(f"Token count for model {model}: {total_tokens}")
return total_tokens
......
......@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "aisbf"
version = "0.99.66"
version = "0.99.69"
description = "AISBF - AI Service Broker Framework || AI Should Be Free - A modular proxy server for managing multiple AI provider integrations"
readme = "README.md"
license = "GPL-3.0-or-later"
......
......@@ -106,7 +106,7 @@ class InstallCommand(_install):
setup(
name="aisbf",
version="0.99.66",
version="0.99.69",
author="AISBF Contributors",
author_email="stefy@nexlab.net",
description="AISBF - AI Service Broker Framework || AI Should Be Free - A modular proxy server for managing multiple AI provider integrations",
......
......@@ -43,17 +43,105 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
<div class="form-group">
<label data-i18n="providers.provider_type">Provider Type</label>
<select id="new-provider-type" onchange="updateNewProviderDefaults()">
<option value="openai">OpenAI</option>
<option value="google">Google</option>
<option value="anthropic">Anthropic</option>
<option value="ollama">Ollama</option>
<option value="kiro">Kiro (Amazon Q Developer)</option>
<option value="claude">Claude (OAuth2)</option>
<option value="kilocode">Kilocode (OAuth2)</option>
<option value="qwen">Qwen (OAuth2)</option>
<option value="codex">Codex (OpenAI OAuth2)</option>
<option value="coderai">CoderAI</option>
<option value="runpod">RunPod</option>
<optgroup label="— Generic types —">
<option value="openai">OpenAI-compatible (generic)</option>
<option value="google">Google (Gemini API)</option>
<option value="anthropic">Anthropic (API key)</option>
</optgroup>
<optgroup label="— OAuth2 / Special —">
<option value="kiro">Kiro (Amazon Q Developer)</option>
<option value="claude">Claude (OAuth2)</option>
<option value="kilocode">Kilocode (OAuth2)</option>
<option value="qwen">Qwen (OAuth2)</option>
<option value="codex">Codex / ChatGPT (OAuth2)</option>
<option value="coderai">CoderAI Broker</option>
<option value="runpod">RunPod (Pod platform)</option>
</optgroup>
<optgroup label="— Pre-configured API providers —">
<option value="abliteration">Abliteration AI</option>
<option value="ai21">AI21 Labs</option>
<option value="aihubmix">AIHubMix</option>
<option value="aiml">AI/ML API</option>
<option value="apertis">Apertis (Stima)</option>
<option value="assemblyai_llm">AssemblyAI LLM Gateway</option>
<option value="baseten">Baseten</option>
<option value="cerebras">Cerebras</option>
<option value="charity_engine">Charity Engine</option>
<option value="chutes">Chutes AI</option>
<option value="clarifai">Clarifai</option>
<option value="cohere">Cohere</option>
<option value="codestral">Codestral (Mistral Code)</option>
<option value="cometapi">CometAPI</option>
<option value="compactifai">CompactifAI</option>
<option value="crusoe">Crusoe Cloud</option>
<option value="dashscope">DashScope (Alibaba / Qwen)</option>
<option value="deepinfra">DeepInfra</option>
<option value="deepseek">DeepSeek</option>
<option value="empower">Empower</option>
<option value="featherless_ai">Featherless AI</option>
<option value="fireworks_ai">Fireworks AI</option>
<option value="friendliai">FriendliAI</option>
<option value="galadriel">Galadriel</option>
<option value="github_models">GitHub Models</option>
<option value="gmi">GMI Serving</option>
<option value="gradient_ai">Gradient AI</option>
<option value="groq">Groq</option>
<option value="helicone">Helicone AI Gateway</option>
<option value="huggingface">HuggingFace Inference API</option>
<option value="hyperbolic">Hyperbolic</option>
<option value="jina_ai">Jina AI</option>
<option value="lambda_ai">Lambda AI</option>
<option value="llamagate">LlamaGate</option>
<option value="maritalk">MariTalk (Maritaca AI)</option>
<option value="meta_llama">Meta Llama API</option>
<option value="minimax">MiniMax</option>
<option value="mistral">Mistral AI</option>
<option value="moonshot">Moonshot AI (Kimi)</option>
<option value="morph">Morph</option>
<option value="nano_gpt">Nano-GPT</option>
<option value="nebius">Nebius AI Studio</option>
<option value="nlp_cloud">NLP Cloud</option>
<option value="novita">Novita AI</option>
<option value="nscale">NScale</option>
<option value="nvidia_nim">NVIDIA NIM</option>
<option value="openrouter">OpenRouter</option>
<option value="ovhcloud">OVHcloud AI Endpoints</option>
<option value="perplexity">Perplexity AI</option>
<option value="poe">Poe API</option>
<option value="predibase">Predibase</option>
<option value="publicai">PublicAI</option>
<option value="runpod">RunPod</option>
<option value="sambanova">SambaNova</option>
<option value="sarvam">Sarvam AI</option>
<option value="scaleway">Scaleway</option>
<option value="synthetic">Synthetic AI</option>
<option value="together_ai">Together AI</option>
<option value="veniceai">Venice AI</option>
<option value="vercel_ai_gateway">Vercel AI Gateway</option>
<option value="volcengine">VolcEngine (ByteDance Ark)</option>
<option value="voyage">VoyageAI</option>
<option value="wandb_inference">W&amp;B Inference</option>
<option value="xai">xAI (Grok)</option>
<option value="xiaomi_mimo">Xiaomi MiMo</option>
<option value="zai">ZAI / 01.AI</option>
</optgroup>
<optgroup label="— Local / self-hosted —">
<option value="ollama">Ollama</option>
<option value="docker_model_runner">Docker Model Runner</option>
<option value="infinity">Infinity</option>
<option value="llamafile">Llamafile</option>
<option value="lm_studio">LM Studio</option>
<option value="oobabooga">Oobabooga (Text Gen WebUI)</option>
<option value="tabbyapi">TabbyAPI</option>
<option value="vllm">vLLM</option>
<option value="xinference">Xinference</option>
</optgroup>
<optgroup label="— Cloud (configure endpoint) —">
<option value="azure_openai">Azure OpenAI</option>
<option value="databricks">Databricks</option>
<option value="heroku">Heroku AI</option>
<option value="snowflake">Snowflake Cortex</option>
</optgroup>
</select>
<small style="color: var(--color-muted); display: block; margin-top: 5px;">Select the type of provider to configure appropriate settings</small>
</div>
......@@ -1590,17 +1678,104 @@ function renderProviderDetails(key) {
<div class="form-group">
<label>${window.i18n.t('providers.provider_type')}</label>
<select onchange="updateProviderType('${key}', this.value)" required>
<option value="google" ${provider.type === 'google' ? 'selected' : ''}>Google</option>
<option value="openai" ${provider.type === 'openai' ? 'selected' : ''}>OpenAI</option>
<option value="anthropic" ${provider.type === 'anthropic' ? 'selected' : ''}>Anthropic</option>
<option value="ollama" ${provider.type === 'ollama' ? 'selected' : ''}>Ollama</option>
<option value="kiro" ${provider.type === 'kiro' ? 'selected' : ''}>Kiro (Amazon Q Developer)</option>
<option value="claude" ${provider.type === 'claude' ? 'selected' : ''}>Claude (OAuth2)</option>
<option value="kilocode" ${provider.type === 'kilocode' ? 'selected' : ''}>Kilocode (OAuth2)</option>
<option value="qwen" ${provider.type === 'qwen' ? 'selected' : ''}>Qwen (OAuth2)</option>
<option value="codex" ${provider.type === 'codex' ? 'selected' : ''}>Codex (OpenAI OAuth2)</option>
<option value="coderai" ${provider.type === 'coderai' ? 'selected' : ''}>CoderAI</option>
<option value="runpod" ${provider.type === 'runpod' ? 'selected' : ''}>RunPod</option>
<optgroup label="Generic types">
<option value="openai" ${provider.type === 'openai' ? 'selected' : ''}>OpenAI</option>
<option value="google" ${provider.type === 'google' ? 'selected' : ''}>Google</option>
<option value="anthropic" ${provider.type === 'anthropic' ? 'selected' : ''}>Anthropic</option>
</optgroup>
<optgroup label="OAuth2 / Special">
<option value="kiro" ${provider.type === 'kiro' ? 'selected' : ''}>Kiro (Amazon Q Developer)</option>
<option value="claude" ${provider.type === 'claude' ? 'selected' : ''}>Claude (OAuth2)</option>
<option value="kilocode" ${provider.type === 'kilocode' ? 'selected' : ''}>Kilocode (OAuth2)</option>
<option value="qwen" ${provider.type === 'qwen' ? 'selected' : ''}>Qwen (OAuth2)</option>
<option value="codex" ${provider.type === 'codex' ? 'selected' : ''}>Codex (OpenAI OAuth2)</option>
<option value="coderai" ${provider.type === 'coderai' ? 'selected' : ''}>CoderAI</option>
<option value="runpod" ${provider.type === 'runpod' ? 'selected' : ''}>RunPod (Pod platform)</option>
</optgroup>
<optgroup label="Pre-configured API providers">
<option value="abliteration" ${provider.type === 'abliteration' ? 'selected' : ''}>Abliteration AI</option>
<option value="ai21" ${provider.type === 'ai21' ? 'selected' : ''}>AI21</option>
<option value="aiml" ${provider.type === 'aiml' ? 'selected' : ''}>AI/ML API</option>
<option value="aihubmix" ${provider.type === 'aihubmix' ? 'selected' : ''}>AIHubMix</option>
<option value="apertis" ${provider.type === 'apertis' ? 'selected' : ''}>Apertis (Stima)</option>
<option value="assemblyai_llm" ${provider.type === 'assemblyai_llm' ? 'selected' : ''}>AssemblyAI LLM</option>
<option value="baseten" ${provider.type === 'baseten' ? 'selected' : ''}>Baseten</option>
<option value="cerebras" ${provider.type === 'cerebras' ? 'selected' : ''}>Cerebras</option>
<option value="charity_engine" ${provider.type === 'charity_engine' ? 'selected' : ''}>Charity Engine</option>
<option value="chutes" ${provider.type === 'chutes' ? 'selected' : ''}>Chutes</option>
<option value="clarifai" ${provider.type === 'clarifai' ? 'selected' : ''}>Clarifai</option>
<option value="cohere" ${provider.type === 'cohere' ? 'selected' : ''}>Cohere</option>
<option value="codestral" ${provider.type === 'codestral' ? 'selected' : ''}>Codestral (Mistral)</option>
<option value="cometapi" ${provider.type === 'cometapi' ? 'selected' : ''}>CometAPI</option>
<option value="compactifai" ${provider.type === 'compactifai' ? 'selected' : ''}>CompactifAI</option>
<option value="crusoe" ${provider.type === 'crusoe' ? 'selected' : ''}>Crusoe Cloud</option>
<option value="dashscope" ${provider.type === 'dashscope' ? 'selected' : ''}>DashScope (Alibaba)</option>
<option value="deepinfra" ${provider.type === 'deepinfra' ? 'selected' : ''}>DeepInfra</option>
<option value="deepseek" ${provider.type === 'deepseek' ? 'selected' : ''}>DeepSeek</option>
<option value="empower" ${provider.type === 'empower' ? 'selected' : ''}>Empower</option>
<option value="featherless_ai" ${provider.type === 'featherless_ai' ? 'selected' : ''}>Featherless AI</option>
<option value="fireworks_ai" ${provider.type === 'fireworks_ai' ? 'selected' : ''}>Fireworks AI</option>
<option value="friendliai" ${provider.type === 'friendliai' ? 'selected' : ''}>Friendli AI</option>
<option value="galadriel" ${provider.type === 'galadriel' ? 'selected' : ''}>Galadriel</option>
<option value="github_models" ${provider.type === 'github_models' ? 'selected' : ''}>GitHub Models</option>
<option value="gmi" ${provider.type === 'gmi' ? 'selected' : ''}>GMI Serving</option>
<option value="gradient_ai" ${provider.type === 'gradient_ai' ? 'selected' : ''}>Gradient AI (DigitalOcean)</option>
<option value="groq" ${provider.type === 'groq' ? 'selected' : ''}>Groq</option>
<option value="helicone" ${provider.type === 'helicone' ? 'selected' : ''}>Helicone AI Gateway</option>
<option value="huggingface" ${provider.type === 'huggingface' ? 'selected' : ''}>HuggingFace Inference</option>
<option value="hyperbolic" ${provider.type === 'hyperbolic' ? 'selected' : ''}>Hyperbolic</option>
<option value="jina_ai" ${provider.type === 'jina_ai' ? 'selected' : ''}>Jina AI</option>
<option value="lambda_ai" ${provider.type === 'lambda_ai' ? 'selected' : ''}>Lambda AI</option>
<option value="llamagate" ${provider.type === 'llamagate' ? 'selected' : ''}>LlamaGate</option>
<option value="maritalk" ${provider.type === 'maritalk' ? 'selected' : ''}>MariTalk</option>
<option value="meta_llama" ${provider.type === 'meta_llama' ? 'selected' : ''}>Meta Llama API</option>
<option value="minimax" ${provider.type === 'minimax' ? 'selected' : ''}>MiniMax</option>
<option value="mistral" ${provider.type === 'mistral' ? 'selected' : ''}>Mistral AI</option>
<option value="moonshot" ${provider.type === 'moonshot' ? 'selected' : ''}>Moonshot AI</option>
<option value="morph" ${provider.type === 'morph' ? 'selected' : ''}>Morph LLM</option>
<option value="nano_gpt" ${provider.type === 'nano_gpt' ? 'selected' : ''}>NanoGPT</option>
<option value="nebius" ${provider.type === 'nebius' ? 'selected' : ''}>Nebius AI Studio</option>
<option value="nlp_cloud" ${provider.type === 'nlp_cloud' ? 'selected' : ''}>NLP Cloud</option>
<option value="novita" ${provider.type === 'novita' ? 'selected' : ''}>Novita AI</option>
<option value="nscale" ${provider.type === 'nscale' ? 'selected' : ''}>NScale</option>
<option value="nvidia_nim" ${provider.type === 'nvidia_nim' ? 'selected' : ''}>NVIDIA NIM</option>
<option value="openrouter" ${provider.type === 'openrouter' ? 'selected' : ''}>OpenRouter</option>
<option value="ovhcloud" ${provider.type === 'ovhcloud' ? 'selected' : ''}>OVHcloud AI</option>
<option value="perplexity" ${provider.type === 'perplexity' ? 'selected' : ''}>Perplexity AI</option>
<option value="poe" ${provider.type === 'poe' ? 'selected' : ''}>Poe</option>
<option value="predibase" ${provider.type === 'predibase' ? 'selected' : ''}>Predibase</option>
<option value="publicai" ${provider.type === 'publicai' ? 'selected' : ''}>PublicAI</option>
<option value="sambanova" ${provider.type === 'sambanova' ? 'selected' : ''}>SambaNova</option>
<option value="sarvam" ${provider.type === 'sarvam' ? 'selected' : ''}>Sarvam AI</option>
<option value="scaleway" ${provider.type === 'scaleway' ? 'selected' : ''}>Scaleway</option>
<option value="synthetic" ${provider.type === 'synthetic' ? 'selected' : ''}>Synthetic</option>
<option value="together_ai" ${provider.type === 'together_ai' ? 'selected' : ''}>Together AI</option>
<option value="veniceai" ${provider.type === 'veniceai' ? 'selected' : ''}>Venice AI</option>
<option value="vercel_ai_gateway" ${provider.type === 'vercel_ai_gateway' ? 'selected' : ''}>Vercel AI Gateway</option>
<option value="volcengine" ${provider.type === 'volcengine' ? 'selected' : ''}>VolcEngine (ByteDance)</option>
<option value="voyage" ${provider.type === 'voyage' ? 'selected' : ''}>Voyage AI</option>
<option value="wandb_inference" ${provider.type === 'wandb_inference' ? 'selected' : ''}>W&amp;B Inference</option>
<option value="xai" ${provider.type === 'xai' ? 'selected' : ''}>xAI (Grok)</option>
<option value="xiaomi_mimo" ${provider.type === 'xiaomi_mimo' ? 'selected' : ''}>Xiaomi MiMo</option>
<option value="zai" ${provider.type === 'zai' ? 'selected' : ''}>Z.AI</option>
</optgroup>
<optgroup label="Local / self-hosted">
<option value="ollama" ${provider.type === 'ollama' ? 'selected' : ''}>Ollama</option>
<option value="docker_model_runner" ${provider.type === 'docker_model_runner' ? 'selected' : ''}>Docker Model Runner</option>
<option value="infinity" ${provider.type === 'infinity' ? 'selected' : ''}>Infinity</option>
<option value="llamafile" ${provider.type === 'llamafile' ? 'selected' : ''}>Llamafile</option>
<option value="lm_studio" ${provider.type === 'lm_studio' ? 'selected' : ''}>LM Studio</option>
<option value="oobabooga" ${provider.type === 'oobabooga' ? 'selected' : ''}>Oobabooga (Text Gen WebUI)</option>
<option value="tabbyapi" ${provider.type === 'tabbyapi' ? 'selected' : ''}>TabbyAPI</option>
<option value="vllm" ${provider.type === 'vllm' ? 'selected' : ''}>vLLM</option>
<option value="xinference" ${provider.type === 'xinference' ? 'selected' : ''}>Xinference</option>
</optgroup>
<optgroup label="Cloud (configure endpoint)">
<option value="azure_openai" ${provider.type === 'azure_openai' ? 'selected' : ''}>Azure OpenAI</option>
<option value="databricks" ${provider.type === 'databricks' ? 'selected' : ''}>Databricks</option>
<option value="heroku" ${provider.type === 'heroku' ? 'selected' : ''}>Heroku AI</option>
<option value="snowflake" ${provider.type === 'snowflake' ? 'selected' : ''}>Snowflake Cortex</option>
</optgroup>
</select>
</div>
......@@ -1993,7 +2168,84 @@ function updateNewProviderDefaults() {
'qwen': 'Qwen provider. Uses OAuth2 Device Authorization Grant or API key. Endpoint: https://dashscope.aliyuncs.com/compatible-mode/v1',
'codex': 'Codex provider. Uses OAuth2 Device Authorization Grant (same protocol as OpenAI). Endpoint: https://api.openai.com/v1',
'coderai': 'CoderAI provider. In broker mode, CoderAI connects inbound to AISBF using a provider-scoped registration token. In direct mode, AISBF calls it as an OpenAI-compatible endpoint. Default endpoint: http://127.0.0.1:11437',
'runpod': 'RunPod provider. Uses the RunPod REST management API for pod lifecycle, serverless endpoints, and public endpoint catalogs. Default endpoint: https://rest.runpod.io/v1'
'abliteration': 'Abliteration AI — OpenAI-compatible inference API. Endpoint: https://api.abliteration.ai/v1',
'ai21': 'AI21 Labs — OpenAI-compatible endpoint for Jamba and Jurassic models. Endpoint: https://api.ai21.com/studio/v1',
'aiml': 'AI/ML API — unified gateway for many models. Endpoint: https://api.aimlapi.com/v1',
'aihubmix': 'AIHubMix — OpenAI-compatible aggregator. Endpoint: https://aihubmix.com/v1',
'apertis': 'Apertis (Stima Tech) — OpenAI-compatible inference. Endpoint: https://api.stima.tech/v1',
'assemblyai_llm': 'AssemblyAI LLM Gateway — OpenAI-compatible endpoint. Endpoint: https://llm-gateway.assemblyai.com/v1',
'baseten': 'Baseten — deploy and serve ML models. Endpoint: https://inference.baseten.co/v1',
'cerebras': 'Cerebras — fast inference on Cerebras hardware. Endpoint: https://api.cerebras.ai/v1',
'charity_engine': 'Charity Engine — distributed compute for AI. Endpoint: https://api.charityengine.services/remotejobs/v2/inference',
'chutes': 'Chutes — decentralized AI inference. Endpoint: https://llm.chutes.ai/v1',
'clarifai': 'Clarifai — AI platform with OpenAI-compatible API. Endpoint: https://api.clarifai.com/v2/ext/openai/v1',
'cohere': 'Cohere — language models via OpenAI compatibility layer. Endpoint: https://api.cohere.ai/compatibility/v1',
'codestral': 'Codestral — Mistral\'s code-focused model endpoint. Endpoint: https://codestral.mistral.ai/v1',
'cometapi': 'CometAPI — OpenAI-compatible model aggregator. Endpoint: https://api.cometapi.com/v1',
'compactifai': 'CompactifAI — efficient model inference. Endpoint: https://api.compactif.ai/v1',
'crusoe': 'Crusoe Cloud — GPU cloud with managed inference. Endpoint: https://managed-inference-api-proxy.crusoecloud.com/v1',
'dashscope': 'DashScope (Alibaba Cloud) — Qwen and other models. Endpoint: https://dashscope.aliyuncs.com/compatible-mode/v1',
'deepinfra': 'DeepInfra — run open-source models at scale. Endpoint: https://api.deepinfra.com/v1/openai',
'deepseek': 'DeepSeek — reasoning and chat models. Endpoint: https://api.deepseek.com/v1',
'empower': 'Empower — AI inference platform. Endpoint: https://app.empower.dev/api/v1',
'featherless_ai': 'Featherless AI — serverless open-source model hosting. Endpoint: https://api.featherless.ai/v1',
'fireworks_ai': 'Fireworks AI — fast open-source model inference. Endpoint: https://api.fireworks.ai/inference/v1',
'friendliai': 'Friendli AI — serverless model inference. Endpoint: https://api.friendli.ai/serverless/v1',
'galadriel': 'Galadriel — decentralized AI inference. Endpoint: https://api.galadriel.com/v1',
'github_models': 'GitHub Models — run AI models from the GitHub Marketplace. Endpoint: https://models.inference.ai.azure.com',
'gmi': 'GMI Serving — OpenAI-compatible GPU inference. Endpoint: https://api.gmi-serving.com/v1',
'gradient_ai': 'Gradient AI / DigitalOcean GenAI — managed inference. Endpoint: https://inference.do-ai.run/v1',
'groq': 'Groq — ultra-fast LPU inference. Endpoint: https://api.groq.com/openai/v1',
'helicone': 'Helicone AI Gateway — observability proxy for LLMs. Endpoint: https://ai-gateway.helicone.ai',
'huggingface': 'HuggingFace Inference — run models from the HuggingFace Hub. Endpoint: https://api-inference.huggingface.co/v1',
'hyperbolic': 'Hyperbolic — GPU cloud inference platform. Endpoint: https://api.hyperbolic.xyz/v1',
'jina_ai': 'Jina AI — embeddings and reranking. Endpoint: https://api.jina.ai/v1',
'lambda_ai': 'Lambda AI — GPU cloud with inference API. Endpoint: https://api.lambda.ai/v1',
'llamagate': 'LlamaGate — open model inference gateway. Endpoint: https://api.llamagate.dev/v1',
'maritalk': 'MariTalk — Brazilian Portuguese AI models. Endpoint: https://api.maritalk.com/v1',
'meta_llama': 'Meta Llama API — official Meta inference endpoint. Endpoint: https://api.llama.com/compat/v1',
'minimax': 'MiniMax — Chinese AI provider with global models. Endpoint: https://api.minimax.io/v1',
'mistral': 'Mistral AI — Mistral and Mixtral models. Endpoint: https://api.mistral.ai/v1',
'moonshot': 'Moonshot AI — long-context Chinese AI provider. Endpoint: https://api.moonshot.ai/v1',
'morph': 'Morph LLM — OpenAI-compatible inference. Endpoint: https://api.morphllm.com/v1',
'nano_gpt': 'NanoGPT — pay-per-token model marketplace. Endpoint: https://nano-gpt.com/api/v1',
'nebius': 'Nebius AI Studio — GPU cloud with inference API. Endpoint: https://api.studio.nebius.ai/v1',
'nlp_cloud': 'NLP Cloud — production-ready NLP models. Endpoint: https://api.nlpcloud.io/v1',
'novita': 'Novita AI — affordable GPU inference. Endpoint: https://api.novita.ai/v3/openai',
'nscale': 'NScale — high-performance GPU inference. Endpoint: https://inference.api.nscale.com/v1',
'nvidia_nim': 'NVIDIA NIM — NVIDIA-optimized model microservices. Endpoint: https://integrate.api.nvidia.com/v1',
'openrouter': 'OpenRouter — unified API for 100+ models across providers. Endpoint: https://openrouter.ai/api/v1',
'ovhcloud': 'OVHcloud AI — European cloud AI endpoint. Endpoint: https://oai.endpoints.kepler.ai.cloud.ovh.net/v1',
'perplexity': 'Perplexity AI — search-augmented language models. Endpoint: https://api.perplexity.ai',
'poe': 'Poe — access many AI models through Poe. Endpoint: https://api.poe.com/v1',
'predibase': 'Predibase — fine-tuned model serving. Endpoint: https://serving.app.predibase.com/v1',
'publicai': 'PublicAI — open model inference. Endpoint: https://api.publicai.co/v1',
'runpod': 'RunPod — serverless GPU cloud. Uses the RunPod REST API. Default endpoint: https://rest.runpod.io/v1',
'sambanova': 'SambaNova — enterprise AI inference platform. Endpoint: https://api.sambanova.ai/v1',
'sarvam': 'Sarvam AI — Indian language AI models. Endpoint: https://api.sarvam.ai/v1',
'scaleway': 'Scaleway — European cloud inference API. Endpoint: https://api.scaleway.ai/v1',
'synthetic': 'Synthetic — AI inference platform. Endpoint: https://api.synthetic.new/openai/v1',
'together_ai': 'Together AI — collaborative open-source model inference. Endpoint: https://api.together.xyz/v1',
'veniceai': 'Venice AI — privacy-first AI inference. Endpoint: https://api.venice.ai/api/v1',
'vercel_ai_gateway': 'Vercel AI Gateway — managed AI gateway from Vercel. Endpoint: https://ai-gateway.vercel.sh/v1',
'volcengine': 'VolcEngine (ByteDance) — Doubao and other models. Endpoint: https://ark.cn-beijing.volces.com/api/v3',
'voyage': 'Voyage AI — specialized embedding and reranking models. Endpoint: https://api.voyageai.com/v1',
'wandb_inference': 'W&B Inference — Weights & Biases model inference. Endpoint: https://api.inference.wandb.ai/v1',
'xai': 'xAI (Grok) — Grok models by xAI. Endpoint: https://api.x.ai/v1',
'xiaomi_mimo': 'Xiaomi MiMo — Xiaomi\'s open-source reasoning model. Endpoint: https://api.xiaomimimo.com/v1',
'zai': 'Z.AI — OpenAI-compatible inference. Endpoint: https://api.z.ai/api/paas/v4',
'docker_model_runner': 'Docker Model Runner — run AI models via Docker Desktop. No API key required. Endpoint: http://localhost:12434/engines/llama.cpp/v1',
'infinity': 'Infinity — fast embedding and reranking server. No API key required. Endpoint: http://localhost:8000/v1',
'llamafile': 'Llamafile — self-contained executable LLM server. No API key required. Endpoint: http://localhost:8080/v1',
'lm_studio': 'LM Studio — local GUI for running LLMs. No API key required. Endpoint: http://localhost:1234/v1',
'oobabooga': 'Oobabooga (Text Generation WebUI) — local LLM frontend. No API key required. Endpoint: http://localhost:5000/v1',
'tabbyapi': 'TabbyAPI — local ExLlamaV2-based inference server. No API key required. Endpoint: http://localhost:5000/v1',
'vllm': 'vLLM — high-throughput local model server. No API key required. Endpoint: http://localhost:8000/v1',
'xinference': 'Xinference — distributed model inference. No API key required. Endpoint: http://localhost:9997/v1',
'azure_openai': 'Azure OpenAI — Microsoft Azure-hosted OpenAI models. Requires your Azure resource endpoint.',
'databricks': 'Databricks — AI/BI and model serving on Databricks. Requires your workspace endpoint.',
'heroku': 'Heroku AI — managed inference on Heroku. Requires your Heroku inference endpoint.',
'snowflake': 'Snowflake Cortex — AI inference within Snowflake. Requires your Snowflake account endpoint.',
};
descriptionEl.textContent = descriptions[providerType] || window.i18n.t('providers.standard_config');
......@@ -3057,7 +3309,84 @@ function getDefaultEndpoint(type) {
'qwen': 'https://dashscope.aliyuncs.com/compatible-mode/v1',
'codex': 'https://api.openai.com/v1',
'coderai': 'http://127.0.0.1:11437',
'runpod': 'https://rest.runpod.io/v1'
'abliteration': 'https://api.abliteration.ai/v1',
'ai21': 'https://api.ai21.com/studio/v1',
'aiml': 'https://api.aimlapi.com/v1',
'aihubmix': 'https://aihubmix.com/v1',
'apertis': 'https://api.stima.tech/v1',
'assemblyai_llm': 'https://llm-gateway.assemblyai.com/v1',
'baseten': 'https://inference.baseten.co/v1',
'cerebras': 'https://api.cerebras.ai/v1',
'charity_engine': 'https://api.charityengine.services/remotejobs/v2/inference',
'chutes': 'https://llm.chutes.ai/v1',
'clarifai': 'https://api.clarifai.com/v2/ext/openai/v1',
'cohere': 'https://api.cohere.ai/compatibility/v1',
'codestral': 'https://codestral.mistral.ai/v1',
'cometapi': 'https://api.cometapi.com/v1',
'compactifai': 'https://api.compactif.ai/v1',
'crusoe': 'https://managed-inference-api-proxy.crusoecloud.com/v1',
'dashscope': 'https://dashscope.aliyuncs.com/compatible-mode/v1',
'deepinfra': 'https://api.deepinfra.com/v1/openai',
'deepseek': 'https://api.deepseek.com/v1',
'empower': 'https://app.empower.dev/api/v1',
'featherless_ai': 'https://api.featherless.ai/v1',
'fireworks_ai': 'https://api.fireworks.ai/inference/v1',
'friendliai': 'https://api.friendli.ai/serverless/v1',
'galadriel': 'https://api.galadriel.com/v1',
'github_models': 'https://models.inference.ai.azure.com',
'gmi': 'https://api.gmi-serving.com/v1',
'gradient_ai': 'https://inference.do-ai.run/v1',
'groq': 'https://api.groq.com/openai/v1',
'helicone': 'https://ai-gateway.helicone.ai',
'huggingface': 'https://api-inference.huggingface.co/v1',
'hyperbolic': 'https://api.hyperbolic.xyz/v1',
'jina_ai': 'https://api.jina.ai/v1',
'lambda_ai': 'https://api.lambda.ai/v1',
'llamagate': 'https://api.llamagate.dev/v1',
'maritalk': 'https://api.maritalk.com/v1',
'meta_llama': 'https://api.llama.com/compat/v1',
'minimax': 'https://api.minimax.io/v1',
'mistral': 'https://api.mistral.ai/v1',
'moonshot': 'https://api.moonshot.ai/v1',
'morph': 'https://api.morphllm.com/v1',
'nano_gpt': 'https://nano-gpt.com/api/v1',
'nebius': 'https://api.studio.nebius.ai/v1',
'nlp_cloud': 'https://api.nlpcloud.io/v1',
'novita': 'https://api.novita.ai/v3/openai',
'nscale': 'https://inference.api.nscale.com/v1',
'nvidia_nim': 'https://integrate.api.nvidia.com/v1',
'openrouter': 'https://openrouter.ai/api/v1',
'ovhcloud': 'https://oai.endpoints.kepler.ai.cloud.ovh.net/v1',
'perplexity': 'https://api.perplexity.ai',
'poe': 'https://api.poe.com/v1',
'predibase': 'https://serving.app.predibase.com/v1',
'publicai': 'https://api.publicai.co/v1',
'runpod': 'https://rest.runpod.io/v1',
'sambanova': 'https://api.sambanova.ai/v1',
'sarvam': 'https://api.sarvam.ai/v1',
'scaleway': 'https://api.scaleway.ai/v1',
'synthetic': 'https://api.synthetic.new/openai/v1',
'together_ai': 'https://api.together.xyz/v1',
'veniceai': 'https://api.venice.ai/api/v1',
'vercel_ai_gateway': 'https://ai-gateway.vercel.sh/v1',
'volcengine': 'https://ark.cn-beijing.volces.com/api/v3',
'voyage': 'https://api.voyageai.com/v1',
'wandb_inference': 'https://api.inference.wandb.ai/v1',
'xai': 'https://api.x.ai/v1',
'xiaomi_mimo': 'https://api.xiaomimimo.com/v1',
'zai': 'https://api.z.ai/api/paas/v4',
'docker_model_runner': 'http://localhost:12434/engines/llama.cpp/v1',
'infinity': 'http://localhost:8000/v1',
'llamafile': 'http://localhost:8080/v1',
'lm_studio': 'http://localhost:1234/v1',
'oobabooga': 'http://localhost:5000/v1',
'tabbyapi': 'http://localhost:5000/v1',
'vllm': 'http://localhost:8000/v1',
'xinference': 'http://localhost:9997/v1',
'azure_openai': '',
'databricks': '',
'heroku': '',
'snowflake': '',
};
return defaults[type] || '';
}
......
......@@ -42,16 +42,104 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
<div class="form-group">
<label data-i18n="providers.provider_type">Provider Type</label>
<select id="new-provider-type" onchange="updateNewProviderDefaults()">
<option value="openai">OpenAI</option>
<option value="google">Google</option>
<option value="anthropic">Anthropic</option>
<option value="ollama">Ollama</option>
<option value="kiro">Kiro (Amazon Q Developer)</option>
<option value="claude">Claude (OAuth2)</option>
<option value="kilocode">Kilocode (OAuth2)</option>
<option value="qwen">Qwen (OAuth2)</option>
<option value="codex">Codex (OpenAI OAuth2)</option>
<option value="coderai">CoderAI</option>
<optgroup label="— Generic types —">
<option value="openai">OpenAI-compatible (generic)</option>
<option value="google">Google (Gemini API)</option>
<option value="anthropic">Anthropic (API key)</option>
</optgroup>
<optgroup label="— OAuth2 / Special —">
<option value="kiro">Kiro (Amazon Q Developer)</option>
<option value="claude">Claude (OAuth2)</option>
<option value="kilocode">Kilocode (OAuth2)</option>
<option value="qwen">Qwen (OAuth2)</option>
<option value="codex">Codex / ChatGPT (OAuth2)</option>
<option value="coderai">CoderAI Broker</option>
<option value="runpod">RunPod (Pod platform)</option>
</optgroup>
<optgroup label="— Pre-configured API providers —">
<option value="abliteration">Abliteration AI</option>
<option value="ai21">AI21 Labs</option>
<option value="aihubmix">AIHubMix</option>
<option value="aiml">AI/ML API</option>
<option value="apertis">Apertis (Stima)</option>
<option value="assemblyai_llm">AssemblyAI LLM Gateway</option>
<option value="baseten">Baseten</option>
<option value="cerebras">Cerebras</option>
<option value="charity_engine">Charity Engine</option>
<option value="chutes">Chutes AI</option>
<option value="clarifai">Clarifai</option>
<option value="cohere">Cohere</option>
<option value="codestral">Codestral (Mistral Code)</option>
<option value="cometapi">CometAPI</option>
<option value="compactifai">CompactifAI</option>
<option value="crusoe">Crusoe Cloud</option>
<option value="dashscope">DashScope (Alibaba / Qwen)</option>
<option value="deepinfra">DeepInfra</option>
<option value="deepseek">DeepSeek</option>
<option value="empower">Empower</option>
<option value="featherless_ai">Featherless AI</option>
<option value="fireworks_ai">Fireworks AI</option>
<option value="friendliai">FriendliAI</option>
<option value="galadriel">Galadriel</option>
<option value="github_models">GitHub Models</option>
<option value="gmi">GMI Serving</option>
<option value="gradient_ai">Gradient AI</option>
<option value="groq">Groq</option>
<option value="helicone">Helicone AI Gateway</option>
<option value="huggingface">HuggingFace Inference API</option>
<option value="hyperbolic">Hyperbolic</option>
<option value="jina_ai">Jina AI</option>
<option value="lambda_ai">Lambda AI</option>
<option value="llamagate">LlamaGate</option>
<option value="maritalk">MariTalk (Maritaca AI)</option>
<option value="meta_llama">Meta Llama API</option>
<option value="minimax">MiniMax</option>
<option value="mistral">Mistral AI</option>
<option value="moonshot">Moonshot AI (Kimi)</option>
<option value="morph">Morph</option>
<option value="nano_gpt">Nano-GPT</option>
<option value="nebius">Nebius AI Studio</option>
<option value="nlp_cloud">NLP Cloud</option>
<option value="novita">Novita AI</option>
<option value="nscale">NScale</option>
<option value="nvidia_nim">NVIDIA NIM</option>
<option value="openrouter">OpenRouter</option>
<option value="ovhcloud">OVHcloud AI Endpoints</option>
<option value="perplexity">Perplexity AI</option>
<option value="poe">Poe API</option>
<option value="predibase">Predibase</option>
<option value="publicai">PublicAI</option>
<option value="sambanova">SambaNova</option>
<option value="sarvam">Sarvam AI</option>
<option value="scaleway">Scaleway</option>
<option value="synthetic">Synthetic AI</option>
<option value="together_ai">Together AI</option>
<option value="veniceai">Venice AI</option>
<option value="vercel_ai_gateway">Vercel AI Gateway</option>
<option value="volcengine">VolcEngine (ByteDance Ark)</option>
<option value="voyage">VoyageAI</option>
<option value="wandb_inference">W&amp;B Inference</option>
<option value="xai">xAI (Grok)</option>
<option value="xiaomi_mimo">Xiaomi MiMo</option>
<option value="zai">ZAI / 01.AI</option>
</optgroup>
<optgroup label="— Local / self-hosted —">
<option value="ollama">Ollama</option>
<option value="docker_model_runner">Docker Model Runner</option>
<option value="infinity">Infinity</option>
<option value="llamafile">Llamafile</option>
<option value="lm_studio">LM Studio</option>
<option value="oobabooga">Oobabooga (Text Gen WebUI)</option>
<option value="tabbyapi">TabbyAPI</option>
<option value="vllm">vLLM</option>
<option value="xinference">Xorbits Inference</option>
</optgroup>
<optgroup label="— Cloud (configure endpoint) —">
<option value="azure_openai">Azure OpenAI</option>
<option value="databricks">Databricks Model Serving</option>
<option value="heroku">Heroku AI</option>
<option value="snowflake">Snowflake Cortex</option>
</optgroup>
</select>
<small style="color: var(--color-muted); display: block; margin-top: 5px;">Select the type of provider to configure appropriate settings</small>
</div>
......@@ -1301,15 +1389,104 @@ function renderProviderDetails(key) {
<div class="form-group">
<label>${window.i18n.t('providers.provider_type')}</label>
<select onchange="updateProviderType('${key}', this.value)" required>
<option value="google" ${provider.type === 'google' ? 'selected' : ''}>Google</option>
<option value="openai" ${provider.type === 'openai' ? 'selected' : ''}>OpenAI</option>
<option value="anthropic" ${provider.type === 'anthropic' ? 'selected' : ''}>Anthropic</option>
<option value="ollama" ${provider.type === 'ollama' ? 'selected' : ''}>Ollama</option>
<option value="kiro" ${provider.type === 'kiro' ? 'selected' : ''}>Kiro (Amazon Q Developer)</option>
<option value="claude" ${provider.type === 'claude' ? 'selected' : ''}>Claude (OAuth2)</option>
<option value="kilocode" ${provider.type === 'kilocode' ? 'selected' : ''}>Kilocode (OAuth2)</option>
<option value="qwen" ${provider.type === 'qwen' ? 'selected' : ''}>Qwen (OAuth2)</option>
<option value="codex" ${provider.type === 'codex' ? 'selected' : ''}>Codex (OpenAI OAuth2)</option>
<optgroup label="Generic types">
<option value="openai" ${provider.type === 'openai' ? 'selected' : ''}>OpenAI</option>
<option value="google" ${provider.type === 'google' ? 'selected' : ''}>Google</option>
<option value="anthropic" ${provider.type === 'anthropic' ? 'selected' : ''}>Anthropic</option>
</optgroup>
<optgroup label="OAuth2 / Special">
<option value="kiro" ${provider.type === 'kiro' ? 'selected' : ''}>Kiro (Amazon Q Developer)</option>
<option value="claude" ${provider.type === 'claude' ? 'selected' : ''}>Claude (OAuth2)</option>
<option value="kilocode" ${provider.type === 'kilocode' ? 'selected' : ''}>Kilocode (OAuth2)</option>
<option value="qwen" ${provider.type === 'qwen' ? 'selected' : ''}>Qwen (OAuth2)</option>
<option value="codex" ${provider.type === 'codex' ? 'selected' : ''}>Codex (OpenAI OAuth2)</option>
<option value="coderai" ${provider.type === 'coderai' ? 'selected' : ''}>CoderAI</option>
<option value="runpod" ${provider.type === 'runpod' ? 'selected' : ''}>RunPod (Pod platform)</option>
</optgroup>
<optgroup label="Pre-configured API providers">
<option value="abliteration" ${provider.type === 'abliteration' ? 'selected' : ''}>Abliteration AI</option>
<option value="ai21" ${provider.type === 'ai21' ? 'selected' : ''}>AI21</option>
<option value="aiml" ${provider.type === 'aiml' ? 'selected' : ''}>AI/ML API</option>
<option value="aihubmix" ${provider.type === 'aihubmix' ? 'selected' : ''}>AIHubMix</option>
<option value="apertis" ${provider.type === 'apertis' ? 'selected' : ''}>Apertis (Stima)</option>
<option value="assemblyai_llm" ${provider.type === 'assemblyai_llm' ? 'selected' : ''}>AssemblyAI LLM</option>
<option value="baseten" ${provider.type === 'baseten' ? 'selected' : ''}>Baseten</option>
<option value="cerebras" ${provider.type === 'cerebras' ? 'selected' : ''}>Cerebras</option>
<option value="charity_engine" ${provider.type === 'charity_engine' ? 'selected' : ''}>Charity Engine</option>
<option value="chutes" ${provider.type === 'chutes' ? 'selected' : ''}>Chutes</option>
<option value="clarifai" ${provider.type === 'clarifai' ? 'selected' : ''}>Clarifai</option>
<option value="cohere" ${provider.type === 'cohere' ? 'selected' : ''}>Cohere</option>
<option value="codestral" ${provider.type === 'codestral' ? 'selected' : ''}>Codestral (Mistral)</option>
<option value="cometapi" ${provider.type === 'cometapi' ? 'selected' : ''}>CometAPI</option>
<option value="compactifai" ${provider.type === 'compactifai' ? 'selected' : ''}>CompactifAI</option>
<option value="crusoe" ${provider.type === 'crusoe' ? 'selected' : ''}>Crusoe Cloud</option>
<option value="dashscope" ${provider.type === 'dashscope' ? 'selected' : ''}>DashScope (Alibaba)</option>
<option value="deepinfra" ${provider.type === 'deepinfra' ? 'selected' : ''}>DeepInfra</option>
<option value="deepseek" ${provider.type === 'deepseek' ? 'selected' : ''}>DeepSeek</option>
<option value="empower" ${provider.type === 'empower' ? 'selected' : ''}>Empower</option>
<option value="featherless_ai" ${provider.type === 'featherless_ai' ? 'selected' : ''}>Featherless AI</option>
<option value="fireworks_ai" ${provider.type === 'fireworks_ai' ? 'selected' : ''}>Fireworks AI</option>
<option value="friendliai" ${provider.type === 'friendliai' ? 'selected' : ''}>Friendli AI</option>
<option value="galadriel" ${provider.type === 'galadriel' ? 'selected' : ''}>Galadriel</option>
<option value="github_models" ${provider.type === 'github_models' ? 'selected' : ''}>GitHub Models</option>
<option value="gmi" ${provider.type === 'gmi' ? 'selected' : ''}>GMI Serving</option>
<option value="gradient_ai" ${provider.type === 'gradient_ai' ? 'selected' : ''}>Gradient AI (DigitalOcean)</option>
<option value="groq" ${provider.type === 'groq' ? 'selected' : ''}>Groq</option>
<option value="helicone" ${provider.type === 'helicone' ? 'selected' : ''}>Helicone AI Gateway</option>
<option value="huggingface" ${provider.type === 'huggingface' ? 'selected' : ''}>HuggingFace Inference</option>
<option value="hyperbolic" ${provider.type === 'hyperbolic' ? 'selected' : ''}>Hyperbolic</option>
<option value="jina_ai" ${provider.type === 'jina_ai' ? 'selected' : ''}>Jina AI</option>
<option value="lambda_ai" ${provider.type === 'lambda_ai' ? 'selected' : ''}>Lambda AI</option>
<option value="llamagate" ${provider.type === 'llamagate' ? 'selected' : ''}>LlamaGate</option>
<option value="maritalk" ${provider.type === 'maritalk' ? 'selected' : ''}>MariTalk</option>
<option value="meta_llama" ${provider.type === 'meta_llama' ? 'selected' : ''}>Meta Llama API</option>
<option value="minimax" ${provider.type === 'minimax' ? 'selected' : ''}>MiniMax</option>
<option value="mistral" ${provider.type === 'mistral' ? 'selected' : ''}>Mistral AI</option>
<option value="moonshot" ${provider.type === 'moonshot' ? 'selected' : ''}>Moonshot AI</option>
<option value="morph" ${provider.type === 'morph' ? 'selected' : ''}>Morph LLM</option>
<option value="nano_gpt" ${provider.type === 'nano_gpt' ? 'selected' : ''}>NanoGPT</option>
<option value="nebius" ${provider.type === 'nebius' ? 'selected' : ''}>Nebius AI Studio</option>
<option value="nlp_cloud" ${provider.type === 'nlp_cloud' ? 'selected' : ''}>NLP Cloud</option>
<option value="novita" ${provider.type === 'novita' ? 'selected' : ''}>Novita AI</option>
<option value="nscale" ${provider.type === 'nscale' ? 'selected' : ''}>NScale</option>
<option value="nvidia_nim" ${provider.type === 'nvidia_nim' ? 'selected' : ''}>NVIDIA NIM</option>
<option value="openrouter" ${provider.type === 'openrouter' ? 'selected' : ''}>OpenRouter</option>
<option value="ovhcloud" ${provider.type === 'ovhcloud' ? 'selected' : ''}>OVHcloud AI</option>
<option value="perplexity" ${provider.type === 'perplexity' ? 'selected' : ''}>Perplexity AI</option>
<option value="poe" ${provider.type === 'poe' ? 'selected' : ''}>Poe</option>
<option value="predibase" ${provider.type === 'predibase' ? 'selected' : ''}>Predibase</option>
<option value="publicai" ${provider.type === 'publicai' ? 'selected' : ''}>PublicAI</option>
<option value="sambanova" ${provider.type === 'sambanova' ? 'selected' : ''}>SambaNova</option>
<option value="sarvam" ${provider.type === 'sarvam' ? 'selected' : ''}>Sarvam AI</option>
<option value="scaleway" ${provider.type === 'scaleway' ? 'selected' : ''}>Scaleway</option>
<option value="synthetic" ${provider.type === 'synthetic' ? 'selected' : ''}>Synthetic</option>
<option value="together_ai" ${provider.type === 'together_ai' ? 'selected' : ''}>Together AI</option>
<option value="veniceai" ${provider.type === 'veniceai' ? 'selected' : ''}>Venice AI</option>
<option value="vercel_ai_gateway" ${provider.type === 'vercel_ai_gateway' ? 'selected' : ''}>Vercel AI Gateway</option>
<option value="volcengine" ${provider.type === 'volcengine' ? 'selected' : ''}>VolcEngine (ByteDance)</option>
<option value="voyage" ${provider.type === 'voyage' ? 'selected' : ''}>Voyage AI</option>
<option value="wandb_inference" ${provider.type === 'wandb_inference' ? 'selected' : ''}>W&amp;B Inference</option>
<option value="xai" ${provider.type === 'xai' ? 'selected' : ''}>xAI (Grok)</option>
<option value="xiaomi_mimo" ${provider.type === 'xiaomi_mimo' ? 'selected' : ''}>Xiaomi MiMo</option>
<option value="zai" ${provider.type === 'zai' ? 'selected' : ''}>Z.AI</option>
</optgroup>
<optgroup label="Local / self-hosted">
<option value="ollama" ${provider.type === 'ollama' ? 'selected' : ''}>Ollama</option>
<option value="docker_model_runner" ${provider.type === 'docker_model_runner' ? 'selected' : ''}>Docker Model Runner</option>
<option value="infinity" ${provider.type === 'infinity' ? 'selected' : ''}>Infinity</option>
<option value="llamafile" ${provider.type === 'llamafile' ? 'selected' : ''}>Llamafile</option>
<option value="lm_studio" ${provider.type === 'lm_studio' ? 'selected' : ''}>LM Studio</option>
<option value="oobabooga" ${provider.type === 'oobabooga' ? 'selected' : ''}>Oobabooga (Text Gen WebUI)</option>
<option value="tabbyapi" ${provider.type === 'tabbyapi' ? 'selected' : ''}>TabbyAPI</option>
<option value="vllm" ${provider.type === 'vllm' ? 'selected' : ''}>vLLM</option>
<option value="xinference" ${provider.type === 'xinference' ? 'selected' : ''}>Xinference</option>
</optgroup>
<optgroup label="Cloud (configure endpoint)">
<option value="azure_openai" ${provider.type === 'azure_openai' ? 'selected' : ''}>Azure OpenAI</option>
<option value="databricks" ${provider.type === 'databricks' ? 'selected' : ''}>Databricks</option>
<option value="heroku" ${provider.type === 'heroku' ? 'selected' : ''}>Heroku AI</option>
<option value="snowflake" ${provider.type === 'snowflake' ? 'selected' : ''}>Snowflake Cortex</option>
</optgroup>
</select>
</div>
......@@ -1726,7 +1903,88 @@ function updateNewProviderDefaults() {
'kilocode': 'Kilocode provider. Uses OAuth2 Device Authorization Grant. Endpoint: https://api.kilo.ai/api/gateway',
'qwen': 'Qwen provider. Uses OAuth2 Device Authorization Grant or API key. Endpoint: https://dashscope.aliyuncs.com/compatible-mode/v1',
'codex': 'Codex provider. Uses OAuth2 Device Authorization Grant (same protocol as OpenAI). Endpoint: https://api.openai.com/v1',
'coderai': 'CoderAI provider. In broker mode, CoderAI connects inbound to AISBF using a provider-scoped registration token. In direct mode, AISBF calls it as an OpenAI-compatible endpoint. Default endpoint: http://127.0.0.1:11437'
'coderai': 'CoderAI provider. In broker mode, CoderAI connects inbound to AISBF using a provider-scoped registration token. In direct mode, AISBF calls it as an OpenAI-compatible endpoint. Default endpoint: http://127.0.0.1:11437',
// Pre-configured API providers
'abliteration': 'Abliteration AI — OpenAI-compatible inference API. Endpoint: https://api.abliteration.ai/v1',
'ai21': 'AI21 Labs — OpenAI-compatible endpoint for Jamba and Jurassic models. Endpoint: https://api.ai21.com/studio/v1',
'aiml': 'AI/ML API — unified gateway for many models. Endpoint: https://api.aimlapi.com/v1',
'aihubmix': 'AIHubMix — OpenAI-compatible aggregator. Endpoint: https://aihubmix.com/v1',
'apertis': 'Apertis (Stima Tech) — OpenAI-compatible inference. Endpoint: https://api.stima.tech/v1',
'assemblyai_llm': 'AssemblyAI LLM Gateway — OpenAI-compatible endpoint. Endpoint: https://llm-gateway.assemblyai.com/v1',
'baseten': 'Baseten — deploy and serve ML models. Endpoint: https://inference.baseten.co/v1',
'cerebras': 'Cerebras — fast inference on Cerebras hardware. Endpoint: https://api.cerebras.ai/v1',
'charity_engine': 'Charity Engine — distributed compute for AI. Endpoint: https://api.charityengine.services/remotejobs/v2/inference',
'chutes': 'Chutes — decentralized AI inference. Endpoint: https://llm.chutes.ai/v1',
'clarifai': 'Clarifai — AI platform with OpenAI-compatible API. Endpoint: https://api.clarifai.com/v2/ext/openai/v1',
'cohere': 'Cohere — language models via OpenAI compatibility layer. Endpoint: https://api.cohere.ai/compatibility/v1',
'codestral': 'Codestral — Mistral\'s code-focused model endpoint. Endpoint: https://codestral.mistral.ai/v1',
'cometapi': 'CometAPI — OpenAI-compatible model aggregator. Endpoint: https://api.cometapi.com/v1',
'compactifai': 'CompactifAI — efficient model inference. Endpoint: https://api.compactif.ai/v1',
'crusoe': 'Crusoe Cloud — GPU cloud with managed inference. Endpoint: https://managed-inference-api-proxy.crusoecloud.com/v1',
'dashscope': 'DashScope (Alibaba Cloud) — Qwen and other models. Endpoint: https://dashscope.aliyuncs.com/compatible-mode/v1',
'deepinfra': 'DeepInfra — run open-source models at scale. Endpoint: https://api.deepinfra.com/v1/openai',
'deepseek': 'DeepSeek — reasoning and chat models. Endpoint: https://api.deepseek.com/v1',
'empower': 'Empower — AI inference platform. Endpoint: https://app.empower.dev/api/v1',
'featherless_ai': 'Featherless AI — serverless open-source model hosting. Endpoint: https://api.featherless.ai/v1',
'fireworks_ai': 'Fireworks AI — fast open-source model inference. Endpoint: https://api.fireworks.ai/inference/v1',
'friendliai': 'Friendli AI — serverless model inference. Endpoint: https://api.friendli.ai/serverless/v1',
'galadriel': 'Galadriel — decentralized AI inference. Endpoint: https://api.galadriel.com/v1',
'github_models': 'GitHub Models — run AI models from the GitHub Marketplace. Endpoint: https://models.inference.ai.azure.com',
'gmi': 'GMI Serving — OpenAI-compatible GPU inference. Endpoint: https://api.gmi-serving.com/v1',
'gradient_ai': 'Gradient AI / DigitalOcean GenAI — managed inference. Endpoint: https://inference.do-ai.run/v1',
'groq': 'Groq — ultra-fast LPU inference. Endpoint: https://api.groq.com/openai/v1',
'helicone': 'Helicone AI Gateway — observability proxy for LLMs. Endpoint: https://ai-gateway.helicone.ai',
'huggingface': 'HuggingFace Inference — run models from the HuggingFace Hub. Endpoint: https://api-inference.huggingface.co/v1',
'hyperbolic': 'Hyperbolic — GPU cloud inference platform. Endpoint: https://api.hyperbolic.xyz/v1',
'jina_ai': 'Jina AI — embeddings and reranking. Endpoint: https://api.jina.ai/v1',
'lambda_ai': 'Lambda AI — GPU cloud with inference API. Endpoint: https://api.lambda.ai/v1',
'llamagate': 'LlamaGate — open model inference gateway. Endpoint: https://api.llamagate.dev/v1',
'maritalk': 'MariTalk — Brazilian Portuguese AI models. Endpoint: https://api.maritalk.com/v1',
'meta_llama': 'Meta Llama API — official Meta inference endpoint. Endpoint: https://api.llama.com/compat/v1',
'minimax': 'MiniMax — Chinese AI provider with global models. Endpoint: https://api.minimax.io/v1',
'mistral': 'Mistral AI — Mistral and Mixtral models. Endpoint: https://api.mistral.ai/v1',
'moonshot': 'Moonshot AI — long-context Chinese AI provider. Endpoint: https://api.moonshot.ai/v1',
'morph': 'Morph LLM — OpenAI-compatible inference. Endpoint: https://api.morphllm.com/v1',
'nano_gpt': 'NanoGPT — pay-per-token model marketplace. Endpoint: https://nano-gpt.com/api/v1',
'nebius': 'Nebius AI Studio — GPU cloud with inference API. Endpoint: https://api.studio.nebius.ai/v1',
'nlp_cloud': 'NLP Cloud — production-ready NLP models. Endpoint: https://api.nlpcloud.io/v1',
'novita': 'Novita AI — affordable GPU inference. Endpoint: https://api.novita.ai/v3/openai',
'nscale': 'NScale — high-performance GPU inference. Endpoint: https://inference.api.nscale.com/v1',
'nvidia_nim': 'NVIDIA NIM — NVIDIA-optimized model microservices. Endpoint: https://integrate.api.nvidia.com/v1',
'openrouter': 'OpenRouter — unified API for 100+ models across providers. Endpoint: https://openrouter.ai/api/v1',
'ovhcloud': 'OVHcloud AI — European cloud AI endpoint. Endpoint: https://oai.endpoints.kepler.ai.cloud.ovh.net/v1',
'perplexity': 'Perplexity AI — search-augmented language models. Endpoint: https://api.perplexity.ai',
'poe': 'Poe — access many AI models through Poe. Endpoint: https://api.poe.com/v1',
'predibase': 'Predibase — fine-tuned model serving. Endpoint: https://serving.app.predibase.com/v1',
'publicai': 'PublicAI — open model inference. Endpoint: https://api.publicai.co/v1',
'runpod': 'RunPod — serverless GPU cloud for AI workloads. Configure endpoint per pod.',
'sambanova': 'SambaNova — enterprise AI inference platform. Endpoint: https://api.sambanova.ai/v1',
'sarvam': 'Sarvam AI — Indian language AI models. Endpoint: https://api.sarvam.ai/v1',
'scaleway': 'Scaleway — European cloud inference API. Endpoint: https://api.scaleway.ai/v1',
'synthetic': 'Synthetic — AI inference platform. Endpoint: https://api.synthetic.new/openai/v1',
'together_ai': 'Together AI — collaborative open-source model inference. Endpoint: https://api.together.xyz/v1',
'veniceai': 'Venice AI — privacy-first AI inference. Endpoint: https://api.venice.ai/api/v1',
'vercel_ai_gateway': 'Vercel AI Gateway — managed AI gateway from Vercel. Endpoint: https://ai-gateway.vercel.sh/v1',
'volcengine': 'VolcEngine (ByteDance) — Doubao and other models. Endpoint: https://ark.cn-beijing.volces.com/api/v3',
'voyage': 'Voyage AI — specialized embedding and reranking models. Endpoint: https://api.voyageai.com/v1',
'wandb_inference': 'W&B Inference — Weights & Biases model inference. Endpoint: https://api.inference.wandb.ai/v1',
'xai': 'xAI (Grok) — Grok models by Elon Musk\'s xAI. Endpoint: https://api.x.ai/v1',
'xiaomi_mimo': 'Xiaomi MiMo — Xiaomi\'s open-source reasoning model. Endpoint: https://api.xiaomimimo.com/v1',
'zai': 'Z.AI — OpenAI-compatible inference. Endpoint: https://api.z.ai/api/paas/v4',
// Local / self-hosted
'docker_model_runner': 'Docker Model Runner — run AI models via Docker Desktop. No API key required. Endpoint: http://localhost:12434/engines/llama.cpp/v1',
'infinity': 'Infinity — fast embedding and reranking server. No API key required. Endpoint: http://localhost:8000/v1',
'llamafile': 'Llamafile — self-contained executable LLM server. No API key required. Endpoint: http://localhost:8080/v1',
'lm_studio': 'LM Studio — local GUI for running LLMs. No API key required. Endpoint: http://localhost:1234/v1',
'oobabooga': 'Oobabooga (Text Generation WebUI) — local LLM frontend. No API key required. Endpoint: http://localhost:5000/v1',
'tabbyapi': 'TabbyAPI — local ExLlamaV2-based inference server. No API key required. Endpoint: http://localhost:5000/v1',
'vllm': 'vLLM — high-throughput local model server. No API key required. Endpoint: http://localhost:8000/v1',
'xinference': 'Xinference — distributed model inference. No API key required. Endpoint: http://localhost:9997/v1',
// Cloud (configure endpoint)
'azure_openai': 'Azure OpenAI — Microsoft Azure-hosted OpenAI models. Requires your Azure resource endpoint (e.g. https://YOUR-RESOURCE.openai.azure.com/openai/v1).',
'databricks': 'Databricks — AI/BI and model serving on Databricks. Requires your workspace endpoint.',
'heroku': 'Heroku AI — managed inference on Heroku. Requires your Heroku inference endpoint.',
'snowflake': 'Snowflake Cortex — AI inference within Snowflake. Requires your Snowflake account endpoint.',
};
descriptionEl.textContent = descriptions[providerType] || window.i18n.t('providers.standard_config');
......@@ -2680,16 +2938,98 @@ async function confirmAddProvider() {
function getDefaultEndpoint(type) {
const defaults = {
// Generic types
'openai': 'https://api.openai.com/v1',
'google': 'https://generativelanguage.googleapis.com/v1beta',
'anthropic': 'https://api.anthropic.com/v1',
'ollama': 'http://localhost:11434/api',
// OAuth2 / Special
'kiro': 'https://q.us-east-1.amazonaws.com',
'claude': 'https://api.anthropic.com/v1',
'kilocode': 'https://api.kilo.ai/api/gateway',
'qwen': 'https://dashscope.aliyuncs.com/compatible-mode/v1',
'codex': 'https://api.openai.com/v1',
'coderai': 'http://127.0.0.1:11437'
'coderai': 'http://127.0.0.1:11437',
// Pre-configured API providers
'abliteration': 'https://api.abliteration.ai/v1',
'ai21': 'https://api.ai21.com/studio/v1',
'aiml': 'https://api.aimlapi.com/v1',
'aihubmix': 'https://aihubmix.com/v1',
'apertis': 'https://api.stima.tech/v1',
'assemblyai_llm': 'https://llm-gateway.assemblyai.com/v1',
'baseten': 'https://inference.baseten.co/v1',
'cerebras': 'https://api.cerebras.ai/v1',
'charity_engine': 'https://api.charityengine.services/remotejobs/v2/inference',
'chutes': 'https://llm.chutes.ai/v1',
'clarifai': 'https://api.clarifai.com/v2/ext/openai/v1',
'cohere': 'https://api.cohere.ai/compatibility/v1',
'codestral': 'https://codestral.mistral.ai/v1',
'cometapi': 'https://api.cometapi.com/v1',
'compactifai': 'https://api.compactif.ai/v1',
'crusoe': 'https://managed-inference-api-proxy.crusoecloud.com/v1',
'dashscope': 'https://dashscope.aliyuncs.com/compatible-mode/v1',
'deepinfra': 'https://api.deepinfra.com/v1/openai',
'deepseek': 'https://api.deepseek.com/v1',
'empower': 'https://app.empower.dev/api/v1',
'featherless_ai': 'https://api.featherless.ai/v1',
'fireworks_ai': 'https://api.fireworks.ai/inference/v1',
'friendliai': 'https://api.friendli.ai/serverless/v1',
'galadriel': 'https://api.galadriel.com/v1',
'github_models': 'https://models.inference.ai.azure.com',
'gmi': 'https://api.gmi-serving.com/v1',
'gradient_ai': 'https://inference.do-ai.run/v1',
'groq': 'https://api.groq.com/openai/v1',
'helicone': 'https://ai-gateway.helicone.ai',
'huggingface': 'https://api-inference.huggingface.co/v1',
'hyperbolic': 'https://api.hyperbolic.xyz/v1',
'jina_ai': 'https://api.jina.ai/v1',
'lambda_ai': 'https://api.lambda.ai/v1',
'llamagate': 'https://api.llamagate.dev/v1',
'maritalk': 'https://api.maritalk.com/v1',
'meta_llama': 'https://api.llama.com/compat/v1',
'minimax': 'https://api.minimax.io/v1',
'mistral': 'https://api.mistral.ai/v1',
'moonshot': 'https://api.moonshot.ai/v1',
'morph': 'https://api.morphllm.com/v1',
'nano_gpt': 'https://nano-gpt.com/api/v1',
'nebius': 'https://api.studio.nebius.ai/v1',
'nlp_cloud': 'https://api.nlpcloud.io/v1',
'novita': 'https://api.novita.ai/v3/openai',
'nscale': 'https://inference.api.nscale.com/v1',
'nvidia_nim': 'https://integrate.api.nvidia.com/v1',
'openrouter': 'https://openrouter.ai/api/v1',
'ovhcloud': 'https://oai.endpoints.kepler.ai.cloud.ovh.net/v1',
'perplexity': 'https://api.perplexity.ai',
'poe': 'https://api.poe.com/v1',
'predibase': 'https://serving.app.predibase.com/v1',
'publicai': 'https://api.publicai.co/v1',
'sambanova': 'https://api.sambanova.ai/v1',
'sarvam': 'https://api.sarvam.ai/v1',
'scaleway': 'https://api.scaleway.ai/v1',
'synthetic': 'https://api.synthetic.new/openai/v1',
'together_ai': 'https://api.together.xyz/v1',
'veniceai': 'https://api.venice.ai/api/v1',
'vercel_ai_gateway': 'https://ai-gateway.vercel.sh/v1',
'volcengine': 'https://ark.cn-beijing.volces.com/api/v3',
'voyage': 'https://api.voyageai.com/v1',
'wandb_inference': 'https://api.inference.wandb.ai/v1',
'xai': 'https://api.x.ai/v1',
'xiaomi_mimo': 'https://api.xiaomimimo.com/v1',
'zai': 'https://api.z.ai/api/paas/v4',
// Local / self-hosted
'docker_model_runner': 'http://localhost:12434/engines/llama.cpp/v1',
'infinity': 'http://localhost:8000/v1',
'llamafile': 'http://localhost:8080/v1',
'lm_studio': 'http://localhost:1234/v1',
'oobabooga': 'http://localhost:5000/v1',
'tabbyapi': 'http://localhost:5000/v1',
'vllm': 'http://localhost:8000/v1',
'xinference': 'http://localhost:9997/v1',
// Cloud (configure endpoint — left empty so user must fill in)
'azure_openai': '',
'databricks': '',
'heroku': '',
'snowflake': '',
};
return defaults[type] || '';
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment