From d0b79cf1bd026726803556ce39e100fe8f8e52e0 Mon Sep 17 00:00:00 2001 From: Liuxinyu176 <1041316040@qq.com> Date: Fri, 9 Oct 2026 09:29:40 +0800 Subject: [PATCH] =?UTF-8?q?fix(proxy):=20Trae=20CN=20=E4=B8=8A=E6=B8=B8?= =?UTF-8?q?=E6=8D=A2=E7=94=A8=20trae-api-cn.mchost.guru=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=20404?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - trae-api-cn.mchost.guru/api/agent/v3/llm_utils_chat 才是模型网关 - api.trae.cn 只是账号/OAuth 主机,不暴露 IDE 模型路由 - 请求头对齐参考实现:真实 x-app-id / x-ide-version / 设备指纹 - llm_utils_chat body 收敛为 SOLO 结构(config_name/model/function/stream) --- app/build.gradle.kts | 4 +- .../rainy/token/data/proxy/TraeChatProxy.kt | 52 +++++++++++-------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 88b9c41..b952496 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -16,8 +16,8 @@ android { applicationId = "com.rainy.token" minSdk = 31 targetSdk = 35 - versionCode = 16 - versionName = "1.6.6" + versionCode = 17 + versionName = "1.6.7" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/app/src/main/java/com/rainy/token/data/proxy/TraeChatProxy.kt b/app/src/main/java/com/rainy/token/data/proxy/TraeChatProxy.kt index 8f3f8af..c5a718d 100644 --- a/app/src/main/java/com/rainy/token/data/proxy/TraeChatProxy.kt +++ b/app/src/main/java/com/rainy/token/data/proxy/TraeChatProxy.kt @@ -51,9 +51,9 @@ class TraeChatProxy @Inject constructor( ProviderRegion.valueOf(credential.region.uppercase()) }.getOrNull() val base = if (effectiveRegion == ProviderRegion.INTL) { - "https://grow-normal.trae.ai" + "https://a0ai-api-sg.byteintlapi.com" } else { - "https://api.trae.cn" + "https://trae-api-cn.mchost.guru" } val upstreamBody = buildUpstreamBody(requestBody, credential) val requestId = UUID.randomUUID().toString() @@ -63,19 +63,24 @@ class TraeChatProxy @Inject constructor( .url(base + "/api/agent/v3/llm_utils_chat") .addHeader("Content-Type", "application/json") .addHeader("Accept", "text/event-stream") - .addHeader("Authorization", "Cloud-IDE-JWT $jwt") + .addHeader("Authorization", "Cloud-IDE-JWT jwt") .addHeader("X-Cloudide-Token", jwt) .addHeader("x-uid", credential.userId ?: "") + .addHeader("x-app-id", "6eefa01c-1036-4c7e-9ca5-d891f63bfcd8") .addHeader("x-device-id", credential.deviceId ?: credential.checkinDeviceId ?: "") .addHeader("x-machine-id", credential.deviceId ?: credential.checkinDeviceId ?: "") .addHeader("x-request-id", requestId) - .addHeader("x-app-id", "trae") - .addHeader("x-ide-version", "1.0.0") - .addHeader("x-ide-version-code", "1000000") + .addHeader("x-ide-version", "3.3.67") + .addHeader("x-ide-version-code", "20260401") .addHeader("x-ide-version-type", "stable") - .addHeader("x-os-version", "Android") - .addHeader("x-system-type", "Android") - .addHeader("User-Agent", "RainyToken/1.0") + .addHeader("x-device-cpu", "AMD") + .addHeader("x-device-brand", "83DG") + .addHeader("x-device-type", "windows") + .addHeader("x-ide-token", jwt) + .addHeader("x-os-version", "Windows 10") + .addHeader("x-system-type", "Windows") + .addHeader("Connection", "keep-alive") + .addHeader("User-Agent", "") .post(upstreamBody.toRequestBody("application/json".toMediaType())) val response = try { @@ -117,19 +122,24 @@ class TraeChatProxy @Inject constructor( .url(base + "/api/agent/v3/llm_utils_chat") .addHeader("Content-Type", "application/json") .addHeader("Accept", "text/event-stream") - .addHeader("Authorization", "Cloud-IDE-JWT $jwt") + .addHeader("Authorization", "Cloud-IDE-JWT jwt") .addHeader("X-Cloudide-Token", jwt) .addHeader("x-uid", credential.userId ?: "") + .addHeader("x-app-id", "6eefa01c-1036-4c7e-9ca5-d891f63bfcd8") .addHeader("x-device-id", credential.deviceId ?: credential.checkinDeviceId ?: "") .addHeader("x-machine-id", credential.deviceId ?: credential.checkinDeviceId ?: "") .addHeader("x-request-id", requestId) - .addHeader("x-app-id", "trae") - .addHeader("x-ide-version", "1.0.0") - .addHeader("x-ide-version-code", "1000000") + .addHeader("x-ide-version", "3.3.67") + .addHeader("x-ide-version-code", "20260401") .addHeader("x-ide-version-type", "stable") - .addHeader("x-os-version", "Android") - .addHeader("x-system-type", "Android") - .addHeader("User-Agent", "RainyToken/1.0") + .addHeader("x-device-cpu", "AMD") + .addHeader("x-device-brand", "83DG") + .addHeader("x-device-type", "windows") + .addHeader("x-ide-token", jwt) + .addHeader("x-os-version", "Windows 10") + .addHeader("x-system-type", "Windows") + .addHeader("Connection", "keep-alive") + .addHeader("User-Agent", "") .post(upstreamBody.toRequestBody("application/json".toMediaType())) val response = try { @@ -162,17 +172,13 @@ class TraeChatProxy @Inject constructor( val sessionId = UUID.randomUUID().toString().replace("-", "") return buildJsonObject { - put("conversation_id", "") - put("session_id", sessionId) - put("user_id", credential.userId ?: "") - put("device_id", credential.deviceId ?: credential.checkinDeviceId ?: "") - put("agent_type", "solo_work_lite") - put("model_name", model + "__dev") + put("messages", messages) put("config_name", model) + put("model", model) put("function", "solo_work_lite") put("stream", true) put("request_id", sessionId) - put("messages", messages) + put("session_id", sessionId) src["tools"]?.let { put("tools", it) } src["tool_choice"]?.let { put("tool_choice", it) } (src["max_tokens"] as? JsonPrimitive)?.contentOrNull?.toIntOrNull()?.let {