@magpie-community/opencode-zcode-auth 0.1.21 → 0.1.23
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/index.mjs +73 -29
- package/package.json +1 -1
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.
|
|
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.
|
|
@@ -578,13 +578,16 @@ async function claimHint(s) {
|
|
|
578
578
|
|
|
579
579
|
// startUsage is a gift-only account's card: its buckets, or the words
|
|
580
580
|
// for having none to show. The card's header already names the plan, so
|
|
581
|
-
// the windows keep their own names
|
|
581
|
+
// the windows of one plan keep their own names; with several plans each
|
|
582
|
+
// bucket is named after its plan (see byPlan).
|
|
582
583
|
const NO_START = "this account has no GLM Coding Plan, and ZCode's Start Plan has ended or was never started"
|
|
583
584
|
async function startUsage(s) {
|
|
584
585
|
const g = await giftOf(s)
|
|
585
586
|
if (!g) return { error: NO_START }
|
|
586
587
|
const best = bestBuckets(g.windows)
|
|
587
|
-
|
|
588
|
+
const label = byPlan(g.windows)
|
|
589
|
+
g.windows = countedFirst(g.windows.map(({ _plan, _spent, ...w }, i) => {
|
|
590
|
+
w.name = label(w.name, _plan)
|
|
588
591
|
if (!w.models?.length) return w
|
|
589
592
|
// a model two plans give (Trust Build's and the Start Plan's Flash)
|
|
590
593
|
// counts on the bucket ZCode spends now; the other stays on the card
|
|
@@ -595,10 +598,28 @@ async function startUsage(s) {
|
|
|
595
598
|
return { ...w, aside: true }
|
|
596
599
|
}
|
|
597
600
|
return { ...w, models: [...models, ...models.map(giftID)] }
|
|
598
|
-
})
|
|
601
|
+
}))
|
|
599
602
|
return g
|
|
600
603
|
}
|
|
601
604
|
|
|
605
|
+
// byPlan names a bucket after its plan ("ZCode 1024 Dev Day · GLM-5.3")
|
|
606
|
+
// when the gift's buckets come from more than one plan: two plans each
|
|
607
|
+
// give a GLM-5.3, and named alike a spent one and a live one can't be
|
|
608
|
+
// told apart (01huadalang, Discord: the new-user plan's spent GLM-5.3
|
|
609
|
+
// showed, the 1024 plan's own GLM-5.3 didn't). One plan's buckets keep
|
|
610
|
+
// their own names, as the card's header names the plan.
|
|
611
|
+
function byPlan(windows) {
|
|
612
|
+
const several = new Set(windows.map((w) => w._plan || "")).size > 1
|
|
613
|
+
return (name, plan) => (several && plan ? plan + " · " + name : name)
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// countedFirst puts the buckets a request spends before those set aside
|
|
617
|
+
// (a spent bucket another plan's live one stands in for), each group in
|
|
618
|
+
// the balance's order: magpie's account row shows a card's first two
|
|
619
|
+
// windows and leaves the rest to its tooltip, so a spent plan listed first
|
|
620
|
+
// hid the live plan's allowance for the same model.
|
|
621
|
+
const countedFirst = (ws) => [...ws.filter((w) => !w.aside), ...ws.filter((w) => w.aside)]
|
|
622
|
+
|
|
602
623
|
// bestBuckets is, for each model the gift's buckets serve, the index of
|
|
603
624
|
// the one a request spends: a live one before a spent one, the least
|
|
604
625
|
// used of those. The server picks among an account's buckets itself
|
|
@@ -641,19 +662,21 @@ async function dualUsage(s) {
|
|
|
641
662
|
if (notModels.length) out.windows = out.windows.map((w) => w.aside ? w : { ...w, notModels })
|
|
642
663
|
// Several buckets may serve one model: one spent sibling cannot block it.
|
|
643
664
|
const best = bestBuckets(g.windows)
|
|
644
|
-
|
|
665
|
+
const label = byPlan(g.windows)
|
|
666
|
+
out.windows.push(...countedFirst(g.windows.map(({ _plan: p, _spent, ...w }, i) => {
|
|
645
667
|
const selected = gift.allModels.filter((m) => best.get(m.toLowerCase()) === i)
|
|
646
668
|
const models = selected.map(giftID)
|
|
647
669
|
const scoped = models.length ? { ...w, models } : { ...w, aside: true }
|
|
648
670
|
// the card names a bucket's model as the picker does (GLM-5.3-Flash-Trial);
|
|
649
|
-
// no plan prefix — the card's section
|
|
671
|
+
// no plan prefix while one plan gives them all — the card's section
|
|
672
|
+
// header already says the account; with several, byPlan names each
|
|
650
673
|
let name = w.name
|
|
651
674
|
for (const m of selected) {
|
|
652
675
|
const at = name.toLowerCase().indexOf(m.toLowerCase())
|
|
653
676
|
if (at >= 0) name = name.slice(0, at) + giftID(m) + name.slice(at + m.length)
|
|
654
677
|
}
|
|
655
|
-
return { ...scoped, name }
|
|
656
|
-
}))
|
|
678
|
+
return { ...scoped, name: label(name, p) }
|
|
679
|
+
})))
|
|
657
680
|
}
|
|
658
681
|
} catch {
|
|
659
682
|
if (cached) {
|
|
@@ -1400,28 +1423,48 @@ function intl() {
|
|
|
1400
1423
|
}
|
|
1401
1424
|
}
|
|
1402
1425
|
|
|
1403
|
-
// startHeaders
|
|
1426
|
+
// startHeaders is a Start Plan request's headers, jwt its key: ZCode's
|
|
1427
|
+
// own (3.16.3's Frn and Vdt in glm/zcode.cjs) and the body's content-type,
|
|
1428
|
+
// and nothing else. The agent's headers never go on: Claude Code's
|
|
1429
|
+
// anthropic-beta, x-app, x-stainless-*, anthropic-dangerous-direct-browser-
|
|
1430
|
+
// access and x-claude-code-session-id reach the plugin through magpie's
|
|
1431
|
+
// gateway, and ZCode sends none of them (no anthropic-beta at all on the
|
|
1432
|
+
// Start Plan: its tool search beta is for coding plans only). Accept and
|
|
1433
|
+
// accept-encoding are left to the HTTP client, as ZCode leaves them to
|
|
1434
|
+
// Node's.
|
|
1404
1435
|
function startHeaders(h, jwt) {
|
|
1405
|
-
|
|
1406
|
-
h.
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
h.set("X-Release-Channel", "production")
|
|
1436
|
+
const out = new Headers()
|
|
1437
|
+
out.set("content-type", h.get("content-type") || "application/json")
|
|
1438
|
+
out.set("Authorization", "Bearer " + jwt)
|
|
1439
|
+
out.set("anthropic-version", "2023-06-01")
|
|
1440
|
+
out.set("HTTP-Referer", ZCODE)
|
|
1441
|
+
out.set("User-Agent", UA + " ai-sdk/anthropic/3.0.81")
|
|
1442
|
+
out.set("X-ZCode-App-Version", APP_VERSION)
|
|
1443
|
+
out.set("X-Title", "Z Code@cli")
|
|
1444
|
+
out.set("X-Release-Channel", "production")
|
|
1415
1445
|
const o = intl()
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1446
|
+
out.set("X-Client-Language", o.locale || "unknown")
|
|
1447
|
+
out.set("X-Client-Timezone", o.timeZone || "unknown")
|
|
1448
|
+
out.set("X-ZCode-Agent", "glm")
|
|
1449
|
+
out.set("X-Platform", platform())
|
|
1450
|
+
out.set("X-Os-Category", osCategory())
|
|
1451
|
+
// os.release() alone, as ZCode's buildZCodeSourceHeadersFromContext
|
|
1452
|
+
// has it; the prompt's OS line is osVersion()
|
|
1453
|
+
out.set("X-Os-Version", release())
|
|
1454
|
+
out.set("x-request-id", uuid())
|
|
1455
|
+
out.set("x-zcode-session-type", "main")
|
|
1456
|
+
out.set("x-zcode-trace-id", uuid())
|
|
1457
|
+
// 3.16's createModelRequestAttributionHeaders: what asked the model
|
|
1458
|
+
out.set("x-zcode-query-source", "main_turn")
|
|
1459
|
+
return out
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
// startURL is a Start Plan request's URL without the query the agent put
|
|
1463
|
+
// on it: Claude Code asks /v1/messages?beta=true, which magpie passes on,
|
|
1464
|
+
// and ZCode asks /v1/messages alone.
|
|
1465
|
+
function startURL(url) {
|
|
1466
|
+
const i = url.indexOf("?")
|
|
1467
|
+
return i < 0 ? url : url.slice(0, i)
|
|
1425
1468
|
}
|
|
1426
1469
|
|
|
1427
1470
|
// WORK_DIR and WORK_GIT are where magpie tells a plugin's fetch the agent
|
|
@@ -1660,7 +1703,8 @@ export async function ZCodeAuthPlugin({ client }) {
|
|
|
1660
1703
|
if (!s.jwt) throw new Error("ZCode's sign-in has no key; sign in again")
|
|
1661
1704
|
swap(START_BASE)
|
|
1662
1705
|
// the Start Plan is served only to what looks like ZCode's own request
|
|
1663
|
-
|
|
1706
|
+
url = startURL(url)
|
|
1707
|
+
h = startHeaders(h, s.jwt)
|
|
1664
1708
|
if (opts.body != null) {
|
|
1665
1709
|
const text = orig ?? (typeof opts.body === "string" ? opts.body : await new Response(opts.body).text())
|
|
1666
1710
|
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.
|
|
3
|
+
"version": "0.1.23",
|
|
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",
|