@magpie-community/opencode-workbuddy-auth 0.1.2 → 0.1.3
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 +53 -6
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -243,7 +243,7 @@ async function browserSignIn(site) {
|
|
|
243
243
|
const deadline = Date.now() + SIGN_IN_MS
|
|
244
244
|
const q = encodeURIComponent(state.state)
|
|
245
245
|
const token = await poll(site, `/v2/plugin/auth/token?state=${q}`, {}, [11217], deadline)
|
|
246
|
-
if (!token.accessToken) return { type: "failed" }
|
|
246
|
+
if (!token.accessToken) return { type: "failed", error: `${site.name} sent back no token` }
|
|
247
247
|
let a = merge({}, token)
|
|
248
248
|
const who = await poll(site, `/v2/plugin/login/account?state=${q}`, {
|
|
249
249
|
Authorization: "Bearer " + a.access,
|
|
@@ -253,8 +253,8 @@ async function browserSignIn(site) {
|
|
|
253
253
|
}, [12151], deadline)
|
|
254
254
|
a.uid = who.uid ?? ""
|
|
255
255
|
return success(site, a, who.nickname || who.phoneNumber || who.uid)
|
|
256
|
-
} catch {
|
|
257
|
-
return { type: "failed" }
|
|
256
|
+
} catch (e) {
|
|
257
|
+
return { type: "failed", error: e.message }
|
|
258
258
|
}
|
|
259
259
|
},
|
|
260
260
|
}
|
|
@@ -319,7 +319,7 @@ function desktopSignIn(site) {
|
|
|
319
319
|
method: "auto",
|
|
320
320
|
async callback() {
|
|
321
321
|
const d = readDesktop(site)
|
|
322
|
-
if (!d) return { type: "failed" }
|
|
322
|
+
if (!d) return { type: "failed", error: `${site.name} desktop isn't signed in` }
|
|
323
323
|
return { type: "success", refresh: "", access: "", expires: 0, source: "desktop", accountId: d.name || site.name, uid: d.uid }
|
|
324
324
|
},
|
|
325
325
|
}
|
|
@@ -439,12 +439,22 @@ function modelOf(site, provider, m) {
|
|
|
439
439
|
},
|
|
440
440
|
release_date: "",
|
|
441
441
|
variants: variants(m.efforts),
|
|
442
|
+
// magpie's own: served at no cost to the plan's credits
|
|
443
|
+
free: !!m.free,
|
|
442
444
|
}
|
|
443
445
|
}
|
|
444
446
|
|
|
445
447
|
// liveModels asks WorkBuddy's product config for the plan's models: the
|
|
446
448
|
// "cli" agent's list, each with its details. The CLI User-Agent picks
|
|
447
449
|
// WorkBuddy's config (a bare WorkBuddy/<v> gets CodeBuddy IDE's, no cli).
|
|
450
|
+
// freeCredits says whether a model's credits are none: "x0.00", "0" or 0.
|
|
451
|
+
// A rate it can't read is not free.
|
|
452
|
+
function freeCredits(c) {
|
|
453
|
+
if (c == null || c === "") return false
|
|
454
|
+
const s = String(c).trim().toLowerCase().replace(/^x/, "")
|
|
455
|
+
return s !== "" && Number.isFinite(Number(s)) && Number(s) === 0
|
|
456
|
+
}
|
|
457
|
+
|
|
448
458
|
async function liveModels(site, a) {
|
|
449
459
|
const headers = new Headers()
|
|
450
460
|
sign(site, a, headers)
|
|
@@ -466,6 +476,7 @@ async function liveModels(site, a) {
|
|
|
466
476
|
m.context = d.maxInputTokens
|
|
467
477
|
m.output = d.maxOutputTokens
|
|
468
478
|
m.images = d.supportsImages === true
|
|
479
|
+
m.free = freeCredits(d.credits)
|
|
469
480
|
const es = d.reasoning?.supportedEfforts ?? []
|
|
470
481
|
if (es.length) {
|
|
471
482
|
const canOff = d.reasoning?.canDisableThinking
|
|
@@ -539,7 +550,8 @@ function makePlugin(site) {
|
|
|
539
550
|
sign(site, a, headers)
|
|
540
551
|
let body = init?.body
|
|
541
552
|
if (body === undefined && req) body = await req.clone().text()
|
|
542
|
-
|
|
553
|
+
const res = await fetch(req ? req.url : input, { ...init, method: init?.method ?? req?.method, headers, body: withSystem(body) })
|
|
554
|
+
return res.status >= 400 ? explained(res) : res
|
|
543
555
|
},
|
|
544
556
|
}
|
|
545
557
|
},
|
|
@@ -571,8 +583,43 @@ function makePlugin(site) {
|
|
|
571
583
|
})
|
|
572
584
|
}
|
|
573
585
|
|
|
586
|
+
// REFUSED_HINT is what the user can do about WorkBuddy's "Illegal API
|
|
587
|
+
// invocation from an unapproved channel": both builds answer it to a chat
|
|
588
|
+
// whose system prompt is Codex's or Claude Code's own (magpie #182),
|
|
589
|
+
// whatever the headers. It ends the error's message, as magpie's built-in
|
|
590
|
+
// put it (provider.WBRefusedHint), so magpie's routing page says it apart.
|
|
591
|
+
const REFUSED_HINT =
|
|
592
|
+
"WorkBuddy refuses chats from Codex and Claude Code (their system prompt); use it from Hermes, OpenCode or Pi, or add another provider to this group"
|
|
593
|
+
const REFUSED = /unapproved channel|illegal api invocation/i
|
|
594
|
+
|
|
595
|
+
// explained is res with REFUSED_HINT added to that refusal's message.
|
|
596
|
+
async function explained(res) {
|
|
597
|
+
const text = await res.text()
|
|
598
|
+
const again = (b) => {
|
|
599
|
+
const headers = new Headers(res.headers)
|
|
600
|
+
headers.delete("content-length")
|
|
601
|
+
headers.delete("content-encoding")
|
|
602
|
+
return new Response(b, { status: res.status, statusText: res.statusText, headers })
|
|
603
|
+
}
|
|
604
|
+
if (!REFUSED.test(text)) return again(text)
|
|
605
|
+
let msg = text.trim()
|
|
606
|
+
let v
|
|
607
|
+
try {
|
|
608
|
+
v = JSON.parse(text)
|
|
609
|
+
} catch {}
|
|
610
|
+
const at = v?.error && typeof v.error === "object" ? v.error : v && typeof v === "object" ? v : null
|
|
611
|
+
if (at && typeof at.message === "string") msg = at.message
|
|
612
|
+
else if (typeof v?.error === "string") msg = v.error
|
|
613
|
+
msg = `${msg} — ${REFUSED_HINT}`
|
|
614
|
+
const headers = new Headers(res.headers)
|
|
615
|
+
headers.set("content-type", "application/json")
|
|
616
|
+
headers.delete("content-length")
|
|
617
|
+
headers.delete("content-encoding")
|
|
618
|
+
return new Response(JSON.stringify({ error: { message: msg, type: "permission_error", code: null } }), { status: res.status, statusText: res.statusText, headers })
|
|
619
|
+
}
|
|
620
|
+
|
|
574
621
|
export const WorkBuddyAuthPlugin = makePlugin(SITES.workbuddy)
|
|
575
622
|
export const WorkBuddyAIAuthPlugin = makePlugin(SITES["workbuddy-ai"])
|
|
576
623
|
|
|
577
624
|
// for tests
|
|
578
|
-
export const _internal = { usageOf, desktopHeld }
|
|
625
|
+
export const _internal = { usageOf, desktopHeld, explained, REFUSED_HINT, freeCredits }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magpie-community/opencode-workbuddy-auth",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "OpenCode provider plugins for WorkBuddy's plans: WorkBuddy (CodeBuddy, copilot.tencent.com) and WorkBuddy AI (www.workbuddy.ai)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.mjs",
|