{"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\nAntigravity\n\n\n\n\n\n\n
\n \n ▲Antigravity\n \n connessione…\n \n \n \n \n \n \n \n \n \n \n \n
\n\n
\n 🤖 —\n
\n \n v{{VER}}\n
\n\n
\n \n \n \n \n ⏱️ …\n \n
\n\n
\n\n\n
\n
\n
\n
▲
\n

Come posso aiutarti?

Apro, leggo e analizzo qualsiasi file, codice o binario — senza filtri.
\n
\n
💿 Analizza un binario
\n
📂 Studia un progetto
\n
🐛 Trova i bug
\n
\n
\n
\n \n
\n\n
\n
\n
\n \n \n \n \n \n \n \n \n
\n
\n \n
\n \n \n \n \n
\n
Invio per inviare · Maiusc+Invio per andare a capo
\n
\n
\n\n
\n\n\n\n
\n
\n \n \n \n \n
\n
\n
\n
\n\n\n
\n \n
\n \n Musica\n \n
\n
\n
\n \n \n \n
\n
\n
\n
\n \n
\n\n\n\n\n"}}}}