fix(proxy): Trae messages.content 转原生块数组,修复 4001
Some checks are pending
Release / build (push) Waiting to run

- 上游 LLMRawMessage.messages.content 要求 []*LLMRawMessageContent
- 字符串转 [{"type":"text","text":...}],列表块按 text/input_text 归一
- 版本升至 1.7.2
This commit is contained in:
Liuxinyu176 2026-10-09 10:21:48 +08:00
parent b5ef9249d8
commit ada750df7e
2 changed files with 68 additions and 4 deletions

View File

@ -16,8 +16,8 @@ android {
applicationId = "com.rainy.token"
minSdk = 31
targetSdk = 35
versionCode = 21
versionName = "1.7.1"
versionCode = 22
versionName = "1.7.2"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {

View File

@ -10,8 +10,11 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonNull
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.contentOrNull
import kotlinx.serialization.json.put
@ -164,6 +167,67 @@ class TraeChatProxy @Inject constructor(
"User-Agent" to "Trae/0.1.52",
)
private fun convertNativeMessages(src: JsonElement?): List<JsonElement> {
val arr = src as? JsonArray ?: return emptyList()
return arr.mapNotNull { el ->
val m = el as? JsonObject ?: return@mapNotNull null
val rawRole = (m["role"] as? JsonPrimitive)?.contentOrNull?.lowercase() ?: "user"
val role = when (rawRole) {
"developer" -> "system"
"system", "user", "assistant", "tool", "function" -> rawRole
else -> "user"
}
buildJsonObject {
put("role", role)
val content = nativeContent(m["content"])
if (content != null) put("content", content)
m["name"]?.let { put("name", it) }
m["tool_call_id"]?.let { put("tool_call_id", it) }
m["tool_calls"]?.let { put("tool_calls", it) }
}
}
}
private fun nativeContent(content: JsonElement?): JsonElement? {
if (content == null || content is JsonNull) return null
if (content is JsonPrimitive) {
return buildJsonArray {
add(buildJsonObject {
put("type", "text")
put("text", content.content)
})
}
}
if (content is JsonArray) {
return buildJsonArray {
content.forEach { block ->
when (block) {
is JsonPrimitive -> add(buildJsonObject {
put("type", "text")
put("text", block.content)
})
is JsonObject -> {
val type = (block["type"] as? JsonPrimitive)?.contentOrNull?.lowercase()
if (type == "text" || type == "input_text") {
val text = (block["text"] as? JsonPrimitive)?.contentOrNull
?: (block["content"] as? JsonPrimitive)?.contentOrNull
?: ""
add(buildJsonObject {
put("type", "text")
put("text", text)
})
} else {
add(block)
}
}
else -> add(block)
}
}
}
}
return null
}
private fun buildUpstreamBody(raw: String, credential: Credential.TraeCredential): String {
val src = try {
json.parseToJsonElement(raw) as? JsonObject
@ -173,11 +237,11 @@ class TraeChatProxy @Inject constructor(
val model = (src["model"] as? JsonPrimitive)?.contentOrNull?.takeIf { it.isNotBlank() }
?: "glm-5.2"
val messages = src["messages"] as? JsonArray ?: JsonArray(emptyList())
val messages = convertNativeMessages(src["messages"])
val sessionId = UUID.randomUUID().toString().replace("-", "")
return buildJsonObject {
put("messages", messages)
put("messages", JsonArray(messages))
put("config_name", model)
put("model", model)
put("function", "solo_work_lite")