const DEFAULT_UPSTREAM_BASE_URL = "https://unlimited.surf"; const DEFAULT_OPENAI_MODEL = "gateway-gpt-5-5"; const DEFAULT_CLAUDE_MODEL = "claude-opus-4-7-20260101"; const CORS_HEADERS = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET,POST,PUT,PATCH,DELETE,OPTIONS", "Access-Control-Allow-Headers": "authorization,content-type,x-api-key,anthropic-api-key,anthropic-version,anthropic-beta,openai-beta", "Access-Control-Expose-Headers": "content-type,request-id,x-request-id", }; export default { async fetch(request, env) { if (request.method === "OPTIONS") { return new Response(null, { status: 204, headers: CORS_HEADERS }); } const url = new URL(request.url); const path = normalizePath(url.pathname); try { const authError = validateWorkerApiKey(request, env); if (authError) return authError; if (path === "/" || path === "/health") { return jsonResponse(serviceInfo(request, env)); } if (path.startsWith("/api/")) { return proxyUpstream(request, env, path); } if (path === "/mcp" || path === "/v1/mcp" || path === "/anthropic/mcp" || path === "/anthropic/v1/mcp") { return jsonResponse(mcpInfo(request)); } if (path === "/codex" || path === "/v1/codex" || path === "/anthropic/codex" || path === "/anthropic/v1/codex") { return textResponse(codexSetup(request), "text/plain; charset=utf-8"); } if (path === "/v1/setup" || path === "/anthropic/setup" || path === "/anthropic/v1/setup") { return textResponse(agentSetup(request), "text/plain; charset=utf-8"); } if (path === "/v1/messages" || (path === "/v1/models" && looksLikeAnthropicRequest(request)) || path.startsWith("/anthropic/")) { return handleAnthropic(request, env, path); } if (path.startsWith("/v1/")) { return handleOpenAI(request, env, path); } return errorResponse(404, "not_found", `No route for ${path}`); } catch (error) { return errorResponse(500, "internal_error", error && error.message ? error.message : String(error)); } }, }; async function handleOpenAI(request, env, path) { if ((path === "/v1/key" || path === "/v1/auth-key" || path === "/v1/usage") && request.method === "GET") { const rawPath = path === "/v1/usage" ? "/api/usage" : "/api/key"; return proxyUpstream(request, env, rawPath); } if (path === "/v1/models" && request.method === "GET") { if (looksLikeAnthropicRequest(request)) { return anthropicModels(request, env); } return openAIModels(request, env); } if (path === "/v1/search" && request.method === "POST") { const body = await readJson(request); return openAIDirectCapability(request, env, body, "/api/search"); } if (path === "/v1/merge" && request.method === "POST") { const body = await readJson(request); return openAIDirectCapability(request, env, body, "/api/merge"); } if (path === "/v1/chat/completions" && request.method === "POST") { const body = await readJson(request); return openAIChatCompletions(request, env, body); } if (path === "/v1/responses" && request.method === "POST") { const body = await readJson(request); return openAIResponses(request, env, body); } if (path === "/v1/files" && request.method === "GET") { return jsonResponse({ object: "list", data: [], has_more: false }); } if (path === "/v1/files" && request.method === "POST") { return openAIFileUpload(request, env); } if ((path === "/v1/files/extract" || path === "/v1/attachments/extract") && request.method === "POST") { const body = await readJson(request); const extracted = await callUnlimitedJson(request, env, "/api/attachments/extract", body); return jsonResponse(extracted); } if (path.startsWith("/v1/files/") && request.method === "GET") { return errorResponse(404, "not_found", "This Worker is stateless. Bind KV/R2 if you need persisted OpenAI file retrieval."); } if (path === "/v1/embeddings" || path.startsWith("/v1/audio/") || path.startsWith("/v1/images/")) { return errorResponse(501, "unsupported_endpoint", `${path} is not exposed by unlimited.surf and cannot be emulated faithfully.`); } return errorResponse(404, "not_found", `Unsupported OpenAI-compatible route ${path}`); } async function openAIDirectCapability(request, env, body, route) { const model = body.model || env.DEFAULT_MODEL || DEFAULT_OPENAI_MODEL; const created = nowSeconds(); const id = `chatcmpl_${randomId()}`; const payload = buildUnlimitedPayload({ ...body, web_search: route === "/api/search", merge: route === "/api/merge" }, route); if (body.stream !== false) { const upstream = await callUnlimitedStream(request, env, route, payload); return sseResponse(streamOpenAIChat(upstream, { id, created, model })); } const result = await collectUnlimitedText(request, env, route, payload); return jsonResponse({ id, object: "chat.completion", created, model, choices: [ { index: 0, message: { role: "assistant", content: result.text }, logprobs: null, finish_reason: result.finishReason || "stop", }, ], usage: usageFromText(payload.message || payload.query || "", result.text), system_fingerprint: `unlimited-surf-worker:${route}`, }); } async function openAIChatCompletions(request, env, body) { const model = body.model || env.DEFAULT_MODEL || DEFAULT_OPENAI_MODEL; const created = nowSeconds(); const id = `chatcmpl_${randomId()}`; const route = chooseUnlimitedRoute(body); const payload = buildUnlimitedPayload(body, route); if (body.stream) { const upstream = await callUnlimitedStream(request, env, route, payload); return sseResponse(streamOpenAIChat(upstream, { id, created, model })); } const result = await collectUnlimitedText(request, env, route, payload); return jsonResponse({ id, object: "chat.completion", created, model, choices: [ { index: 0, message: { role: "assistant", content: result.text }, logprobs: null, finish_reason: result.finishReason || "stop", }, ], usage: usageFromText(payload.message || "", result.text), system_fingerprint: "unlimited-surf-worker", }); } async function openAIResponses(request, env, body) { const model = body.model || env.DEFAULT_MODEL || DEFAULT_OPENAI_MODEL; const created = nowSeconds(); const id = `resp_${randomId()}`; const syntheticChatBody = responsesToChatBody(body, model); const route = chooseUnlimitedRoute(syntheticChatBody); const payload = buildUnlimitedPayload(syntheticChatBody, route); if (body.stream) { const upstream = await callUnlimitedStream(request, env, route, payload); return sseResponse(streamOpenAIResponses(upstream, { id, created, model })); } const result = await collectUnlimitedText(request, env, route, payload); return jsonResponse({ id, object: "response", created_at: created, status: "completed", error: null, incomplete_details: null, instructions: body.instructions || null, max_output_tokens: body.max_output_tokens || body.max_tokens || null, model, output: [ { id: `msg_${randomId()}`, type: "message", status: "completed", role: "assistant", content: [{ type: "output_text", text: result.text, annotations: [] }], }, ], output_text: result.text, parallel_tool_calls: true, previous_response_id: body.previous_response_id || null, reasoning: body.reasoning || null, store: body.store || false, temperature: body.temperature || null, text: body.text || { format: { type: "text" } }, tool_choice: body.tool_choice || "auto", tools: body.tools || [], top_p: body.top_p || null, truncation: body.truncation || "disabled", usage: responseUsageFromText(payload.message || "", result.text), user: body.user || null, }); } async function handleAnthropic(request, env, path) { const anthPath = path.startsWith("/anthropic/") ? normalizePath(path.slice("/anthropic".length) || "/") : path; if ((anthPath === "/v1/key" || anthPath === "/key" || anthPath === "/v1/auth-key" || anthPath === "/auth-key") && request.method === "GET") { return proxyUpstream(request, env, "/api/key"); } if ((anthPath === "/v1/usage" || anthPath === "/usage") && request.method === "GET") { return proxyUpstream(request, env, "/api/usage"); } if ((anthPath === "/v1/models" || anthPath === "/models") && request.method === "GET") { return anthropicModels(request, env); } if ((anthPath === "/v1/messages" || anthPath === "/messages") && request.method === "POST") { const body = await readJson(request); return anthropicMessages(request, env, body); } if ((anthPath === "/v1/search" || anthPath === "/search") && request.method === "POST") { const body = await readJson(request); return anthropicDirectCapability(request, env, body, "/api/search"); } if ((anthPath === "/v1/merge" || anthPath === "/merge") && request.method === "POST") { const body = await readJson(request); return anthropicDirectCapability(request, env, body, "/api/merge"); } if (anthPath === "/v1/setup" || anthPath === "/setup") { return textResponse(agentSetup(request), "text/plain; charset=utf-8"); } return errorResponse(404, "not_found", `Unsupported Anthropic-compatible route ${path}`); } async function anthropicDirectCapability(request, env, body, route) { const requestedModel = body.model || env.DEFAULT_CLAUDE_MODEL || DEFAULT_CLAUDE_MODEL; const payload = buildAnthropicUnlimitedPayload({ ...body, web_search: route === "/api/search", merge: route === "/api/merge" }, route); const id = `msg_${randomId()}`; if (body.stream !== false) { const upstream = await callUnlimitedStream(request, env, route, payload); return sseResponse(streamAnthropicMessages(upstream, { id, model: requestedModel })); } const result = await collectUnlimitedText(request, env, route, payload); return jsonResponse({ id, type: "message", role: "assistant", model: requestedModel, content: [{ type: "text", text: result.text }], stop_reason: anthropicStopReason(result.finishReason), stop_sequence: null, usage: anthropicUsageFromText(payload.message || payload.query || "", result.text), }); } async function anthropicMessages(request, env, body) { const requestedModel = body.model || env.DEFAULT_CLAUDE_MODEL || DEFAULT_CLAUDE_MODEL; const route = chooseUnlimitedRoute(body); const payload = buildAnthropicUnlimitedPayload(body, route); const id = `msg_${randomId()}`; if (body.stream) { const upstream = await callUnlimitedStream(request, env, route, payload); return sseResponse(streamAnthropicMessages(upstream, { id, model: requestedModel })); } const result = await collectUnlimitedText(request, env, route, payload); return jsonResponse({ id, type: "message", role: "assistant", model: requestedModel, content: [{ type: "text", text: result.text }], stop_reason: anthropicStopReason(result.finishReason), stop_sequence: null, usage: anthropicUsageFromText(payload.message || "", result.text), }); } async function openAIModels(request, env) { const catalog = await getModelCatalog(request, env); return jsonResponse({ object: "list", data: catalog.map((model) => ({ id: model.id, object: "model", created: 0, owned_by: model.provider || "unlimited.surf", permission: [], root: model.id, parent: null, })), }); } async function anthropicModels(request, env) { const catalog = await getModelCatalog(request, env); const claudeModels = catalog .filter((model) => /claude|anthropic/i.test(`${model.id} ${model.name || ""} ${model.provider || ""}`)) .map((model) => toAnthropicModel(model)); return jsonResponse({ data: claudeModels.length ? claudeModels : [toAnthropicModel({ id: DEFAULT_CLAUDE_MODEL, name: "Claude Opus 4.7" })], has_more: false, first_id: claudeModels[0] ? claudeModels[0].id : DEFAULT_CLAUDE_MODEL, last_id: claudeModels[claudeModels.length - 1] ? claudeModels[claudeModels.length - 1].id : DEFAULT_CLAUDE_MODEL, }); } async function openAIFileUpload(request, env) { const contentType = request.headers.get("content-type") || ""; if (!contentType.includes("multipart/form-data")) { return errorResponse(400, "invalid_request_error", "OpenAI file upload expects multipart/form-data with a file field."); } const form = await request.formData(); const file = form.get("file"); if (!file || typeof file === "string") { return errorResponse(400, "invalid_request_error", "Missing multipart file field named file."); } const bytes = new Uint8Array(await file.arrayBuffer()); const payload = { name: file.name || "upload.bin", type: file.type || "application/octet-stream", data: bytesToBase64(bytes), }; const extracted = await callUnlimitedJson(request, env, "/api/attachments/extract", payload); const id = `file_${randomId()}`; return jsonResponse({ id, object: "file", bytes: bytes.byteLength, created_at: nowSeconds(), filename: payload.name, purpose: form.get("purpose") || "assistants", status: extracted && extracted.success === false ? "error" : "processed", status_details: null, unlimited_extract: extracted, }); } function chooseUnlimitedRoute(body) { if (body.models && Array.isArray(body.models) && body.models.length >= 2) return "/api/merge"; if (body.merge || body.merge_ai) return "/api/merge"; if (body.query || body.web_search || body.web_search_options || hasWebSearchTool(body.tools)) return "/api/search"; return "/api/chat"; } function buildUnlimitedPayload(body, route) { if (route === "/api/search") { return { query: body.query || latestUserText(body.messages) || inputToText(body.input) || body.prompt || "", model: mapUpstreamModel(body.model), effort: body.effort || reasoningEffort(body), }; } const message = body.message || messagesToText(body.messages) || inputToText(body.input) || body.prompt || ""; const payload = { message, model: mapUpstreamModel(body.model), effort: body.effort || reasoningEffort(body), }; if (route === "/api/merge") { payload.models = Array.isArray(body.models) && body.models.length ? body.models.map(mapUpstreamModel) : undefined; } return payload; } function buildAnthropicUnlimitedPayload(body, route) { if (route === "/api/search") { return { query: latestUserText(body.messages) || body.query || "", model: mapUpstreamModel(body.model), effort: body.effort || reasoningEffort(body), }; } const prompt = anthropicMessagesToText(body); const payload = { message: prompt, model: mapUpstreamModel(body.model), effort: body.effort || reasoningEffort(body), }; if (route === "/api/merge") { payload.models = Array.isArray(body.models) && body.models.length ? body.models.map(mapUpstreamModel) : undefined; } return payload; } function responsesToChatBody(body, fallbackModel) { const messages = []; if (body.instructions) messages.push({ role: "system", content: body.instructions }); const inputText = inputToText(body.input); if (inputText) messages.push({ role: "user", content: inputText }); return { ...body, model: body.model || fallbackModel, messages, stream: body.stream, }; } async function proxyUpstream(request, env, path) { const upstreamUrl = new URL(path + new URL(request.url).search, upstreamBase(env)); const headers = new Headers(request.headers); const key = optionalUpstreamApiKey(request, env); if (key) headers.set("authorization", `Bearer ${key}`); headers.delete("host"); const init = { method: request.method, headers, body: request.method === "GET" || request.method === "HEAD" ? undefined : request.body, redirect: "manual", }; const response = await fetch(upstreamUrl, init); return addCors(response); } async function callUnlimitedJson(request, env, path, payload) { const response = await fetch(new URL(path, upstreamBase(env)), { method: "POST", headers: upstreamHeaders(request, env, false), body: JSON.stringify(payload || {}), }); if (!response.ok) { throw new Error(`upstream ${path} failed: ${response.status} ${await response.text()}`); } return response.json(); } async function callUnlimitedStream(request, env, path, payload) { const response = await fetch(new URL(path, upstreamBase(env)), { method: "POST", headers: upstreamHeaders(request, env, true), body: JSON.stringify(payload || {}), }); if (!response.ok) { throw new Error(`upstream ${path} failed: ${response.status} ${await response.text()}`); } return response; } async function collectUnlimitedText(request, env, path, payload) { const response = await callUnlimitedStream(request, env, path, payload); const events = await readUnlimitedEvents(response); let text = ""; let finishReason = "stop"; const annotations = []; for (const event of events) { if (typeof event.delta === "string") text += event.delta; if (event.results) annotations.push(event.results); if (event.finish && event.reason) finishReason = event.reason; } return { text, finishReason, annotations, rawEvents: events }; } async function getModelCatalog(request, env) { try { const headers = new Headers(); const key = optionalUpstreamApiKey(request, env); if (key) headers.set("Authorization", `Bearer ${key}`); const response = await fetch(new URL("/api/models", upstreamBase(env)), { headers }); if (!response.ok) throw new Error(`models failed: ${response.status}`); const data = await response.json(); const models = Array.isArray(data) ? data : Array.isArray(data.data) ? data.data : []; return models.map((model) => ({ id: model.id || model.name || String(model), name: model.name || model.id || String(model), provider: model.provider || providerFromModel(model.id || model.name || ""), tier: model.tier || undefined, })).filter((model) => model.id); } catch (_) { return fallbackModels(); } } function streamOpenAIChat(upstream, meta) { return streamUnlimitedEvents(upstream, { start(controller) { writeSse(controller, { id: meta.id, object: "chat.completion.chunk", created: meta.created, model: meta.model, choices: [{ index: 0, delta: { role: "assistant", content: "" }, finish_reason: null }], }); }, delta(controller, text) { writeSse(controller, { id: meta.id, object: "chat.completion.chunk", created: meta.created, model: meta.model, choices: [{ index: 0, delta: { content: text }, finish_reason: null }], }); }, finish(controller, reason) { writeSse(controller, { id: meta.id, object: "chat.completion.chunk", created: meta.created, model: meta.model, choices: [{ index: 0, delta: {}, finish_reason: openAIStopReason(reason) }], }); writeRawSse(controller, "data: [DONE]\n\n"); }, }); } function streamOpenAIResponses(upstream, meta) { const outputId = `msg_${randomId()}`; return streamUnlimitedEvents(upstream, { start(controller) { writeSseEvent(controller, "response.created", { type: "response.created", response: { id: meta.id, object: "response", created_at: meta.created, status: "in_progress", model: meta.model, output: [], }, }); writeSseEvent(controller, "response.output_item.added", { type: "response.output_item.added", output_index: 0, item: { id: outputId, type: "message", status: "in_progress", role: "assistant", content: [] }, }); writeSseEvent(controller, "response.content_part.added", { type: "response.content_part.added", item_id: outputId, output_index: 0, content_index: 0, part: { type: "output_text", text: "", annotations: [] }, }); }, delta(controller, text) { writeSseEvent(controller, "response.output_text.delta", { type: "response.output_text.delta", item_id: outputId, output_index: 0, content_index: 0, delta: text, }); }, finish(controller) { writeSseEvent(controller, "response.output_text.done", { type: "response.output_text.done", item_id: outputId, output_index: 0, content_index: 0, text: "", }); writeSseEvent(controller, "response.content_part.done", { type: "response.content_part.done", item_id: outputId, output_index: 0, content_index: 0, part: { type: "output_text", text: "", annotations: [] }, }); writeSseEvent(controller, "response.output_item.done", { type: "response.output_item.done", output_index: 0, item: { id: outputId, type: "message", status: "completed", role: "assistant", content: [] }, }); writeSseEvent(controller, "response.completed", { type: "response.completed", response: { id: meta.id, object: "response", created_at: meta.created, status: "completed", model: meta.model }, }); writeRawSse(controller, "data: [DONE]\n\n"); }, }); } function streamAnthropicMessages(upstream, meta) { return streamUnlimitedEvents(upstream, { start(controller) { writeSseEvent(controller, "message_start", { type: "message_start", message: { id: meta.id, type: "message", role: "assistant", model: meta.model, content: [], stop_reason: null, stop_sequence: null, usage: { input_tokens: 0, output_tokens: 0 }, }, }); writeSseEvent(controller, "content_block_start", { type: "content_block_start", index: 0, content_block: { type: "text", text: "" }, }); }, delta(controller, text) { writeSseEvent(controller, "content_block_delta", { type: "content_block_delta", index: 0, delta: { type: "text_delta", text }, }); }, finish(controller, reason) { writeSseEvent(controller, "content_block_stop", { type: "content_block_stop", index: 0 }); writeSseEvent(controller, "message_delta", { type: "message_delta", delta: { stop_reason: anthropicStopReason(reason), stop_sequence: null }, usage: { output_tokens: 0 }, }); writeSseEvent(controller, "message_stop", { type: "message_stop" }); }, }); } function streamUnlimitedEvents(upstream, handlers) { const encoder = new TextEncoder(); const decoder = new TextDecoder(); return new ReadableStream({ async start(controller) { let finished = false; handlers.start && handlers.start(controller); try { const reader = upstream.body.getReader(); let buffer = ""; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split(/\r?\n/); buffer = lines.pop() || ""; for (const line of lines) { if (!line.startsWith("data:")) continue; const parsed = parseSseJson(line.slice(5).trim()); if (!parsed) continue; if (typeof parsed.delta === "string" && parsed.delta.length) { handlers.delta && handlers.delta(controller, parsed.delta, parsed); } if (parsed.finish || parsed.done) { finished = true; handlers.finish && handlers.finish(controller, parsed.reason || "stop", parsed); } } } if (!finished) handlers.finish && handlers.finish(controller, "stop", {}); } catch (error) { controller.enqueue(encoder.encode(`event: error\ndata: ${JSON.stringify({ error: error.message || String(error) })}\n\n`)); } finally { controller.close(); } }, }); } async function readUnlimitedEvents(response) { const decoder = new TextDecoder(); const reader = response.body.getReader(); const events = []; let buffer = ""; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split(/\r?\n/); buffer = lines.pop() || ""; for (const line of lines) { if (!line.startsWith("data:")) continue; const parsed = parseSseJson(line.slice(5).trim()); if (parsed) events.push(parsed); } } if (buffer.startsWith("data:")) { const parsed = parseSseJson(buffer.slice(5).trim()); if (parsed) events.push(parsed); } return events; } function writeSse(controller, data) { writeRawSse(controller, `data: ${JSON.stringify(data)}\n\n`); } function writeSseEvent(controller, event, data) { writeRawSse(controller, `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`); } function writeRawSse(controller, chunk) { controller.enqueue(new TextEncoder().encode(chunk)); } function sseResponse(body) { return new Response(body, { headers: { ...CORS_HEADERS, "Content-Type": "text/event-stream; charset=utf-8", "Cache-Control": "no-cache, no-transform", "Connection": "keep-alive", "X-Accel-Buffering": "no", }, }); } function jsonResponse(data, init = {}) { return new Response(JSON.stringify(data, null, 2), { ...init, headers: { ...CORS_HEADERS, "Content-Type": "application/json; charset=utf-8", "Cache-Control": "no-store", ...(init.headers || {}), }, }); } function textResponse(text, contentType, init = {}) { return new Response(text, { ...init, headers: { ...CORS_HEADERS, "Content-Type": contentType, "Cache-Control": "no-store", ...(init.headers || {}), }, }); } function errorResponse(status, code, message) { return jsonResponse({ error: { message, type: code, code, }, }, { status }); } function addCors(response) { const headers = new Headers(response.headers); for (const [key, value] of Object.entries(CORS_HEADERS)) headers.set(key, value); return new Response(response.body, { status: response.status, statusText: response.statusText, headers }); } async function readJson(request) { if (!request.body) return {}; const text = await request.text(); if (!text.trim()) return {}; try { return JSON.parse(text); } catch (_) { throw new Error("Request body must be valid JSON."); } } function upstreamHeaders(request, env, wantsStream) { const headers = new Headers(); headers.set("Authorization", `Bearer ${upstreamApiKey(request, env)}`); headers.set("Content-Type", "application/json"); if (wantsStream) headers.set("Accept", "text/event-stream"); return headers; } function upstreamApiKey(request, env) { const key = optionalUpstreamApiKey(request, env); if (key) return key; if (env.WORKER_API_KEY) { throw new Error("Missing upstream API key. Set UNLIMITED_SURF_API_KEY when WORKER_API_KEY is enabled."); } throw new Error("Missing upstream API key. Set UNLIMITED_SURF_API_KEY or pass Authorization: Bearer / x-api-key: ."); } function optionalUpstreamApiKey(request, env) { const configured = env.UNLIMITED_SURF_API_KEY || env.API_KEY || env.AUTH_KEY; if (configured) return configured; if (env.WORKER_API_KEY) return ""; return clientApiKey(request); } function validateWorkerApiKey(request, env) { const expected = env.WORKER_API_KEY; if (!expected) return null; const actual = clientApiKey(request); if (actual && constantTimeEqual(actual, expected)) return null; return jsonResponse({ error: { message: "Invalid or missing Worker API key.", type: "authentication_error", code: "invalid_api_key", }, }, { status: 401, headers: { "WWW-Authenticate": "Bearer" } }); } function clientApiKey(request) { const auth = request.headers.get("authorization") || ""; if (/^bearer\s+/i.test(auth)) return auth.replace(/^bearer\s+/i, "").trim(); const xKey = request.headers.get("x-api-key") || request.headers.get("anthropic-api-key"); return xKey ? xKey.trim() : ""; } function constantTimeEqual(actual, expected) { const actualText = String(actual || ""); const expectedText = String(expected || ""); if (actualText.length !== expectedText.length) return false; let diff = 0; for (let i = 0; i < actualText.length; i += 1) { diff |= actualText.charCodeAt(i) ^ expectedText.charCodeAt(i); } return diff === 0; } function upstreamBase(env) { return stripTrailingSlash(env.UPSTREAM_BASE_URL || DEFAULT_UPSTREAM_BASE_URL) + "/"; } function normalizePath(path) { if (!path || path === "") return "/"; const normalized = path.replace(/\/+/g, "/"); return normalized.length > 1 ? normalized.replace(/\/+$/, "") : normalized; } function messagesToText(messages) { if (!Array.isArray(messages)) return ""; return messages.map((message) => { const role = message.role || "user"; return `${role}: ${contentToText(message.content)}`; }).filter(Boolean).join("\n\n"); } function anthropicMessagesToText(body) { const parts = []; if (body.system) parts.push(`system: ${contentToText(body.system)}`); if (Array.isArray(body.tools) && body.tools.length) { parts.push(`available tools: ${JSON.stringify(body.tools)}`); parts.push("If a tool is required, describe the intended tool call clearly. MCP and local tools must be executed by the client agent."); } if (Array.isArray(body.messages)) parts.push(messagesToText(body.messages)); return parts.filter(Boolean).join("\n\n"); } function inputToText(input) { if (!input) return ""; if (typeof input === "string") return input; if (!Array.isArray(input)) return contentToText(input); return input.map((item) => { if (typeof item === "string") return item; if (item.type === "message") return `${item.role || "user"}: ${contentToText(item.content)}`; if (item.role) return `${item.role}: ${contentToText(item.content)}`; if (item.type === "input_text" || item.type === "output_text") return item.text || ""; return contentToText(item); }).filter(Boolean).join("\n\n"); } function contentToText(content) { if (content == null) return ""; if (typeof content === "string") return content; if (Array.isArray(content)) { return content.map((part) => contentToText(part)).filter(Boolean).join("\n"); } if (typeof content === "object") { if (typeof content.text === "string") return content.text; if (typeof content.input_text === "string") return content.input_text; if (content.type === "text" && typeof content.text === "string") return content.text; if (content.type === "input_text" && typeof content.text === "string") return content.text; if (content.type === "image_url") return `[image: ${content.image_url && content.image_url.url ? content.image_url.url : "attached"}]`; if (content.type === "image") return "[image attached]"; if (content.type === "tool_result") return `[tool_result ${content.tool_use_id || ""}] ${contentToText(content.content)}`; if (content.type === "tool_use") return `[tool_use ${content.name || "tool"}] ${JSON.stringify(content.input || {})}`; if (content.type) return `[${content.type}] ${JSON.stringify(content)}`; } return String(content); } function latestUserText(messages) { if (!Array.isArray(messages)) return ""; for (let i = messages.length - 1; i >= 0; i -= 1) { if ((messages[i].role || "user") === "user") return contentToText(messages[i].content); } return ""; } function hasWebSearchTool(tools) { if (!Array.isArray(tools)) return false; return tools.some((tool) => { const type = tool && (tool.type || tool.name || (tool.function && tool.function.name)); return /web.?search|browser|search/i.test(String(type || "")); }); } function reasoningEffort(body) { if (body.effort) return body.effort; if (typeof body.reasoning_effort === "string") return body.reasoning_effort; if (body.reasoning && typeof body.reasoning.effort === "string") return body.reasoning.effort; return "medium"; } function mapUpstreamModel(model) { if (!model) return DEFAULT_OPENAI_MODEL; if (model.startsWith("gateway-")) return model; if (/^claude-/i.test(model)) return `gateway-${model.replace(/-\d{8}$/, "")}`; if (/^gpt-/i.test(model)) return `gateway-${model}`; if (/^gemini-/i.test(model)) return `gateway-google-${model.replace(/^gemini-/i, "")}`; return model; } function toAnthropicModel(model) { const id = model.id.startsWith("gateway-") ? model.id.replace(/^gateway-/, "") : model.id; const versioned = /^claude-.*-\d{8}$/.test(id) ? id : anthropicVersionedId(id); return { id: versioned, type: "model", display_name: model.name || versioned, created_at: "2026-01-01T00:00:00Z", }; } function anthropicVersionedId(id) { if (/^claude-/i.test(id)) return `${id}-20260101`; return id; } function providerFromModel(model) { if (/claude|anthropic/i.test(model)) return "anthropic"; if (/gemini|google/i.test(model)) return "google"; if (/gpt|openai/i.test(model)) return "openai"; return "unlimited.surf"; } function fallbackModels() { return [ { id: "gateway-gpt-5", name: "GPT-5", provider: "openai", tier: "flagship" }, { id: "gateway-gpt-5-1", name: "GPT-5.1", provider: "openai", tier: "flagship" }, { id: "gateway-claude-opus-4-7", name: "Claude Opus 4.7", provider: "anthropic", tier: "flagship" }, { id: "gateway-google-2.5-pro", name: "Gemini 2.5 Pro", provider: "google", tier: "flagship" }, { id: "gateway-gemini-3-flash", name: "Gemini 3 Flash", provider: "google", tier: "fast" }, ]; } function parseSseJson(data) { if (!data || data === "[DONE]") return null; try { return JSON.parse(data); } catch (_) { return null; } } function openAIStopReason(reason) { if (!reason) return "stop"; if (reason === "max_tokens") return "length"; if (reason === "tool_use") return "tool_calls"; return reason === "end_turn" ? "stop" : reason; } function anthropicStopReason(reason) { if (!reason || reason === "stop") return "end_turn"; if (reason === "length") return "max_tokens"; if (reason === "tool_calls") return "tool_use"; return reason; } function usageFromText(input, output) { const promptTokens = estimateTokens(input); const completionTokens = estimateTokens(output); return { prompt_tokens: promptTokens, completion_tokens: completionTokens, total_tokens: promptTokens + completionTokens }; } function responseUsageFromText(input, output) { const inputTokens = estimateTokens(input); const outputTokens = estimateTokens(output); return { input_tokens: inputTokens, output_tokens: outputTokens, total_tokens: inputTokens + outputTokens }; } function anthropicUsageFromText(input, output) { return { input_tokens: estimateTokens(input), output_tokens: estimateTokens(output) }; } function estimateTokens(text) { if (!text) return 0; return Math.max(1, Math.ceil(String(text).length / 4)); } function nowSeconds() { return Math.floor(Date.now() / 1000); } function randomId() { const bytes = new Uint8Array(12); crypto.getRandomValues(bytes); return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join(""); } function stripTrailingSlash(value) { return String(value || "").replace(/\/+$/, ""); } function bytesToBase64(bytes) { let binary = ""; const chunkSize = 0x8000; for (let i = 0; i < bytes.length; i += chunkSize) { binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize)); } return btoa(binary); } function looksLikeAnthropicRequest(request) { return request.headers.has("anthropic-version") || request.headers.has("anthropic-beta") || request.headers.has("x-api-key"); } function serviceInfo(request, env) { const origin = new URL(request.url).origin; return { ok: true, service: "unlimited.surf OpenAI/Anthropic compatibility Worker", upstream: stripTrailingSlash(env.UPSTREAM_BASE_URL || DEFAULT_UPSTREAM_BASE_URL), routes: { raw: `${origin}/api/chat, /api/search, /api/merge, /api/models, /api/key, /api/attachments/extract`, openai: `${origin}/v1/chat/completions, /v1/responses, /v1/models, /v1/files`, anthropic: `${origin}/v1/messages or ${origin}/anthropic/v1/messages`, setup: `${origin}/v1/setup, /v1/codex, /v1/mcp`, }, }; } function agentSetup(request) { const origin = new URL(request.url).origin; return `Claude Code / Anthropic-compatible setup PowerShell: $env:ANTHROPIC_BASE_URL = "${origin}" $env:ANTHROPIC_AUTH_TOKEN = "" $env:ANTHROPIC_API_KEY = "" $env:ANTHROPIC_MODEL = "${DEFAULT_CLAUDE_MODEL}" claude Bash: export ANTHROPIC_BASE_URL="${origin}" export ANTHROPIC_AUTH_TOKEN="" export ANTHROPIC_API_KEY="" export ANTHROPIC_MODEL="${DEFAULT_CLAUDE_MODEL}" claude Goose / Hermes / other agents: Provider: Anthropic-compatible Base URL: ${origin} API key: Model: ${DEFAULT_CLAUDE_MODEL} Messages endpoint: POST ${origin}/v1/messages Models endpoint: GET ${origin}/v1/models MCP tools run in the client/agent environment. Use this Worker as the model endpoint, then configure MCP servers in your IDE or agent. `; } function codexSetup(request) { const origin = new URL(request.url).origin; return `Codex custom provider notes OpenAI-compatible Chat Completions: base_url = "${origin}/v1" api_key = "" model = "${DEFAULT_OPENAI_MODEL}" OpenAI Responses-compatible route for newer agents: POST ${origin}/v1/responses Direct smoke test: curl ${origin}/v1/chat/completions \\ -H "Authorization: Bearer " \\ -H "Content-Type: application/json" \\ -d '{"model":"${DEFAULT_OPENAI_MODEL}","messages":[{"role":"user","content":"Write a small test function."}],"stream":true}' Anthropic-compatible agent route: POST ${origin}/v1/messages MCP execution remains client-side; configure MCP servers in Codex or your IDE, and point the model provider at this Worker. `; } function mcpInfo(request) { const origin = new URL(request.url).origin; return { supported: true, model_endpoint: origin, note: "MCP servers execute inside the client or agent. This Worker supplies OpenAI/Anthropic-compatible model endpoints and does not run local MCP tools in the browser or edge runtime.", endpoints: { openai_responses: `${origin}/v1/responses`, openai_chat_completions: `${origin}/v1/chat/completions`, anthropic_messages: `${origin}/v1/messages`, setup: `${origin}/v1/setup`, }, }; }