{"repo": "alcafer2011/antigravity", "files": {"src/providerCatalog.js": {"b004d67566fd93489bf4cb3fbc1b4d93bfed8e95": {"t": 1785768876.9269176, "n": 32790, "h": "d1a42bf1831b3598", "c": "\"use strict\";\n\n/**\n * providerCatalog — CATALOGO PRECONFIGURATO di TUTTI i provider LLM noti\n * (OpenAI-compatibili) + delle piattaforme GPU dove ospitare i modelli tuoi.\n *\n * ★ 2026-07-30 — PERCHÉ ESISTE QUESTO FILE\n * Il cacciatore di taglie proponeva provider (letti dalle liste online) che NON\n * erano nel registro: creavi la chiave, la incollavi e il rilevamento diceva\n * \"provider non riconosciuto\", oppure il selettore manuale conteneva solo i 25\n * provider scritti a mano in providerRegistry.js. Qui c'è la lista LARGA, già\n * pronta con endpoint, nome della variabile .env, formato della chiave e alias\n * (i nomi con cui le liste online li chiamano), così:\n * 1) incolli la chiave → il provider si riconosce da solo (detect);\n * 2) se non si riconosce → il selettore manuale contiene TUTTI questi provider;\n * 3) il cacciatore, quando trova \"Nebius\"/\"Cohere\"/\"Scaleway\"/..., riesce ad\n * agganciarli a una voce vera (knownId) e mostra il bottone \"Incolla qui\".\n *\n * providerRegistry.js FONDE questo catalogo con le sue voci curate: le voci\n * curate VINCONO (hanno note/quote tarate a mano), da qui arriva tutto il resto.\n *\n * Campi (stessi di providerRegistry, più questi):\n * aliases[] nomi alternativi (come li scrivono le liste online / il cacciatore)\n * verified true = endpoint controllato · false = plausibile ma da confermare\n * col bottone \"Verifica\" del pannello chiavi. Le voci non verificate\n * restano selezionabili: al massimo il probe risponde 404 e lo vedi.\n * strong true = il prefisso della chiave è UNICO → riconoscimento diretto\n * freeModels[] modelli gratuiti noti (per la scheda del cacciatore)\n *\n * REGOLA: qui NON vanno chiavi/segreti. Solo endpoint pubblici e link ufficiali.\n */\n\nconst NV = \"⚠️ endpoint da confermare col bottone «Verifica» dopo aver salvato la chiave.\";\n\nconst CATALOG = [\n // ================= GRANDI CLOUD / OPENAI-COMPAT =========================\n {\n id: \"nebius\", label: \"Nebius AI Studio\", env: \"NEBIUS_API_KEY\",\n host: \"api.studio.nebius.com\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^eyJ[A-Za-z0-9_-]+\\./, strong: false,\n keyFmt: \"JWT (inizia con eyJ...)\", signup: \"https://studio.nebius.com/settings/api-keys\",\n free: true, billed: true, verified: true,\n aliases: [\"nebius\", \"nebius ai studio\", \"nebius token factory\"],\n freeModels: [\"meta-llama/Llama-3.3-70B-Instruct\", \"Qwen/Qwen2.5-Coder-32B-Instruct\", \"deepseek-ai/DeepSeek-V3\"],\n note: \"Catalogo open grosso (llama, qwen-coder, deepseek) con credito iniziale gratuito. Chiave JWT come Hyperbolic: se il rilevamento propone entrambi, scegli tu.\"\n },\n {\n id: \"moonshot\", label: \"Moonshot AI (Kimi)\", env: \"MOONSHOT_API_KEY\",\n host: \"api.moonshot.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^sk-/, keyFmt: \"Inizia con sk- (es. sk-xxxx)\",\n signup: \"https://platform.moonshot.ai/console/api-keys\",\n free: false, billed: true, verified: true,\n aliases: [\"moonshot\", \"moonshot ai\", \"kimi\", \"kimi k2\", \"moonshotai\"],\n freeModels: [],\n note: \"Kimi K2 (contesto enorme, forte nel coding agentico). A consumo, prezzi bassi.\"\n },\n {\n id: \"zai\", label: \"Z.ai (GLM / Zhipu)\", env: \"ZAI_API_KEY\",\n host: \"api.z.ai\", chatPath: \"/api/paas/v4/chat/completions\", modelsPath: null,\n detect: /^[0-9a-f]{32}\\.[A-Za-z0-9]{10,}$/, keyFmt: \"Forma id.segreto (32 esadecimali + punto + segreto)\",\n signup: \"https://z.ai/manage-apikey/apikey-list\",\n free: true, billed: true, verified: true,\n aliases: [\"z ai\", \"zai\", \"zhipu\", \"zhipu ai\", \"glm\", \"bigmodel\"],\n freeModels: [\"glm-4.5-flash\", \"glm-4.6-flash\"],\n note: \"GLM (glm-4.x/5): i modelli *-flash hanno un piano gratuito. Chiave in forma id.segreto come Ollama Cloud: se il rilevamento è incerto, scegli tu.\"\n },\n {\n id: \"bigmodel\", label: \"Zhipu BigModel (Cina)\", env: \"BIGMODEL_API_KEY\",\n host: \"open.bigmodel.cn\", chatPath: \"/api/paas/v4/chat/completions\", modelsPath: null,\n detect: /^[0-9a-f]{32}\\.[A-Za-z0-9]{10,}$/, keyFmt: \"Forma id.segreto (come Z.ai)\",\n signup: \"https://open.bigmodel.cn/usercenter/apikeys\",\n free: true, billed: true, verified: true,\n aliases: [\"bigmodel\", \"open bigmodel\", \"zhipu bigmodel\", \"chatglm\"],\n freeModels: [\"glm-4-flash\", \"glm-4.5-flash\"],\n note: \"Portale cinese di Zhipu: glm-4-flash gratis. Stesso endpoint di Z.ai ma dominio .cn (più lento dall'Italia).\"\n },\n {\n id: \"minimax\", label: \"MiniMax\", env: \"MINIMAX_API_KEY\",\n host: \"api.minimax.io\", chatPath: \"/v1/text/chatcompletion_v2\", modelsPath: null,\n detect: /^eyJ[A-Za-z0-9_-]+\\./, keyFmt: \"JWT (inizia con eyJ...)\",\n signup: \"https://www.minimax.io/platform/user-center/basic-information/interface-key\",\n free: false, billed: true, verified: false,\n aliases: [\"minimax\", \"minimax m2\", \"minimaxi\"],\n freeModels: [],\n note: \"MiniMax M2 (coding/agent, contesto grande). Endpoint OpenAI-compat su /v1/text/chatcompletion_v2. \" + NV\n },\n {\n id: \"siliconflow\", label: \"SiliconFlow\", env: \"SILICONFLOW_API_KEY\",\n host: \"api.siliconflow.com\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^sk-/, keyFmt: \"Inizia con sk- (es. sk-xxxx)\",\n signup: \"https://cloud.siliconflow.com/account/ak\",\n free: true, billed: true, verified: true,\n aliases: [\"siliconflow\", \"silicon flow\", \"siliconcloud\"],\n freeModels: [\"Qwen/Qwen2.5-7B-Instruct\", \"THUDM/glm-4-9b-chat\", \"deepseek-ai/DeepSeek-R1-Distill-Qwen-7B\"],\n note: \"Gateway cinese con molti modelli open; alcuni piccoli sono gratis a vita, gli altri a consumo economico.\"\n },\n {\n id: \"hunyuan\", label: \"Tencent Hunyuan\", env: \"HUNYUAN_API_KEY\",\n host: \"api.hunyuan.cloud.tencent.com\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^sk-/, keyFmt: \"Inizia con sk- (es. sk-xxxx)\",\n signup: \"https://console.cloud.tencent.com/hunyuan/api-key\",\n free: true, billed: true, verified: false,\n aliases: [\"hunyuan\", \"tencent\", \"tencent hunyuan\", \"tencent cloud\"],\n freeModels: [\"hunyuan-lite\"],\n note: \"hunyuan-lite è gratuito; i modelli grossi a consumo. \" + NV\n },\n {\n id: \"stepfun\", label: \"StepFun\", env: \"STEPFUN_API_KEY\",\n host: \"api.stepfun.com\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: null, keyFmt: \"Chiave alfanumerica lunga (senza prefisso fisso)\",\n signup: \"https://platform.stepfun.com/interface-key\",\n free: false, billed: true, verified: false,\n aliases: [\"stepfun\", \"step fun\", \"step-3\", \"step 3.5\"],\n freeModels: [],\n note: \"Modelli step-* (gli stessi :free che passano da Kilo). \" + NV\n },\n {\n id: \"qianfan\", label: \"Baidu Qianfan (ERNIE)\", env: \"QIANFAN_API_KEY\",\n host: \"qianfan.baidubce.com\", chatPath: \"/v2/chat/completions\", modelsPath: null,\n detect: /^bce-v3\\//, strong: true, keyFmt: \"Inizia con bce-v3/ (es. bce-v3/ALTAK-...)\",\n signup: \"https://console.bce.baidu.com/iam/#/iam/apikey/list\",\n free: true, billed: true, verified: false,\n aliases: [\"qianfan\", \"baidu\", \"baidu qianfan\", \"ernie\", \"wenxin\"],\n freeModels: [\"ernie-speed-128k\", \"ernie-lite-8k\"],\n note: \"ERNIE: le versioni speed/lite sono gratuite. \" + NV\n },\n {\n id: \"modelscope\", label: \"ModelScope (Alibaba, free)\", env: \"MODELSCOPE_API_KEY\",\n host: \"api-inference.modelscope.cn\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^ms-[0-9a-fA-F-]{20,}$/, strong: true, keyFmt: \"Inizia con ms- (es. ms-xxxxxxxx-....)\",\n signup: \"https://modelscope.cn/my/myaccesstoken\",\n free: true, billed: false, verified: true,\n aliases: [\"modelscope\", \"model scope\", \"modelscope inference\"],\n freeModels: [\"Qwen/Qwen3-Coder-480B-A35B-Instruct\", \"deepseek-ai/DeepSeek-V3\", \"Qwen/QwQ-32B\"],\n note: \"GRATIS ~2000 chiamate/giorno su modelli GROSSI (qwen3-coder-480b, deepseek). Serve solo un account ModelScope (Alibaba), niente carta.\"\n },\n {\n id: \"ppinfra\", label: \"PPIO / PPInfra (Novita Cina)\", env: \"PPINFRA_API_KEY\",\n host: \"api.ppinfra.com\", chatPath: \"/v3/openai/chat/completions\", modelsPath: \"/v3/openai/models\",\n detect: /^sk_/, keyFmt: \"Inizia con sk_ (come Novita)\",\n signup: \"https://ppinfra.com/settings/key-management\",\n free: true, billed: true, verified: false,\n aliases: [\"ppinfra\", \"ppio\", \"pp infra\"],\n freeModels: [],\n note: \"Gemello cinese di Novita (stessa API /v3/openai). Credito di benvenuto. \" + NV\n },\n\n // ================= GATEWAY / AGGREGATORI ================================\n {\n id: \"vercel\", label: \"Vercel AI Gateway\", env: \"VERCEL_AI_API_KEY\",\n host: \"ai-gateway.vercel.sh\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^vck_/, strong: true, keyFmt: \"Inizia con vck_ (es. vck_xxxx)\",\n signup: \"https://vercel.com/docs/ai-gateway\",\n free: true, billed: true, verified: true,\n aliases: [\"vercel\", \"vercel ai gateway\", \"ai gateway\"],\n freeModels: [\"(router a molti provider — credito mensile incluso nel piano Hobby)\"],\n note: \"Aggregatore: una chiave sola, tutti i provider dietro. Credito gratuito mensile col piano Hobby.\"\n },\n {\n id: \"requesty\", label: \"Requesty (router)\", env: \"REQUESTY_API_KEY\",\n host: \"router.requesty.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: null, keyFmt: \"Chiave alfanumerica lunga (senza prefisso fisso)\",\n signup: \"https://app.requesty.ai/api-keys\",\n free: true, billed: true, verified: false,\n aliases: [\"requesty\", \"requesty router\", \"requesty ai\"],\n freeModels: [],\n note: \"Router tipo OpenRouter con credito di prova. \" + NV\n },\n {\n id: \"aimlapi\", label: \"AI/ML API\", env: \"AIMLAPI_API_KEY\",\n host: \"api.aimlapi.com\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^[0-9a-fA-F]{32,80}$/, keyFmt: \"chiave esadecimale (32–80 caratteri)\",\n signup: \"https://aimlapi.com/app/keys\",\n free: true, billed: true, verified: false,\n aliases: [\"aimlapi\", \"ai ml api\", \"ai/ml api\"],\n freeModels: [\"(200+ modelli, piccolo credito free all'iscrizione)\"],\n note: \"Aggregatore con 200+ modelli e un piccolo credito gratuito. \" + NV\n },\n {\n id: \"aihubmix\", label: \"AiHubMix\", env: \"AIHUBMIX_API_KEY\",\n host: \"aihubmix.com\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^sk-/, keyFmt: \"Inizia con sk-\",\n signup: \"https://aihubmix.com/token\",\n free: false, billed: true, verified: false,\n aliases: [\"aihubmix\", \"ai hub mix\"],\n freeModels: [],\n note: \"Aggregatore (anche modelli cinesi) OpenAI-compat. \" + NV\n },\n {\n id: \"api302\", label: \"302.AI\", env: \"API302_API_KEY\",\n host: \"api.302.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^sk-/, keyFmt: \"Inizia con sk-\",\n signup: \"https://dash.302.ai/apis/list\",\n free: false, billed: true, verified: false,\n aliases: [\"302 ai\", \"302ai\", \"302.ai\"],\n freeModels: [],\n note: \"Aggregatore a consumo, credito di prova all'iscrizione. \" + NV\n },\n\n // ================= PROVIDER CON PIANO FREE / TRIAL ======================\n {\n id: \"cohere\", label: \"Cohere (trial gratis)\", env: \"COHERE_API_KEY\",\n host: \"api.cohere.ai\", chatPath: \"/compatibility/v1/chat/completions\", modelsPath: \"/compatibility/v1/models\",\n detect: /^[A-Za-z0-9]{40}$/, keyFmt: \"40 caratteri alfanumerici\",\n signup: \"https://dashboard.cohere.com/api-keys\",\n free: true, billed: false, verified: true,\n aliases: [\"cohere\", \"command a\", \"command r\", \"command r+\"],\n freeModels: [\"command-a-03-2025\", \"command-r-plus-08-2024\", \"command-r7b-12-2024\"],\n note: \"Chiave 'Trial' gratuita: 1000 chiamate/mese, nessuna carta. ★ Ora punta all'endpoint OpenAI-compat /compatibility/v1, quindi può entrare nel failover (prima era escluso).\"\n },\n {\n id: \"codestral\", label: \"Mistral Codestral (chiave free dedicata)\", env: \"CODESTRAL_API_KEY\",\n host: \"codestral.mistral.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^[A-Za-z0-9]{32}$/, keyFmt: \"32 caratteri alfanumerici (come Mistral)\",\n signup: \"https://console.mistral.ai/codestral\",\n free: true, billed: false, verified: true,\n aliases: [\"codestral\", \"mistral codestral\", \"codestral api\"],\n freeModels: [\"codestral-latest\", \"codestral-2501\"],\n note: \"Chiave Codestral SEPARATA e gratuita (endpoint dedicato codestral.mistral.ai): ottima per il completamento di codice.\"\n },\n {\n id: \"upstage\", label: \"Upstage Solar\", env: \"UPSTAGE_API_KEY\",\n host: \"api.upstage.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^up_/, strong: true, keyFmt: \"Inizia con up_ (es. up_xxxx)\",\n signup: \"https://console.upstage.ai/api-keys\",\n free: true, billed: true, verified: true,\n aliases: [\"upstage\", \"solar\", \"solar pro\", \"upstage solar\"],\n freeModels: [\"solar-pro2 (credito di benvenuto)\"],\n note: \"Solar Pro (coreano, veloce e capace). Credito gratuito all'iscrizione.\"\n },\n {\n id: \"friendli\", label: \"FriendliAI\", env: \"FRIENDLI_TOKEN\",\n host: \"api.friendli.ai\", chatPath: \"/serverless/v1/chat/completions\", modelsPath: \"/serverless/v1/models\",\n detect: /^flp_/, strong: true, keyFmt: \"Inizia con flp_ (es. flp_xxxx)\",\n signup: \"https://suite.friendli.ai/user-settings/tokens\",\n free: true, billed: true, verified: true,\n aliases: [\"friendli\", \"friendliai\", \"friendli ai\", \"periflow\"],\n freeModels: [\"meta-llama-3.3-70b-instruct\", \"deepseek-r1\", \"qwen2.5-coder-32b\"],\n note: \"Serverless veloce sui modelli open, con credito gratuito iniziale.\"\n },\n {\n id: \"inference-net\", label: \"Inference.net\", env: \"INFERENCE_API_KEY\",\n host: \"api.inference.net\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^inference-/, strong: true, keyFmt: \"Inizia con inference- (es. inference-xxxx)\",\n signup: \"https://inference.net/dashboard/api-keys\",\n free: true, billed: true, verified: true,\n aliases: [\"inference net\", \"inference.net\", \"inferencenet\"],\n freeModels: [\"meta-llama/llama-3.3-70b-instruct/fp-8\", \"deepseek/deepseek-r1-distill-llama-70b\"],\n note: \"Credito gratuito iniziale su modelli open. OpenAI-compat pulito.\"\n },\n {\n id: \"kluster\", label: \"Kluster.ai\", env: \"KLUSTER_API_KEY\",\n host: \"api.kluster.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: null, keyFmt: \"Chiave alfanumerica lunga (senza prefisso fisso)\",\n signup: \"https://platform.kluster.ai/apikeys\",\n free: true, billed: true, verified: true,\n aliases: [\"kluster\", \"kluster ai\", \"kluster.ai\"],\n freeModels: [\"klusterai/Meta-Llama-3.3-70B-Instruct-Turbo\", \"deepseek-ai/DeepSeek-V3\"],\n note: \"Credito di prova gratuito su modelli open grossi (e batch a metà prezzo).\"\n },\n {\n id: \"io-intelligence\", label: \"io.net Intelligence (free)\", env: \"IOINTELLIGENCE_API_KEY\",\n host: \"api.intelligence.io.solutions\", chatPath: \"/api/v1/chat/completions\", modelsPath: \"/api/v1/models\",\n detect: /^eyJ[A-Za-z0-9_-]+\\./, keyFmt: \"JWT (inizia con eyJ...)\",\n signup: \"https://ai.io.net/ai/api-keys\",\n free: true, billed: false, verified: true,\n aliases: [\"io net\", \"io.net\", \"io intelligence\", \"ionet\"],\n freeModels: [\"meta-llama/Llama-3.3-70B-Instruct\", \"deepseek-ai/DeepSeek-R1-0528\", \"Qwen/Qwen3-235B-A22B\"],\n note: \"Piano GRATUITO con quota giornaliera su modelli grossi (llama-70b, deepseek-r1, qwen-235b). Chiave JWT.\"\n },\n {\n id: \"scaleway\", label: \"Scaleway Generative APIs\", env: \"SCALEWAY_API_KEY\",\n host: \"api.scaleway.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/, strong: true,\n keyFmt: \"UUID (8-4-4-4-12, es. 0a1b2c3d-....)\",\n signup: \"https://console.scaleway.com/iam/api-keys\",\n free: true, billed: true, verified: true,\n aliases: [\"scaleway\", \"scaleway generative apis\", \"scaleway ai\"],\n freeModels: [\"llama-3.3-70b-instruct\", \"qwen2.5-coder-32b-instruct\", \"deepseek-r1-distill-llama-70b\"],\n note: \"Datacenter europeo (Parigi): quota gratuita mensile, poi a consumo. Buono se ti interessa che i dati restino in UE.\"\n },\n {\n id: \"lambda\", label: \"Lambda Inference\", env: \"LAMBDA_API_KEY\",\n host: \"api.lambda.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^secret_/, strong: true, keyFmt: \"Inizia con secret_ (es. secret_xxxx)\",\n signup: \"https://cloud.lambda.ai/api-keys\",\n free: false, billed: true, verified: true,\n aliases: [\"lambda\", \"lambda labs\", \"lambda ai\", \"lambda inference\"],\n freeModels: [],\n note: \"Modelli open a prezzi bassi (llama, qwen, deepseek). A consumo.\"\n },\n {\n id: \"baseten\", label: \"Baseten\", env: \"BASETEN_API_KEY\",\n host: \"inference.baseten.co\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: null, keyFmt: \"Chiave alfanumerica lunga (senza prefisso fisso)\",\n signup: \"https://app.baseten.co/settings/api_keys\",\n free: true, billed: true, verified: false,\n aliases: [\"baseten\", \"base ten\"],\n freeModels: [\"(credito di prova su llama/qwen/deepseek)\"],\n note: \"Model APIs OpenAI-compat + possibilità di ospitare modelli tuoi. Credito di prova. \" + NV\n },\n {\n id: \"avian\", label: \"Avian.io\", env: \"AVIAN_API_KEY\",\n host: \"api.avian.io\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: null, keyFmt: \"Chiave alfanumerica lunga (senza prefisso fisso)\",\n signup: \"https://avian.io/dashboard\",\n free: false, billed: true, verified: false,\n aliases: [\"avian\", \"avian io\", \"avian.io\"],\n freeModels: [],\n note: \"Inference veloce su modelli open. \" + NV\n },\n {\n id: \"parasail\", label: \"Parasail\", env: \"PARASAIL_API_KEY\",\n host: \"api.parasail.io\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: null, keyFmt: \"Chiave alfanumerica lunga (senza prefisso fisso)\",\n signup: \"https://www.parasail.io/\",\n free: true, billed: true, verified: false,\n aliases: [\"parasail\", \"parasail io\"],\n freeModels: [\"(credito di prova, modelli open)\"],\n note: \"Serverless su GPU a basso costo, credito di prova. \" + NV\n },\n {\n id: \"ai21\", label: \"AI21 Jamba\", env: \"AI21_API_KEY\",\n host: \"api.ai21.com\", chatPath: \"/studio/v1/chat/completions\", modelsPath: null,\n detect: null, keyFmt: \"Chiave alfanumerica lunga (senza prefisso fisso)\",\n signup: \"https://studio.ai21.com/account/api-key\",\n free: true, billed: true, verified: false,\n aliases: [\"ai21\", \"ai21 labs\", \"jamba\"],\n freeModels: [\"jamba-mini (credito di prova)\"],\n note: \"Jamba (contesto lunghissimo). Credito di prova gratuito. \" + NV\n },\n {\n id: \"writer\", label: \"Writer Palmyra\", env: \"WRITER_API_KEY\",\n host: \"api.writer.com\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: null, keyFmt: \"Chiave alfanumerica lunga (senza prefisso fisso)\",\n signup: \"https://app.writer.com/aistudio/organization/api-keys\",\n free: true, billed: true, verified: false,\n aliases: [\"writer\", \"writer ai\", \"palmyra\"],\n freeModels: [\"palmyra-x5 (credito di prova)\"],\n note: \"Palmyra X (buono sui testi lunghi). Credito di prova. \" + NV\n },\n {\n id: \"reka\", label: \"Reka AI\", env: \"REKA_API_KEY\",\n host: \"api.reka.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: null, keyFmt: \"Chiave alfanumerica lunga (senza prefisso fisso)\",\n signup: \"https://platform.reka.ai/apikeys\",\n free: false, billed: true, verified: false,\n aliases: [\"reka\", \"reka ai\", \"reka core\", \"reka flash\"],\n freeModels: [],\n note: \"Reka Flash/Core (multimodale). \" + NV\n },\n\n // ================= SENZA FILTRI / ROLEPLAY (uncensored) ==================\n {\n id: \"nanogpt\", label: \"NanoGPT (senza filtri)\", env: \"NANOGPT_API_KEY\",\n host: \"nano-gpt.com\", chatPath: \"/api/v1/chat/completions\", modelsPath: \"/api/v1/models\",\n detect: null, keyFmt: \"Chiave alfanumerica lunga (senza prefisso fisso)\",\n signup: \"https://nano-gpt.com/api\",\n free: false, billed: true, uncensored: true, verified: true,\n aliases: [\"nanogpt\", \"nano gpt\", \"nano-gpt\"],\n freeModels: [\"(pay-per-prompt: anche modelli abliterated/uncensored)\"],\n note: \"Si paga a singolo prompt (pochi centesimi, carta o cripto) e include modelli SENZA FILTRI. Nessun abbonamento.\"\n },\n {\n id: \"infermatic\", label: \"Infermatic / TotalGPT (RP senza filtri)\", env: \"INFERMATIC_API_KEY\",\n host: \"api.totalgpt.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: null, keyFmt: \"Chiave alfanumerica lunga (senza prefisso fisso)\",\n signup: \"https://infermatic.ai/\",\n free: false, billed: true, uncensored: true, verified: false,\n aliases: [\"infermatic\", \"totalgpt\", \"total gpt\", \"infermatic ai\"],\n freeModels: [\"(abbonamento fisso: modelli RP/abliterated illimitati)\"],\n note: \"Abbonamento mensile fisso con modelli roleplay/abliterated (Midnight-Miqu, magnum...). \" + NV\n },\n {\n id: \"mancer\", label: \"Mancer (senza filtri)\", env: \"MANCER_API_KEY\",\n host: \"neuro.mancer.tech\", chatPath: \"/oai/v1/chat/completions\", modelsPath: \"/oai/v1/models\",\n detect: null, keyFmt: \"Chiave alfanumerica lunga (senza prefisso fisso)\",\n signup: \"https://mancer.tech/\",\n free: false, billed: true, uncensored: true, verified: false,\n aliases: [\"mancer\", \"mancer tech\", \"mancer ai\"],\n freeModels: [\"(a crediti: mytholite, weaver — nessun filtro)\"],\n note: \"Storico provider RP senza filtri, a crediti. Endpoint OpenAI-compat su /oai/v1. \" + NV\n },\n {\n id: \"targon\", label: \"Targon (Bittensor)\", env: \"TARGON_API_KEY\",\n host: \"api.targon.com\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^sn4_/, strong: true, keyFmt: \"Inizia con sn4_ (es. sn4_xxxx)\",\n signup: \"https://targon.com/\",\n free: true, billed: false, uncensored: true, verified: false,\n aliases: [\"targon\", \"bittensor\", \"sybil\", \"manifold\"],\n freeModels: [\"deepseek-ai/DeepSeek-V3\", \"(modelli open serviti dai miner Bittensor)\"],\n note: \"Rete decentralizzata Bittensor: quota gratuita, nessun filtro aggiunto dal gateway. \" + NV\n },\n {\n id: \"nineteen\", label: \"Nineteen.ai (Bittensor)\", env: \"NINETEEN_API_KEY\",\n host: \"api.nineteen.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: null, keyFmt: \"Chiave alfanumerica lunga (senza prefisso fisso)\",\n signup: \"https://nineteen.ai/app/api\",\n free: true, billed: false, uncensored: true, verified: false,\n aliases: [\"nineteen\", \"nineteen ai\", \"nineteen.ai\", \"sn19\"],\n freeModels: [\"unsloth/Llama-3.2-3B-Instruct\", \"(modelli open dai miner)\"],\n note: \"Gateway Bittensor con piano gratuito, modelli open senza filtri aggiuntivi. \" + NV\n },\n {\n id: \"redpill\", label: \"RedPill\", env: \"REDPILL_API_KEY\",\n host: \"api.redpill.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\",\n detect: /^sk-/, keyFmt: \"Inizia con sk-\",\n signup: \"https://red-pill.ai/\",\n free: false, billed: true, uncensored: true, verified: false,\n aliases: [\"redpill\", \"red pill\", \"red-pill\"],\n freeModels: [],\n note: \"Router (anche TEE/privacy) con modelli open non filtrati. \" + NV\n }\n];\n\n/**\n * PIATTAFORME GPU aggiuntive (dove PORTI i tuoi modelli abliterated).\n * Stessa forma di gpuPlatforms.PLATFORMS: gpuPlatforms le fonde con le sue e\n * le sue vincono (Kaggle è cablata e ha lo stato live).\n */\nconst PLATFORMS_EXTRA = [\n {\n id: \"beam\", url: \"https://www.beam.cloud/\", name: \"Beam Cloud (serverless GPU)\",\n kind: \"freemium\", freeGpu: true, alwaysOn: false, uncensoredOk: true, remote: false,\n costo: \"ore GPU gratis ogni mese sul free tier, poi a consumo al secondo\",\n pros: [\n \"Ore GPU gratis ogni mese senza carta\",\n \"Serverless: paghi solo i secondi di inferenza\",\n \"Container tuoi: nessun controllo sui modelli abliterated\",\n \"Deploy da CLI in un minuto\"\n ],\n cons: [\n \"Cold start di qualche decina di secondi\",\n \"Serve un token nel .env per accenderlo da remoto (non ancora cablato)\"\n ],\n howto: \"Da cablare: BEAM_TOKEN nel .env, deploy di un endpoint Ollama/vLLM e puntarlo al failover come Kaggle.\",\n note: \"Buon compromesso: gratis all'inizio e non si scollega come Colab.\"\n },\n {\n id: \"cerebrium\", url: \"https://www.cerebrium.ai/\", name: \"Cerebrium (serverless GPU)\",\n kind: \"freemium\", freeGpu: true, alwaysOn: false, uncensoredOk: true, remote: false,\n costo: \"credito gratuito iniziale, poi fatturazione al secondo\",\n pros: [\"Credito iniziale gratis\", \"Scale-to-zero: spento non costa\", \"Modelli tuoi senza restrizioni\"],\n cons: [\"Finito il credito si paga\", \"Cold start\", \"Non ancora cablato in Antigravity\"],\n howto: \"Da cablare: deploy di un runtime vLLM/Ollama e puntarlo al failover.\",\n note: \"Alternativa a Modal, molto simile nell'uso.\"\n },\n {\n id: \"koyeb\", url: \"https://www.koyeb.com/\", name: \"Koyeb (dominio stabile, GPU a consumo)\",\n kind: \"freemium\", freeGpu: false, alwaysOn: true, uncensoredOk: true, remote: false,\n costo: \"free tier solo CPU; GPU a consumo con scale-to-zero\",\n pros: [\"Servizi sempre accesi con dominio pubblico incluso (niente ngrok)\", \"Deploy da Git/Docker semplicissimo\"],\n cons: [\"Le GPU non sono gratis\", \"Sul free tier (CPU) girano solo modelli minuscoli\"],\n howto: \"Utile come PONTE stabile (dominio fisso) davanti a un backend GPU, al posto di ngrok.\",\n note: \"Da considerare per togliere di mezzo ngrok, più che per la GPU.\"\n },\n {\n id: \"flyio\", url: \"https://fly.io/gpu\", name: \"Fly.io (GPU a consumo)\",\n kind: \"paid\", freeGpu: false, alwaysOn: true, uncensoredOk: true, remote: false,\n costo: \"GPU a ore, con macchine che si sospendono da sole quando sono inattive\",\n pros: [\"Macchine sospendibili: paghi solo quando servono\", \"Rete globale e dominio stabile\", \"Nessun limite sui modelli\"],\n cons: [\"Nessuna GPU gratis\", \"Serve carta di credito\"],\n howto: \"Da cablare: FLY_API_TOKEN nel .env per accendere/spegnere la macchina come Kaggle.\",\n note: \"Buono se vuoi un endpoint tuo affidabile pagando a ore.\"\n },\n {\n id: \"tensordock\", url: \"https://tensordock.com/\", name: \"TensorDock (marketplace GPU)\",\n kind: \"paid\", freeGpu: false, alwaysOn: true, uncensoredOk: true, remote: false,\n costo: \"marketplace: prezzi molto bassi anche su 4090/A100\",\n pros: [\"Prezzi bassissimi\", \"VM complete: ci metti quello che vuoi\", \"Nessun limite sui modelli\"],\n cons: [\"A pagamento\", \"Affidabilità variabile (host indipendenti)\", \"Setup manuale\"],\n howto: \"Da cablare: API TensorDock per creare/distruggere la VM da remoto.\",\n note: \"Alternativa a Vast.ai, spesso con listino più chiaro.\"\n },\n {\n id: \"jarvislabs\", url: \"https://jarvislabs.ai/\", name: \"JarvisLabs (GPU a ore, disco che resta)\",\n kind: \"paid\", freeGpu: false, alwaysOn: false, uncensoredOk: true, remote: false,\n costo: \"a ore (A5000/A6000), con pausa/riprendi\",\n pros: [\"Pausa e riprendi tenendo il disco: i modelli restano scaricati\", \"Semplice, orientato ai notebook\", \"API per accendere/spegnere\"],\n cons: [\"A pagamento\", \"Niente free tier\"],\n howto: \"Da cablare: JARVISLABS_API_KEY per accendere/spegnere e puntare al failover.\",\n note: \"Comodo perché il disco resta: non riscarichi 20 GB di modello ogni volta.\"\n },\n {\n id: \"novita-gpu\", url: \"https://novita.ai/gpu-instance\", name: \"Novita GPU Instance\",\n kind: \"paid\", freeGpu: false, alwaysOn: true, uncensoredOk: true, remote: false,\n costo: \"a ore (4090/A100), fatturazione al minuto\",\n pros: [\"Stesso account che usi già per l'API Novita\", \"Template Ollama/vLLM pronti\", \"Modelli tuoi senza restrizioni\"],\n cons: [\"A pagamento\", \"Nessuna GPU gratis\"],\n howto: \"Da cablare: la chiave Novita che hai già serve anche per le istanze GPU.\",\n note: \"Se hai già la chiave Novita, è la strada più corta per una GPU 24/7.\"\n },\n {\n id: \"sagemaker-lab\", url: \"https://studiolab.sagemaker.aws/\", name: \"Amazon SageMaker Studio Lab\",\n kind: \"free\", freeGpu: true, alwaysOn: false, uncensoredOk: true, remote: false,\n costo: \"0€ — sessioni GPU a tempo, nessuna carta di credito\",\n pros: [\"GPU gratis senza carta\", \"Ambiente persistente (il disco resta)\", \"Più stabile di Colab\"],\n cons: [\"Sessioni a tempo, poi va riavviato a mano\", \"Approvazione dell'account non immediata\", \"Non gestibile da remoto\"],\n howto: \"Alternativa gratuita a Kaggle quando la quota settimanale è finita.\",\n note: \"Ore GPU gratis in più, utili come riserva.\"\n },\n {\n id: \"saturn\", url: \"https://saturncloud.io/\", name: \"Saturn Cloud (free GPU)\",\n kind: \"freemium\", freeGpu: true, alwaysOn: false, uncensoredOk: true, remote: false,\n costo: \"0€ — ore di calcolo gratis ogni mese (una parte su GPU)\",\n pros: [\"Ore GPU gratis al mese\", \"Ambienti Jupyter persistenti\", \"Niente carta per il free tier\"],\n cons: [\"Risorse gratis limitate e a volte in coda\", \"Non cablato in Antigravity\"],\n howto: \"Come Kaggle: notebook con Ollama + tunnel, da puntare al failover.\",\n note: \"Buona riserva quando Kaggle è a quota zero.\"\n },\n {\n id: \"thunder\", url: \"https://www.thundercompute.com/\", name: \"Thunder Compute (GPU low cost)\",\n kind: \"paid\", freeGpu: false, alwaysOn: true, uncensoredOk: true, remote: false,\n costo: \"A100 virtualizzata a poche decine di centesimi l'ora, al minuto\",\n pros: [\"Tra i prezzi più bassi per una A100\", \"CLI semplice, istanze in pochi secondi\", \"Nessun limite sui modelli\"],\n cons: [\"A pagamento\", \"GPU virtualizzata: qualche punto percentuale di prestazioni in meno\"],\n howto: \"Da cablare: token nel .env per accendere/spegnere l'istanza.\",\n note: \"Se serve un modello 70B senza spendere come su AWS.\"\n },\n {\n id: \"primeintellect\", url: \"https://www.primeintellect.ai/\", name: \"Prime Intellect (confronto prezzi GPU)\",\n kind: \"paid\", freeGpu: false, alwaysOn: true, uncensoredOk: true, remote: false,\n costo: \"aggregatore: prende il prezzo più basso tra molti fornitori\",\n pros: [\"Confronta i prezzi di molti fornitori in un unico posto\", \"API unica per accendere/spegnere\", \"Nessun limite sui modelli\"],\n cons: [\"A pagamento\", \"La qualità dipende dal fornitore che ti assegna\"],\n howto: \"Da cablare: API key per creare/distruggere l'istanza dal telefono.\",\n note: \"Comodo per trovare la GPU più economica disponibile al momento.\"\n },\n {\n id: \"hyperstack\", url: \"https://www.hyperstack.cloud/\", name: \"Hyperstack (GPU europee)\",\n kind: \"paid\", freeGpu: false, alwaysOn: true, uncensoredOk: true, remote: false,\n costo: \"a ore (A100/H100), datacenter in Europa\",\n pros: [\"Datacenter europei: latenza bassa dall'Italia e dati in UE\", \"API completa per accendere/spegnere\", \"Modelli tuoi senza restrizioni\"],\n cons: [\"A pagamento\", \"Niente free tier\"],\n howto: \"Da cablare: HYPERSTACK_API_KEY nel .env.\",\n note: \"La scelta 'europea' se ti interessa dove stanno i dati.\"\n }\n];\n\nmodule.exports = { CATALOG, PLATFORMS_EXTRA };\n"}}, "src/providerRegistry.js": {"b004d67566fd93489bf4cb3fbc1b4d93bfed8e95": {"t": 1786068492.7513866, "n": 35643, "h": "e346422b4a2d4928", "c": "\"use strict\";\n\n/**\n * providerRegistry — catalogo dei provider LLM (OpenAI-compatibili) con\n * RILEVAMENTO AUTOMATICO dalla forma della chiave. L'utente incolla SOLO la\n * chiave: endpoint (host/base_url), nome variabile .env e altro si auto-compilano.\n *\n * Ogni voce:\n * id identificatore interno (usato come \"id::modello\")\n * label nome leggibile\n * env nome variabile in .env\n * host host HTTPS dell'endpoint OpenAI-compat\n * chatPath path chat completions\n * modelsPath path per elencare i modelli (GET, OpenAI-compat) — opzionale\n * detect regex sul formato della chiave (per l'auto-rilevamento)\n * signup URL dove ottenere la chiave (reindirizzamento)\n * free true se ha un piano gratuito utile\n * keyFmt descrizione UMANA del formato della chiave (es. \"sk-or-v1-...\",\n * \"chiave senza prefisso fisso\", \"JWT (eyJ...)\") — la UI la mostra\n * così l'utente sa COSA incollare e il cacciatore può scriverlo in\n * automatico sotto il nome del provider.\n * note suggerimento breve (perché è utile / cosa offre)\n * billed true se a consumo (costi) — la barra uso lo considera\n *\n * NB: alcune chiavi hanno prefissi condivisi (`sk-...` = OpenAI/DeepSeek/Alibaba):\n * per quelle il rilevamento propone il candidato più probabile con ambiguous=true,\n * e la UI lascia scegliere/confermare.\n */\n\nconst PROVIDERS = [\n // ---- GRATIS, ottimi per coding/reverse engineering -------------------\n // ⚠️ 2026-07-24 — i :free grossi (llama-3.3-70b, hermes-405b) sono passati a\n // PAGAMENTO: rispondono 404 \"use the paid slug\". Tenuto nel registro (il giorno\n // che c'è budget si riaccende con OPENROUTER_ENABLE=1) ma fuori dal failover free.\n { keyFmt: \"Inizia con sk-or-v1- (es. «redacted:sk-or-v1-...»)\", id: \"openrouter\", label: \"OpenRouter (aggregatore)\", env: \"OPENROUTER_API_KEY\", host: \"openrouter.ai\", chatPath: \"/api/v1/chat/completions\", modelsPath: \"/api/v1/models\", detect: /^sk-or-v1-/, signup: \"https://openrouter.ai/keys\", free: false, note: \"⚠️ i modelli :free grossi ora sono a pagamento. Riattivabile con OPENROUTER_ENABLE=1 nel .env.\" },\n { keyFmt: \"Inizia con gsk_ (es. gsk_xxxx)\", id: \"groq\", label: \"Groq\", env: \"GROQ_API_KEY\", host: \"api.groq.com\", chatPath: \"/openai/v1/chat/completions\", modelsPath: \"/openai/v1/models\", detect: /^gsk_/, signup: \"https://console.groq.com/keys\", free: true, note: \"Velocissimo, gratis: llama-3.3-70b, qwen, gpt-oss-120b, deepseek-distill.\" },\n { keyFmt: \"Inizia con csk- (es. csk-xxxx)\", id: \"cerebras\", label: \"Cerebras\", env: \"CEREBRAS_API_KEY\", host: \"api.cerebras.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: /^csk-/, signup: \"https://cloud.cerebras.ai/\", free: true, note: \"Gratis e ULTRA-veloce: llama-3.3-70b, qwen-3-32b/coder. Ottimo per l'agente.\" },\n { keyFmt: \"Inizia con nvapi- (es. nvapi-xxxx)\", id: \"nvidia\", label: \"NVIDIA NIM\", env: \"NVIDIA_API_KEY\", host: \"integrate.api.nvidia.com\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: /^nvapi-/, signup: \"https://build.nvidia.com/\", free: true, note: \"Gratis: modelli GROSSI (nemotron, deepseek, qwen-coder, llama-405b). Ottimo per RE.\" },\n { keyFmt: \"Chiave senza prefisso fisso (50+ caratteri alfanumerici)\", id: \"sambanova\", label: \"SambaNova\", env: \"SAMBANOVA_API_KEY\", host: \"api.sambanova.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: null, signup: \"https://cloud.sambanova.ai/apis\", free: true, note: \"Gratis e veloce: llama-3.1-405B, qwen. Chiave senza prefisso fisso.\" },\n { keyFmt: \"Inizia con hf_ (es. hf_xxxx)\", id: \"hf\", label: \"HuggingFace\", env: \"HF_TOKEN\", envAliases: [\"HUGGINGFACE_API_KEY\"], host: \"router.huggingface.co\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: /^hf_/, signup: \"https://huggingface.co/settings/tokens\", free: true, note: \"Router su molti provider; modelli abliterated/uncensored. Crediti free mensili.\", billed: true },\n { keyFmt: \"Inizia con AIza o AQ. (chiave Google AI Studio)\", id: \"google\", label: \"Google Gemini\", env: \"GOOGLE_API_KEY\", envAliases: [\"GEMINI_API_KEY\"], host: \"generativelanguage.googleapis.com\", chatPath: \"/v1beta/openai/chat/completions\", modelsPath: \"/v1beta/openai/models\", detect: /^AIza/, signup: \"https://aistudio.google.com/app/apikey\", free: true, note: \"Gratis: gemini-2.x-flash (grande contesto). Buono anche per immagini.\" },\n { keyFmt: \"32 caratteri alfanumerici (es. abcdef0123456789abcdef0123456789)\", id: \"mistral\", label: \"Mistral\", env: \"MISTRAL_API_KEY\", host: \"api.mistral.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: /^[A-Za-z0-9]{32}$/, signup: \"https://console.mistral.ai/api-keys/\", free: true, note: \"Piano free: mistral-large, codestral (coding). Chiave 32 caratteri.\" },\n // ⚠️ 2026-07-24 — verificato con la chiave reale: 402 \"insufficient funds\".\n // Resta selezionabile a mano, ma è FUORI dal failover gratuito (creava buchi).\n { keyFmt: \"JWT (inizia con eyJ...)\", id: \"hyperbolic\", label: \"Hyperbolic\", env: \"HYPERBOLIC_API_KEY\", host: \"api.hyperbolic.xyz\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: /^eyJ/, signup: \"https://app.hyperbolic.xyz/settings\", free: false, note: \"⚠️ credito esaurito (402). Riattivabile con HYPERBOLIC_ENABLE=1 nel .env.\" },\n // ★ 2026-07-24 — NUOVA CORSIA GRATIS: GitHub Models. Basta un token GitHub\n // (ghp_/github_pat_), nessuna carta: gpt-4o-mini, llama, phi, qwen, deepseek.\n // ★ 2026-07-24 — CLOUDFLARE WORKERS AI. Caso particolare: l'endpoint contiene\n // l'ID dell'account, quindi oltre alla chiave (CLOUDFLARE_API_KEY, formato\n // cfat_...) serve CLOUDFLARE_ACCOUNT_ID nel .env. Il segnaposto {ACCOUNT} viene\n // sostituito da cloudEngine._buildProviders; senza ID il provider resta spento.\n { keyFmt: \"Inizia con cfat_ o cfut_ (es. cfat_xxxx)\", id: \"cloudflare\", label: \"Cloudflare Workers AI\", env: \"CLOUDFLARE_API_KEY\", host: \"api.cloudflare.com\", chatPath: \"/client/v4/accounts/{ACCOUNT}/ai/v1/chat/completions\", modelsPath: \"/client/v4/accounts/{ACCOUNT}/ai/models/search?task=Text+Generation&per_page=100\", needsEnv: \"CLOUDFLARE_ACCOUNT_ID\", detect: /^cf(at|ut)_/, signup: \"https://dash.cloudflare.com/profile/api-tokens\", free: true, note: \"Gratis ogni giorno sull'edge Cloudflare: gpt-oss-120b, kimi-k2, deepseek-r1-distill. Serve anche CLOUDFLARE_ACCOUNT_ID.\" },\n { keyFmt: \"Inizia con ghp_ o github_pat_\", id: \"github\", label: \"GitHub Models\", env: \"GITHUB_TOKEN\", host: \"models.github.ai\", chatPath: \"/inference/chat/completions\", modelsPath: \"/catalog/models\", models: [\"openai/gpt-4o-mini\"], detect: /^(ghp_|github_pat_)/, signup: \"https://github.com/settings/tokens\", free: true, note: \"Gratis col tuo account GitHub (token classic o fine-grained): gpt-4o-mini, llama, phi, qwen, deepseek.\" },\n { keyFmt: \"Inizia con sk_ (es. sk_xxxx)\", id: \"novita\", label: \"Novita AI\", env: \"NOVITA_API_KEY\", host: \"api.novita.ai\", chatPath: \"/v3/openai/chat/completions\", modelsPath: \"/v3/openai/models\", detect: /^sk_/, signup: \"https://novita.ai/settings/key-management\", free: true, note: \"Crediti gratis: molti modelli open (llama, qwen, deepseek).\" },\n { keyFmt: \"Inizia con cpk_ (es. cpk_xxxx)\", id: \"chutes\", label: \"Chutes\", env: \"CHUTES_API_KEY\", host: \"llm.chutes.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: /^cpk_/, signup: \"https://chutes.ai/\", free: true, note: \"Modelli open serverless, molti gratuiti (deepseek, qwen).\" },\n { keyFmt: \"Inizia con glhf_ (es. glhf_xxxx)\", id: \"glhf\", label: \"glhf.chat\", env: \"GLHF_API_KEY\", host: \"glhf.chat\", chatPath: \"/api/openai/v1/chat/completions\", modelsPath: \"/api/openai/v1/models\", detect: /^glhf_/, signup: \"https://glhf.chat/\", free: true, note: \"Esegue quasi ogni modello HuggingFace, gratis in beta.\" },\n { keyFmt: \"Forma id.segreto (es. 0123456789abcdef0123456789abcdef.secret)\", id: \"ollama-cloud\", label: \"Ollama Cloud\", env: \"OLLAMA_API_KEY\", host: \"ollama.com\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: /^[0-9a-f]{32}\\./, signup: \"https://ollama.com/settings/keys\", free: true, note: \"I tuoi modelli Ollama nel cloud (qwen, deepseek-coder). Chiave id.segreto.\" },\n // ★ CORSIA PRIORITARIA dell'utente: abliterated coder su GPU Kaggle (Ollama) via\n // tunnel ngrok con dominio FISSO. Attiva quando il notebook Kaggle gira. La chiave\n // è fittizia (Ollama la ignora): basta KAGGLE_KEY=ollama nel .env per attivarla.\n { keyFmt: \"Chiave fittizia: basta KAGGLE_KEY=ollama (il notebook non la usa)\", id: \"kaggle\", label: \"Kaggle GPU (abliterated coder)\", env: \"KAGGLE_KEY\", host: \"paving-preschool-facelift.ngrok-free.dev\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: null, signup: \"https://www.kaggle.com/code\", free: true, note: \"La TUA corsia abliterated coder (Qwen2.5-Coder 14B/32B) su GPU Kaggle via tunnel ngrok. Priorità nel failover quando il notebook è acceso.\" },\n // ★ 2026-07-30 — HOST CORRETTO. Puntava al workspace eu-central (Francoforte):\n // con una chiave creata sul portale CINESE (bailian.console.aliyun.com) quel\n // dominio risponde 401 \"Incorrect API key\", e il pannello dichiarava \"chiave\n // obsoleta\" una chiave in realtà PERFETTAMENTE VIVA. Verificato dal vivo:\n // dashscope.aliyuncs.com → 200 col tuo sk-ws-... · eu-central e -intl → 401.\n // Se un domani la chiave la fai sul portale internazionale, usa la voce\n // \"alibaba-intl\" qui sotto (DASHSCOPE_INTL_API_KEY).\n { keyFmt: \"Inizia con sk- (es. sk-ws-xxxx)\", id: \"alibaba\", label: \"Alibaba Qwen (DashScope Cina)\", env: \"DASHSCOPE_API_KEY\", host: \"dashscope.aliyuncs.com\", chatPath: \"/compatible-mode/v1/chat/completions\", modelsPath: \"/compatible-mode/v1/models\", detect: /^sk-/, signup: \"https://bailian.console.aliyun.com/\", free: true, note: \"Model Studio CINESE (qwen-coder/max/flash). La chiave del portale cinese funziona SOLO su dashscope.aliyuncs.com, non sui domini -intl/eu-central.\", ambiguousHint: true },\n { keyFmt: \"Inizia con sk- (es. sk-xxxx)\", id: \"alibaba-intl\", label: \"Alibaba Qwen (DashScope internazionale)\", env: \"DASHSCOPE_INTL_API_KEY\", host: \"dashscope-intl.aliyuncs.com\", chatPath: \"/compatible-mode/v1/chat/completions\", modelsPath: \"/compatible-mode/v1/models\", detect: /^sk-/, signup: \"https://bailian.console.alibabacloud.com/\", free: true, note: \"Model Studio INTERNAZIONALE (Singapore/Francoforte). Chiave separata da quella cinese: le due NON sono intercambiabili.\", ambiguousHint: true },\n\n // ★ 2026-07-27 — NUOVI GATEWAY GRATUITI (scoperti dal cacciatore online):\n // veri endpoint OpenAI-compat, piano free senza carta -> entrano nel failover.\n { keyFmt: \"Chiave fittizia: KILO_KEY=none (nessun account richiesto)\", id: \"kilo\", label: \"Kilo Gateway (free, no account)\", env: \"KILO_API_KEY\", host: \"api.kilo.ai\", chatPath: \"/api/gateway/v1/chat/completions\", modelsPath: \"/api/gateway/v1/models\", detect: null, signup: \"https://kilo.ai/docs/gateway\", free: true, note: \"Gateway OpenAI-compat: free model senza account (kilo-auto/free router, minimax-m2.5:free, step-3.5-flash:free, nemotron-3-super-120b:free). Limite ~200 req/h per IP. Chiave fittizia: KILO_KEY=none.\", ambiguousHint: false },\n { keyFmt: \"Chiave fittizia: OPENCODE_ZEN_KEY=none (nessun account richiesto)\", id: \"opencode\", label: \"OpenCode Zen (gateway free)\", env: \"OPENCODE_ZEN_KEY\", host: \"opencode.ai\", chatPath: \"/zen/v1/chat/completions\", modelsPath: \"/zen/v1/models\", detect: null, signup: \"https://opencode.ai/docs/zen/\", free: true, note: \"Gateway curato di modelli free (DeepSeek V4 Flash Free, Laguna S 2.1 Free, Ling-3.0-flash Free, North Mini Code Free). OpenAI-compat. Chiave fittizia: OPENCODE_ZEN_KEY=none.\" },\n\n // ★ AGGIUNTO — Venice AI: OpenAI-compat, modelli UNCENSORED (venice-uncensored,\n // zai-org-glm-5-2). Chiave + base URL nel .env (VENICE_API_KEY, VENICE_BASE_URL).\n { keyFmt: \"Inizia con VENICE_ (es. VENICE_xxxx)\", id: \"venice\", label: \"Venice AI (uncensored)\", env: \"VENICE_API_KEY\", host: \"api.venice.ai\", chatPath: \"/api/v1/chat/completions\", modelsPath: \"/api/v1/models\", detect: /^VENICE_/, signup: \"https://venice.ai/\", free: true, note: \"Uncensored: venice-uncensored, glm-5-2. OpenAI-compat su api.venice.ai.\" },\n\n // ★ 2026-07-27 — NUOVI PROVIDER (endpoint verificati live con curl). OpenAI-compat.\n // ArliAI: specializzato in modelli UNCENSORED/RP (senza filtri), piano free con\n // limite di richieste. Endpoint api.arliai.com/v1 (401 senza chiave = vivo).\n // Chiave: alphanumerica, 40+ caratteri, senza prefisso fisso.\n { keyFmt: \"Chiave alfanumerica lunga (40+ caratteri, es. abcdef123456...)\", id: \"arliai\", label: \"ArliAI (uncensored/RP)\", env: \"ARLIAI_API_KEY\", host: \"api.arliai.com\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: /^[A-Za-z0-9]{40,}$/, signup: \"https://www.arliai.com/\", free: true, note: \"Modelli UNCENSORED/roleplay illimitati sul piano (Mistral-Nemo, Llama-3.1-8B abliterated, Qwen2.5-Coder (varie)). Piano free disponibile.\", uncensored: true },\n // DeepInfra: catalogo enorme open-weight, credito iniziale gratuito, OpenAI-compat.\n // Chiave: alphanumerica, 40+ caratteri, senza prefisso fisso.\n { keyFmt: \"Chiave alfanumerica lunga (40+ caratteri, es. abcdef123456...)\", id: \"deepinfra\", label: \"DeepInfra\", env: \"DEEPINFRA_API_KEY\", host: \"api.deepinfra.com\", chatPath: \"/v1/openai/chat/completions\", modelsPath: \"/v1/openai/models\", detect: /^[A-Za-z0-9]{40,}$/, signup: \"https://deepinfra.com/dash/api_keys\", free: true, note: \"Tanti modelli open (llama, qwen, deepseek, mixtral). Credito iniziale gratuito, poi economico. Chiave alfanumerica lunga.\", billed: true },\n // Featherless: 'run any HuggingFace model', include molti abliterated/uncensored.\n { keyFmt: \"Inizia con rc_ (es. rc_xxxx)\", id: \"featherless\", label: \"Featherless (HF models)\", env: \"FEATHERLESS_API_KEY\", host: \"api.featherless.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: /^rc_/, signup: \"https://featherless.ai/\", free: false, note: \"Esegue quasi ogni modello HuggingFace, inclusi abliterated/uncensored. Abbonamento a prezzo fisso. Chiave rc_...\", uncensored: true, billed: true },\n // Cloudrift: gateway inference OpenAI-compat, credito di prova.\n // Chiave: alphanumerica, 40+ caratteri, senza prefisso fisso.\n { keyFmt: \"Chiave alfanumerica lunga (40+ caratteri, es. abcdef123456...)\", id: \"cloudrift\", label: \"Cloudrift\", env: \"CLOUDRIFT_API_KEY\", host: \"inference.cloudrift.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: /^[A-Za-z0-9]{40,}$/, signup: \"https://www.cloudrift.ai/\", free: true, note: \"Gateway inference OpenAI-compat (deepseek, qwen, llama). Credito di prova gratuito. Chiave alfanumerica lunga.\", uncensored: true },\n\n // ---- A PAGAMENTO / trial (utili ma con costi) ------------------------\n { keyFmt: \"Inizia con sk- (es. sk-proj-xxxx o sk-xxxx)\", id: \"openai\", label: \"OpenAI\", env: \"OPENAI_API_KEY\", host: \"api.openai.com\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: /^sk-(proj-|svcacct-)?[A-Za-z0-9_-]{20,}$/, signup: \"https://platform.openai.com/api-keys\", free: false, billed: true, note: \"GPT-4o/4.1/o-series. A pagamento. Chiave sk-... o sk-proj-...\", ambiguousHint: true },\n { keyFmt: \"Inizia con sk- (es. sk-xxxx)\", id: \"deepseek\", label: \"DeepSeek\", env: \"DEEPSEEK_API_KEY\", host: \"api.deepseek.com\", chatPath: \"/chat/completions\", modelsPath: \"/models\", detect: /^sk-/, signup: \"https://platform.deepseek.com/api_keys\", free: false, billed: true, note: \"deepseek-chat/reasoner, economici e forti nel coding. Chiave sk-... (ambigua).\", ambiguousHint: true },\n { keyFmt: \"Inizia con sk-ant- (es. sk-ant-xxxx)\", id: \"anthropic\", label: \"Anthropic Claude\", env: \"ANTHROPIC_API_KEY\", host: \"api.anthropic.com\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: /^sk-ant-/, signup: \"https://console.anthropic.com/settings/keys\", free: false, billed: true, note: \"Claude (Opus/Sonnet). Endpoint OpenAI-compat su /v1. A pagamento.\" },\n { keyFmt: \"Inizia con xai- (es. xai-xxxx)\", id: \"xai\", label: \"xAI Grok\", env: \"XAI_API_KEY\", host: \"api.x.ai\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: /^xai-/, signup: \"https://console.x.ai/\", free: false, billed: true, note: \"Grok. Trial iniziale, poi a pagamento.\" },\n { keyFmt: \"Inizia con pplx- (es. pplx-xxxx)\", id: \"perplexity\", label: \"Perplexity\", env: \"PERPLEXITY_API_KEY\", host: \"api.perplexity.ai\", chatPath: \"/chat/completions\", modelsPath: null, detect: /^pplx-/, signup: \"https://www.perplexity.ai/settings/api\", free: false, billed: true, note: \"Sonar con ricerca web integrata. A pagamento.\" },\n { keyFmt: \"Inizia con fw_ (es. fw_xxxx)\", id: \"fireworks\", label: \"Fireworks AI\", env: \"FIREWORKS_API_KEY\", host: \"api.fireworks.ai\", chatPath: \"/inference/v1/chat/completions\", modelsPath: \"/inference/v1/models\", detect: /^fw_/, signup: \"https://fireworks.ai/account/api-keys\", free: false, billed: true, note: \"Modelli open velocissimi (llama, qwen, deepseek). Credito di prova.\" },\n { keyFmt: \"64 caratteri esadecimali (es. a1b2c3...f0)\", id: \"together\", label: \"Together AI\", env: \"TOGETHER_API_KEY\", host: \"api.together.xyz\", chatPath: \"/v1/chat/completions\", modelsPath: \"/v1/models\", detect: /^[0-9a-f]{64}$/, signup: \"https://api.together.ai/settings/api-keys\", free: false, billed: true, note: \"Molti modelli open. Credito iniziale gratuito. Chiave 64 esadecimali.\" },\n];\n\n// ★ 2026-07-30 — FUSIONE COL CATALOGO PRECONFIGURATO (providerCatalog.js).\n// Il registro qui sopra è la lista CURATA (note e quote tarate a mano); il\n// catalogo è la lista LARGA di tutti i provider noti, con endpoint e formato\n// della chiave già pronti. Le voci curate VINCONO: dal catalogo prendono solo i\n// campi che non hanno (alias, freeModels, verified). Le voci nuove si aggiungono\n// in coda, così il selettore manuale e il rilevamento le vedono subito.\n// Se il file manca, il registro continua a funzionare com'era (nessun crash).\nlet CATALOG = [];\ntry { CATALOG = require(\"./providerCatalog\").CATALOG || []; } catch (_) { CATALOG = []; }\nfor (const c of CATALOG) {\n const cur = PROVIDERS.find(p => p.id === c.id);\n if (cur) {\n for (const k of [\"aliases\", \"verified\", \"freeModels\", \"keyFmt\", \"signup\", \"keyUrl\"]) {\n if (cur[k] === undefined && c[k] !== undefined) cur[k] = c[k];\n }\n continue;\n }\n PROVIDERS.push(Object.assign({}, c));\n}\n\n/** Quanto è \"probabile\" un candidato: gratis e verificati prima, a pagamento e\n * da confermare dopo. Serve a ordinare le proposte quando la chiave è ambigua. */\nfunction candRank(p) {\n return (p.free ? 0 : 3) + (p.verified === false ? 2 : 0) + (p.billed ? 1 : 0);\n}\n\n/**\n * Rileva il/i provider da una chiave incollata. Ritorna:\n * { best, candidates:[{id,label,...,ambiguous}], value }\n * best = miglior candidato (o null). candidates = tutti i plausibili (ordinati).\n */\nfunction detectProvider(rawKey) {\n const key = String(rawKey || \"\").trim();\n if (!key) return { best: null, candidates: [] };\n\n // 1) Prefissi FORTI (un solo provider possibile) — controllati in ordine.\n const STRONG = [\n [/^sk-or-v1-/, \"openrouter\"],\n [/^sk-ant-/, \"anthropic\"],\n [/^sk-(proj|svcacct)-/, \"openai\"],\n [/^gsk_/, \"groq\"],\n [/^hf_/, \"hf\"],\n [/^csk-/, \"cerebras\"],\n [/^nvapi-/, \"nvidia\"],\n [/^xai-/, \"xai\"],\n [/^pplx-/, \"perplexity\"],\n [/^fw_/, \"fireworks\"],\n [/^glhf_/, \"glhf\"],\n [/^cpk_/, \"chutes\"],\n [/^rc_/, \"featherless\"],\n // Cloudflare: `cfat_` = account token, `cfut_` = user token (quello che si\n // ottiene creando il token dal profilo). Vanno bene entrambi.\n [/^cf(at|ut)_/, \"cloudflare\"],\n [/^ghp_/, \"github\"],\n [/^github_pat_/, \"github\"],\n // ★ 2026-07-30 — JWT (eyJ...) e id.segreto NON sono più \"forti\": li usano\n // più provider (JWT: Hyperbolic, Nebius, io.net, MiniMax · id.segreto:\n // Ollama Cloud, Z.ai, BigModel). Prima vinceva sempre il primo della lista\n // — cioè Hyperbolic, che è pure a credito zero — e la chiave finiva salvata\n // sul provider sbagliato. Ora scendono fra i casi ambigui e scegli tu.\n [/^AIza[0-9A-Za-z_-]{10,}$/, \"google\"]\n ];\n for (const [rx, id] of STRONG) {\n if (rx.test(key)) return { best: publicView(byId(id)), candidates: [Object.assign(publicView(byId(id)), { ambiguous: false })] };\n }\n\n // 1-ter) ★ 2026-07-30 — TRAPPOLA GOOGLE. Un token che inizia con \"AQ.\" NON è\n // una chiave API di AI Studio: è un token OAuth TEMPORANEO (dura circa un'ora)\n // che si prende copiando dal posto sbagliato — di solito dalla sessione del\n // browser o dagli strumenti Gemini/Code Assist. Prima il registro lo trattava\n // come chiave Google valida: veniva salvato nel .env, funzionava per qualche\n // minuto e poi il pannello lo dichiarava \"chiave obsoleta\". Verificato dal vivo\n // il 2026-07-30: 401 \"Expected OAuth 2 access token\" su tutti e tre i modi\n // (Bearer, ?key=, x-goog-api-key). Ora lo diciamo PRIMA di salvarlo.\n if (/^AQ\\./.test(key)) {\n const g = byId(\"google\");\n return {\n best: null,\n candidates: g ? [Object.assign(publicView(g), { ambiguous: true })] : [],\n warn: \"Questo NON è una chiave API di Google: i token che iniziano con «AQ.» sono temporanei e scadono in circa un'ora. La chiave vera inizia con «AIza» e si prende su aistudio.google.com/app/apikey → «Create API key».\"\n };\n }\n\n // 1-bis) ★ 2026-07-30 — PREFISSI FORTI DEL CATALOGO (vck_, up_, flp_, sn4_,\n // secret_, inference-, ms-, bce-v3/, UUID Scaleway...): sono prefissi unici,\n // quindi valgono come la lista STRONG qui sopra. Prima questi provider non\n // venivano riconosciuti affatto e finivano in \"provider non riconosciuto\".\n const strongCat = PROVIDERS.filter(p => p.strong && p.detect && p.detect.test(key));\n if (strongCat.length === 1) {\n return { best: publicView(strongCat[0]), candidates: [Object.assign(publicView(strongCat[0]), { ambiguous: false })] };\n }\n\n // 2) Forme AMBIGUE (più provider plausibili) → proponi i candidati, UI conferma.\n let ids = [];\n if (/^sk-[A-Za-z0-9]/.test(key)) {\n // sk- generico: molti provider lo usano. Includi i principali + together\n // (alcune chiavi Together hanno prefisso sk-). La UI fa scegliere.\n ids = [\"deepseek\", \"openai\", \"alibaba\", \"together\", \"mistral\"];\n }\n else if (/^eyJ[A-Za-z0-9_-]+\\./.test(key)) ids = [\"io-intelligence\", \"nebius\", \"minimax\", \"hyperbolic\"];\n else if (/^[0-9a-f]{32}\\.[A-Za-z0-9_-]{10,}$/.test(key)) ids = [\"ollama-cloud\", \"zai\", \"bigmodel\"];\n else if (/^sk_/.test(key)) ids = [\"novita\", \"ppinfra\"];\n else if (/^[0-9a-f]{64}$/.test(key)) ids = [\"together\"];\n else if (/^[A-Za-z0-9]{32}$/.test(key)) ids = [\"deepinfra\", \"mistral\", \"together\"];\n\n // ★ 2026-07-30 — CANDIDATI DAL CATALOGO: qualunque altra voce la cui regex\n // riconosce questa chiave entra fra i candidati (in coda a quelli storici,\n // che restano i preferiti), ordinata per probabilità: gratis e verificati\n // prima. Così una chiave sk- propone anche moonshot/siliconflow/hunyuan/...\n // invece di lasciare l'utente davanti a un elenco vuoto.\n const extra = PROVIDERS\n .filter(p => p.detect && p.detect.test(key) && ids.indexOf(p.id) < 0)\n .sort((a, b) => candRank(a) - candRank(b))\n .map(p => p.id);\n ids = ids.concat(extra);\n\n const cands = ids.map(byId).filter(Boolean);\n return {\n best: cands[0] ? Object.assign(publicView(cands[0]), { ambiguous: cands.length > 1 }) : null,\n candidates: cands.map(p => Object.assign(publicView(p), { ambiguous: cands.length > 1 }))\n };\n}\n\n/** Vista \"pubblica\" (senza la regex) di una voce provider. */\nfunction publicView(p) {\n return {\n id: p.id, label: p.label, env: p.env, host: p.host,\n chatPath: p.chatPath, modelsPath: p.modelsPath || null,\n signup: p.signup, free: !!p.free, billed: !!p.billed, note: p.note || \"\",\n keyFmt: p.keyFmt || \"\", uncensored: !!p.uncensored,\n // ★ 2026-07-30 — verified:false = endpoint preso dal catalogo ma non ancora\n // confermato dal vivo. La UI lo mostra, così sai che dopo il salvataggio\n // conviene premere \"Verifica\".\n verified: p.verified !== false\n };\n}\n\nfunction byId(id) { return PROVIDERS.find(p => p.id === id) || null; }\nfunction byEnv(env) { return PROVIDERS.find(p => p.env === env) || null; }\nfunction all() { return PROVIDERS.map(publicView); }\n/** Solo i provider con piano gratuito, per i \"suggerimenti\". */\nfunction freeSuggestions() { return PROVIDERS.filter(p => p.free).map(publicView); }\n\n/**\n * FREE_PROVIDERS — \"Cacciatore di taglie\": lista CURATA (NON discovery automatica)\n * di provider/modelli gratuiti verificati. L'agente la mantiene a mano qui, così\n * la UI può proporli all'utente senza rischi di rate-limit/ban/falsi positivi.\n * Ogni voce:\n * id identificatore (coincide con PROVIDERS[].id quando esiste)\n * name nome leggibile\n * keyUrl dove prendere la chiave (apre il sito; MAI esponre chiavi altrui)\n * freeModels elenco (curato) di modelli :free noti\n * note perché vale la pena / cosa offre\n * uncensored true per provider/modelli senza filtri (dolphin/abliterated)\n */\nconst FREE_PROVIDERS = [\n { id: \"openrouter\", name: \"OpenRouter ⚠️ (ora a pagamento)\", keyUrl: \"https://openrouter.ai/keys\",\n freeModels: [],\n note: \"⚠️ Verificato 2026-07-24: i modelli :free grossi sono passati a pagamento (404 → 'use the paid slug'). Escluso dal failover gratuito per non creare buchi. Si riattiva con OPENROUTER_ENABLE=1 nel .env.\" },\n { id: \"github\", name: \"GitHub Models (gratis col tuo account)\", keyUrl: \"https://github.com/settings/tokens\",\n freeModels: [\"openai/gpt-4o-mini\", \"meta/llama-3.3-70b-instruct\", \"microsoft/phi-4\", \"deepseek/deepseek-v3\", \"mistral-ai/codestral-2501\"],\n note: \"Gratis con un token GitHub (nessuna carta). Metti il token come GITHUB_TOKEN: diventa subito una corsia del failover.\" },\n { id: \"mistral\", name: \"Mistral (piano free)\", keyUrl: \"https://console.mistral.ai/api-keys/\",\n freeModels: [\"codestral-latest\", \"devstral-medium-latest\", \"mistral-large-latest\", \"mistral-small-latest\"],\n note: \"Piano free con 50 richieste/minuto: codestral è ottimo per il codice. Chiave da 32 caratteri.\" },\n { id: \"groq\", name: \"Groq\", keyUrl: \"https://console.groq.com/keys\",\n freeModels: [\"llama-3.3-70b-versatile\", \"qwen-qwq-32b\", \"gpt-oss-120b\", \"deepseek-r1-distill-llama-70b\"],\n note: \"Velocissimo, gratis: llama-3.3-70b, qwen, gpt-oss-120b, deepseek-distill.\" },\n { id: \"google\", name: \"Google AI Studio (Gemini)\", keyUrl: \"https://aistudio.google.com/app/apikey\",\n freeModels: [\"gemini-2.0-flash\", \"gemini-2.5-flash\", \"gemini-2.5-pro (quota giornaliera)\"],\n note: \"Gratis: gemini-2.x-flash (grande contesto). Buono anche per immagini.\" },\n { id: \"hf\", name: \"HuggingFace Inference\", keyUrl: \"https://huggingface.co/settings/tokens\",\n freeModels: [\"meta-llama/Llama-3.3-70B-Instruct\", \"Qwen/Qwen2.5-Coder-32B-Instruct\", \"deepseek-ai/DeepSeek-V3-0324\"],\n note: \"Router su molti provider; crediti free mensili. Ospita anche modelli abliterated (vedi uncensored).\",\n uncensored: false },\n { id: \"cloudflare\", name: \"Cloudflare Workers AI\", keyUrl: \"https://dash.cloudflare.com/profile/api-tokens\",\n freeModels: [\"@cf/openai/gpt-oss-120b\", \"@cf/moonshotai/kimi-k2.7-code\", \"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b\"],\n note: \"Gratis ogni giorno (quota neuroni). Oltre alla chiave cfat_... serve CLOUDFLARE_ACCOUNT_ID nel .env, perché l'indirizzo contiene l'ID account.\" },\n { id: \"cerebras\", name: \"Cerebras\", keyUrl: \"https://cloud.cerebras.ai/\",\n freeModels: [\"gpt-oss-120b\", \"zai-glm-4.7\", \"gemma-4-31b\"],\n note: \"Gratis e ULTRA-veloce. ATTENZIONE al limite vero: 5 richieste al MINUTO (2400 al giorno) — non è la quota che finisce, è la raffica. Il router ora lo rispetta da solo.\" },\n { id: \"nvidia\", name: \"NVIDIA NIM\", keyUrl: \"https://build.nvidia.com/\",\n freeModels: [\"nvidia/llama-3.1-nemotron-ultra-253b-v1\", \"deepseek-ai/deepseek-v3-0324\", \"qwen/qwen3-coder-480b-a35b\"],\n note: \"Gratis: modelli GROSSI (nemotron, deepseek, qwen-coder, llama-405b). Ottimo per RE.\",\n uncensored: true },\n { id: \"sambanova\", name: \"SambaNova\", keyUrl: \"https://cloud.sambanova.ai/apis\",\n freeModels: [\"Meta-Llama-3.3-70B-Instruct\", \"Qwen2.5-Coder-32B-Instruct\", \"DeepSeek-V3-0324\"],\n note: \"Gratis e veloce: llama-3.1-405B, qwen. Chiave senza prefisso fisso.\" },\n { id: \"hyperbolic\", name: \"Hyperbolic ⚠️ (credito finito)\", keyUrl: \"https://app.hyperbolic.xyz/settings\",\n freeModels: [],\n note: \"⚠️ Verificato 2026-07-24: 402 'insufficient funds'. Fuori dal failover finché non ha credito (HYPERBOLIC_ENABLE=1 per riaccenderlo).\" },\n { id: \"novita\", name: \"Novita AI\", keyUrl: \"https://novita.ai/settings/key-management\",\n freeModels: [\"meta-llama/llama-3.3-70b-instruct\", \"qwen/qwen2.5-coder-32b-instruct\", \"deepseek/deepseek-v3-turbo\"],\n note: \"Crediti gratis: molti modelli open (llama, qwen, deepseek).\" },\n { id: \"chutes\", name: \"Chutes\", keyUrl: \"https://chutes.ai/\",\n freeModels: [\"deepseek-ai/DeepSeek-V3\", \"Qwen/Qwen3-235B-A22B\", \"meta-llama/Llama-3.3-70B-Instruct\"],\n note: \"Modelli open serverless, molti gratuiti (deepseek, qwen).\" },\n { id: \"ollama-cloud\", name: \"Ollama Cloud\", keyUrl: \"https://ollama.com/settings/keys\",\n freeModels: [\"qwen2.5-coder:32b\", \"deepseek-r1:70b\", \"llama3.3:70b\"],\n note: \"I tuoi modelli Ollama nel cloud (qwen, deepseek-coder). Chiave id.segreto.\" },\n { id: \"kaggle\", name: \"Kaggle GPU (abliterated coder)\", keyUrl: \"https://www.kaggle.com/code\",\n freeModels: [\"Qwen2.5-Coder-14B-Instruct-abliterated (notebook 14B)\", \"Qwen3-Coder-30B-A3B MoE abliterated (notebook 30B)\"],\n note: \"La TUA corsia abliterated coder su GPU Kaggle via tunnel ngrok. Priorità nel failover quando il notebook è acceso.\" },\n\n // ★ 2026-07-27 — NUOVI GATEWAY FREE (scoperti dal cacciatore online). OpenAI-compat,\n // piano gratuito senza carta: entrano nel failover quando incolli la chiave fittizia.\n { id: \"kilo\", name: \"Kilo Gateway (free, no account)\", keyUrl: \"https://kilo.ai/docs/gateway\",\n freeModels: [\"kilo-auto/free (router)\", \"minimax/minimax-m2.5:free\", \"stepfun/step-3.5-flash:free\", \"nvidia/nemotron-3-super-120b-a12b:free\"],\n note: \"Gateway OpenAI-compat: i modelli free funzionano SENZA account (basta KILO_KEY=none nel .env). Limite ~200 req/h per IP condiviso. Buon rinforzo al failover.\" },\n { id: \"opencode\", name: \"OpenCode Zen (gateway free)\", keyUrl: \"https://opencode.ai/docs/zen/\",\n freeModels: [\"DeepSeek V4 Flash Free\", \"Laguna S 2.1 Free\", \"Ling-3.0-flash Free\", \"North Mini Code Free\"],\n note: \"Gateway curato di modelli free (OpenAI-compat su opencode.ai/zen/v1). Metti OPENCODE_ZEN_KEY=none nel .env per attivarlo.\" },\n\n // ★ 2026-07-27 — NUOVI PROVIDER (endpoint verificati live). Uncensored dove indicato.\n { id: \"arliai\", name: \"ArliAI (senza filtri / roleplay)\", keyUrl: \"https://www.arliai.com/\",\n freeModels: [\"Mistral-Nemo-12B-ArliAI-RPMax\", \"Llama-3.1-8B abliterated\", \"Qwen2.5-Coder (varie)\"],\n note: \"Specializzato in modelli SENZA FILTRI e roleplay: sul piano le richieste sono illimitate come modelli, con un limite di richieste in parallelo. Piano free disponibile.\",\n uncensored: true },\n { id: \"deepinfra\", name: \"DeepInfra (catalogo enorme open)\", keyUrl: \"https://deepinfra.com/dash/api_keys\",\n freeModels: [\"meta-llama/Llama-3.3-70B-Instruct\", \"Qwen/Qwen2.5-Coder-32B-Instruct\", \"deepseek-ai/DeepSeek-V3\", \"mistralai/Mixtral\"],\n note: \"Tantissimi modelli open a prezzo bassissimo, con credito iniziale gratuito. OpenAI-compat, ottimo come rincalzo.\",\n uncensored: false },\n { id: \"featherless\", name: \"Featherless (ogni modello HuggingFace)\", keyUrl: \"https://featherless.ai/\",\n freeModels: [\"qualsiasi modello HF, inclusi abliterated/uncensored\"],\n note: \"Esegue quasi OGNI modello di HuggingFace (compresi gli abliterated senza filtri) ad abbonamento fisso. Chiave rc_...\",\n uncensored: true },\n { id: \"cloudrift\", name: \"Cloudrift (gateway inference)\", keyUrl: \"https://www.cloudrift.ai/\",\n freeModels: [\"deepseek\", \"qwen\", \"llama (secondo catalogo live)\"],\n note: \"Gateway inference OpenAI-compat con credito di prova gratuito. Buon rincalzo al failover.\",\n uncensored: true },\n\n // ★ 2026-07-27 — SUGGERIMENTI (NON nel failover: endpoint non OpenAI-compat standard\n // o richiedono account). Il cacciatore li propone, ma Antigravity non li usa attivamente.\n { id: \"cohere\", name: \"Cohere (free trial, no carta)\", keyUrl: \"https://dashboard.cohere.com/api-keys\",\n freeModels: [\"command-a-03-2025\", \"command-r-plus-08-2024\", \"command-r7b-12-2024\"],\n note: \"Free 'Trial' 1000 chiamate/mese, no carta, ma endpoint /v2 NON OpenAI-compat -> non usato dal failover. Utile solo chiamandolo a mano.\" },\n { id: \"vercel\", name: \"Vercel AI Gateway (aggregatore)\", keyUrl: \"https://vercel.com/docs/ai-gateway\",\n freeModels: [\"(router a molti provider, $5/mese di credito)\"],\n note: \"Aggregatore che instrada a tanti provider. Richiede account Vercel + chiave -> non nel failover automatico, ma buono come fonte di modelli.\" },\n // ★ 2026-07-24 — RIMOSSE tre voci che facevano perdere tempo all'utente:\n // • \"nous\" → creare la chiave sul portale Nous CHIEDE SOLDI, non è gratis;\n // • \"hf-uncensored\" e \"ollama-uncensored\" → non sono provider con API gratuita:\n // scaricano modelli da far girare IN LOCALE, e su una Quadro T1000 (4 GB)\n // non gira niente di utile. Proporli era una presa in giro.\n // Il cacciatore deve proporre SOLO API gratuite raggiungibili dalla rete.\n];\n\n// ★ 2026-07-30 — Il cacciatore ora propone anche TUTTI i provider del catalogo\n// preconfigurato (scheda \"Provider\" e scheda \"Senza filtri\"). Ogni proposta ha\n// già id/endpoint/variabile .env nel registro: premendo \"Incolla qui\" e\n// incollando la chiave, il salvataggio funziona davvero e il provider entra nel\n// failover senza toccare il codice.\nfor (const c of CATALOG) {\n if (FREE_PROVIDERS.some(f => f.id === c.id)) continue;\n FREE_PROVIDERS.push({\n id: c.id,\n name: c.label + (c.verified === false ? \" (da verificare)\" : \"\"),\n keyUrl: c.signup || \"\",\n freeModels: c.freeModels || [],\n note: c.note || \"\",\n uncensored: !!c.uncensored,\n // niente piano gratuito vero: resta proposto ma marcato, così sai che è\n // credito di prova / a consumo prima di perderci tempo.\n paid: !c.free\n });\n}\n\n/** Vista pubblica della lista curata (niente chiavi/segreti).\n * type: undefined|\"all\" → tutto · \"uncensored\" → solo senza filtri. */\nfunction freeProviders(type) {\n let list = FREE_PROVIDERS;\n if (type === \"uncensored\") list = list.filter(p => p.uncensored);\n return list.map(p => Object.assign({}, p));\n}\n\nmodule.exports = { PROVIDERS, detectProvider, publicView, byId, byEnv, all, freeSuggestions, FREE_PROVIDERS, freeProviders };\n"}}, "src/mobile-page.html": {"b004d67566fd93489bf4cb3fbc1b4d93bfed8e95": {"t": 1786068563.5188546, "n": 128482, "h": "66697b5c4c5dd32d", "c": "\n\n
\n\n\n\n