@magpie-community/opencode-trae-auth 0.1.11 → 0.1.13

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.
Files changed (2) hide show
  1. package/index.mjs +28 -8
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -39,12 +39,15 @@ const DAY = 24 * 3600 * 1000
39
39
  // then SOLO Lite's agent
40
40
  const FUNCTIONS = ["chat_v3", "solo_work_lite", "solo_agent", "solo_agent_lite"]
41
41
 
42
- const MODEL = { attachment: false, tool_call: true, reasoning: true, temperature: true, limit: { context: 128_000, output: 32_000 }, modalities: { input: ["text"], output: ["text"] } }
42
+ // a reply limit of 0 is one Trae doesn't say: magpie then takes models.dev's
43
+ // for the model (magpie's catalog), where a made-up 32K told agents a far
44
+ // smaller one than DeepSeek V4.1 Flash's (ARNO on magpie's Discord)
45
+ const MODEL = { attachment: false, tool_call: true, reasoning: true, temperature: true, limit: { context: 128_000, output: 0 }, modalities: { input: ["text"], output: ["text"] } }
43
46
  // what Trae CN's chat_v3 is known to serve; the live list replaces it
44
47
  const MODELS = {
45
48
  "glm-5.2": { name: "GLM-5.2", ...MODEL, limit: { context: 200_000, output: 32_000 } },
46
49
  "glm-5": { name: "GLM-5", ...MODEL },
47
- "kimi-k2.6": { name: "Kimi K2.6", ...MODEL, limit: { context: 256_000, output: 32_000 } },
50
+ "kimi-k2.6": { name: "Kimi K2.6", ...MODEL, limit: { context: 256_000, output: 0 } },
48
51
  "qwen-3.7-plus": { name: "Qwen 3.7 Plus", ...MODEL },
49
52
  "DeepSeek-V4-Pro": { name: "DeepSeek V4 Pro", ...MODEL },
50
53
  "DeepSeek-V4-Flash": { name: "DeepSeek V4 Flash", ...MODEL },
@@ -444,8 +447,10 @@ const nativeTools = (tools) =>
444
447
  })
445
448
 
446
449
  // chatBody is the request for llm_utils_chat; modelName is the model the
447
- // function's list names for the config (its __dev one), when it named one
448
- function chatBody(req, fn, modelName) {
450
+ // function's list names for the config (its __dev one), when it named one,
451
+ // and most the max_tokens it gives that model (0: none given), which a
452
+ // request asking more is held to
453
+ function chatBody(req, fn, modelName, most = 0) {
449
454
  const session = randomUUID()
450
455
  const body = {
451
456
  messages: traeMessages(req),
@@ -458,7 +463,7 @@ function chatBody(req, fn, modelName) {
458
463
  session_id: session,
459
464
  }
460
465
  const max = req.max_completion_tokens ?? req.max_tokens
461
- if (Number.isFinite(max) && max > 0) body.max_tokens = Math.floor(max)
466
+ if (Number.isFinite(max) && max > 0) body.max_tokens = most > 0 ? Math.min(Math.floor(max), most) : Math.floor(max)
462
467
  if (typeof req.temperature === "number") body.temperature = req.temperature
463
468
  if (Array.isArray(req.tools) && req.tools.length && req.tool_choice !== "none") {
464
469
  body.tools = nativeTools(req.tools)
@@ -552,6 +557,11 @@ class TextTools {
552
557
  const m = this.buf.match(LEFTOVER)
553
558
  if (m) this.buf = this.buf.slice(m[0].length)
554
559
  if (!this.buf || (!end && MARKS.some((k) => k.startsWith(this.buf)))) break
560
+ // a tag cut short at the end (</), after the others: dropped too
561
+ if (end && this.buf.length > 1 && MARKS.some((k) => k.startsWith(this.buf.trimEnd()))) {
562
+ this.buf = ""
563
+ break
564
+ }
555
565
  this.after = false
556
566
  }
557
567
  const i = this.buf.indexOf(OPEN)
@@ -592,6 +602,16 @@ class TextTools {
592
602
  continue
593
603
  }
594
604
  const o = objectEnd(this.buf, i + OPEN.length)
605
+ const inner = this.buf.slice(i + OPEN.length).trimStart()
606
+ if (inner.startsWith("<") || (end && !inner)) {
607
+ // no JSON in it: DeepSeek's own invoke, or only the closes of one
608
+ // (magpie#823 again); the opener is dropped and what follows read
609
+ // as it is
610
+ text += this.buf.slice(0, i)
611
+ this.buf = inner
612
+ this.after = true
613
+ continue
614
+ }
595
615
  const v = o > 0 ? looseJSON(this.buf.slice(i + OPEN.length, o)) : null
596
616
  if (v?.name) {
597
617
  text += this.buf.slice(0, i)
@@ -1197,7 +1217,7 @@ export const TraeCNAuthPlugin = async ({ client }) => {
1197
1217
  for (const [id, { m, fn }] of out) {
1198
1218
  listedBy.set(id, fn)
1199
1219
  const dev = devModel(m)
1200
- if (dev) modelNames.set(id, { fn, name: dev.model_name })
1220
+ if (dev) modelNames.set(id, { fn, name: dev.model_name, most: Number(dev.max_tokens) || 0 })
1201
1221
  else modelNames.delete(id)
1202
1222
  }
1203
1223
  return [...out.values()].map((x) => x.m)
@@ -1208,7 +1228,7 @@ export const TraeCNAuthPlugin = async ({ client }) => {
1208
1228
  const was = provider.models?.[id] ?? {}
1209
1229
  // context_window_tokens: dev is what a request gets, max only in Max mode
1210
1230
  const ctx = Number(m.context_window_tokens?.dev ?? m.context_window_size?.max?.[0] ?? m.context_window_size?.max ?? m.context_window_tokens?.max ?? m.prompt_max_tokens) || was.limit?.context || MODEL.limit.context
1211
- const out = Number(devModel(m)?.max_tokens) || was.limit?.output || MODEL.limit.output
1231
+ const out = Number(devModel(m)?.max_tokens) || was.limit?.output || 0
1212
1232
  const name = m.display_config?.display_name || m.display_name || m.display_model_name || was.name || id
1213
1233
  return { ...MODEL, ...was, id, providerID: ID, name: String(name), limit: { context: ctx, output: out }, api: was.api ?? { id, url: HOSTS.api, npm: "@ai-sdk/openai-compatible" } }
1214
1234
  }
@@ -1281,7 +1301,7 @@ export const TraeCNAuthPlugin = async ({ client }) => {
1281
1301
  const res = await fetch(apiOf(a) + "/api/agent/v3/llm_utils_chat", {
1282
1302
  method: "POST",
1283
1303
  headers: ideHeaders(a, { Accept: "text/event-stream", "X-Request-ID": randomUUID() }),
1284
- body: JSON.stringify(chatBody(req, fn, named?.fn === fn ? named.name : "")),
1304
+ body: JSON.stringify(chatBody(req, fn, named?.fn === fn ? named.name : "", named?.fn === fn ? named.most : 0)),
1285
1305
  signal: init.signal ?? r0?.signal,
1286
1306
  })
1287
1307
  if (!res.ok) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magpie-community/opencode-trae-auth",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
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",