vipcode 0.0.0-stage → 0.2.1
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.
- package/LICENSE +21 -0
- package/README.en.md +60 -0
- package/README.md +401 -2
- package/dist/agent.js +502 -0
- package/dist/agents.js +174 -0
- package/dist/app.js +1025 -0
- package/dist/auth.js +108 -0
- package/dist/catalog.js +487 -0
- package/dist/commands.js +121 -0
- package/dist/config.js +230 -0
- package/dist/debug.js +32 -0
- package/dist/discovery.js +277 -0
- package/dist/frontmatter.js +45 -0
- package/dist/images.js +81 -0
- package/dist/index.js +623 -0
- package/dist/login.js +157 -0
- package/dist/lsp.js +480 -0
- package/dist/markdown.js +262 -0
- package/dist/match.js +8 -0
- package/dist/mcp.js +225 -0
- package/dist/meta.js +7 -0
- package/dist/paths.js +53 -0
- package/dist/permissions.js +144 -0
- package/dist/prompt.js +123 -0
- package/dist/ranking.js +230 -0
- package/dist/router.js +726 -0
- package/dist/sanitize.js +38 -0
- package/dist/session.js +219 -0
- package/dist/skills.js +374 -0
- package/dist/snapshot.js +199 -0
- package/dist/tools.js +1311 -0
- package/dist/trust.js +171 -0
- package/dist/tui/app.js +1019 -0
- package/dist/tui/dialogs.js +197 -0
- package/dist/tui/editor.js +120 -0
- package/dist/ui.js +184 -0
- package/dist/update.js +237 -0
- package/package.json +64 -4
package/dist/auth.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { AUTH_PATH, ensureHomeDir } from "./paths.js";
|
|
3
|
+
export function readAuth() {
|
|
4
|
+
try {
|
|
5
|
+
const data = JSON.parse(fs.readFileSync(AUTH_PATH, "utf8"));
|
|
6
|
+
if (data && typeof data === "object") {
|
|
7
|
+
return data;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
// sin fichero todavía
|
|
12
|
+
}
|
|
13
|
+
return {};
|
|
14
|
+
}
|
|
15
|
+
function writeAuth(data) {
|
|
16
|
+
ensureHomeDir();
|
|
17
|
+
// 0600: solo tu usuario puede leer las claves
|
|
18
|
+
fs.writeFileSync(AUTH_PATH, JSON.stringify(data, null, 2), { mode: 0o600 });
|
|
19
|
+
fs.chmodSync(AUTH_PATH, 0o600);
|
|
20
|
+
}
|
|
21
|
+
export function saveAuth(provider, entry) {
|
|
22
|
+
const data = readAuth();
|
|
23
|
+
const previous = data[provider] || {};
|
|
24
|
+
data[provider] = { ...previous, ...entry, vars: { ...(previous.vars || {}), ...(entry.vars || {}) } };
|
|
25
|
+
if (Object.keys(data[provider].vars || {}).length === 0) {
|
|
26
|
+
delete data[provider].vars;
|
|
27
|
+
}
|
|
28
|
+
writeAuth(data);
|
|
29
|
+
}
|
|
30
|
+
export function removeAuth(provider) {
|
|
31
|
+
const data = readAuth();
|
|
32
|
+
if (!data[provider]) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
delete data[provider];
|
|
36
|
+
writeAuth(data);
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
export function envNames(provider) {
|
|
40
|
+
if (!provider.apiKeyEnv) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
if (Array.isArray(provider.apiKeyEnv)) {
|
|
44
|
+
return provider.apiKeyEnv;
|
|
45
|
+
}
|
|
46
|
+
return [provider.apiKeyEnv];
|
|
47
|
+
}
|
|
48
|
+
// Variables que usa la URL, por ejemplo ${CLOUDFLARE_ACCOUNT_ID}
|
|
49
|
+
export function urlVars(provider) {
|
|
50
|
+
const names = new Set(provider.requiredVars || []);
|
|
51
|
+
for (const match of provider.baseURL.matchAll(/\$\{(\w+)\}/g)) {
|
|
52
|
+
names.add(match[1]);
|
|
53
|
+
}
|
|
54
|
+
return [...names];
|
|
55
|
+
}
|
|
56
|
+
// Devuelve la clave y la URL final del proveedor, o null si falta algo
|
|
57
|
+
export function resolveCredentials(provider, auth = readAuth()) {
|
|
58
|
+
const entry = auth[provider.name] || {};
|
|
59
|
+
let apiKey = "";
|
|
60
|
+
let source = "config";
|
|
61
|
+
if (provider.apiKey) {
|
|
62
|
+
apiKey = provider.apiKey;
|
|
63
|
+
}
|
|
64
|
+
else if (entry.key) {
|
|
65
|
+
apiKey = entry.key;
|
|
66
|
+
source = "auth";
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
for (const name of envNames(provider)) {
|
|
70
|
+
if (process.env[name]) {
|
|
71
|
+
apiKey = String(process.env[name]);
|
|
72
|
+
source = "env";
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (!apiKey) {
|
|
78
|
+
// Sin clave solo valen los anónimos de internet y los locales
|
|
79
|
+
if (!provider.noKey) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
apiKey = "no-key";
|
|
83
|
+
source = "sin clave";
|
|
84
|
+
}
|
|
85
|
+
let missing = false;
|
|
86
|
+
const baseURL = provider.baseURL.replace(/\$\{(\w+)\}/g, (_match, name) => {
|
|
87
|
+
const value = entry.vars?.[name] || process.env[name];
|
|
88
|
+
if (!value) {
|
|
89
|
+
missing = true;
|
|
90
|
+
return "";
|
|
91
|
+
}
|
|
92
|
+
return value;
|
|
93
|
+
});
|
|
94
|
+
if (missing) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
return { apiKey, baseURL, source };
|
|
98
|
+
}
|
|
99
|
+
// Oculta una clave para enseñarla en pantalla: sk-ab…wxyz
|
|
100
|
+
export function maskKey(key) {
|
|
101
|
+
if (key === "no-key") {
|
|
102
|
+
return "(sin clave)";
|
|
103
|
+
}
|
|
104
|
+
if (key.length <= 10) {
|
|
105
|
+
return "…";
|
|
106
|
+
}
|
|
107
|
+
return `${key.slice(0, 5)}…${key.slice(-4)}`;
|
|
108
|
+
}
|
package/dist/catalog.js
ADDED
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
import { REPO_URL } from "./meta.js";
|
|
2
|
+
// Catálogo de proveedores con plan gratuito (revisado en octubre de 2026).
|
|
3
|
+
// El orden es la prioridad: el router prueba de arriba abajo y salta al siguiente cuando uno se agota.
|
|
4
|
+
// Los modelos nuevos se añaden solos con "vipcode models --refresh" (o una vez al día al arrancar).
|
|
5
|
+
function m(id, context, extra = {}) {
|
|
6
|
+
return { id, context, ...extra };
|
|
7
|
+
}
|
|
8
|
+
const V = { vision: true };
|
|
9
|
+
export const CATALOG = [
|
|
10
|
+
{
|
|
11
|
+
name: "gemini",
|
|
12
|
+
label: "Google Gemini (AI Studio)",
|
|
13
|
+
baseURL: "https://generativelanguage.googleapis.com/v1beta/openai/",
|
|
14
|
+
apiKeyEnv: ["GEMINI_API_KEY", "GOOGLE_API_KEY", "GOOGLE_GENERATIVE_AI_API_KEY"],
|
|
15
|
+
signup: "https://aistudio.google.com/apikey",
|
|
16
|
+
freeInfo: "Plan gratis para Flash y Flash-Lite (y algo de 2.5 Pro), con límites por minuto y por día en cada modelo.",
|
|
17
|
+
discover: "openai",
|
|
18
|
+
modelFilter: "^(gemini|gemma)-",
|
|
19
|
+
limitScope: "model",
|
|
20
|
+
defaultContext: 250000,
|
|
21
|
+
// El plan gratis limita los tokens por minuto, así que no mandamos más de esto aunque el modelo admita 1M
|
|
22
|
+
contextCap: 250000,
|
|
23
|
+
models: [
|
|
24
|
+
m("gemini-3.8-flash", 250000, V),
|
|
25
|
+
m("gemini-3.7-flash", 250000, V),
|
|
26
|
+
m("gemini-3.6-flash", 250000, V),
|
|
27
|
+
m("gemini-3.5-flash", 250000, V),
|
|
28
|
+
m("gemini-2.5-pro", 250000, V),
|
|
29
|
+
m("gemini-2.5-flash", 250000, V),
|
|
30
|
+
m("gemini-flash-latest", 250000, V),
|
|
31
|
+
m("gemini-3.5-flash-lite", 250000, V),
|
|
32
|
+
m("gemini-3.1-flash-lite", 250000, V),
|
|
33
|
+
m("gemini-flash-lite-latest", 250000, V),
|
|
34
|
+
m("gemini-2.5-flash-lite", 250000, V),
|
|
35
|
+
m("gemma-4-31b-it", 15000, V),
|
|
36
|
+
m("gemma-4-26b-a4b-it", 15000, V),
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: "nvidia",
|
|
41
|
+
label: "NVIDIA NIM (build.nvidia.com)",
|
|
42
|
+
baseURL: "https://integrate.api.nvidia.com/v1",
|
|
43
|
+
apiKeyEnv: "NVIDIA_API_KEY",
|
|
44
|
+
signup: "https://build.nvidia.com/settings/api-keys",
|
|
45
|
+
freeInfo: "Gratis para desarrollo, unas 40 peticiones por minuto para toda la cuenta. No envíes datos confidenciales.",
|
|
46
|
+
discover: "openai",
|
|
47
|
+
pruneMissing: true,
|
|
48
|
+
limitScope: "provider",
|
|
49
|
+
defaultContext: 128000,
|
|
50
|
+
models: [
|
|
51
|
+
m("z-ai/glm-5.3", 1000000),
|
|
52
|
+
m("deepseek-ai/deepseek-v4.1-flash", 1000000, V),
|
|
53
|
+
m("minimaxai/minimax-m3.1-flash", 262144, V),
|
|
54
|
+
m("nvidia/nemotron-3-ultra-550b-a55b", 1000000),
|
|
55
|
+
m("stepfun-ai/step-5-preview", 1048576, V),
|
|
56
|
+
m("z-ai/glm-5.3-flash", 1000000, V),
|
|
57
|
+
m("nvidia/nemotron-3.5-super-vl-120b-a12b", 1048576, V),
|
|
58
|
+
m("google/gemma-4-31b-it", 256000, V),
|
|
59
|
+
m("meta/muse-glimmer-30b", 131072, V),
|
|
60
|
+
m("poolside/laguna-xs-2.1", 262144),
|
|
61
|
+
m("nvidia/nemotron-3.5-lightning-30b-a3b", 262144),
|
|
62
|
+
m("openai/gpt-oss-20b", 131072),
|
|
63
|
+
m("nvidia/nemotron-3-nano-omni-30b-a3b-reasoning", 256000, V),
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "mistral",
|
|
68
|
+
label: "Mistral AI (plan Experiment)",
|
|
69
|
+
baseURL: "https://api.mistral.ai/v1",
|
|
70
|
+
apiKeyEnv: "MISTRAL_API_KEY",
|
|
71
|
+
signup: "https://console.mistral.ai/api-keys",
|
|
72
|
+
freeInfo: "Plan Experiment gratis: ~1 petición por segundo y ~1.000 millones de tokens al mes (a cambio pueden usar tus datos).",
|
|
73
|
+
discover: "openai",
|
|
74
|
+
pruneMissing: true,
|
|
75
|
+
limitScope: "provider",
|
|
76
|
+
defaultContext: 128000,
|
|
77
|
+
models: [
|
|
78
|
+
m("mistral-large-4", 1048576, V),
|
|
79
|
+
m("mistral-medium-latest", 262144, V),
|
|
80
|
+
m("zai-glm-5-3", 1048576),
|
|
81
|
+
m("deepseek-v4-1-flash-1017", 1048576),
|
|
82
|
+
m("mistral-large-latest", 262144, V),
|
|
83
|
+
m("codestral-latest", 256000),
|
|
84
|
+
m("zai-glm-5-3-flash", 1048576, V),
|
|
85
|
+
m("mistral-small-latest", 262144, V),
|
|
86
|
+
m("ministral-14b-2512", 262144, V),
|
|
87
|
+
m("ministral-8b-latest", 262144, V),
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: "cerebras",
|
|
92
|
+
label: "Cerebras",
|
|
93
|
+
baseURL: "https://api.cerebras.ai/v1",
|
|
94
|
+
apiKeyEnv: "CEREBRAS_API_KEY",
|
|
95
|
+
signup: "https://cloud.cerebras.ai",
|
|
96
|
+
freeInfo: "Plan gratis muy rápido: ~30 peticiones por minuto y 14.400 al día por modelo, con contexto limitado (~64k).",
|
|
97
|
+
discover: "openai",
|
|
98
|
+
pruneMissing: true,
|
|
99
|
+
limitScope: "model",
|
|
100
|
+
defaultContext: 60000,
|
|
101
|
+
contextCap: 60000,
|
|
102
|
+
models: [m("gpt-oss-120b", 60000), m("qwen-3.8-27b", 60000, V)],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: "openrouter",
|
|
106
|
+
label: "OpenRouter (modelos :free)",
|
|
107
|
+
baseURL: "https://openrouter.ai/api/v1",
|
|
108
|
+
apiKeyEnv: "OPENROUTER_API_KEY",
|
|
109
|
+
// OpenRouter y Kilo usan estas cabeceras para saber qué aplicación hace las peticiones
|
|
110
|
+
headers: { "HTTP-Referer": REPO_URL, "X-Title": "vipcode" },
|
|
111
|
+
signup: "https://openrouter.ai/settings/keys",
|
|
112
|
+
login: "openrouter",
|
|
113
|
+
freeInfo: "Modelos :free: 20 peticiones por minuto y 50 al día en total (1.000 al día si has comprado 10 $ de créditos alguna vez).",
|
|
114
|
+
discover: "openrouter",
|
|
115
|
+
freeOnly: true,
|
|
116
|
+
pruneMissing: true,
|
|
117
|
+
limitScope: "provider",
|
|
118
|
+
defaultContext: 128000,
|
|
119
|
+
models: [
|
|
120
|
+
m("nvidia/nemotron-3-ultra-550b-a55b:free", 1000000),
|
|
121
|
+
m("thinkingmachines/inkling:free", 1048576, V),
|
|
122
|
+
m("poolside/laguna-s-2.1:free", 262144),
|
|
123
|
+
m("google/gemma-4-31b-it:free", 262144, V),
|
|
124
|
+
m("nvidia/nemotron-3.5-super-vl:free", 1000000, V),
|
|
125
|
+
m("cohere/north-mini-code:free", 256000),
|
|
126
|
+
m("dots-studio/dots-3-note-preview:free", 512000, V),
|
|
127
|
+
m("thinkingmachines/inkling-small:free", 1048576, V),
|
|
128
|
+
m("xingchen-agi/xing4.0-29b-a4b:free", 262144),
|
|
129
|
+
m("recursive/flint-v1.0:free", 262144),
|
|
130
|
+
m("poolside/laguna-xs-2.1:free", 262144),
|
|
131
|
+
m("nvidia/nemotron-3.5-lightning:free", 1000000),
|
|
132
|
+
m("google/gemma-4-26b-a4b-it:free", 262144, V),
|
|
133
|
+
m("nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free", 256000, V),
|
|
134
|
+
m("openrouter/free", 200000, V),
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: "groq",
|
|
139
|
+
label: "Groq",
|
|
140
|
+
baseURL: "https://api.groq.com/openai/v1",
|
|
141
|
+
apiKeyEnv: "GROQ_API_KEY",
|
|
142
|
+
signup: "https://console.groq.com/keys",
|
|
143
|
+
freeInfo: "Plan gratis rapidísimo: ~30 peticiones por minuto y 1.000 al día por modelo, pero pocos tokens por minuto (solo vale para peticiones cortas).",
|
|
144
|
+
discover: "openai",
|
|
145
|
+
pruneMissing: true,
|
|
146
|
+
limitScope: "model",
|
|
147
|
+
defaultContext: 7000,
|
|
148
|
+
// El plan gratis de Groq limita los tokens por minuto, así que solo vale para conversaciones cortas
|
|
149
|
+
contextCap: 11000,
|
|
150
|
+
models: [
|
|
151
|
+
m("openai/gpt-oss-120b", 7000),
|
|
152
|
+
m("qwen/qwen3.8-27b", 5500, V),
|
|
153
|
+
m("openai/gpt-oss-20b", 7000),
|
|
154
|
+
m("llama-3.3-70b-versatile", 11000),
|
|
155
|
+
],
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: "zai",
|
|
159
|
+
label: "Z.ai (GLM Flash gratis)",
|
|
160
|
+
baseURL: "https://api.z.ai/api/paas/v4",
|
|
161
|
+
apiKeyEnv: ["ZAI_API_KEY", "ZHIPU_API_KEY"],
|
|
162
|
+
signup: "https://z.ai/manage-apikey/apikey-list",
|
|
163
|
+
freeInfo: "GLM-4.7-Flash, GLM-4.6V-Flash y GLM-4.5-Flash son gratis.",
|
|
164
|
+
limitScope: "model",
|
|
165
|
+
models: [m("glm-4.7-flash", 200000), m("glm-4.6v-flash", 128000, V), m("glm-4.5-flash", 131072)],
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: "zhipu",
|
|
169
|
+
label: "Zhipu BigModel (China)",
|
|
170
|
+
baseURL: "https://open.bigmodel.cn/api/paas/v4",
|
|
171
|
+
apiKeyEnv: "ZHIPU_API_KEY",
|
|
172
|
+
signup: "https://open.bigmodel.cn/usercenter/apikeys",
|
|
173
|
+
freeInfo: "Los mismos GLM Flash gratis, desde la plataforma china.",
|
|
174
|
+
limitScope: "model",
|
|
175
|
+
models: [m("glm-4.7-flash", 200000), m("glm-4.6v-flash", 128000, V), m("glm-4.5-flash", 131072)],
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: "poolside",
|
|
179
|
+
label: "Poolside",
|
|
180
|
+
baseURL: "https://inference.poolside.ai/v1",
|
|
181
|
+
apiKeyEnv: "POOLSIDE_API_KEY",
|
|
182
|
+
signup: "https://platform.poolside.ai",
|
|
183
|
+
freeInfo: "Modelos Laguna (especializados en código) gratis.",
|
|
184
|
+
limitScope: "model",
|
|
185
|
+
models: [m("poolside/laguna-s-2.1", 1048576), m("poolside/laguna-m.1", 262144), m("poolside/laguna-xs-2.1", 262144)],
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
name: "reflection",
|
|
189
|
+
label: "Reflection AI",
|
|
190
|
+
baseURL: "https://api.reflection.ai/openai/v1",
|
|
191
|
+
apiKeyEnv: "REFLECTION_API_KEY",
|
|
192
|
+
signup: "https://developers.reflection.ai",
|
|
193
|
+
freeInfo: "Beam 1.0 gratis (guardan los datos 30 días por seguridad).",
|
|
194
|
+
limitScope: "model",
|
|
195
|
+
models: [m("Beam-1.0-501B-A23B", 1048576)],
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
name: "nova",
|
|
199
|
+
label: "Amazon Nova",
|
|
200
|
+
baseURL: "https://api.nova.amazon.com/v1",
|
|
201
|
+
apiKeyEnv: "NOVA_API_KEY",
|
|
202
|
+
signup: "https://nova.amazon.com/dev",
|
|
203
|
+
freeInfo: "Nova 2 Pro y Nova 2 Lite gratis en la API para desarrolladores.",
|
|
204
|
+
limitScope: "model",
|
|
205
|
+
models: [m("nova-2-pro-v1", 1000000, V), m("nova-2-lite-v1", 1000000, V)],
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
name: "cohere",
|
|
209
|
+
label: "Cohere (clave de prueba)",
|
|
210
|
+
baseURL: "https://api.cohere.ai/compatibility/v1",
|
|
211
|
+
apiKeyEnv: "COHERE_API_KEY",
|
|
212
|
+
signup: "https://dashboard.cohere.com/api-keys",
|
|
213
|
+
freeInfo: "Clave de prueba gratis: 1.000 llamadas al mes y 20 por minuto, solo para uso no comercial.",
|
|
214
|
+
limitScope: "provider",
|
|
215
|
+
models: [
|
|
216
|
+
m("north-mini-code-1-0", 256000),
|
|
217
|
+
m("command-a-plus-05-2026", 128000, V),
|
|
218
|
+
m("command-a-reasoning-08-2025", 256000),
|
|
219
|
+
m("command-a-03-2025", 256000),
|
|
220
|
+
],
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
name: "sambanova",
|
|
224
|
+
label: "SambaNova Cloud",
|
|
225
|
+
baseURL: "https://api.sambanova.ai/v1",
|
|
226
|
+
apiKeyEnv: "SAMBANOVA_API_KEY",
|
|
227
|
+
signup: "https://cloud.sambanova.ai/apis",
|
|
228
|
+
freeInfo: "Plan gratis con un límite diario de tokens por modelo.",
|
|
229
|
+
discover: "openai",
|
|
230
|
+
limitScope: "model",
|
|
231
|
+
defaultContext: 32768,
|
|
232
|
+
contextCap: 131072,
|
|
233
|
+
models: [
|
|
234
|
+
m("MiniMax-M3", 131072),
|
|
235
|
+
m("gpt-oss-120b", 131072),
|
|
236
|
+
m("DeepSeek-V3.1", 131072),
|
|
237
|
+
m("gemma-4-31B-it", 131072, V),
|
|
238
|
+
m("Meta-Llama-3.3-70B-Instruct", 131072),
|
|
239
|
+
m("DeepSeek-V3.2", 32768),
|
|
240
|
+
],
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: "hetzner",
|
|
244
|
+
label: "Hetzner Inference (beta)",
|
|
245
|
+
baseURL: "https://inference.hetzner.com/api/v1",
|
|
246
|
+
apiKeyEnv: "HETZNER_API_KEY",
|
|
247
|
+
signup: "https://experiments.hetzner.com",
|
|
248
|
+
freeInfo: "Beta gratuita con modelos Qwen.",
|
|
249
|
+
limitScope: "model",
|
|
250
|
+
models: [m("Qwen3.8-27B", 262144, V), m("Qwen/Qwen3.6-35B-A3B-FP8", 262144, V)],
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
name: "vercel",
|
|
254
|
+
label: "Vercel AI Gateway",
|
|
255
|
+
baseURL: "https://ai-gateway.vercel.sh/v1",
|
|
256
|
+
apiKeyEnv: ["AI_GATEWAY_API_KEY", "VERCEL_AI_GATEWAY_API_KEY"],
|
|
257
|
+
signup: "https://vercel.com/ai-gateway",
|
|
258
|
+
freeInfo: "5 $ de crédito gratis al mes; los modelos -free no lo gastan.",
|
|
259
|
+
limitScope: "provider",
|
|
260
|
+
models: [
|
|
261
|
+
m("reflection/beam-free", 1048576),
|
|
262
|
+
m("poolside/laguna-s-2.1-free", 256000),
|
|
263
|
+
m("nvidia/nemotron-3.5-lightning-free", 1000000),
|
|
264
|
+
m("stealth/glyph-cluster", 256000),
|
|
265
|
+
],
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: "cloudflare",
|
|
269
|
+
label: "Cloudflare Workers AI",
|
|
270
|
+
baseURL: "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/ai/v1",
|
|
271
|
+
apiKeyEnv: ["CLOUDFLARE_API_KEY", "CLOUDFLARE_API_TOKEN"],
|
|
272
|
+
requiredVars: ["CLOUDFLARE_ACCOUNT_ID"],
|
|
273
|
+
signup: "https://dash.cloudflare.com/profile/api-tokens",
|
|
274
|
+
freeInfo: "10.000 «neuronas» gratis al día (los modelos grandes gastan más). Necesita también CLOUDFLARE_ACCOUNT_ID.",
|
|
275
|
+
limitScope: "provider",
|
|
276
|
+
models: [
|
|
277
|
+
m("@cf/zai-org/glm-5.3-flash", 131072, V),
|
|
278
|
+
m("@cf/moonshotai/kimi-k2.7-code", 262144, V),
|
|
279
|
+
m("@cf/openai/gpt-oss-120b", 128000),
|
|
280
|
+
m("@cf/qwen/qwen3.8-27b", 262144, V),
|
|
281
|
+
m("@cf/deepseek-ai/deepseek-v4.1-flash-1017", 131072, V),
|
|
282
|
+
m("@cf/google/gemma-4-26b-a4b-it", 256000, V),
|
|
283
|
+
m("@cf/nvidia/nemotron-3-120b-a12b", 256000),
|
|
284
|
+
m("@cf/meta/llama-4-scout-17b-16e-instruct", 131000, V),
|
|
285
|
+
m("@cf/mistralai/mistral-small-3.1-24b-instruct", 128000, V),
|
|
286
|
+
m("@cf/zai-org/glm-4.7-flash", 131072),
|
|
287
|
+
],
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
name: "huggingface",
|
|
291
|
+
label: "Hugging Face Inference Providers",
|
|
292
|
+
baseURL: "https://router.huggingface.co/v1",
|
|
293
|
+
apiKeyEnv: ["HF_TOKEN", "HUGGINGFACE_API_KEY"],
|
|
294
|
+
signup: "https://huggingface.co/settings/tokens",
|
|
295
|
+
freeInfo: "0,10 $ de crédito gratis al mes; GLM-4.7-Flash no gasta.",
|
|
296
|
+
limitScope: "provider",
|
|
297
|
+
models: [
|
|
298
|
+
m("zai-org/GLM-4.7-Flash", 200000),
|
|
299
|
+
m("openai/gpt-oss-120b", 131072),
|
|
300
|
+
m("Qwen/Qwen3-Coder-30B-A3B-Instruct", 262144),
|
|
301
|
+
m("deepseek-ai/DeepSeek-V4-Flash", 262144),
|
|
302
|
+
],
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
name: "modelscope",
|
|
306
|
+
label: "ModelScope (China)",
|
|
307
|
+
baseURL: "https://api-inference.modelscope.cn/v1",
|
|
308
|
+
apiKeyEnv: "MODELSCOPE_API_KEY",
|
|
309
|
+
signup: "https://modelscope.cn/my/myaccesstoken",
|
|
310
|
+
freeInfo: "2.000 llamadas gratis al día (hay que vincular una cuenta de Alibaba Cloud).",
|
|
311
|
+
limitScope: "provider",
|
|
312
|
+
models: [
|
|
313
|
+
m("Qwen/Qwen3-Coder-30B-A3B-Instruct", 262144),
|
|
314
|
+
m("Qwen/Qwen3-235B-A22B-Instruct-2507", 262144),
|
|
315
|
+
m("ZhipuAI/GLM-4.6", 202752),
|
|
316
|
+
m("ZhipuAI/GLM-4.5", 131072),
|
|
317
|
+
m("Qwen/Qwen3-30B-A3B-Instruct-2507", 262144),
|
|
318
|
+
],
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
name: "ollama-cloud",
|
|
322
|
+
label: "Ollama Cloud",
|
|
323
|
+
baseURL: "https://ollama.com/v1",
|
|
324
|
+
apiKeyEnv: "OLLAMA_API_KEY",
|
|
325
|
+
signup: "https://ollama.com/settings/keys",
|
|
326
|
+
freeInfo: "Plan gratis con límites por hora y por semana.",
|
|
327
|
+
discover: "openai",
|
|
328
|
+
limitScope: "provider",
|
|
329
|
+
defaultContext: 131072,
|
|
330
|
+
models: [
|
|
331
|
+
m("glm-5.3", 1048576),
|
|
332
|
+
m("deepseek-v4.1-flash", 1048576, V),
|
|
333
|
+
m("kimi-k2.7-code", 262144, V),
|
|
334
|
+
m("minimax-m3.1-flash", 1000000, V),
|
|
335
|
+
m("nemotron-3-ultra", 262144),
|
|
336
|
+
m("mistral-large-4", 1048576, V),
|
|
337
|
+
m("gpt-oss:120b", 131072),
|
|
338
|
+
m("gemma4:31b", 262144, V),
|
|
339
|
+
m("gpt-oss:20b", 131072),
|
|
340
|
+
],
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
name: "unorouter",
|
|
344
|
+
label: "UnoRouter (modelos :free)",
|
|
345
|
+
baseURL: "https://api.unorouter.com/v1",
|
|
346
|
+
apiKeyEnv: "UNOROUTER_API_KEY",
|
|
347
|
+
signup: "https://unorouter.com/en/token",
|
|
348
|
+
freeInfo: "Modelos :free gratis, pero solo ~1 petición por minuto en cada uno.",
|
|
349
|
+
discover: "openai",
|
|
350
|
+
freeOnly: true,
|
|
351
|
+
limitScope: "model",
|
|
352
|
+
defaultContext: 131072,
|
|
353
|
+
models: [
|
|
354
|
+
m("nemotron-3-ultra-550b-a55b:free", 1000000),
|
|
355
|
+
m("gemma-4-31b-it:free", 262144, V),
|
|
356
|
+
m("minimax-m2.7:free", 204800),
|
|
357
|
+
m("glm-4.5-flash:free", 131072),
|
|
358
|
+
],
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
name: "kilo",
|
|
362
|
+
label: "Kilo Gateway (sin clave)",
|
|
363
|
+
baseURL: "https://api.kilo.ai/api/gateway",
|
|
364
|
+
headers: { "HTTP-Referer": REPO_URL, "X-Title": "vipcode" },
|
|
365
|
+
apiKeyEnv: "KILO_API_KEY",
|
|
366
|
+
// Kilo permite usar sus modelos gratis sin cuenta (200 peticiones por hora por IP)
|
|
367
|
+
noKey: true,
|
|
368
|
+
signup: "https://app.kilo.ai",
|
|
369
|
+
freeInfo: "Funciona sin clave: 200 peticiones por hora por IP en sus modelos gratis. Pueden guardar lo que envías.",
|
|
370
|
+
discover: "kilo",
|
|
371
|
+
freeOnly: true,
|
|
372
|
+
pruneMissing: true,
|
|
373
|
+
limitScope: "provider",
|
|
374
|
+
defaultContext: 128000,
|
|
375
|
+
// Primero modelos concretos y buenos con herramientas; kilo-auto/free elige uno al azar (a veces flojo)
|
|
376
|
+
models: [
|
|
377
|
+
m("nvidia/nemotron-3-ultra-550b-a55b:free", 1000000),
|
|
378
|
+
m("reflection/beam-free", 1048576),
|
|
379
|
+
m("poolside/laguna-s-2.1:free", 262144),
|
|
380
|
+
m("cohere/north-mini-code:free", 256000),
|
|
381
|
+
m("nvidia/nemotron-3.5-super-vl:free", 1000000, V),
|
|
382
|
+
m("kilo-auto/free", 256000),
|
|
383
|
+
m("stealth/glyph-cluster", 256000),
|
|
384
|
+
m("recursive/flint-v1.0:free", 262144),
|
|
385
|
+
m("dots-studio/dots-3-note-preview:free", 512000, V),
|
|
386
|
+
m("xingchen-agi/xing4.0-29b-a4b:free", 262144),
|
|
387
|
+
],
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
name: "ovhcloud",
|
|
391
|
+
label: "OVHcloud AI Endpoints (sin clave)",
|
|
392
|
+
baseURL: "https://oai.endpoints.kepler.ai.cloud.ovh.net/v1",
|
|
393
|
+
apiKeyEnv: "OVHCLOUD_API_KEY",
|
|
394
|
+
// Acceso anónimo oficial: 2 peticiones por minuto por IP en cada modelo (400 con clave)
|
|
395
|
+
noKey: true,
|
|
396
|
+
signup: "https://www.ovhcloud.com/es-es/public-cloud/ai-endpoints/",
|
|
397
|
+
freeInfo: "Funciona sin clave, pero solo 2 peticiones por minuto en cada modelo (con clave, 400).",
|
|
398
|
+
discover: "openai",
|
|
399
|
+
limitScope: "model",
|
|
400
|
+
defaultContext: 131072,
|
|
401
|
+
models: [
|
|
402
|
+
m("gpt-oss-120b", 131072),
|
|
403
|
+
m("Qwen3.5-397B-A17B", 262144, V),
|
|
404
|
+
m("Qwen3.8-27B", 262144, V),
|
|
405
|
+
m("Qwen3.6-27B", 262144, V),
|
|
406
|
+
m("Meta-Llama-3_3-70B-Instruct", 131072),
|
|
407
|
+
m("Mistral-Small-3.2-24B-Instruct-2506", 131072, V),
|
|
408
|
+
m("gpt-oss-20b", 131072),
|
|
409
|
+
m("Qwen3.5-9B", 262144, V),
|
|
410
|
+
],
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
name: "llm7",
|
|
414
|
+
label: "LLM7.io (sin clave)",
|
|
415
|
+
baseURL: "https://api.llm7.io/v1",
|
|
416
|
+
apiKeyEnv: "LLM7_API_KEY",
|
|
417
|
+
noKey: true,
|
|
418
|
+
signup: "https://token.llm7.io",
|
|
419
|
+
freeInfo: "Funciona sin registrarse (unas 60 peticiones por hora; más con un token gratis). Pueden guardar lo que envías.",
|
|
420
|
+
// Sus modelos gratis cambian a menudo: se descubren solos y se quitan los que ya no están
|
|
421
|
+
discover: "llm7",
|
|
422
|
+
freeOnly: true,
|
|
423
|
+
pruneMissing: true,
|
|
424
|
+
limitScope: "provider",
|
|
425
|
+
defaultContext: 128000,
|
|
426
|
+
models: [
|
|
427
|
+
m("minimax-m2.7", 180000),
|
|
428
|
+
m("codestral-latest", 32000),
|
|
429
|
+
m("nemotron-3-nano:30b", 1000000),
|
|
430
|
+
m("gpt-oss:20b", 128000),
|
|
431
|
+
],
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
name: "pollinations",
|
|
435
|
+
label: "Pollinations (sin clave)",
|
|
436
|
+
baseURL: "https://text.pollinations.ai/openai",
|
|
437
|
+
apiKeyEnv: "POLLINATIONS_API_KEY",
|
|
438
|
+
noKey: true,
|
|
439
|
+
signup: "https://auth.pollinations.ai",
|
|
440
|
+
freeInfo: "Funciona sin registrarse con GPT-OSS 20B, con límite por hora y por IP. Pueden guardar lo que envías.",
|
|
441
|
+
limitScope: "provider",
|
|
442
|
+
models: [m("openai-fast", 131072)],
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
name: "ollama",
|
|
446
|
+
label: "Ollama (local)",
|
|
447
|
+
baseURL: "http://localhost:11434/v1",
|
|
448
|
+
noKey: true,
|
|
449
|
+
local: true,
|
|
450
|
+
signup: "https://ollama.com/download",
|
|
451
|
+
freeInfo: "Modelos en tu ordenador, sin límites ni internet. Sube el contexto con OLLAMA_CONTEXT_LENGTH=32768.",
|
|
452
|
+
discover: "openai",
|
|
453
|
+
defaultContext: 16000,
|
|
454
|
+
models: [],
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
name: "lmstudio",
|
|
458
|
+
label: "LM Studio (local)",
|
|
459
|
+
baseURL: "http://127.0.0.1:1234/v1",
|
|
460
|
+
noKey: true,
|
|
461
|
+
local: true,
|
|
462
|
+
signup: "https://lmstudio.ai",
|
|
463
|
+
freeInfo: "Modelos en tu ordenador servidos por LM Studio.",
|
|
464
|
+
discover: "openai",
|
|
465
|
+
defaultContext: 16000,
|
|
466
|
+
models: [],
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
name: "llamacpp",
|
|
470
|
+
label: "llama.cpp server (local)",
|
|
471
|
+
baseURL: "http://127.0.0.1:8080/v1",
|
|
472
|
+
noKey: true,
|
|
473
|
+
local: true,
|
|
474
|
+
signup: "https://github.com/ggml-org/llama.cpp",
|
|
475
|
+
freeInfo: "Modelos en tu ordenador servidos por llama-server.",
|
|
476
|
+
discover: "openai",
|
|
477
|
+
defaultContext: 16000,
|
|
478
|
+
models: [],
|
|
479
|
+
},
|
|
480
|
+
];
|
|
481
|
+
// Proveedores que ya no existen: si aparecen en un config antiguo se ignoran
|
|
482
|
+
export const RETIRED_PROVIDERS = {
|
|
483
|
+
github: "GitHub Models cerró el 30 de julio de 2026",
|
|
484
|
+
};
|
|
485
|
+
export function catalogProvider(name) {
|
|
486
|
+
return CATALOG.find((provider) => provider.name === name);
|
|
487
|
+
}
|