devcopilot 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- api/__init__.py +17 -0
- api/admin_config.py +1303 -0
- api/admin_routes.py +287 -0
- api/admin_static/admin.css +459 -0
- api/admin_static/admin.js +497 -0
- api/admin_static/index.html +77 -0
- api/admin_urls.py +34 -0
- api/app.py +194 -0
- api/command_utils.py +164 -0
- api/dependencies.py +144 -0
- api/detection.py +152 -0
- api/gateway_model_ids.py +54 -0
- api/model_catalog.py +133 -0
- api/model_router.py +125 -0
- api/models/__init__.py +45 -0
- api/models/anthropic.py +234 -0
- api/models/openai_responses.py +28 -0
- api/models/responses.py +60 -0
- api/optimization_handlers.py +154 -0
- api/request_pipeline.py +424 -0
- api/routes.py +156 -0
- api/runtime.py +334 -0
- api/validation_log.py +48 -0
- api/web_server_tools.py +22 -0
- api/web_tools/__init__.py +17 -0
- api/web_tools/constants.py +15 -0
- api/web_tools/egress.py +99 -0
- api/web_tools/outbound.py +278 -0
- api/web_tools/parsers.py +104 -0
- api/web_tools/request.py +87 -0
- api/web_tools/streaming.py +206 -0
- cli/__init__.py +5 -0
- cli/claude_env.py +12 -0
- cli/entrypoints.py +166 -0
- cli/env.example +209 -0
- cli/launchers/__init__.py +1 -0
- cli/launchers/claude.py +84 -0
- cli/launchers/codex.py +204 -0
- cli/launchers/codex_model_catalog.py +186 -0
- cli/launchers/common.py +93 -0
- cli/managed/__init__.py +6 -0
- cli/managed/claude.py +215 -0
- cli/managed/manager.py +157 -0
- cli/managed/session.py +260 -0
- cli/process_registry.py +78 -0
- config/__init__.py +5 -0
- config/constants.py +13 -0
- config/logging_config.py +159 -0
- config/nim.py +118 -0
- config/paths.py +91 -0
- config/provider_catalog.py +259 -0
- config/provider_ids.py +7 -0
- config/settings.py +538 -0
- core/__init__.py +1 -0
- core/anthropic/__init__.py +46 -0
- core/anthropic/content.py +31 -0
- core/anthropic/conversion.py +587 -0
- core/anthropic/emitted_sse_tracker.py +346 -0
- core/anthropic/errors.py +70 -0
- core/anthropic/native_messages_request.py +280 -0
- core/anthropic/native_sse_block_policy.py +313 -0
- core/anthropic/provider_stream_error.py +34 -0
- core/anthropic/server_tool_sse.py +14 -0
- core/anthropic/sse.py +440 -0
- core/anthropic/stream_contracts.py +205 -0
- core/anthropic/stream_recovery.py +346 -0
- core/anthropic/stream_recovery_session.py +133 -0
- core/anthropic/thinking.py +140 -0
- core/anthropic/tokens.py +117 -0
- core/anthropic/tools.py +212 -0
- core/anthropic/utils.py +9 -0
- core/openai_responses/__init__.py +5 -0
- core/openai_responses/adapter.py +31 -0
- core/openai_responses/anthropic_sse.py +59 -0
- core/openai_responses/errors.py +22 -0
- core/openai_responses/events.py +19 -0
- core/openai_responses/ids.py +21 -0
- core/openai_responses/input.py +258 -0
- core/openai_responses/items.py +37 -0
- core/openai_responses/reasoning.py +52 -0
- core/openai_responses/stream.py +25 -0
- core/openai_responses/stream_state.py +654 -0
- core/openai_responses/tools.py +374 -0
- core/openai_responses/usage.py +37 -0
- core/rate_limit.py +60 -0
- core/trace.py +216 -0
- devcopilot-0.2.0.dist-info/METADATA +687 -0
- devcopilot-0.2.0.dist-info/RECORD +189 -0
- devcopilot-0.2.0.dist-info/WHEEL +4 -0
- devcopilot-0.2.0.dist-info/entry_points.txt +6 -0
- devcopilot-0.2.0.dist-info/licenses/LICENSE +21 -0
- messaging/__init__.py +26 -0
- messaging/cli_event_constants.py +67 -0
- messaging/command_context.py +66 -0
- messaging/command_dispatcher.py +37 -0
- messaging/commands.py +275 -0
- messaging/event_parser.py +181 -0
- messaging/limiter.py +300 -0
- messaging/models.py +36 -0
- messaging/node_event_pipeline.py +127 -0
- messaging/node_runner.py +342 -0
- messaging/platforms/__init__.py +15 -0
- messaging/platforms/base.py +228 -0
- messaging/platforms/discord.py +567 -0
- messaging/platforms/factory.py +103 -0
- messaging/platforms/outbox.py +144 -0
- messaging/platforms/telegram.py +688 -0
- messaging/platforms/voice_flow.py +295 -0
- messaging/rendering/__init__.py +3 -0
- messaging/rendering/discord_markdown.py +318 -0
- messaging/rendering/markdown_tables.py +49 -0
- messaging/rendering/profiles.py +55 -0
- messaging/rendering/telegram_markdown.py +327 -0
- messaging/safe_diagnostics.py +17 -0
- messaging/session.py +334 -0
- messaging/transcript.py +581 -0
- messaging/transcription.py +164 -0
- messaging/trees/__init__.py +15 -0
- messaging/trees/data.py +482 -0
- messaging/trees/manager.py +433 -0
- messaging/trees/processor.py +179 -0
- messaging/trees/repository.py +177 -0
- messaging/turn_intake.py +235 -0
- messaging/ui_updates.py +101 -0
- messaging/voice.py +76 -0
- messaging/workflow.py +200 -0
- providers/__init__.py +31 -0
- providers/base.py +152 -0
- providers/cerebras/__init__.py +7 -0
- providers/cerebras/client.py +31 -0
- providers/cerebras/request.py +55 -0
- providers/codestral/__init__.py +7 -0
- providers/codestral/client.py +34 -0
- providers/deepseek/__init__.py +11 -0
- providers/deepseek/client.py +51 -0
- providers/deepseek/request.py +475 -0
- providers/defaults.py +41 -0
- providers/error_mapping.py +309 -0
- providers/exceptions.py +113 -0
- providers/fireworks/__init__.py +5 -0
- providers/fireworks/client.py +45 -0
- providers/fireworks/request.py +48 -0
- providers/gemini/__init__.py +7 -0
- providers/gemini/client.py +49 -0
- providers/gemini/request.py +199 -0
- providers/groq/__init__.py +7 -0
- providers/groq/client.py +31 -0
- providers/groq/request.py +83 -0
- providers/kimi/__init__.py +10 -0
- providers/kimi/client.py +53 -0
- providers/kimi/request.py +42 -0
- providers/llamacpp/__init__.py +3 -0
- providers/llamacpp/client.py +16 -0
- providers/lmstudio/__init__.py +5 -0
- providers/lmstudio/client.py +16 -0
- providers/mistral/__init__.py +7 -0
- providers/mistral/client.py +31 -0
- providers/mistral/request.py +37 -0
- providers/model_listing.py +133 -0
- providers/nvidia_nim/__init__.py +7 -0
- providers/nvidia_nim/client.py +91 -0
- providers/nvidia_nim/request.py +430 -0
- providers/nvidia_nim/voice.py +95 -0
- providers/ollama/__init__.py +7 -0
- providers/ollama/client.py +39 -0
- providers/open_router/__init__.py +7 -0
- providers/open_router/client.py +124 -0
- providers/open_router/request.py +42 -0
- providers/opencode/__init__.py +11 -0
- providers/opencode/client.py +31 -0
- providers/opencode/request.py +35 -0
- providers/rate_limit.py +300 -0
- providers/registry.py +527 -0
- providers/transports/__init__.py +1 -0
- providers/transports/anthropic_messages/__init__.py +5 -0
- providers/transports/anthropic_messages/http.py +118 -0
- providers/transports/anthropic_messages/recovery.py +206 -0
- providers/transports/anthropic_messages/stream.py +295 -0
- providers/transports/anthropic_messages/transport.py +236 -0
- providers/transports/openai_chat/__init__.py +5 -0
- providers/transports/openai_chat/recovery.py +217 -0
- providers/transports/openai_chat/stream.py +384 -0
- providers/transports/openai_chat/tool_calls.py +293 -0
- providers/transports/openai_chat/transport.py +156 -0
- providers/wafer/__init__.py +10 -0
- providers/wafer/client.py +50 -0
- providers/zai/__init__.py +10 -0
- providers/zai/client.py +46 -0
- providers/zai/request.py +42 -0
config/paths.py
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""Shared filesystem paths for DevCopilot configuration."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import shutil
|
|
5
|
+
|
|
6
|
+
DEVCOPILOT_CONFIG_DIRNAME = ".dc"
|
|
7
|
+
FCC_CONFIG_DIRNAME = ".fcc"
|
|
8
|
+
|
|
9
|
+
ENV_FILENAME = ".env"
|
|
10
|
+
|
|
11
|
+
LEGACY_REPO_DIRNAME = "free-claude-code"
|
|
12
|
+
LEGACY_XDG_CONFIG_DIRNAME = ".config"
|
|
13
|
+
|
|
14
|
+
CLAUDE_WORKSPACE_DIRNAME = "agent_workspace"
|
|
15
|
+
LOGS_DIRNAME = "logs"
|
|
16
|
+
SERVER_LOG_FILENAME = "server.log"
|
|
17
|
+
CODEX_MODEL_CATALOG_FILENAME = "codex-model-catalog.json"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def repo_env_path() -> Path:
|
|
21
|
+
"""Local development .env inside the repository."""
|
|
22
|
+
return Path.cwd() / ENV_FILENAME
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def config_dir_path() -> Path:
|
|
26
|
+
"""
|
|
27
|
+
Priority:
|
|
28
|
+
|
|
29
|
+
1. repo/.env
|
|
30
|
+
2. ~/.dc
|
|
31
|
+
3. migrate from ~/.fcc
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
home = Path.home()
|
|
35
|
+
|
|
36
|
+
dc_dir = home / DEVCOPILOT_CONFIG_DIRNAME
|
|
37
|
+
fcc_dir = home / FCC_CONFIG_DIRNAME
|
|
38
|
+
|
|
39
|
+
# Development mode
|
|
40
|
+
if repo_env_path().exists():
|
|
41
|
+
return Path.cwd()
|
|
42
|
+
|
|
43
|
+
# Existing DevCopilot config
|
|
44
|
+
if dc_dir.exists():
|
|
45
|
+
return dc_dir
|
|
46
|
+
|
|
47
|
+
# Migrate legacy FCC config
|
|
48
|
+
if fcc_dir.exists():
|
|
49
|
+
dc_dir.mkdir(parents=True, exist_ok=True)
|
|
50
|
+
|
|
51
|
+
fcc_env = fcc_dir / ENV_FILENAME
|
|
52
|
+
dc_env = dc_dir / ENV_FILENAME
|
|
53
|
+
|
|
54
|
+
if fcc_env.exists() and not dc_env.exists():
|
|
55
|
+
shutil.copy2(fcc_env, dc_env)
|
|
56
|
+
|
|
57
|
+
return dc_dir
|
|
58
|
+
|
|
59
|
+
# First startup
|
|
60
|
+
dc_dir.mkdir(parents=True, exist_ok=True)
|
|
61
|
+
return dc_dir
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def managed_env_path() -> Path:
|
|
65
|
+
"""Return active env path."""
|
|
66
|
+
|
|
67
|
+
if repo_env_path().exists():
|
|
68
|
+
return repo_env_path()
|
|
69
|
+
|
|
70
|
+
return config_dir_path() / ENV_FILENAME
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def legacy_env_paths() -> tuple[Path, ...]:
|
|
74
|
+
home = Path.home()
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
home / LEGACY_REPO_DIRNAME / ENV_FILENAME,
|
|
78
|
+
home / LEGACY_XDG_CONFIG_DIRNAME / LEGACY_REPO_DIRNAME / ENV_FILENAME,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def default_claude_workspace_path() -> Path:
|
|
83
|
+
return config_dir_path() / CLAUDE_WORKSPACE_DIRNAME
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def server_log_path() -> Path:
|
|
87
|
+
return config_dir_path() / LOGS_DIRNAME / SERVER_LOG_FILENAME
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def codex_model_catalog_path() -> Path:
|
|
91
|
+
return config_dir_path() / CODEX_MODEL_CATALOG_FILENAME
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"""Neutral provider catalog: IDs, credentials, defaults, proxy and capability metadata.
|
|
2
|
+
|
|
3
|
+
Adapter factories live in :mod:`providers.registry`; this module stays free of
|
|
4
|
+
provider implementation imports (see contract tests).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
from typing import Literal
|
|
11
|
+
|
|
12
|
+
TransportType = Literal["openai_chat", "anthropic_messages"]
|
|
13
|
+
|
|
14
|
+
# Default upstream base URLs (also re-exported via :mod:`providers.defaults`)
|
|
15
|
+
NVIDIA_NIM_DEFAULT_BASE = "https://integrate.api.nvidia.com/v1"
|
|
16
|
+
# Moonshot Kimi Anthropic-compatible Messages API (POST …/messages).
|
|
17
|
+
KIMI_DEFAULT_BASE = "https://api.moonshot.ai/anthropic/v1"
|
|
18
|
+
WAFER_DEFAULT_BASE = "https://pass.wafer.ai/v1"
|
|
19
|
+
# DeepSeek Anthropic-compatible Messages API (not OpenAI ``/v1`` chat completions).
|
|
20
|
+
DEEPSEEK_ANTHROPIC_DEFAULT_BASE = "https://api.deepseek.com/anthropic"
|
|
21
|
+
# Historical export name: DeepSeek upstream is the native Anthropic path above.
|
|
22
|
+
DEEPSEEK_DEFAULT_BASE = DEEPSEEK_ANTHROPIC_DEFAULT_BASE
|
|
23
|
+
FIREWORKS_DEFAULT_BASE = "https://api.fireworks.ai/inference/v1"
|
|
24
|
+
OPENROUTER_DEFAULT_BASE = "https://openrouter.ai/api/v1"
|
|
25
|
+
MISTRAL_DEFAULT_BASE = "https://api.mistral.ai/v1"
|
|
26
|
+
# Codestral IDE/personal endpoint (distinct from La Plateforme ``api.mistral.ai`` keys).
|
|
27
|
+
CODESTRAL_DEFAULT_BASE = "https://codestral.mistral.ai/v1"
|
|
28
|
+
LMSTUDIO_DEFAULT_BASE = "http://localhost:1234/v1"
|
|
29
|
+
LLAMACPP_DEFAULT_BASE = "http://localhost:8080/v1"
|
|
30
|
+
OLLAMA_DEFAULT_BASE = "http://localhost:11434"
|
|
31
|
+
OPENCODE_DEFAULT_BASE = "https://opencode.ai/zen/v1"
|
|
32
|
+
OPENCODE_GO_DEFAULT_BASE = "https://opencode.ai/zen/go/v1"
|
|
33
|
+
# Z.ai Anthropic-compatible Messages API (not OpenAI Coding Plan chat completions).
|
|
34
|
+
ZAI_DEFAULT_BASE = "https://api.z.ai/api/anthropic/v1"
|
|
35
|
+
# Google AI Studio Gemini API OpenAI-compat layer (not Vertex AI).
|
|
36
|
+
GEMINI_DEFAULT_BASE = "https://generativelanguage.googleapis.com/v1beta/openai/"
|
|
37
|
+
GROQ_DEFAULT_BASE = "https://api.groq.com/openai/v1"
|
|
38
|
+
CEREBRAS_DEFAULT_BASE = "https://api.cerebras.ai/v1"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass(frozen=True, slots=True)
|
|
42
|
+
class ProviderDescriptor:
|
|
43
|
+
"""Metadata for building :class:`~providers.base.ProviderConfig` and factory wiring."""
|
|
44
|
+
|
|
45
|
+
provider_id: str
|
|
46
|
+
transport_type: TransportType
|
|
47
|
+
capabilities: tuple[str, ...]
|
|
48
|
+
credential_env: str | None = None
|
|
49
|
+
credential_url: str | None = None
|
|
50
|
+
credential_attr: str | None = None
|
|
51
|
+
static_credential: str | None = None
|
|
52
|
+
default_base_url: str | None = None
|
|
53
|
+
base_url_attr: str | None = None
|
|
54
|
+
proxy_attr: str | None = None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
PROVIDER_CATALOG: dict[str, ProviderDescriptor] = {
|
|
58
|
+
"nvidia_nim": ProviderDescriptor(
|
|
59
|
+
provider_id="nvidia_nim",
|
|
60
|
+
transport_type="openai_chat",
|
|
61
|
+
credential_env="NVIDIA_NIM_API_KEY",
|
|
62
|
+
credential_url="https://build.nvidia.com/settings/api-keys",
|
|
63
|
+
credential_attr="nvidia_nim_api_key",
|
|
64
|
+
default_base_url=NVIDIA_NIM_DEFAULT_BASE,
|
|
65
|
+
proxy_attr="nvidia_nim_proxy",
|
|
66
|
+
capabilities=("chat", "streaming", "tools", "thinking", "rate_limit"),
|
|
67
|
+
),
|
|
68
|
+
"open_router": ProviderDescriptor(
|
|
69
|
+
provider_id="open_router",
|
|
70
|
+
transport_type="anthropic_messages",
|
|
71
|
+
credential_env="OPENROUTER_API_KEY",
|
|
72
|
+
credential_url="https://openrouter.ai/keys",
|
|
73
|
+
credential_attr="open_router_api_key",
|
|
74
|
+
default_base_url=OPENROUTER_DEFAULT_BASE,
|
|
75
|
+
proxy_attr="open_router_proxy",
|
|
76
|
+
capabilities=("chat", "streaming", "tools", "thinking", "native_anthropic"),
|
|
77
|
+
),
|
|
78
|
+
"gemini": ProviderDescriptor(
|
|
79
|
+
provider_id="gemini",
|
|
80
|
+
transport_type="openai_chat",
|
|
81
|
+
credential_env="GEMINI_API_KEY",
|
|
82
|
+
credential_url="https://aistudio.google.com/apikey",
|
|
83
|
+
credential_attr="gemini_api_key",
|
|
84
|
+
default_base_url=GEMINI_DEFAULT_BASE,
|
|
85
|
+
proxy_attr="gemini_proxy",
|
|
86
|
+
capabilities=("chat", "streaming", "tools", "thinking", "rate_limit"),
|
|
87
|
+
),
|
|
88
|
+
"deepseek": ProviderDescriptor(
|
|
89
|
+
provider_id="deepseek",
|
|
90
|
+
transport_type="anthropic_messages",
|
|
91
|
+
credential_env="DEEPSEEK_API_KEY",
|
|
92
|
+
credential_url="https://platform.deepseek.com/api_keys",
|
|
93
|
+
credential_attr="deepseek_api_key",
|
|
94
|
+
default_base_url=DEEPSEEK_ANTHROPIC_DEFAULT_BASE,
|
|
95
|
+
capabilities=("chat", "streaming", "tools", "thinking", "native_anthropic"),
|
|
96
|
+
),
|
|
97
|
+
"mistral": ProviderDescriptor(
|
|
98
|
+
provider_id="mistral",
|
|
99
|
+
transport_type="openai_chat",
|
|
100
|
+
credential_env="MISTRAL_API_KEY",
|
|
101
|
+
credential_url="https://console.mistral.ai/",
|
|
102
|
+
credential_attr="mistral_api_key",
|
|
103
|
+
default_base_url=MISTRAL_DEFAULT_BASE,
|
|
104
|
+
proxy_attr="mistral_proxy",
|
|
105
|
+
capabilities=("chat", "streaming", "tools", "thinking", "rate_limit"),
|
|
106
|
+
),
|
|
107
|
+
"mistral_codestral": ProviderDescriptor(
|
|
108
|
+
provider_id="mistral_codestral",
|
|
109
|
+
transport_type="openai_chat",
|
|
110
|
+
credential_env="CODESTRAL_API_KEY",
|
|
111
|
+
credential_url="https://console.mistral.ai/",
|
|
112
|
+
credential_attr="codestral_api_key",
|
|
113
|
+
default_base_url=CODESTRAL_DEFAULT_BASE,
|
|
114
|
+
proxy_attr="codestral_proxy",
|
|
115
|
+
capabilities=("chat", "streaming", "tools", "thinking", "rate_limit"),
|
|
116
|
+
),
|
|
117
|
+
"opencode": ProviderDescriptor(
|
|
118
|
+
provider_id="opencode",
|
|
119
|
+
transport_type="openai_chat",
|
|
120
|
+
credential_env="OPENCODE_API_KEY",
|
|
121
|
+
credential_url="https://opencode.ai/auth",
|
|
122
|
+
credential_attr="opencode_api_key",
|
|
123
|
+
default_base_url=OPENCODE_DEFAULT_BASE,
|
|
124
|
+
proxy_attr="opencode_proxy",
|
|
125
|
+
capabilities=("chat", "streaming", "tools", "thinking", "rate_limit"),
|
|
126
|
+
),
|
|
127
|
+
"opencode_go": ProviderDescriptor(
|
|
128
|
+
provider_id="opencode_go",
|
|
129
|
+
transport_type="openai_chat",
|
|
130
|
+
credential_env="OPENCODE_API_KEY",
|
|
131
|
+
credential_url="https://opencode.ai/auth",
|
|
132
|
+
credential_attr="opencode_api_key",
|
|
133
|
+
default_base_url=OPENCODE_GO_DEFAULT_BASE,
|
|
134
|
+
proxy_attr="opencode_go_proxy",
|
|
135
|
+
capabilities=("chat", "streaming", "tools", "thinking", "rate_limit"),
|
|
136
|
+
),
|
|
137
|
+
"wafer": ProviderDescriptor(
|
|
138
|
+
provider_id="wafer",
|
|
139
|
+
transport_type="anthropic_messages",
|
|
140
|
+
credential_env="WAFER_API_KEY",
|
|
141
|
+
credential_url="https://www.wafer.ai/pass",
|
|
142
|
+
credential_attr="wafer_api_key",
|
|
143
|
+
default_base_url=WAFER_DEFAULT_BASE,
|
|
144
|
+
proxy_attr="wafer_proxy",
|
|
145
|
+
capabilities=("chat", "streaming", "tools", "thinking", "native_anthropic"),
|
|
146
|
+
),
|
|
147
|
+
"kimi": ProviderDescriptor(
|
|
148
|
+
provider_id="kimi",
|
|
149
|
+
transport_type="anthropic_messages",
|
|
150
|
+
credential_env="KIMI_API_KEY",
|
|
151
|
+
credential_url="https://platform.moonshot.cn/console/api-keys",
|
|
152
|
+
credential_attr="kimi_api_key",
|
|
153
|
+
default_base_url=KIMI_DEFAULT_BASE,
|
|
154
|
+
proxy_attr="kimi_proxy",
|
|
155
|
+
capabilities=(
|
|
156
|
+
"chat",
|
|
157
|
+
"streaming",
|
|
158
|
+
"tools",
|
|
159
|
+
"thinking",
|
|
160
|
+
"native_anthropic",
|
|
161
|
+
),
|
|
162
|
+
),
|
|
163
|
+
"cerebras": ProviderDescriptor(
|
|
164
|
+
provider_id="cerebras",
|
|
165
|
+
transport_type="openai_chat",
|
|
166
|
+
credential_env="CEREBRAS_API_KEY",
|
|
167
|
+
credential_url="https://cloud.cerebras.ai",
|
|
168
|
+
credential_attr="cerebras_api_key",
|
|
169
|
+
default_base_url=CEREBRAS_DEFAULT_BASE,
|
|
170
|
+
proxy_attr="cerebras_proxy",
|
|
171
|
+
capabilities=("chat", "streaming", "tools", "thinking", "rate_limit"),
|
|
172
|
+
),
|
|
173
|
+
"groq": ProviderDescriptor(
|
|
174
|
+
provider_id="groq",
|
|
175
|
+
transport_type="openai_chat",
|
|
176
|
+
credential_env="GROQ_API_KEY",
|
|
177
|
+
credential_url="https://console.groq.com/keys",
|
|
178
|
+
credential_attr="groq_api_key",
|
|
179
|
+
default_base_url=GROQ_DEFAULT_BASE,
|
|
180
|
+
proxy_attr="groq_proxy",
|
|
181
|
+
capabilities=("chat", "streaming", "tools", "thinking", "rate_limit"),
|
|
182
|
+
),
|
|
183
|
+
"fireworks": ProviderDescriptor(
|
|
184
|
+
provider_id="fireworks",
|
|
185
|
+
transport_type="anthropic_messages",
|
|
186
|
+
credential_env="FIREWORKS_API_KEY",
|
|
187
|
+
credential_url="https://fireworks.ai/account/api-keys",
|
|
188
|
+
credential_attr="fireworks_api_key",
|
|
189
|
+
default_base_url=FIREWORKS_DEFAULT_BASE,
|
|
190
|
+
proxy_attr="fireworks_proxy",
|
|
191
|
+
capabilities=(
|
|
192
|
+
"chat",
|
|
193
|
+
"streaming",
|
|
194
|
+
"tools",
|
|
195
|
+
"thinking",
|
|
196
|
+
"native_anthropic",
|
|
197
|
+
"rate_limit",
|
|
198
|
+
),
|
|
199
|
+
),
|
|
200
|
+
"zai": ProviderDescriptor(
|
|
201
|
+
provider_id="zai",
|
|
202
|
+
transport_type="anthropic_messages",
|
|
203
|
+
credential_env="ZAI_API_KEY",
|
|
204
|
+
credential_attr="zai_api_key",
|
|
205
|
+
default_base_url=ZAI_DEFAULT_BASE,
|
|
206
|
+
proxy_attr="zai_proxy",
|
|
207
|
+
capabilities=(
|
|
208
|
+
"chat",
|
|
209
|
+
"streaming",
|
|
210
|
+
"tools",
|
|
211
|
+
"thinking",
|
|
212
|
+
"native_anthropic",
|
|
213
|
+
"rate_limit",
|
|
214
|
+
),
|
|
215
|
+
),
|
|
216
|
+
"lmstudio": ProviderDescriptor(
|
|
217
|
+
provider_id="lmstudio",
|
|
218
|
+
transport_type="anthropic_messages",
|
|
219
|
+
static_credential="lm-studio",
|
|
220
|
+
default_base_url=LMSTUDIO_DEFAULT_BASE,
|
|
221
|
+
base_url_attr="lm_studio_base_url",
|
|
222
|
+
proxy_attr="lmstudio_proxy",
|
|
223
|
+
capabilities=("chat", "streaming", "tools", "native_anthropic", "local"),
|
|
224
|
+
),
|
|
225
|
+
"llamacpp": ProviderDescriptor(
|
|
226
|
+
provider_id="llamacpp",
|
|
227
|
+
transport_type="anthropic_messages",
|
|
228
|
+
static_credential="llamacpp",
|
|
229
|
+
default_base_url=LLAMACPP_DEFAULT_BASE,
|
|
230
|
+
base_url_attr="llamacpp_base_url",
|
|
231
|
+
proxy_attr="llamacpp_proxy",
|
|
232
|
+
capabilities=("chat", "streaming", "tools", "native_anthropic", "local"),
|
|
233
|
+
),
|
|
234
|
+
"ollama": ProviderDescriptor(
|
|
235
|
+
provider_id="ollama",
|
|
236
|
+
transport_type="anthropic_messages",
|
|
237
|
+
static_credential="ollama",
|
|
238
|
+
default_base_url=OLLAMA_DEFAULT_BASE,
|
|
239
|
+
base_url_attr="ollama_base_url",
|
|
240
|
+
capabilities=(
|
|
241
|
+
"chat",
|
|
242
|
+
"streaming",
|
|
243
|
+
"tools",
|
|
244
|
+
"thinking",
|
|
245
|
+
"native_anthropic",
|
|
246
|
+
"local",
|
|
247
|
+
),
|
|
248
|
+
),
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
# Key order:
|
|
252
|
+
# NVIDIA NIM first (README default), DeepSeek fourth, Wafer ninth / Kimi tenth; then cerebras /
|
|
253
|
+
# groq / fireworks overlap; remainder and locals last per project plan (
|
|
254
|
+
# github.com/cheahjs/free-llm-api-resources Free Providers TOC as rough guide beyond fixed slots).
|
|
255
|
+
# ``SUPPORTED_PROVIDER_IDS`` inherits this insertion order for UI and error-message listing.
|
|
256
|
+
SUPPORTED_PROVIDER_IDS: tuple[str, ...] = tuple(PROVIDER_CATALOG.keys())
|
|
257
|
+
|
|
258
|
+
if len(set(SUPPORTED_PROVIDER_IDS)) != len(SUPPORTED_PROVIDER_IDS):
|
|
259
|
+
raise AssertionError("Duplicate provider ids in PROVIDER_CATALOG key order")
|