diff --git a/.env.example b/.env.example index 55d3ddc7..973ca0ef 100644 --- a/.env.example +++ b/.env.example @@ -142,10 +142,32 @@ GITHUB_USER_AGENT=GitHubCopilotChat/0.26.7 ANTIGRAVITY_USER_AGENT=antigravity/1.104.0 darwin/arm64 KIRO_USER_AGENT=AWS-SDK-JS/3.0.0 kiro-ide/1.0.0 IFLOW_USER_AGENT=iFlow-Cli -QWEN_USER_AGENT=google-api-nodejs-client/9.15.1 +QWEN_USER_AGENT=QwenCode/0.12.3 (linux; x64) CURSOR_USER_AGENT=connect-es/1.6.1 GEMINI_CLI_USER_AGENT=google-api-nodejs-client/9.15.1 +# ───────────────────────────────────────────────────────────────────────────── +# CLI Fingerprint Compatibility (optional — match native CLI binary signatures) +# ───────────────────────────────────────────────────────────────────────────── +# When enabled, OmniRoute reorders HTTP headers and JSON body fields to match +# the exact signature of official CLI tools, reducing account flagging risk. +# Your proxy IP is preserved — you get both stealth AND IP masking. +# +# Enable per-provider: +# CLI_COMPAT_CODEX=1 +# CLI_COMPAT_CLAUDE=1 +# CLI_COMPAT_GITHUB=1 +# CLI_COMPAT_ANTIGRAVITY=1 +# CLI_COMPAT_KIRO=1 +# CLI_COMPAT_CURSOR=1 +# CLI_COMPAT_KIMI_CODING=1 +# CLI_COMPAT_KILOCODE=1 +# CLI_COMPAT_CLINE=1 +# CLI_COMPAT_QWEN=1 +# +# Or enable for all providers at once: +# CLI_COMPAT_ALL=1 + # API Key Providers (Phase 1 + Phase 4) # Add via Dashboard → Providers → Add API Key, or set here # DEEPSEEK_API_KEY= diff --git a/open-sse/config/cliFingerprints.ts b/open-sse/config/cliFingerprints.ts index 61c2f73f..87e76c17 100644 --- a/open-sse/config/cliFingerprints.ts +++ b/open-sse/config/cliFingerprints.ts @@ -118,6 +118,58 @@ export const CLI_FINGERPRINTS: Record = { bodyFieldOrder: ["project", "model", "userAgent", "requestType", "requestId", "request"], userAgent: "antigravity", }, + qwen: { + headerOrder: [ + "Host", + "Content-Type", + "Authorization", + "User-Agent", + "X-Dashscope-AuthType", + "X-Dashscope-CacheControl", + "X-Dashscope-UserAgent", + "X-Stainless-Arch", + "X-Stainless-Lang", + "X-Stainless-Os", + "X-Stainless-Package-Version", + "X-Stainless-Retry-Count", + "X-Stainless-Runtime", + "X-Stainless-Runtime-Version", + "Connection", + "Accept", + "Accept-Language", + "Sec-Fetch-Mode", + "Accept-Encoding", + ], + bodyFieldOrder: [ + "model", + "messages", + "temperature", + "top_p", + "max_tokens", + "stream", + "tools", + "tool_choice", + "response_format", + "n", + "stop", + ], + userAgent: "QwenCode/0.12.3 (linux; x64)", + extraHeaders: { + "X-Dashscope-AuthType": "qwen-oauth", + "X-Dashscope-CacheControl": "enable", + "X-Dashscope-UserAgent": "QwenCode/0.12.3 (linux; x64)", + "X-Stainless-Arch": "x64", + "X-Stainless-Lang": "js", + "X-Stainless-Os": "Linux", + "X-Stainless-Package-Version": "5.11.0", + "X-Stainless-Retry-Count": "1", + "X-Stainless-Runtime": "node", + "X-Stainless-Runtime-Version": "v18.19.1", + Connection: "keep-alive", + "Accept-Language": "*", + "Sec-Fetch-Mode": "cors", + }, + }, }; /** diff --git a/open-sse/config/providerRegistry.ts b/open-sse/config/providerRegistry.ts index d019103c..01032bb1 100644 --- a/open-sse/config/providerRegistry.ts +++ b/open-sse/config/providerRegistry.ts @@ -212,8 +212,20 @@ export const REGISTRY: Record = { authType: "oauth", authHeader: "bearer", headers: { - "User-Agent": "google-api-nodejs-client/9.15.1", - "X-Goog-Api-Client": "gl-node/22.17.0", + "User-Agent": "QwenCode/0.12.3 (linux; x64)", + "X-Dashscope-AuthType": "qwen-oauth", + "X-Dashscope-CacheControl": "enable", + "X-Dashscope-UserAgent": "QwenCode/0.12.3 (linux; x64)", + "X-Stainless-Arch": "x64", + "X-Stainless-Lang": "js", + "X-Stainless-Os": "Linux", + "X-Stainless-Package-Version": "5.11.0", + "X-Stainless-Retry-Count": "1", + "X-Stainless-Runtime": "node", + "X-Stainless-Runtime-Version": "v18.19.1", + Connection: "keep-alive", + "Accept-Language": "*", + "Sec-Fetch-Mode": "cors", }, oauth: { clientIdEnv: "QWEN_OAUTH_CLIENT_ID", diff --git a/src/app/(dashboard)/dashboard/agents/page.tsx b/src/app/(dashboard)/dashboard/agents/page.tsx index 6c62c42f..a7d3ebfe 100644 --- a/src/app/(dashboard)/dashboard/agents/page.tsx +++ b/src/app/(dashboard)/dashboard/agents/page.tsx @@ -203,6 +203,7 @@ export default function AgentsPage() { "kimi-coding", "kilocode", "cline", + "qwen", ] as const ).map((providerId) => { const providerMeta = Object.values(AI_PROVIDERS).find(