[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81100":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":15,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":17,"rankGlobal":10,"rankLanguage":10,"license":18,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":21,"hasPages":19,"topics":22,"createdAt":10,"pushedAt":10,"updatedAt":23,"readmeContent":24,"aiSummary":25,"trendingCount":16,"starSnapshotCount":16,"syncStatus":26,"lastSyncTime":27,"discoverSource":28},81100,"Luna-Proxy","wholock2210\u002FLuna-Proxy","wholock2210","A local OpenAI-compatible proxy that bridges Qwen's web chat to any OpenAI-compatible client, with multi-account routing, session tracking, and a built-in React admin UI.","",null,"JavaScript",41,15,40,1,0,43.71,"MIT License",false,"main",true,[],"2026-06-12 04:01:31","# LunaProxy\n\n\n\nLunaProxy is a local reverse proxy that exposes Qwen's web chat as a fully OpenAI-compatible API. It handles credential management, multi-account concurrency, session persistence, and prompt overflow — all from a single process with a built-in React admin UI served on the same port.\nDesigned for local development and controlled routing. No cloud dependency, no third-party relay — just a direct bridge between your OpenAI-compatible tooling and Qwen.\n\n---\n\n> [!WARNING]\n>  # **Disclaimer**\n>\n> This repository is provided for learning, research, personal experimentation, and internal validation only. It does not grant any commercial authorization and comes with no warranty of fitness, stability, or results.\n>\n> The author and repository maintainers are not responsible for any direct or indirect loss, account suspension, data loss, legal risk, or third-party claims arising from use, modification, distribution, deployment, or reliance on this project.\n\n---\n\n## Features\n\n- **OpenAI-compatible API** — drop-in `\u002Fv1\u002Fchat\u002Fcompletions` and `\u002Fv1\u002Fmodels` endpoints\n- **Anthropic-compatible API** — `\u002Fv1\u002Fmessages` and `\u002Fv1\u002Fmessages\u002Fcount_tokens` for Claude-style clients\n- **Streaming support** — SSE streaming and non-streaming responses\n- **Tool-call bridging** — injects an XML tool contract for Qwen, parses tool calls, and returns OpenAI `tool_calls` or Anthropic `tool_use`\n- **Built-in Admin UI** — React dashboard served alongside the API on the same port\n- **Credential management** — automatic OAuth capture via Puppeteer or manual token\u002Fcookie input\n- **Multi-account routing** — queue and concurrency controls across providers, accounts, and workers\n- **Session & run tracking** — persistent sessions, run history, thread binding, and admin cleanup controls\n- **Prompt overflow handling** — automatically offloads large prompts to file-backed context\n- **Runtime prompt overrides** — inspect and update protocol prompts from the admin API\n- **Worker routing** — optional egress\u002FIP verification and worker forwarding\n- **Diagnostics APIs** — built-in logs, runtime inspection, and debug roundtrip endpoints\n\n---\n\n## Requirements\n\n- [Node.js](https:\u002F\u002Fnodejs.org) 18+ (for npm\u002Fpnpm\u002Fbun compatibility)\n- One package manager: [npm](https:\u002F\u002Fwww.npmjs.com), [pnpm](https:\u002F\u002Fpnpm.io), or [Bun](https:\u002F\u002Fbun.sh)\n- Qwen credentials — configured via the admin UI or environment variables\n- Chrome \u002F Chromium — only needed for the automatic OAuth capture flow\n\n---\n\n## Quick Start\n\nChoose one package manager:\n\n```bash\n# npm\nnpm install\nnpm run dev\n```\n\n```bash\n# pnpm\npnpm install\npnpm run dev\n```\n\n```bash\n# bun\nbun install\nbun run dev\n```\n\nOpen the admin UI at `http:\u002F\u002F127.0.0.1:8080\u002F`, then go to **Providers** and configure your Qwen credentials.\n\n### Setup Provider\n\nConfigure the Qwen provider from the built-in admin UI:\n\n![Configure Qwen provider in the LunaProxy admin UI](.\u002FResource\u002FSetupProvider.gif)\n\n### Client Demos\n\nUse LunaProxy from Cline in VS Code:\n\n![LunaProxy demo with Cline in VS Code](.\u002FResource\u002FDemoCline.gif)\n\nUse LunaProxy from Claude Code CLI:\n\n![LunaProxy demo with Claude Code CLI](.\u002FResource\u002FDemoClaudeCode.gif)\n\nHealth check:\n\n```bash\ncurl http:\u002F\u002F127.0.0.1:8080\u002Fhealth\n```\n\n---\n\n## Configuration\n\nThe proxy listens on `127.0.0.1:8080` by default. All runtime configuration is stored at:\n\n```\ndata\u002Fconfig.json\n```\n\n---\n\n## Supported Models\n\nLunaProxy exposes the built-in Qwen model catalog through the `\u002Fv1\u002Fmodels` endpoint in OpenAI-compatible format. The model list, descriptions, limits, modalities, and display-name-to-provider-id mappings are maintained in `src\u002Fmain\u002Fproviders\u002Fbuiltin\u002Fqwen-ai.ts`; this is the single source used by `\u002Fapi\u002Fmodels`, `\u002Fapi\u002Fmodels\u002Frefresh`, and `\u002Fv1\u002Fmodels`.\n\n```bash\ncurl -sS http:\u002F\u002F127.0.0.1:8080\u002Fv1\u002Fmodels\n```\n\nExample response:\n\n```json\n{\n  \"object\": \"list\",\n  \"data\": [\n    {\n      \"id\": \"qwen3.6-plus\",\n      \"object\": \"model\",\n      \"created\": 0,\n      \"owned_by\": \"qwen-ai\",\n      \"name\": \"Qwen3.6 Plus\"\n    }\n  ]\n}\n```\n\nThe **Models** page can refresh\u002Fsync the runtime config from this built-in catalog via `POST \u002Fapi\u002Fmodels\u002Frefresh`; it does not fetch a separate model list from Qwen at runtime. Chat requests may use either the display name, such as `Qwen3.7-Max-Preview`, or the provider model id, such as `qwen-latest-series-invite-beta-v24`; both resolve to the same upstream model.\n\n---\n\n## Credentials\n\nLunaProxy supports two ways to configure Qwen credentials.\n\n### Automatic OAuth Capture\n\nOpens a real browser window, captures the Qwen web token and cookies after you log in, and saves them automatically.\n\n**Requirements:** Chrome or Chromium must be installed. Access to `https:\u002F\u002Fchat.qwen.ai` is required.\n\nFrom the admin UI:\n\n1. Open `http:\u002F\u002F127.0.0.1:8080\u002F`\n2. Go to **Providers → qwen-ai → OAuth tab**\n3. Click **Start OAuth** and log in to Qwen in the browser window\n4. Wait for LunaProxy to capture and save the credentials\n\nEquivalent API call:\n\n```bash\ncurl -X POST http:\u002F\u002F127.0.0.1:8080\u002Fapi\u002Fprovider\u002Foauth\u002Fcapture \\\n  -H 'Content-Type: application\u002Fjson' \\\n  -d '{\"providerId\": \"qwen-ai\", \"timeout\": 300000}'\n```\n\nIf the browser is not found automatically, set the path explicitly:\n\n```bash\n# npm\nPUPPETEER_EXECUTABLE_PATH=\u002Fusr\u002Fbin\u002Fchromium npm run dev\n\n# pnpm\nPUPPETEER_EXECUTABLE_PATH=\u002Fusr\u002Fbin\u002Fchromium pnpm run dev\n\n# bun\nPUPPETEER_EXECUTABLE_PATH=\u002Fusr\u002Fbin\u002Fchromium bun run dev\n```\n\n### Manual Token & Cookie Input\n\nUse this when you already have a valid Qwen token and cookie header.\n\nFrom the admin UI:\n\n1. Go to **Providers → qwen-ai → Config tab**\n2. Paste your token and cookie header\n3. Click **Validate**, then **Save**\n\nVia API:\n\n```bash\n# Set credentials\ncurl -X POST http:\u002F\u002F127.0.0.1:8080\u002Fapi\u002Fprovider\u002Ftoken \\\n  -H 'Content-Type: application\u002Fjson' \\\n  -d '{\n    \"providerId\": \"qwen-ai\",\n    \"credentials\": {\n      \"token\": \"YOUR_QWEN_TOKEN\",\n      \"cookies\": \"YOUR_QWEN_COOKIES\"\n    }\n  }'\n\n# Validate credentials\ncurl -X POST http:\u002F\u002F127.0.0.1:8080\u002Fapi\u002Fprovider\u002Fvalidate \\\n  -H 'Content-Type: application\u002Fjson' \\\n  -d '{\n    \"providerId\": \"qwen-ai\",\n    \"credentials\": {\n      \"token\": \"YOUR_QWEN_TOKEN\",\n      \"cookies\": \"YOUR_QWEN_COOKIES\"\n    }\n  }'\n\n# Check provider status\ncurl 'http:\u002F\u002F127.0.0.1:8080\u002Fapi\u002Fprovider\u002Fstatus?providerId=qwen-ai'\n```\n\n### Environment Variables\n\nLunaProxy also reads credentials from environment variables as a fallback:\n\n```\nQWEN_AI_TOKEN\nQWEN_AI_COOKIES\n```\n\n### Proxy Key Authentication\n\nIf `proxy.key` is set in `data\u002Fconfig.json`, all requests to `\u002Fv1\u002Fchat\u002Fcompletions` and `\u002Fv1\u002Fmodels` must include the key via either:\n\n```\nAuthorization: Bearer \u003Cproxy-key>\n```\n\nor:\n\n```\nx-proxy-key: \u003Cproxy-key>\n```\n\n---\n\n## Chat API\n\n**Endpoint:** `POST \u002Fv1\u002Fchat\u002Fcompletions`\n\n### Non-streaming request\n\n```bash\ncurl -sS -X POST http:\u002F\u002F127.0.0.1:8080\u002Fv1\u002Fchat\u002Fcompletions \\\n  -H 'Content-Type: application\u002Fjson' \\\n  -d '{\n    \"model\": \"qwen3.6-plus\",\n    \"stream\": false,\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"Hello!\"}\n    ]\n  }'\n```\n\n### Streaming request\n\n```bash\ncurl -N -sS -X POST http:\u002F\u002F127.0.0.1:8080\u002Fv1\u002Fchat\u002Fcompletions \\\n  -H 'Content-Type: application\u002Fjson' \\\n  -d '{\n    \"model\": \"qwen3.6-plus\",\n    \"stream\": true,\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"Write a short introduction\"}\n    ]\n  }'\n```\n\n### Request fields\n\n| Field | Type | Description |\n|---|---|---|\n| `model` | string | Qwen model name or mapped model ID |\n| `messages` | array | OpenAI-style message array |\n| `stream` | boolean | `true` for SSE streaming, `false` for collected response |\n| `account` | string | *(optional)* Preferred provider account ID |\n| `session_id` | string | *(optional)* LunaProxy session ID |\n| `providerSessionId` | string | *(optional)* Upstream Qwen chat ID |\n| `file_ids` | array | *(optional)* Pre-uploaded Qwen file IDs |\n| `thinking_mode` | string | *(optional)* Qwen thinking mode |\n| `reasoning_effort` | string | *(optional)* Reasoning effort level |\n| `enable_thinking` | boolean | *(optional)* Enable thinking mode |\n| `thinking_budget` | number | *(optional)* Token budget for thinking |\n| `tools` | array | *(optional)* OpenAI-style tool definitions |\n| `tool_choice` | string\u002Fobject | *(optional)* `auto`, `none`, `required`, or a specific function |\n\n### Session headers\n\nUseful request headers:\n\n```\nx-luna-session-id\nx-luna-source\nx-luna-workspace\nx-luna-thread-id\nx-luna-provider-session-id\nx-luna-account-id\n```\n\nResponse headers (when a session is resolved):\n\n```\nx-luna-session-id\nx-luna-thread-id\nx-luna-provider-session-id\n```\n\n---\n\n## Anthropic API\n\n**Endpoint:** `POST \u002Fv1\u002Fmessages`\n\nThis endpoint accepts Anthropic-style `system`, `messages`, `tools`, and `tool_choice` fields, converts them to the internal chat format, routes the request through Qwen, then renders the response back as Anthropic-compatible content blocks.\n\n```bash\ncurl -N -sS -X POST http:\u002F\u002F127.0.0.1:8080\u002Fv1\u002Fmessages \\\n  -H 'Content-Type: application\u002Fjson' \\\n  -H 'anthropic-version: 2023-06-01' \\\n  -d '{\n    \"model\": \"qwen3.6-plus\",\n    \"max_tokens\": 1024,\n    \"stream\": true,\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"Read the project README and summarize it\"}\n    ],\n    \"tools\": [\n      {\n        \"name\": \"Read\",\n        \"description\": \"Read a local file\",\n        \"input_schema\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"file_path\": {\"type\": \"string\"}\n          },\n          \"required\": [\"file_path\"]\n        }\n      }\n    ]\n  }'\n```\n\n`POST \u002Fv1\u002Fmessages\u002Fcount_tokens` returns a local estimate. It does not call Qwen.\n\n---\n\n## Tool Calling\n\nQwen web chat does not provide the same local tool runtime as clients such as Claude Code or Cline. LunaProxy bridges that gap at the protocol layer:\n\n1. The client sends OpenAI `tools` or Anthropic `tools`.\n2. LunaProxy injects a strict ML_XML tool-call contract into the prompt.\n3. If Qwen emits `\u003Cml_tool_calls>...\u003C\u002Fml_tool_calls>`, LunaProxy parses it.\n4. If Qwen emits native `function_call` deltas, LunaProxy intercepts them before Qwen's own web backend can leak `Tool ... does not exists.`\n5. LunaProxy returns standard OpenAI `tool_calls` or Anthropic `tool_use` blocks to the client.\n6. The client executes the tool and sends the result back in the next request.\n\nLunaProxy does not execute `Read`, `Bash`, `Edit`, or other client tools itself. It only translates model output into the client protocol. A client without tool execution support will still need its own executor.\n\nThe tool prompt defaults live in:\n\n```\nsrc\u002Fmain\u002Fproxy\u002Fprompts\u002Fprompts.ts\nsrc\u002Fmain\u002Fproxy\u002Ftoolcall\u002Ftoolcall.ts\n```\n\nRuntime prompt overrides are available through `GET \u002Fapi\u002Fprompts`, `POST \u002Fapi\u002Fprompts`, and `POST \u002Fapi\u002Fprompts\u002Freset`.\n\n---\n\n## Prompt Overflow\n\nWhen a prompt exceeds the configured token threshold, LunaProxy writes the full prompt to an overflow file and sends a compact transport prompt + the file to Qwen instead. The file is treated as the primary conversation context, not as a reference attachment.\n\nOverflow files are stored at:\n\n```\ndata\u002Foverflow\u002F\n```\n\nDefault overflow settings are configured in `data\u002Fconfig.json` under `settings.tokenOverflow`.\n\nThe `TOTAL_TOKENS` value written into an overflow file is local debug metadata. It is not sent to Qwen as an API parameter and changing it does not change provider-side token accounting. Qwen still parses and tokenizes the attached file content. Very large tool results or session histories can still trigger provider errors such as `Allocated quota exceeded` even if the advertised model context window is larger.\n\nWhen debugging overflow problems, inspect:\n\n```\ndata\u002Foverflow\u002F\ndata\u002Fwire-logs\u002F\ndata\u002Fconfig.json\n```\n\nIf overflow files keep growing, reduce retained session history, compact old tool results, or avoid persisting large file reads as full prompt history.\n\n---\n\n## Sessions & Runs\n\nLunaProxy persists session and run state to disk:\n\n```\ndata\u002Fsessions.json   # session history and provider bindings\ndata\u002Fruns.json       # run history\n```\n\nSession behavior is configured under `settings.session`. Concurrency and queueing behavior is under `settings.multiThread`.\n\nThe admin UI includes dedicated pages for browsing sessions, runs, logs, providers, models, and workers. Logs, Runs, and Sessions render lazily in batches while you scroll, so long histories do not block the UI. Session and run detail views open in an overlay panel, similar to the Logs detail view, so selecting an item does not require scrolling past a long table.\n\nCleanup controls:\n\n- Logs can be cleared from the Logs page or with `DELETE \u002Fapi\u002Flogs`.\n- Runs can be deleted individually or all at once from the Runs page.\n- Sessions can be deleted individually or all at once from the Sessions page.\n\nOverflow and compact artifacts are preserved locally for debugging:\n\n```\ndata\u002Foverflow\u002F   # full prompt overflow files\ndata\u002Fcompact\u002F    # compact-session source files\n```\n\nIf Qwen file upload or parse-status polling fails during overflow, LunaProxy falls back to the original request messages instead of sending a fake attachment prompt. If compact upload fails, the local compact file is kept and compaction is skipped.\n\n---\n\n## API Reference\n\n### Core endpoints\n\n| Method | Path | Description |\n|---|---|---|\n| `GET` | `\u002Fhealth` | Health check |\n| `GET` | `\u002Fv1\u002Fmodels` | List available models |\n| `POST` | `\u002Fv1\u002Fchat\u002Fcompletions` | Chat completions |\n| `POST` | `\u002Fv1\u002Fmessages` | Anthropic-compatible messages |\n| `POST` | `\u002Fv1\u002Fmessages\u002Fcount_tokens` | Anthropic-compatible token estimate |\n\n### Admin & config\n\n| Method | Path | Description |\n|---|---|---|\n| `GET` | `\u002Fapi\u002Fconfig` | Read current config |\n| `POST` | `\u002Fapi\u002Fconfig` | Update config |\n| `GET` | `\u002Fapi\u002Fprompts` | List runtime prompt definitions and overrides |\n| `POST` | `\u002Fapi\u002Fprompts` | Set a prompt override |\n| `POST` | `\u002Fapi\u002Fprompts\u002Freset` | Reset prompt overrides |\n| `GET` | `\u002Fapi\u002Fmodels` | List models |\n| `POST` | `\u002Fapi\u002Fmodels\u002Frefresh` | Refresh model list from provider |\n\n### Provider management\n\n| Method | Path | Description |\n|---|---|---|\n| `POST` | `\u002Fapi\u002Fprovider\u002Ftoken` | Set provider credentials |\n| `POST` | `\u002Fapi\u002Fprovider\u002Fvalidate` | Validate credentials |\n| `GET` | `\u002Fapi\u002Fprovider\u002Fstatus` | Get provider status |\n| `POST` | `\u002Fapi\u002Fprovider\u002Foauth\u002Fcapture` | Start OAuth capture flow |\n\n### Runtime & diagnostics\n\n| Method | Path | Description |\n|---|---|---|\n| `GET` | `\u002Fapi\u002Flogs` | Fetch logs |\n| `DELETE` | `\u002Fapi\u002Flogs` | Clear logs |\n| `GET` | `\u002Fapi\u002Fsessions` | List sessions |\n| `GET` | `\u002Fapi\u002Fsessions\u002F:id` | Get session detail |\n| `DELETE` | `\u002Fapi\u002Fsessions\u002F:id` | Delete one session |\n| `DELETE` | `\u002Fapi\u002Fsessions` | Delete all sessions |\n| `POST` | `\u002Fapi\u002Fsessions\u002F:id\u002Fclear` | Clear one session's history |\n| `POST` | `\u002Fapi\u002Fsessions\u002F:id\u002Fcompact` | Compact one session |\n| `POST` | `\u002Fapi\u002Fsessions\u002F:id\u002Frename` | Rename one session |\n| `POST` | `\u002Fapi\u002Fsessions\u002F:id\u002Freset-provider` | Reset provider chat binding |\n| `POST` | `\u002Fapi\u002Fsessions\u002Freload` | Reload sessions from disk |\n| `GET` | `\u002Fapi\u002Fruns` | List runs |\n| `GET` | `\u002Fapi\u002Fruns\u002F:id` | Get run detail |\n| `POST` | `\u002Fapi\u002Fruns\u002F:id\u002Fcancel` | Cancel an active run |\n| `DELETE` | `\u002Fapi\u002Fruns\u002F:id` | Delete one run |\n| `DELETE` | `\u002Fapi\u002Fruns` | Delete all runs |\n| `GET` | `\u002Fapi\u002Fruntime` | Runtime state |\n| `GET` | `\u002Fapi\u002Fprovider-runtime` | Provider runtime state |\n| `GET` | `\u002Fapi\u002Fnetwork-profiles` | Network profiles |\n| `GET` | `\u002Fapi\u002Fworkers` | Worker list |\n\n### Debug endpoints\n\n```\nGET \u002Fapi\u002Fdebug\u002Fqwen-roundtrip\nGET \u002Fapi\u002Fdebug\u002Fqwen-wire\nGET \u002Fapi\u002Fdebug\u002Fqwen-file-flow\n```\n\n---\n\n## Project Structure\n\n```\nLunaProxy\u002F\n├── src\u002F                  # Backend proxy source (Koa, scheduler, adapters)\n│   ├── server.ts         # Main Koa server and API routes\n│   ├── configStore.ts    # Config and log persistence\n│   ├── sessionStore.ts   # Session persistence and bindings\n│   ├── modules\u002F          # Overflow, session, stream, worker modules\n│   ├── runtime\u002F          # Scheduler, locks, routing, run tracking\n│   └── main\u002F             # OAuth, provider definitions, Qwen adapter\n├── frontend\u002F             # React admin UI source\n├── public\u002F               # Built static UI served by the backend\n├── tests\u002F                # TypeScript tests\n├── data\u002F                 # Runtime state, logs, overflow files (generated)\n└── lib\u002F                  # TypeScript build output (generated)\n```\n\n> See [STRUCTURE.md](.\u002FSTRUCTURE.md) for the full directory map and module ownership notes.\n\n---\n\n## Development\n\n```bash\n# Start dev server\nnpm run dev\n# or\npnpm run dev\n# or\nbun run dev\n\n# Watch mode\nnpm run dev:watch\n# or\npnpm run dev:watch\n# or\nbun run dev:watch\n\n# Type check\nnpm run typecheck\n# or\npnpm run typecheck\n# or\nbun run typecheck\n\n# Build\nnpm run build\n# or\npnpm run build\n# or\nbun run build\n```\n\n`npm run dev`, `pnpm run dev`, and `bun run dev` all execute `bun .\u002Fsrc\u002Fdev.ts`. TypeScript build output goes to `lib\u002F`.\n\nRun the focused tool-call suite with:\n\n```bash\nnpx ts-node tests\u002Ftoolcall.test.ts\n```\n\nThe frontend source lives in `frontend\u002F`. The backend serves the pre-built static UI from `public\u002F`. To rebuild the UI, run the frontend build separately and copy the output to `public\u002F`.\n\n---\n\n## Troubleshooting\n\n**`Token\u002Fcookies not configured`**\nConfigure Qwen credentials via the admin UI or `POST \u002Fapi\u002Fprovider\u002Ftoken`.\n\n**`Unauthorized: invalid proxy key`**\nPass the configured proxy key via `Authorization: Bearer \u003Ckey>` or the `x-proxy-key` header.\n\n**`Scheduler queue timeout`**\nCheck active runs, account concurrency limits, and worker availability in the admin UI under **Runs** and **Runtime**.\n\n**Overflow or file upload failures**\nInspect `data\u002Foverflow\u002F`, `data\u002Fwire-logs\u002F`, and `data\u002Fconfig.json`. Use the debug endpoints for deeper inspection.\n\n**`Allocated quota exceeded` from Qwen**\nThe provider rejected the effective prompt allocation. This can happen when overflow files contain very large histories or tool results. The local `TOTAL_TOKENS` line in the overflow file is only metadata; reduce the actual prompt\u002Ffile content instead.\n\n**`Tool ... does not exists` in provider logs**\nQwen may emit native `function_call` deltas and then its web backend may report missing tools. LunaProxy intercepts that pattern in the stream transformer and returns client-compatible tool calls. If the text reaches the client, restart the dev server and inspect `data\u002Fwire-logs\u002F` plus `tests\u002Ftoolcall.test.ts`.\n\n**Stream issues**\nCheck the **Logs** and **Runs** pages in the admin UI, or query `GET \u002Fapi\u002Flogs` and `GET \u002Fapi\u002Fruns` directly.\n","Luna-Proxy 是一个本地反向代理，能够将Qwen的网页聊天功能以完全兼容OpenAI API的形式暴露出来。该项目支持多账户路由、会话跟踪，并提供了一个内置的React管理界面。它通过单个进程处理凭证管理、多账户并发、会话持久化以及提示溢出等问题。特别适合需要在本地开发环境中直接与Qwen交互而不依赖云服务或第三方中继的应用场景。用户可以利用其提供的OpenAI和Anthropic兼容API接口轻松集成到现有的工具链中，同时享受流式传输支持、工具调用桥接等高级特性。",2,"2026-06-11 04:03:30","CREATED_QUERY"]