Last active
March 10, 2026 14:13
-
-
Save PeronGH/3b8f8ecc9a013c2429cb150eb4abf635 to your computer and use it in GitHub Desktop.
LLM API Extraction PoC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env -S deno run -A --env | |
| /** | |
| * factory-api.ts — Factory.ai auth + local API proxy. | |
| * | |
| * Login (saves credentials to .env): | |
| * deno run -A factory-api.ts login > .env | |
| * | |
| * Serve (auto-reads .env, proxies with injected credentials): | |
| * deno run -A --env factory-api.ts serve [--port 8000] [--host 127.0.0.1] | |
| * | |
| * The local proxy injects Factory credentials so SDK clients can use | |
| * any non-empty string as API key: | |
| * | |
| * ANTHROPIC_BASE_URL=http://localhost:8000/anthropic ANTHROPIC_API_KEY=x | |
| * OPENAI_BASE_URL=http://localhost:8000/openai/v1 OPENAI_API_KEY=x | |
| */ | |
| // ── Constants ─────────────────────────────────────────────────────── | |
| const CLIENT_ID = "client_01HNM792M5G5G1A2THWPXKFMXB"; | |
| const AUTH_URL = | |
| "https://api.workos.com/user_management/authorize/device"; | |
| const TOKEN_URL = | |
| "https://api.workos.com/user_management/authenticate"; | |
| const FACTORY = "https://api.factory.ai"; | |
| /** Provider route prefix → Factory proxy path + x-api-provider value. */ | |
| const ROUTES: Record<string, { path: string; provider: string }> = { | |
| anthropic: { path: "/api/llm/a", provider: "anthropic" }, | |
| openai: { path: "/api/llm/o", provider: "openai" }, | |
| google: { path: "/api/llm/g", provider: "google" }, | |
| bedrock: { path: "/api/llm/a", provider: "bedrock_anthropic" }, | |
| vertex: { path: "/api/llm/a", provider: "vertex_anthropic" }, | |
| }; | |
| // ── Auth ──────────────────────────────────────────────────────────── | |
| interface TokenSet { | |
| access_token: string; | |
| refresh_token: string; | |
| [k: string]: unknown; | |
| } | |
| function decodeJwt(token: string): Record<string, unknown> { | |
| const seg = token.split(".")[1]; | |
| const pad = seg + "=".repeat((4 - (seg.length % 4)) % 4); | |
| return JSON.parse( | |
| new TextDecoder().decode( | |
| Uint8Array.from( | |
| atob(pad.replace(/-/g, "+").replace(/_/g, "/")), | |
| (c) => c.charCodeAt(0), | |
| ), | |
| ), | |
| ); | |
| } | |
| async function deviceAuth() { | |
| const res = await fetch(AUTH_URL, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/x-www-form-urlencoded" }, | |
| body: new URLSearchParams({ client_id: CLIENT_ID }), | |
| }); | |
| if (!res.ok) { | |
| throw new Error(`Device auth failed (${res.status}): ${await res.text()}`); | |
| } | |
| return res.json() as Promise<{ | |
| device_code: string; | |
| user_code: string; | |
| verification_uri_complete: string; | |
| expires_in: number; | |
| interval: number; | |
| }>; | |
| } | |
| async function pollToken( | |
| code: string, | |
| expiresIn: number, | |
| interval: number, | |
| ): Promise<TokenSet> { | |
| const deadline = Date.now() + expiresIn * 1000; | |
| let delay = interval; | |
| while (Date.now() < deadline) { | |
| const res = await fetch(TOKEN_URL, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/x-www-form-urlencoded" }, | |
| body: new URLSearchParams({ | |
| grant_type: "urn:ietf:params:oauth:grant-type:device_code", | |
| device_code: code, | |
| client_id: CLIENT_ID, | |
| }), | |
| }); | |
| const body = await res.json(); | |
| if (res.ok) return body as TokenSet; | |
| if (body.error === "slow_down") delay += 1; | |
| else if (body.error !== "authorization_pending") { | |
| throw new Error(`Auth failed: ${body.error}`); | |
| } | |
| await new Promise((r) => setTimeout(r, delay * 1000)); | |
| } | |
| throw new Error("Device authorization timed out"); | |
| } | |
| async function refreshToken(rt: string, orgId?: string): Promise<TokenSet> { | |
| const p: Record<string, string> = { | |
| grant_type: "refresh_token", | |
| refresh_token: rt, | |
| client_id: CLIENT_ID, | |
| }; | |
| if (orgId) p.organization_id = orgId; | |
| const res = await fetch(TOKEN_URL, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/x-www-form-urlencoded" }, | |
| body: new URLSearchParams(p), | |
| }); | |
| if (!res.ok) { | |
| throw new Error(`Refresh failed (${res.status}): ${await res.text()}`); | |
| } | |
| return res.json(); | |
| } | |
| async function resolveOrg(token: string): Promise<string> { | |
| const res = await fetch(`${FACTORY}/api/cli/org`, { | |
| headers: { Authorization: `Bearer ${token}` }, | |
| }); | |
| if (!res.ok) { | |
| throw new Error( | |
| `Org resolution failed (${res.status}): ${await res.text()}`, | |
| ); | |
| } | |
| const { workosOrgIds } = await res.json(); | |
| if (!workosOrgIds?.length) { | |
| throw new Error( | |
| "No org found. Visit https://app.factory.ai/cli-onboarding", | |
| ); | |
| } | |
| return workosOrgIds[0]; | |
| } | |
| function tryOpen(url: string) { | |
| const cmds: Record<string, string[]> = { | |
| darwin: ["open", url], | |
| windows: ["cmd", "/c", "start", url], | |
| linux: ["xdg-open", url], | |
| }; | |
| const [cmd, ...args] = cmds[Deno.build.os] ?? cmds.linux; | |
| try { | |
| new Deno.Command(cmd, { | |
| args, | |
| stdin: "null", | |
| stdout: "null", | |
| stderr: "null", | |
| }).spawn(); | |
| } catch { /* browser open is best-effort */ } | |
| } | |
| // ── Token Manager ─────────────────────────────────────────────────── | |
| class Tokens { | |
| #at: string; | |
| #rt: string; | |
| #org: string; | |
| #exp = 0; | |
| #pending: Promise<void> | null = null; | |
| constructor(at: string, rt: string, org: string) { | |
| this.#at = at; | |
| this.#rt = rt; | |
| this.#org = org; | |
| this.#readExp(); | |
| } | |
| #readExp() { | |
| try { | |
| const { exp } = decodeJwt(this.#at); | |
| this.#exp = typeof exp === "number" ? exp * 1000 : Date.now() + 3600_000; | |
| } catch { | |
| this.#exp = Date.now() + 3600_000; | |
| } | |
| } | |
| get expiresAt() { | |
| return this.#exp; | |
| } | |
| async access(): Promise<string> { | |
| if (Date.now() > this.#exp - 300_000) { | |
| this.#pending ??= this.#refresh().finally(() => { | |
| this.#pending = null; | |
| }); | |
| await this.#pending; | |
| } | |
| return this.#at; | |
| } | |
| async #refresh() { | |
| console.error("[proxy] refreshing token..."); | |
| const t = await refreshToken(this.#rt, this.#org); | |
| this.#at = t.access_token; | |
| this.#rt = t.refresh_token; | |
| this.#readExp(); | |
| console.error( | |
| `[proxy] refreshed — expires ${new Date(this.#exp).toISOString()}`, | |
| ); | |
| } | |
| } | |
| // ── Proxy ─────────────────────────────────────────────────────────── | |
| function resolveRoute( | |
| pathname: string, | |
| ): { upstream: string; provider: string | null } { | |
| for (const [name, { path, provider }] of Object.entries(ROUTES)) { | |
| const pfx = `/${name}`; | |
| if (pathname === pfx || pathname.startsWith(`${pfx}/`)) { | |
| return { | |
| upstream: FACTORY + path + pathname.slice(pfx.length), | |
| provider, | |
| }; | |
| } | |
| } | |
| // Catch-all: forward to api.factory.ai as-is | |
| return { upstream: FACTORY + pathname, provider: null }; | |
| } | |
| async function handle(req: Request, tm: Tokens): Promise<Response> { | |
| const url = new URL(req.url); | |
| // Health / info endpoint | |
| if (url.pathname === "/" && req.method === "GET") { | |
| return Response.json({ | |
| status: "ok", | |
| routes: Object.keys(ROUTES).map((r) => `/${r}/*`), | |
| }); | |
| } | |
| const { upstream, provider } = resolveRoute(url.pathname); | |
| const target = upstream + url.search; | |
| const token = await tm.access(); | |
| // Build upstream headers | |
| const h = new Headers(req.headers); | |
| h.set("Authorization", `Bearer ${token}`); | |
| h.set("User-Agent", "factory-cli/0.62.1"); | |
| if (!h.has("x-session-id")) h.set("x-session-id", crypto.randomUUID()); | |
| if (!h.has("x-assistant-message-id")) { | |
| h.set("x-assistant-message-id", crypto.randomUUID()); | |
| } | |
| if (provider && !h.has("x-api-provider")) { | |
| h.set("x-api-provider", provider); | |
| } | |
| h.delete("host"); | |
| const body = | |
| req.body && !["GET", "HEAD"].includes(req.method) | |
| ? await req.arrayBuffer() | |
| : null; | |
| try { | |
| const res = await fetch(target, { method: req.method, headers: h, body }); | |
| // Strip hop-by-hop / encoding headers — Deno's fetch may have decoded | |
| const rh = new Headers(res.headers); | |
| rh.delete("content-encoding"); | |
| rh.delete("content-length"); | |
| console.error(`${req.method} ${url.pathname} → ${res.status}`); | |
| return new Response(res.body, { status: res.status, headers: rh }); | |
| } catch (e) { | |
| console.error(`[proxy] ${e}`); | |
| return Response.json( | |
| { error: "proxy_error", message: String(e) }, | |
| { status: 502 }, | |
| ); | |
| } | |
| } | |
| // ── CLI: login ────────────────────────────────────────────────────── | |
| async function cmdLogin() { | |
| console.error("Factory.ai — Device Flow Login\n"); | |
| const dev = await deviceAuth(); | |
| console.error( | |
| `Open this URL to log in:\n ${dev.verification_uri_complete}\n`, | |
| ); | |
| console.error(`Code: ${dev.user_code} (expires in ${dev.expires_in}s)\n`); | |
| tryOpen(dev.verification_uri_complete); | |
| console.error("Waiting for approval...\n"); | |
| const tokens = await pollToken( | |
| dev.device_code, | |
| dev.expires_in, | |
| dev.interval, | |
| ); | |
| console.error("Authenticated!\n"); | |
| // Resolve org & get org-scoped token | |
| let orgId: string; | |
| let claims: Record<string, unknown> | null = null; | |
| try { | |
| claims = decodeJwt(tokens.access_token); | |
| } catch { /* not a valid JWT */ } | |
| if (claims?.org_id) { | |
| orgId = claims.org_id as string; | |
| } else { | |
| console.error("Resolving organization..."); | |
| orgId = await resolveOrg(tokens.access_token); | |
| const scoped = await refreshToken(tokens.refresh_token, orgId); | |
| tokens.access_token = scoped.access_token; | |
| tokens.refresh_token = scoped.refresh_token; | |
| console.error("Done.\n"); | |
| } | |
| // dotenv to stdout | |
| console.log(`FACTORY_ACCESS_TOKEN=${tokens.access_token}`); | |
| console.log(`FACTORY_REFRESH_TOKEN=${tokens.refresh_token}`); | |
| console.log(`FACTORY_ORG_ID=${orgId}`); | |
| // Human-readable info to stderr | |
| try { | |
| const c = decodeJwt(tokens.access_token); | |
| console.error( | |
| `\nLogged in as ${c.email} (org: ${c.external_org_id ?? orgId})`, | |
| ); | |
| if (typeof c.exp === "number") { | |
| console.error(`Token expires: ${new Date(c.exp * 1000).toISOString()}`); | |
| } | |
| } catch { /* ignore */ } | |
| } | |
| // ── CLI: serve ────────────────────────────────────────────────────── | |
| function cmdServe(host: string, port: number) { | |
| const at = Deno.env.get("FACTORY_ACCESS_TOKEN"); | |
| const rt = Deno.env.get("FACTORY_REFRESH_TOKEN"); | |
| const org = Deno.env.get("FACTORY_ORG_ID") ?? ""; | |
| if (!at || !rt) { | |
| console.error("Missing FACTORY_ACCESS_TOKEN / FACTORY_REFRESH_TOKEN."); | |
| console.error("Run: deno run -A factory-api.ts login > .env"); | |
| Deno.exit(1); | |
| } | |
| const tm = new Tokens(at, rt, org); | |
| const ms = tm.expiresAt - Date.now(); | |
| const h = Math.floor(ms / 3600_000); | |
| const m = Math.floor((ms % 3600_000) / 60_000); | |
| const listenUrl = `http://${host.includes(":") ? `[${host}]` : host}:${port}`; | |
| console.error(`Factory API proxy · ${listenUrl}\n`); | |
| console.error("Provider routes:"); | |
| for (const [name, { provider }] of Object.entries(ROUTES)) { | |
| console.error(` /${name.padEnd(10)} → ${provider}`); | |
| } | |
| console.error(` /* → api.factory.ai (raw)\n`); | |
| console.error("SDK config (API key can be any non-empty string):"); | |
| console.error( | |
| ` ANTHROPIC_BASE_URL=${listenUrl}/anthropic`, | |
| ); | |
| console.error( | |
| ` OPENAI_BASE_URL=${listenUrl}/openai/v1\n`, | |
| ); | |
| console.error( | |
| `Token: ${ms > 0 ? `expires in ${h}h ${m}m` : "expired"} (auto-refresh on)\n`, | |
| ); | |
| Deno.serve({ hostname: host, port, onListen() {} }, (req) => handle(req, tm)); | |
| } | |
| // ── Main ──────────────────────────────────────────────────────────── | |
| const HELP = `factory-api.ts — Factory.ai auth + local API proxy | |
| Commands: | |
| login Login via browser, print dotenv to stdout | |
| serve [--host ADDR] [--port N] Start local API proxy (default: 127.0.0.1:8000) | |
| help Show this message | |
| Options: | |
| --host ADDR Listen address (default: 127.0.0.1, use 0.0.0.0 for all interfaces) | |
| --port N Listen port (default: 8000) | |
| --help Show this message | |
| Examples: | |
| deno run -A factory-api.ts login > .env | |
| deno run -A --env factory-api.ts serve | |
| deno run -A --env factory-api.ts serve --port 9000 | |
| deno run -A --env factory-api.ts serve --host 0.0.0.0 --port 3000`; | |
| function getFlag(name: string): string | undefined { | |
| const idx = Deno.args.indexOf(name); | |
| return idx !== -1 && idx + 1 < Deno.args.length | |
| ? Deno.args[idx + 1] | |
| : undefined; | |
| } | |
| if (import.meta.main) { | |
| const sub = Deno.args.find((a) => !a.startsWith("-")); | |
| const port = parseInt(getFlag("--port") ?? "8000"); | |
| const host = getFlag("--host") ?? "127.0.0.1"; | |
| if (sub === "serve") { | |
| cmdServe(host, port); | |
| } else if (sub === "login") { | |
| cmdLogin().catch((e) => { | |
| console.error(`\nError: ${e.message}`); | |
| Deno.exit(1); | |
| }); | |
| } else if (sub === "help" || Deno.args.includes("--help")) { | |
| console.error(HELP); | |
| } else if (Deno.args.length === 0) { | |
| console.error(HELP); | |
| } else { | |
| console.error(`Unknown command: ${sub ?? Deno.args[0]}\n`); | |
| console.error(HELP); | |
| Deno.exit(1); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment