@magpie-community/opencode-trae-auth 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/index.mjs +30 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,9 +32,10 @@ agent's `POST https://trae-api-cn.mchost.guru/api/agent/v3/llm_utils_chat`:
|
|
|
32
32
|
- **Request:**
|
|
33
33
|
- The messages go as `{role, content: [{type: "text", text}]}`.
|
|
34
34
|
- The model goes as `config_name` and `model`.
|
|
35
|
-
- The function is
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
- The function is the one whose model list has the model (`chat_v3`, the
|
|
36
|
+
classic IDE's, first; else `solo_work_lite`, SOLO's). If Trae answers
|
|
37
|
+
4001, 4023 or 1005, the plugin tries the other once and remembers which
|
|
38
|
+
one worked.
|
|
38
39
|
- **Headers:** the IDE's: `Authorization: Cloud-IDE-JWT …`,
|
|
39
40
|
`X-Cloudide-Token`, `x-app-id`, `x-ide-version`, the device headers and
|
|
40
41
|
`x-uid`.
|
|
@@ -54,8 +55,9 @@ agent's `POST https://trae-api-cn.mchost.guru/api/agent/v3/llm_utils_chat`:
|
|
|
54
55
|
- Earlier calls and their results go back in as text.
|
|
55
56
|
- Images aren't sent.
|
|
56
57
|
|
|
57
|
-
The model list is the account's own, from `/api/ide/v1/get_detail_param
|
|
58
|
-
|
|
58
|
+
The model list is the account's own, from `/api/ide/v1/get_detail_param`,
|
|
59
|
+
asked for both functions and put together: SOLO lists models `chat_v3`
|
|
60
|
+
doesn't (DeepSeek-V4.1-Flash). When neither can be read, the plugin uses the models Trae CN's `chat_v3` is
|
|
59
61
|
known to serve: GLM-5.2, GLM-5, Kimi K2.6, Qwen 3.7 Plus, DeepSeek V4 Pro
|
|
60
62
|
and DeepSeek V4 Flash.
|
|
61
63
|
|
package/index.mjs
CHANGED
|
@@ -727,6 +727,8 @@ export const TraeCNAuthPlugin = async ({ client }) => {
|
|
|
727
727
|
const renewed = new Map()
|
|
728
728
|
// the chat function that served each account last
|
|
729
729
|
const fnOf = new Map()
|
|
730
|
+
// the first chat function whose model list has each model
|
|
731
|
+
const listedBy = new Map()
|
|
730
732
|
|
|
731
733
|
const save = async (auth) => {
|
|
732
734
|
try {
|
|
@@ -814,10 +816,10 @@ export const TraeCNAuthPlugin = async ({ client }) => {
|
|
|
814
816
|
return out
|
|
815
817
|
}
|
|
816
818
|
|
|
817
|
-
//
|
|
818
|
-
const
|
|
819
|
+
// listOf is one function's model list, as the IDE asks for it
|
|
820
|
+
const listOf = async (a, fn) => {
|
|
819
821
|
const r = await post(a, apiOf(a) + "/api/ide/v1/get_detail_param", {
|
|
820
|
-
function:
|
|
822
|
+
function: fn, config_names: null, need_prompt: false, current_config_info: null, poly_prompt: true, mode_type: null, agent_type: null,
|
|
821
823
|
})
|
|
822
824
|
if (r.status === 401 || lapsedCode(errorOf(r.v).code)) throw new Expired("Trae CN's sign-in has expired; sign in again")
|
|
823
825
|
if (r.status !== 200) throw new Error(`Trae CN models: ${statusLine(r.status)}`)
|
|
@@ -825,6 +827,28 @@ export const TraeCNAuthPlugin = async ({ client }) => {
|
|
|
825
827
|
return list.filter((m) => m?.config_name)
|
|
826
828
|
}
|
|
827
829
|
|
|
830
|
+
// liveModels is the account's model list: every chat function's, since
|
|
831
|
+
// SOLO lists models the classic IDE's chat_v3 doesn't (DeepSeek-V4.1-Flash
|
|
832
|
+
// came to SOLO first, yetone/magpie#681); a model listed by one function
|
|
833
|
+
// only is asked through that one. One function's list failing leaves the
|
|
834
|
+
// others'; all failing is the error.
|
|
835
|
+
const liveModels = async (a) => {
|
|
836
|
+
const got = await Promise.allSettled(FUNCTIONS.map((fn) => listOf(a, fn)))
|
|
837
|
+
const expired = got.find((g) => g.status === "rejected" && g.reason instanceof Expired)
|
|
838
|
+
if (expired) throw expired.reason
|
|
839
|
+
if (got.every((g) => g.status === "rejected")) throw got[0].reason
|
|
840
|
+
const out = new Map()
|
|
841
|
+
got.forEach((g, i) => {
|
|
842
|
+
if (g.status !== "fulfilled") return
|
|
843
|
+
for (const m of g.value) {
|
|
844
|
+
const id = String(m.config_name)
|
|
845
|
+
if (!out.has(id)) out.set(id, { m, fn: FUNCTIONS[i] })
|
|
846
|
+
}
|
|
847
|
+
})
|
|
848
|
+
for (const [id, { fn }] of out) listedBy.set(id, fn)
|
|
849
|
+
return [...out.values()].map((x) => x.m)
|
|
850
|
+
}
|
|
851
|
+
|
|
828
852
|
const modelOf = (provider, m) => {
|
|
829
853
|
const id = String(m.config_name)
|
|
830
854
|
const was = provider.models?.[id] ?? {}
|
|
@@ -889,7 +913,9 @@ export const TraeCNAuthPlugin = async ({ client }) => {
|
|
|
889
913
|
}
|
|
890
914
|
const signIn = a.renewed ? "renewed" : "kept"
|
|
891
915
|
const who = a.uid || a.name
|
|
892
|
-
|
|
916
|
+
// the function that lists the model first, then the one that
|
|
917
|
+
// served this account last, then the rest
|
|
918
|
+
const fns = [...new Set([listedBy.get(String(req.model)), fnOf.get(who), ...FUNCTIONS].filter(Boolean))]
|
|
893
919
|
let last
|
|
894
920
|
for (const fn of fns) {
|
|
895
921
|
const res = await fetch(apiOf(a) + "/api/agent/v3/llm_utils_chat", {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magpie-community/opencode-trae-auth",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "OpenCode provider plugin for Trae CN (trae.cn): your Trae CN account's models, free tier included, with Trae's own browser sign-in",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.mjs",
|