@magpie-community/opencode-zcode-auth 0.1.20 → 0.1.22

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 (3) hide show
  1. package/README.md +3 -2
  2. package/index.mjs +55 -31
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -21,8 +21,9 @@ over Anthropic's Messages API. Provider id: `zcode`.
21
21
  - zcode.z.ai serves the Start Plan only to requests that look like the
22
22
  ZCode client's own, and refuses others with HTTP 405 "request has been
23
23
  blocked due to unusual activity". So a Start Plan request goes as
24
- ZCode's does: ZCode's headers, ZCode's system prompt ahead of the
25
- agent's, the day in a `<system-reminder>` turn before the agent's
24
+ ZCode's does: ZCode's headers, ZCode's three system blocks with the
25
+ agent's system prompt at the end of the third (a fourth block is
26
+ refused, #343), the day in a `<system-reminder>` turn before the agent's
26
27
  turns, and the sign-in's device id in `metadata.user_id`. GLM Coding
27
28
  Plan and team requests go as the agent sent them. One it still turns
28
29
  away (a 405, the block page or code 3012) comes back with what to do
package/index.mjs CHANGED
@@ -29,7 +29,7 @@ const BIGMODEL_API = "https://bigmodel.cn" // BigModel's business API, where ZCo
29
29
  const ZAI_BASE = "https://api.z.ai/api/anthropic"
30
30
  const BIGMODEL_BASE = "https://open.bigmodel.cn/api/anthropic"
31
31
  const START_BASE = ZCODE + "/api/v1/zcode-plan/anthropic"
32
- const APP_VERSION = "3.14.3" // the ZCode whose sign-in this makes
32
+ const APP_VERSION = "3.16.3" // the ZCode whose sign-in this makes
33
33
  const UA = "ZCode/" + APP_VERSION
34
34
 
35
35
  // ZCode's models before its config is read; the Start Plan has all but GLM-5.3.
@@ -1400,28 +1400,48 @@ function intl() {
1400
1400
  }
1401
1401
  }
1402
1402
 
1403
- // startHeaders puts ZCode's headers on a Start Plan request, jwt its key.
1403
+ // startHeaders is a Start Plan request's headers, jwt its key: ZCode's
1404
+ // own (3.16.3's Frn and Vdt in glm/zcode.cjs) and the body's content-type,
1405
+ // and nothing else. The agent's headers never go on: Claude Code's
1406
+ // anthropic-beta, x-app, x-stainless-*, anthropic-dangerous-direct-browser-
1407
+ // access and x-claude-code-session-id reach the plugin through magpie's
1408
+ // gateway, and ZCode sends none of them (no anthropic-beta at all on the
1409
+ // Start Plan: its tool search beta is for coding plans only). Accept and
1410
+ // accept-encoding are left to the HTTP client, as ZCode leaves them to
1411
+ // Node's.
1404
1412
  function startHeaders(h, jwt) {
1405
- h.delete("x-api-key")
1406
- h.delete("authorization")
1407
- h.delete("X-Device-Mid")
1408
- h.set("Authorization", "Bearer " + jwt)
1409
- h.set("anthropic-version", "2023-06-01")
1410
- h.set("HTTP-Referer", ZCODE)
1411
- h.set("User-Agent", UA + " ai-sdk/anthropic/3.0.81")
1412
- h.set("X-ZCode-App-Version", APP_VERSION)
1413
- h.set("X-Title", "Z Code@cli")
1414
- h.set("X-Release-Channel", "production")
1413
+ const out = new Headers()
1414
+ out.set("content-type", h.get("content-type") || "application/json")
1415
+ out.set("Authorization", "Bearer " + jwt)
1416
+ out.set("anthropic-version", "2023-06-01")
1417
+ out.set("HTTP-Referer", ZCODE)
1418
+ out.set("User-Agent", UA + " ai-sdk/anthropic/3.0.81")
1419
+ out.set("X-ZCode-App-Version", APP_VERSION)
1420
+ out.set("X-Title", "Z Code@cli")
1421
+ out.set("X-Release-Channel", "production")
1415
1422
  const o = intl()
1416
- h.set("X-Client-Language", o.locale || "unknown")
1417
- if (o.timeZone) h.set("X-Client-Timezone", o.timeZone)
1418
- h.set("X-ZCode-Agent", "glm")
1419
- h.set("X-Platform", platform())
1420
- h.set("X-Os-Category", osCategory())
1421
- h.set("X-Os-Version", osVersion())
1422
- h.set("x-request-id", uuid())
1423
- h.set("x-zcode-session-type", "main")
1424
- h.set("x-zcode-trace-id", uuid())
1423
+ out.set("X-Client-Language", o.locale || "unknown")
1424
+ out.set("X-Client-Timezone", o.timeZone || "unknown")
1425
+ out.set("X-ZCode-Agent", "glm")
1426
+ out.set("X-Platform", platform())
1427
+ out.set("X-Os-Category", osCategory())
1428
+ // os.release() alone, as ZCode's buildZCodeSourceHeadersFromContext
1429
+ // has it; the prompt's OS line is osVersion()
1430
+ out.set("X-Os-Version", release())
1431
+ out.set("x-request-id", uuid())
1432
+ out.set("x-zcode-session-type", "main")
1433
+ out.set("x-zcode-trace-id", uuid())
1434
+ // 3.16's createModelRequestAttributionHeaders: what asked the model
1435
+ out.set("x-zcode-query-source", "main_turn")
1436
+ return out
1437
+ }
1438
+
1439
+ // startURL is a Start Plan request's URL without the query the agent put
1440
+ // on it: Claude Code asks /v1/messages?beta=true, which magpie passes on,
1441
+ // and ZCode asks /v1/messages alone.
1442
+ function startURL(url) {
1443
+ const i = url.indexOf("?")
1444
+ return i < 0 ? url : url.slice(0, i)
1425
1445
  }
1426
1446
 
1427
1447
  // WORK_DIR and WORK_GIT are where magpie tells a plugin's fetch the agent
@@ -1484,7 +1504,8 @@ function contextPrefix() {
1484
1504
  }
1485
1505
 
1486
1506
  // dress is a Messages request body as ZCode sends it: ZCode's three cached
1487
- // system blocks, then the agent's own system text uncached; the context
1507
+ // system blocks and no more, the agent's own system text at the end of the
1508
+ // third (#343); the context
1488
1509
  // prefix as the first turn; no cache mark in the turns but on the last
1489
1510
  // block of the last; none on the tools; metadata.user_id naming the
1490
1511
  // sign-in's device. site names the powered-by line's provider, place where
@@ -1502,18 +1523,20 @@ function dress(text, site, device, place) {
1502
1523
  const cached = (t) => ({ type: "text", text: t, cache_control: { type: "ephemeral" } })
1503
1524
  const provider = site === "bigmodel" ? "bigmodel-api" : "zai-api"
1504
1525
  const model = typeof b.model === "string" ? b.model : ""
1526
+ // The agent's own system text joins the third block, as ZCode's
1527
+ // ContextBuilder (3.14.3, glm/zcode.cjs assembleSystemMessages) joins
1528
+ // every dynamic system section, an added one too, with "\n\n" into
1529
+ // that one block: ZCode never sends more than three. zcode.z.ai turns a
1530
+ // fourth block away with 405/3012 (#343), and the first two must stay
1531
+ // byte for byte ZCode's.
1505
1532
  const own = []
1506
1533
  if (typeof b.system === "string") {
1507
- if (b.system.trim()) own.push({ type: "text", text: b.system })
1534
+ if (b.system.trim()) own.push(b.system)
1508
1535
  } else if (Array.isArray(b.system)) {
1509
- for (const x of b.system) if (x?.type === "text" && typeof x.text === "string" && x.text) own.push({ type: "text", text: x.text })
1536
+ for (const x of b.system) if (x?.type === "text" && typeof x.text === "string" && x.text.trim()) own.push(x.text)
1510
1537
  }
1511
- b.system = [
1512
- cached(PROMPT.cliPrefix),
1513
- cached(PROMPT.stableSections.join("\n\n")),
1514
- cached("\n\n" + [PROMPT.beforeEnvironment, environment(provider, model, place), PROMPT.afterEnvironment].join("\n\n")),
1515
- ...own,
1516
- ]
1538
+ const dynamic = [PROMPT.beforeEnvironment, environment(provider, model, place), PROMPT.afterEnvironment, ...own]
1539
+ b.system = [cached(PROMPT.cliPrefix), cached(PROMPT.stableSections.join("\n\n")), cached("\n\n" + dynamic.join("\n\n"))]
1517
1540
  b.messages = [contextPrefix(), ...b.messages]
1518
1541
  let last = null
1519
1542
  for (const m of b.messages) {
@@ -1657,7 +1680,8 @@ export async function ZCodeAuthPlugin({ client }) {
1657
1680
  if (!s.jwt) throw new Error("ZCode's sign-in has no key; sign in again")
1658
1681
  swap(START_BASE)
1659
1682
  // the Start Plan is served only to what looks like ZCode's own request
1660
- startHeaders(h, s.jwt)
1683
+ url = startURL(url)
1684
+ h = startHeaders(h, s.jwt)
1661
1685
  if (opts.body != null) {
1662
1686
  const text = orig ?? (typeof opts.body === "string" ? opts.body : await new Response(opts.body).text())
1663
1687
  opts.body = dress(text, s.site, s.device, place)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magpie-community/opencode-zcode-auth",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "description": "OpenCode provider plugin: signs in to Z.ai's or BigModel's (智谱) GLM Coding Plan as ZCode does, including team seats and ZCode's Start Plan",
5
5
  "type": "module",
6
6
  "main": "./index.mjs",