""" Free LLM Provider Tester — finds 3 working models beyond Groq Get free keys at: - Gemini: https://aistudio.google.com/apikey - Cerebras: https://cloud.cerebras.ai (free tier) - OpenRouter:https://openrouter.ai (free models, no CC needed) - Together: https://api.together.xyz ($5 free credit) - Mistral: https://console.mistral.ai (free tier) - Cohere: https://dashboard.cohere.com (free trial key) Run: python test_free_llms.py Leave blank and hit Enter to skip a provider. """ import urllib.request, urllib.error, json, time, os def ask(label, env_var): val = os.environ.get(env_var, "").strip() if not val: val = input(f" {label} API key (blank to skip): ").strip() return val or None print("\n=== Free LLM Provider Test ===\n") print("Paste keys for providers you have. Skip others.\n") print() results = [] def post(url, headers, payload, timeout=20): data = json.dumps(payload).encode() req = urllib.request.Request(url, data=data, headers=headers, method="POST") try: with urllib.request.urlopen(req, timeout=timeout) as r: return r.getcode(), json.loads(r.read().decode()) except urllib.error.HTTPError as e: return e.code, e.read().decode()[:300] except Exception as ex: return -1, str(ex) # ── 1. GOOGLE GEMINI ────────────────────────────────────────────────────────── if GEMINI_KEY: print("Testing Google Gemini...") for model in ["gemini-2.0-flash-lite", "gemini-1.5-flash", "gemini-1.5-flash-8b"]: url = f"https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent?key={GEMINI_KEY}" payload = {"contents": [{"parts": [{"text": "What is 2+2? Reply with just the number."}]}]} code, resp = post(url, {"Content-Type": "application/json"}, payload) if code == 200: try: reply = resp["candidates"][0]["content"]["parts"][0]["text"].strip() print(f" ✅ google/{model} → \"{reply}\"") results.append({"provider": "gemini", "model": model, "reply": reply}) except: print(f" ⚠️ google/{model} [200 but parse error]: {str(resp)[:80]}") else: print(f" ❌ google/{model} [{code}]: {str(resp)[:80]}") time.sleep(0.3) # ── 2. CEREBRAS ─────────────────────────────────────────────────────────────── if CEREBRAS_KEY: print("Testing Cerebras...") for model in ["llama3.1-8b", "llama3.3-70b", "llama-4-scout-17b-16e-instruct"]: url = "https://api.cerebras.ai/v1/chat/completions" headers = {"Authorization": f"Bearer {CEREBRAS_KEY}", "Content-Type": "application/json"} payload = {"model": model, "messages": [{"role": "user", "content": "What is 2+2? Reply with just the number."}], "max_tokens": 10} code, resp = post(url, headers, payload) if code == 200: try: reply = resp["choices"][0]["message"]["content"].strip() print(f" ✅ cerebras/{model} → \"{reply}\"") results.append({"provider": "cerebras", "model": model, "reply": reply}) except: print(f" ⚠️ cerebras/{model} [200 parse error]: {str(resp)[:80]}") else: print(f" ❌ cerebras/{model} [{code}]: {str(resp)[:80]}") time.sleep(0.3) # ── 3. OPENROUTER (has genuinely free :free models) ─────────────────────────── if OPENROUTER_KEY: print("Testing OpenRouter (free models)...") free_models = [ "meta-llama/llama-3.2-3b-instruct:free", "meta-llama/llama-3.1-8b-instruct:free", "mistralai/mistral-7b-instruct:free", "google/gemma-3-4b-it:free", "microsoft/phi-3-mini-128k-instruct:free", "qwen/qwen3-8b:free", ] url = "https://openrouter.ai/api/v1/chat/completions" headers = { "Authorization": f"Bearer {OPENROUTER_KEY}", "Content-Type": "application/json", "HTTP-Referer": "https://github.com/test", } for model in free_models: payload = {"model": model, "messages": [{"role": "user", "content": "What is 2+2? Reply with just the number."}], "max_tokens": 10} code, resp = post(url, headers, payload) if code == 200: try: reply = resp["choices"][0]["message"]["content"].strip() print(f" ✅ openrouter/{model} → \"{reply}\"") results.append({"provider": "openrouter", "model": model, "reply": reply}) except: print(f" ⚠️ openrouter/{model} [200 parse error]: {str(resp)[:80]}") elif code == 429: print(f" ⏳ openrouter/{model} — rate limited") else: print(f" ❌ openrouter/{model} [{code}]: {str(resp)[:100]}") time.sleep(0.5) # ── 4. TOGETHER AI ──────────────────────────────────────────────────────────── if TOGETHER_KEY: print("Testing Together AI...") together_models = [ "meta-llama/Llama-3.2-3B-Instruct-Turbo", "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo", "mistralai/Mistral-7B-Instruct-v0.3", "Qwen/Qwen2.5-7B-Instruct-Turbo", ] url = "https://api.together.xyz/v1/chat/completions" headers = {"Authorization": f"Bearer {TOGETHER_KEY}", "Content-Type": "application/json"} for model in together_models: payload = {"model": model, "messages": [{"role": "user", "content": "What is 2+2?"}], "max_tokens": 10} code, resp = post(url, headers, payload) if code == 200: try: reply = resp["choices"][0]["message"]["content"].strip() print(f" ✅ together/{model} → \"{reply}\"") results.append({"provider": "together", "model": model, "reply": reply}) except: print(f" ⚠️ together/{model}: {str(resp)[:80]}") else: print(f" ❌ together/{model} [{code}]: {str(resp)[:100]}") time.sleep(0.3) # ── 5. MISTRAL ──────────────────────────────────────────────────────────────── if MISTRAL_KEY: print("Testing Mistral...") for model in ["mistral-small-latest", "open-mistral-nemo", "open-mistral-7b"]: url = "https://api.mistral.ai/v1/chat/completions" headers = {"Authorization": f"Bearer {MISTRAL_KEY}", "Content-Type": "application/json"} payload = {"model": model, "messages": [{"role": "user", "content": "What is 2+2?"}], "max_tokens": 10} code, resp = post(url, headers, payload) if code == 200: try: reply = resp["choices"][0]["message"]["content"].strip() print(f" ✅ mistral/{model} → \"{reply}\"") results.append({"provider": "mistral", "model": model, "reply": reply}) except: print(f" ⚠️ mistral/{model}: {str(resp)[:80]}") else: print(f" ❌ mistral/{model} [{code}]: {str(resp)[:100]}") time.sleep(0.3) # ── 6. COHERE ───────────────────────────────────────────────────────────────── if COHERE_KEY: print("Testing Cohere...") url = "https://api.cohere.com/v2/chat" headers = {"Authorization": f"Bearer {COHERE_KEY}", "Content-Type": "application/json"} for model in ["command-r7b-12-2024", "command-r-plus-08-2024"]: payload = {"model": model, "messages": [{"role": "user", "content": "What is 2+2?"}], "max_tokens": 10} code, resp = post(url, headers, payload) if code == 200: try: reply = resp["message"]["content"][0]["text"].strip() print(f" ✅ cohere/{model} → \"{reply}\"") results.append({"provider": "cohere", "model": model, "reply": reply}) except: print(f" ⚠️ cohere/{model}: {str(resp)[:80]}") else: print(f" ❌ cohere/{model} [{code}]: {str(resp)[:100]}") time.sleep(0.3) # ── SUMMARY ─────────────────────────────────────────────────────────────────── print("\n" + "="*60) print(f" WORKING: {len(results)} models found") print("="*60) if results: print("\n✅ These are ready to plug in:\n") seen_providers = set() for r in results: tag = f"[{r['provider'].upper()}]" print(f" {tag:15} {r['model']}") seen_providers.add(r['provider']) print("\n📋 Recommended top 3 (one per provider for diversity):") shown = set() count = 0 for r in results: if r['provider'] not in shown and count < 3: print(f" {count+1}. provider={r['provider']!r}, model={r['model']!r}") shown.add(r['provider']) count += 1 else: print("\n No providers tested or all failed.") print(" Get free keys at the URLs at the top of this file!")