Skip to content

Latest commit

 

History

History
272 lines (193 loc) · 13.4 KB

getting-started.md

File metadata and controls

272 lines (193 loc) · 13.4 KB

Getting Started

This guide walks through installing, configuring, and running Free Provider end to end.


Requirements

  • Node.js 20.12+ (uses native fetch, process.loadEnvFile, ESM)
  • Optional: pnpm or npm for installing the server dependency (express)
  • Optional: Git and gh CLI if you cloned / forked the repo

1. Install

# From the repo root, install the client deps (undici for proxy support)
npm install        # or: pnpm install

# Then the server dependency (express + undici)
cd server
npm install        # or: pnpm install

The chat client itself has zero hard dependencies — only proxy rotation needs undici, which is installed above. The HTTP server needs express.


2. Run the server

npm start          # or: pnpm start

You should see output like:

Free Provider Server
  Frontend: http://localhost:3000
  API:      http://localhost:3000/v1
  API Key:  sk-free-… (generated, saved in .api-key)
  -> export OPENAI_API_KEY="sk-free-…"
  Models:   gpt-5.6-luna, gpt-4o, gpt-4o-mini, gpt-3.5-turbo, gemini-3-pro, gemini-3-flash, gemini-3-lite

Open http://localhost:3000 in your browser to use the chat UI.


3. Configuration

All configuration lives in server/config.mjs and can be overridden with environment variables:

.env is auto-loaded from the repository root on startup (process.loadEnvFile). Values already set in your shell win over .env. A template with all options lives at .env.example.

Variable Default Description
PORT 3000 HTTP port
OPENAI_API_KEY (generated) Bearer token required by clients. If unset, a random key is generated and saved to .api-key
DEFAULT_MODEL auto Fallback model when none is sent. The default auto alternates each request between ChatGPT and Gemini (see Auto model balancing)
GEMINI_DEFAULT_MODEL gemini-3-flash Default Gemini model for gemini-* requests
CHATGPT_COOKIES client/cookies.json Optional file of ChatGPT cookies for authenticated mode
PROXY_URLS (empty) Comma-separated proxies (socks5://…, http://…) rotated on Cloudflare blocks
PROXY_FILE client/proxies.txt File with one proxy URL per line, merged with PROXY_URLS; blank lines and # comments are ignored
COOLDOWN_SECONDS 30 Seconds ALL requests pause after MAX_CONSECUTIVE_BLOCKS consecutive blocks
MAX_COOLDOWN_SECONDS 300 Upper bound of the (escalating) cooldown period
MAX_CONSECUTIVE_BLOCKS 3 Consecutive blocks before the global cooldown engages
INTER_REQUEST_DELAY_MS 0 Minimum ms between outgoing requests (anti-hammering; 0 = off)
MAX_REQ_PER_WINDOW 12 Requests allowed per pacing window before throttling (0 disables pacing)
PACING_WINDOW_SECONDS 30 Length of the pacing window
INIT_TTL_MS 600000 How long the page-init (buildId/deviceId) is cached to skip GET / per message
AGENT_COUNT 3 Independent client agents per provider (chatgpt + gemini), round-robin. Each has its own proxy rotation, cooldown, pacing and session state. In auto mode the N-th window of each provider form pair N. Set 1 for single-agent behavior
FETCH_TIMEOUT_MS 120000 Max ms per outgoing request to ChatGPT (the pipeline does several sequential requests per answer)
STREAM_RETRIES 2 Extra retries for streaming requests before giving up
PROXY_COOLDOWN_SECONDS 60 Seconds a proxy is benched after being blocked

A template with all options lives at .env.example.

Set a persistent API key

export OPENAI_API_KEY="sk-my-own-key"
npm start

You can also edit .api-key directly — it is auto-read on startup if OPENAI_API_KEY is not set.


4. Use it

Via the browser UI

Just type a message. Configure the server URL and API key under Settings (gear icon).

Via cURL

API_KEY=$(cat /mnt/d/Open-source/AI_Proofy_unoffical/.api-key)   # or your exported key

curl http://localhost:3000/v1/chat/completions \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o","messages":[{"role":"user","content":"Hello"}],"stream":true}'

Via any OpenAI SDK

Point the base URL at the server and use any model listed in GET /v1/models:

const client = new OpenAI({
  baseURL: "http://localhost:3000/v1",
  apiKey: "sk-free-…",
});

Requests are routed by model prefix: gemini-* → the Gemini web backend, everything else → ChatGPT. Both return identical OpenAI-compatible responses, so you can mix models freely.

Auto model balancing

Leave model off (or send "auto") and requests split evenly across both backends instead of hitting one provider:

req #1 → chatgpt, pair 0      req #3 → chatgpt, pair 1
req #2 → gemini, pair 0       req #4 → gemini, pair 1   … wraps after AGENT_COUNT pairs

Pair i = ChatGPT window i + Gemini window i, so alternating requests hop chatgpt → gemini and rotate through the pairs. Great when you want to halve the hammering on a single backend and share the load. Send an explicit model any time you want to pin a backend.

curl http://localhost:3000/v1/chat/completions \
  -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"auto","messages":[{"role":"user","content":"Hello"}]}'

4b. A second free provider: Gemini

Besides the ChatGPT backend, Free Provider also speaks to Gemini through a cookie-free, guest-mode client. No account or cookies are needed — it scrapes gemini.google.com, obtains an anonymous session, and uses the same agent-pool/cooldown machinery as ChatGPT.

  • Models: gemini-3-pro, gemini-3-flash (default), gemini-3-lite — use any listed in /v1/models.
  • Works over plain HTTPS (no proxy required); Gemini blocks surface as 429 just like ChatGPT blocks.
  • Swap a chat: "model":"gemini-3-flash" instead of "model":"gpt-4o".

Standalone smoke test (no server):

node client/gemini.mjs "Hello"        # one-shot
node client/gemini.mjs --stream "Hello"  # token stream

5. Adding ChatGPT cookies (optional)

Drop a file at client/cookies.json:

[
  { "name": "__Secure-next-auth.session-token", "value": "…" },
  { "name": "cf_clearance", "value": "…" }
]

See client/cookies.json.example for the exact shape. When present, the client uses authenticated endpoints and unlocks more capabilities.


6. Avoiding "Blocked by Cloudflare"

The ChatGPT web backend rate-limits and bot-checks aggressive usage. Free Provider layers several defenses:

a) Adaptive pacing (keeps you fast, under the radar)

The transport runs a sliding-window token bucket: requests fire instantly until a burst limit, then the next ones are spaced just under the threshold — so normal usage stays instant while bursts don't trip the guard.

  • MAX_REQ_PER_WINDOW — allowed requests per PACING_WINDOW_SECONDS (default 12 per 30s). Set 0 to disable.
  • After any Cloudflare block the bucket tightens (halves capacity) until a request succeeds, then relaxes again.
  • Combined with INTER_REQUEST_DELAY_MS, every outbound request (init, tokens, conduit, conversation) is counted, not just completions.

On top of that, per-message init() is now cached (INIT_TTL_MS, default 10 min), so each message costs 3 requests instead of 4.

b) Rate limiting / cooldown

  • After MAX_CONSECUTIVE_BLOCKS (default 3) consecutive Cloudflare blocks, the server enters a global cooldown. The wait escalates (30s → 60s → 120s … capped at MAX_COOLDOWN_SECONDS, default 300s) and resets after a success. During cooldown, /v1/chat/completions returns 429 with a Retry-After header:
    { "error": { "message": "Server cooling down after Cloudflare blocks (retry in 30s)", "type": "rate_limit_error", "code": "server_cooldown" } }
  • Each block also triggers exponential backoff (1s → 2s → 4s … capped at 16s) and User-Agent rotation.

c) Proxy rotation

Configure a pool of proxies and the client rotates to a fresh IP on each block:

# .env or shell
PROXY_URLS=socks5://user:pass@host:1080,http://user:pass@proxy.example.com:8080

or a file (client/proxies.txt, gitignored):

socks5://user:pass@proxy1:1080
http://user:pass@proxy2:8080
  • Supported protocols: http://, https://, socks4://, socks5://. HTTP(S) proxies use undici.ProxyAgent; socks5:// uses undici's built-in Socks5ProxyAgent (native TLS over the tunnel); socks4:// uses a custom connector that TLS-wraps the tunneled socket.
  • A blocked proxy is benched for PROXY_COOLDOWN_SECONDS before reuse; the pool round-robins through the rest.
  • If every proxy is benched, the whole instance cools down and reports the wait time.

d) Streaming retry

Streaming requests now retry like normal requests (STREAM_RETRIES, default 2) with backoff, proxy + UA rotation — previously they gave up on the first failure.

Getting the right status codes

SDK/tool clients (OpenAI SDK, mentor, etc.) only retry rate-limit errors cleanly. Free Provider returns:

  • 429 + Retry-After for rate-limit situations (all agents cooling down, a proxy pool exhausted, a ChatGPT block/flag). The SDK then respects the backoff instead of hammering.
  • 200 + SSE for a normal stream; if the stream fails after the first token, an error event is sent and the SDK surfaces it as a stream error.
  • 500 only for genuine unexpected provider failures.

Streaming headers are flushed on the first chunk (not before), so a block that happens during init/tokens still returns a proper 429 instead of a 200 with an error event.

e) Multi-agent round-robin

With AGENT_COUNT > 1 (default 3), the server runs several independent ChatGPT client instances. Each agent has its own:

  • ChatGPT client + session state (buildId, deviceId, tokens)
  • CFBypass transport with its own pacing window, cooldown, proxy rotation and internal lock

Incoming requests are distributed round-robin across agents, so several can be in flight at once (each under its own lock). If one agent enters cooldown from Cloudflare blocks, the others keep serving — the server only returns 429 when all agents are cooling down simultaneously.

Set AGENT_COUNT=1 to get the original single-agent behavior.

f) Multiple proxies (the reliable fix for flagged IPs)

When ChatGPT flags your IP ("Unusual activity") or Cloudflare challenges it, the only reliable fix is clean proxy IPs. Free Provider supports a pool of mixed proxies:

# client/proxies.txt (already created, gitignored)
socks5://user:pass@proxy1.net:1080
socks5://user:pass@proxy2.net:1080
http://user:pass@proxy3.net:8080
  • All agents rotate through the same list round-robin.
  • A flagged/blocked proxy is benched for PROXY_COOLDOWN_SECONDS while the others keep serving — the pool self-heals.
  • Mix http://, https://, socks4://, socks5:// freely.

Monitor the live pool with GET /v1/pool (Bearer key required) — it reports each agent's readiness, cooldown, and every proxy's status/bench time left.

Tor as a quick test. No real proxies handy? A local Tor instance works too — just point the pool at it:

# .env
PROXY_URLS=socks5://127.0.0.1:9050

(start tor so it listens on 9050). This is the equivalent of proxychains node server/index.mjs but stays inside the agent pool. Note: Tor exit nodes are slow and often blocked/flagged by chatgpt.com, so use real http/socks5 proxies for production.


7. Logs

Every chat request is logged — user messages and AI responses — both to the terminal and to server/chat.log:

{"timestamp":"…","type":"completion","stream":true,"model":"gpt-4o","user":["Hi"],"assistant":"Hello!"}

See Security for what log output may contain.


Troubleshooting

  • EADDRINUSE on startup — another process holds port 3000. Stop it or set PORT to another value.
  • Conversation returns 404 — the provider is stateless on purpose; context travels in the messages array. Sending a full history keeps things working.
  • Blocked by Cloudflare — the web backend sometimes challenges a datacenter/abusive IP. Wait for the cooldown, add proxies (PROXY_URLS / proxies.txt), lower concurrency with INTER_REQUEST_DELAY_MS, or use a residential proxy.
  • Flagged as unusual activity by ChatGPT — ChatGPT's backend (not Cloudflare) temporarily flags an IP/device that sent too many anonymous requests. The transport now detects this, retries with UA/cookie rotation (and proxy rotation if proxies are configured), then escalates cooldown and reports the wait as a 429 + Retry-After so client tools respect the backoff. The flag is time-based: wait and retry, or use CHATGPT_COOKIES (logged-in) or clean proxies to sidestep the flag — see f) Multiple proxies.
  • HTTP 500 with Conversation failed: 4xx — the underlying call to chatgpt.com was rejected. 429/403/503 are now retried with backoff, UA + proxy rotation; the response body is what actually failed, so check chat.log for the reason.
  • Repeated 500 / "fetch failed" despite a healthy provider — you may be hitting a stale server that kept running after a config change (it still holds the old port/proxies). Check ss -tlnp | grep 3000 for what's actually bound, kill it, and start fresh with the new config.