@magpie-community/opencode-trae-auth 0.1.0 → 0.1.2
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 +8 -5
- package/index.mjs +35 -7
- 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 Work mode; else
|
|
37
|
+
`solo_agent`, the TRAE agent's). If Trae answers 4001, 4023 or 1005,
|
|
38
|
+
the plugin tries the others once and remembers which 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,10 @@ 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 each of those functions and put together: SOLO and the TRAE
|
|
60
|
+
agent list models `chat_v3` doesn't (deepseek-v4.1-flash is the TRAE
|
|
61
|
+
agent's, `solo_agent`). When neither can be read, the plugin uses the models Trae CN's `chat_v3` is
|
|
59
62
|
known to serve: GLM-5.2, GLM-5, Kimi K2.6, Qwen 3.7 Plus, DeepSeek V4 Pro
|
|
60
63
|
and DeepSeek V4 Flash.
|
|
61
64
|
|
package/index.mjs
CHANGED
|
@@ -26,8 +26,10 @@ const SIGN_IN_TIMEOUT = 10 * 60 * 1000
|
|
|
26
26
|
const EARLY_MS = 2 * 60 * 1000 // a token this close to its end is renewed before a request
|
|
27
27
|
const LEAD_MS = 10 * 60 * 1000 // and this close, magpie renews it ahead of time (auth.refresh)
|
|
28
28
|
const DAY = 24 * 3600 * 1000
|
|
29
|
-
// the IDE's chat functions: the classic IDE's agent, then SOLO's
|
|
30
|
-
|
|
29
|
+
// the IDE's chat functions: the classic IDE's agent, then SOLO's Work
|
|
30
|
+
// mode, then the TRAE agent (solo_agent): Trae CN 3.3.104's agent-type map
|
|
31
|
+
// files its models under "trae", and only that one has deepseek-v4.1-flash
|
|
32
|
+
const FUNCTIONS = ["chat_v3", "solo_work_lite", "solo_agent"]
|
|
31
33
|
|
|
32
34
|
const MODEL = { attachment: false, tool_call: true, reasoning: true, temperature: true, limit: { context: 128_000, output: 32_000 }, modalities: { input: ["text"], output: ["text"] } }
|
|
33
35
|
// what Trae CN's chat_v3 is known to serve; the live list replaces it
|
|
@@ -689,7 +691,7 @@ async function openai(req, it) {
|
|
|
689
691
|
return new Response(stream, { status: 200, headers: { "content-type": "text/event-stream", "cache-control": "no-cache" } })
|
|
690
692
|
}
|
|
691
693
|
|
|
692
|
-
// a model or function this account's chat_v3 doesn't take:
|
|
694
|
+
// a model or function this account's chat_v3 doesn't take: another may
|
|
693
695
|
const wrongFunction = (code) => ["4001", "4023", "1005"].includes(String(code))
|
|
694
696
|
|
|
695
697
|
// ---- usage ------------------------------------------------------------------------
|
|
@@ -727,6 +729,8 @@ export const TraeCNAuthPlugin = async ({ client }) => {
|
|
|
727
729
|
const renewed = new Map()
|
|
728
730
|
// the chat function that served each account last
|
|
729
731
|
const fnOf = new Map()
|
|
732
|
+
// the first chat function whose model list has each model
|
|
733
|
+
const listedBy = new Map()
|
|
730
734
|
|
|
731
735
|
const save = async (auth) => {
|
|
732
736
|
try {
|
|
@@ -814,10 +818,10 @@ export const TraeCNAuthPlugin = async ({ client }) => {
|
|
|
814
818
|
return out
|
|
815
819
|
}
|
|
816
820
|
|
|
817
|
-
//
|
|
818
|
-
const
|
|
821
|
+
// listOf is one function's model list, as the IDE asks for it
|
|
822
|
+
const listOf = async (a, fn) => {
|
|
819
823
|
const r = await post(a, apiOf(a) + "/api/ide/v1/get_detail_param", {
|
|
820
|
-
function:
|
|
824
|
+
function: fn, config_names: null, need_prompt: false, current_config_info: null, poly_prompt: true, mode_type: null, agent_type: null,
|
|
821
825
|
})
|
|
822
826
|
if (r.status === 401 || lapsedCode(errorOf(r.v).code)) throw new Expired("Trae CN's sign-in has expired; sign in again")
|
|
823
827
|
if (r.status !== 200) throw new Error(`Trae CN models: ${statusLine(r.status)}`)
|
|
@@ -825,6 +829,28 @@ export const TraeCNAuthPlugin = async ({ client }) => {
|
|
|
825
829
|
return list.filter((m) => m?.config_name)
|
|
826
830
|
}
|
|
827
831
|
|
|
832
|
+
// liveModels is the account's model list: every chat function's, since
|
|
833
|
+
// SOLO lists models the classic IDE's chat_v3 doesn't (deepseek-v4.1-flash
|
|
834
|
+
// came to the TRAE agent's first, yetone/magpie#681); a model listed by one function
|
|
835
|
+
// only is asked through that one. One function's list failing leaves the
|
|
836
|
+
// others'; all failing is the error.
|
|
837
|
+
const liveModels = async (a) => {
|
|
838
|
+
const got = await Promise.allSettled(FUNCTIONS.map((fn) => listOf(a, fn)))
|
|
839
|
+
const expired = got.find((g) => g.status === "rejected" && g.reason instanceof Expired)
|
|
840
|
+
if (expired) throw expired.reason
|
|
841
|
+
if (got.every((g) => g.status === "rejected")) throw got[0].reason
|
|
842
|
+
const out = new Map()
|
|
843
|
+
got.forEach((g, i) => {
|
|
844
|
+
if (g.status !== "fulfilled") return
|
|
845
|
+
for (const m of g.value) {
|
|
846
|
+
const id = String(m.config_name)
|
|
847
|
+
if (!out.has(id)) out.set(id, { m, fn: FUNCTIONS[i] })
|
|
848
|
+
}
|
|
849
|
+
})
|
|
850
|
+
for (const [id, { fn }] of out) listedBy.set(id, fn)
|
|
851
|
+
return [...out.values()].map((x) => x.m)
|
|
852
|
+
}
|
|
853
|
+
|
|
828
854
|
const modelOf = (provider, m) => {
|
|
829
855
|
const id = String(m.config_name)
|
|
830
856
|
const was = provider.models?.[id] ?? {}
|
|
@@ -889,7 +915,9 @@ export const TraeCNAuthPlugin = async ({ client }) => {
|
|
|
889
915
|
}
|
|
890
916
|
const signIn = a.renewed ? "renewed" : "kept"
|
|
891
917
|
const who = a.uid || a.name
|
|
892
|
-
|
|
918
|
+
// the function that lists the model first, then the one that
|
|
919
|
+
// served this account last, then the rest
|
|
920
|
+
const fns = [...new Set([listedBy.get(String(req.model)), fnOf.get(who), ...FUNCTIONS].filter(Boolean))]
|
|
893
921
|
let last
|
|
894
922
|
for (const fn of fns) {
|
|
895
923
|
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.2",
|
|
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",
|