const COOKIES = `__gads=ID=fa119d4bd4f0deb4:T=1767802127:RT=1769915891:S=ALNI_MadOwOvOyuYGa63fhmTXAOSMuMPzA; __gpi=UID=000011dec0f55e42:T=1767802127:RT=1769915891:S=ALNI_MbmxAr7exkcHsXJpxvp5Jda40UEhQ; __eoi=ID=1b168e49673ee98a:T=1767802127:RT=1769915891:S=AA-Afjb1OtBK1G-c16acoNoP6uKS; NEXT_LOCALE=zh; u_device_id=d403ec97-7698-4c1a-a5ad-4121004056df; home_chat_id=f2b45c03-aeee-4c9e-862f-50aa2e7ba549; __Secure-authjs.callback-url=https%3A%2F%2Fapp.unlimitedai.chat; __Host-authjs.csrf-token=85724d6088bf62366e70be6dca13329f84a248a2e682b9469ea9c4edea86294b%7Cb6d8881d70b2a9fcb7b3bdc9c67cec59c17caba2225b24909cddbc1d6092d9c3; _clck=1ehq05y%5E2%5Eg5e%5E0%5E2302; _clsk=1j5vo0j%5E1776785008641%5E1%5E1%5Ez.clarity.ms%2Fcollect`; // 目标 API 地址 const TARGET_API = "https://app.unlimitedai.chat/api/chat"; // 模拟的设备 ID (保持会话连续性) const DEVICE_ID = "d403ec97-7698-4c1a-a5ad-4121004056de"; // --- 核心逻辑 --- async function handler(req: Request): Promise { const url = new URL(req.url); // CORS 处理 if (req.method === 'OPTIONS') { return new Response(null, { status: 204, headers: corsHeaders() }); } // 静态页面 if (url.pathname === '/') { return new Response(getUI(), { headers: { 'Content-Type': 'text/html; charset=utf-8' } }); } // 模型列表 if (url.pathname === '/v1/models' && req.method === 'GET') { return new Response(JSON.stringify({ object: "list", data: [ { id: "chat-model-reasoning", object: "model", created: Date.now(), owned_by: "unlimitedai" } ] }), { headers: { 'Content-Type': 'application/json', ...corsHeaders() } }); } // 聊天补全 if (url.pathname === '/v1/chat/completions' && req.method === 'POST') { return handleChatCompletion(req); } return new Response("Not Found", { status: 404 }); } async function handleChatCompletion(req: Request): Promise { try { const body = await req.json(); const model = body.model || "chat-model-reasoning"; const openAiMessages = body.messages || []; // 1. 构建 UnlimitedAI 格式的请求体 // 需要为每条消息生成 ID 和时间戳 const now = new Date().toISOString(); const uaiMessages = openAiMessages.map((msg: any, index: number) => ({ id: crypto.randomUUID(), role: msg.role, content: msg.content, parts: [{ type: "text", text: msg.content }], // UnlimitedAI 特有的 parts 结构 createdAt: now })); // 生成一个新的会话 ID (实际生产中可能需要根据历史消息复用 ID) // 这里为了简单演示,每次请求生成一个新的 Chat ID const chatId = crypto.randomUUID(); const payload = { chatId: chatId, messages: uaiMessages, selectedChatModel: model, selectedCharacter: null, selectedStory: null, deviceId: DEVICE_ID, locale: "zh" }; // 2. 构建请求头 (完全模拟抓包数据) const headers: Record = { "accept": "*/*", "content-type": "application/json", "cookie": COOKIES, "origin": "https://app.unlimitedai.chat", "referer": "https://app.unlimitedai.chat/zh", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0", "x-next-intl-locale": "zh", "sec-ch-ua": '"Microsoft Edge";v="147", "Not.A/Brand";v="8", "Chromium";v="147"', "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": '"Windows"', "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-origin" }; // 3. 发起上游请求 const upstreamRes = await fetch(TARGET_API, { method: "POST", headers, body: JSON.stringify(payload) }); if (!upstreamRes.ok) { const errText = await upstreamRes.text(); return new Response(JSON.stringify({ error: { message: `Upstream Error ${upstreamRes.status}: ${errText}` } }), { status: upstreamRes.status, headers: { 'Content-Type': 'application/json' } }); } // 4. 流式转换处理 (NDJSON -> SSE) const { readable, writable } = new TransformStream(); const writer = writable.getWriter(); const encoder = new TextEncoder(); // 用于跟踪会话 ID const openAiChatId = crypto.randomUUID(); (async () => { try { const reader = upstreamRes.body?.getReader(); if (!reader) throw new Error("No body"); const decoder = new TextDecoder(); let buffer = ""; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop() || ""; // 保留最后一个可能不完整的块 for (const line of lines) { if (!line.trim()) continue; try { const json = JSON.parse(line); // UnlimitedAI 返回格式: {"type":"delta","delta":"你好!"} if (json.type === 'delta' && json.delta) { const content = json.delta; // 转换为 OpenAI SSE 格式 const sseChunk = { id: openAiChatId, object: "chat.completion.chunk", created: Math.floor(Date.now() / 1000), model: model, choices: [{ index: 0, delta: { content: content }, finish_reason: null }] }; writer.write(encoder.encode(`data: ${JSON.stringify(sseChunk)}\n\n`)); } } catch (e) { console.error("Parse error", e); } } } // 发送结束标记 writer.write(encoder.encode(`data: ${JSON.stringify({ id: openAiChatId, object: "chat.completion.chunk", created: Math.floor(Date.now() / 1000), model: model, choices: [{ index: 0, delta: {}, finish_reason: "stop" }] })}\n\n`)); writer.write(encoder.encode('data: [DONE]\n\n')); } catch (err: any) { console.error("Stream processing error:", err); writer.write(encoder.encode(`data: ${JSON.stringify({ error: { message: err.message } })}\n\n`)); } finally { writer.close(); } })(); return new Response(readable, { headers: { "Content-Type": "text/event-stream; charset=utf-8", "Cache-Control": "no-cache", "Connection": "keep-alive", ...corsHeaders() } }); } catch (error: any) { return new Response(JSON.stringify({ error: { message: error.message } }), { status: 500, headers: { 'Content-Type': 'application/json' } }); } } // --- 辅助函数 --- function corsHeaders() { return { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', 'Access-Control-Max-Age': '86400', }; } // --- 简单的测试 UI --- function getUI() { return ` UnlimitedAI Proxy Test

UnlimitedAI Proxy (OpenAI 兼容)

API Endpoint: http://localhost:8000/v1/chat/completions

等待响应...
`; } // --- 启动服务 --- const PORT = 7860; console.log(`UnlimitedAI Proxy running on http://localhost:${PORT}`); await Deno.serve({ port: PORT }, handler);