@magpie-community/opencode-workbuddy-auth 0.1.46 → 0.1.47
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 +5 -2
- package/index.mjs +56 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -137,8 +137,11 @@ Each chat carries WorkBuddy's headers:
|
|
|
137
137
|
- the conversation's ids: `X-Conversation-ID`, `X-Conversation-Request-ID`,
|
|
138
138
|
`X-Conversation-Message-ID`, `X-Request-ID`. WorkBuddy's backend counts a
|
|
139
139
|
user send as one request by `X-Conversation-Request-ID`, so every step of
|
|
140
|
-
one send — a tool result sent back, a retry
|
|
141
|
-
|
|
140
|
+
one send — a tool result sent back, a retry — carries the same one, and
|
|
141
|
+
the user's next message carries another. Both ids are one account's own,
|
|
142
|
+
as WorkBuddy's client is signed in as one: a conversation sent as another
|
|
143
|
+
account (another of a group, or a sign-in saved since) carries that
|
|
144
|
+
account's ids, never the same ones under two `X-User-Id`s. The
|
|
142
145
|
conversation's is the session magpie (or OpenCode) names the request by,
|
|
143
146
|
else the chat's first user message; nothing is made up when neither names
|
|
144
147
|
one, a made-up conversation of the request's own being what splits one
|
package/index.mjs
CHANGED
|
@@ -446,7 +446,7 @@ async function enterpriseOf(site, a, who) {
|
|
|
446
446
|
// itself, and the request that carried it. Its backend counts a user send as
|
|
447
447
|
// one request by X-Conversation-Request-ID: a chat carrying a new one every
|
|
448
448
|
// time is counted on its own, so one send that takes several steps — a tool
|
|
449
|
-
// call answered and sent again, a retry
|
|
449
|
+
// call answered and sent again, a retry — shows up
|
|
450
450
|
// in the usage detail as many requests. The ids below are made from what
|
|
451
451
|
// names the conversation and the turn, so every step of one send carries the
|
|
452
452
|
// same turn id and the user's next message carries another, as WorkBuddy's
|
|
@@ -719,22 +719,64 @@ function sessionOf(headers) {
|
|
|
719
719
|
// turn's (one user send, whatever it takes), and the conversation's. A header
|
|
720
720
|
// already there — the caller's own, or another plugin's — is kept, and the
|
|
721
721
|
// message and request ids are the same one, as WorkBuddy's client has them.
|
|
722
|
-
|
|
723
|
-
|
|
722
|
+
//
|
|
723
|
+
// who is the account the chat goes as (scopeOf). The ids are that account's
|
|
724
|
+
// own: WorkBuddy's client runs as one account, so one conversation or turn
|
|
725
|
+
// never shows up under two. Without it, one magpie session spread over a
|
|
726
|
+
// group of accounts sent the same X-Conversation-ID and
|
|
727
|
+
// X-Conversation-Request-ID under every account's X-User-Id.
|
|
728
|
+
function attend(headers, body, session, who = "") {
|
|
729
|
+
return attendChat(headers, chatOf(body), session, who)
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
// attendChat is attend with the chat read already. It returns what reattend
|
|
733
|
+
// needs to set the ids again for another account once the chat itself is
|
|
734
|
+
// let go: the ids it set itself (not the caller's), and the digests of what
|
|
735
|
+
// names the turn and the conversation, which are never sent as they are.
|
|
736
|
+
function attendChat(headers, chat, session, who = "") {
|
|
737
|
+
const conv = conversationParts(chat, session)
|
|
738
|
+
const turn = turnParts(chat)
|
|
739
|
+
const ids = {
|
|
740
|
+
set: [],
|
|
741
|
+
// a turn is a conversation's own: two conversations whose user message
|
|
742
|
+
// reads the same are still two sends, not one
|
|
743
|
+
turn: turn.length ? idFor("turn", [...conv, "|", ...turn]) : "",
|
|
744
|
+
conv: conv.length ? idFor("conversation", conv) : "",
|
|
745
|
+
}
|
|
746
|
+
return setIds(headers, ids, who)
|
|
724
747
|
}
|
|
725
748
|
|
|
726
|
-
|
|
727
|
-
|
|
749
|
+
// setIds sets the message's id, and the turn's and conversation's for the
|
|
750
|
+
// account who, where the caller set none.
|
|
751
|
+
function setIds(headers, ids, who) {
|
|
728
752
|
const msg = hex()
|
|
729
753
|
headers.set("X-Conversation-Message-ID", msg)
|
|
730
754
|
headers.set("X-Request-ID", msg)
|
|
755
|
+
const set = []
|
|
756
|
+
const own = (kind, base) => (who ? idFor(kind, [`account:${who}`, "|", base]) : base)
|
|
731
757
|
if (!headers.has("X-Conversation-Request-ID")) {
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
758
|
+
headers.set("X-Conversation-Request-ID", ids.turn ? own("turn", ids.turn) : hex())
|
|
759
|
+
set.push("X-Conversation-Request-ID")
|
|
760
|
+
}
|
|
761
|
+
if (ids.conv && !headers.has("X-Conversation-ID")) {
|
|
762
|
+
headers.set("X-Conversation-ID", own("conversation", ids.conv))
|
|
763
|
+
set.push("X-Conversation-ID")
|
|
736
764
|
}
|
|
737
|
-
|
|
765
|
+
return { ...ids, set }
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
// scopeOf names the account a chat goes as for attend: its uid, its
|
|
769
|
+
// enterprise, and for a key account the key (only ever hashed).
|
|
770
|
+
function scopeOf(a) {
|
|
771
|
+
return `${a?.uid ?? ""}|${a?.enterpriseId ?? ""}|${a?.source === "key" ? a.key ?? "" : ""}`
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// reattend sets a chat's ids again for the account it is now sent as, when
|
|
775
|
+
// that is another account than the one they were set for.
|
|
776
|
+
function reattend(headers, ids, was, now) {
|
|
777
|
+
if (was === now) return ids
|
|
778
|
+
for (const h of ids.set) headers.delete(h)
|
|
779
|
+
return setIds(headers, ids, now)
|
|
738
780
|
}
|
|
739
781
|
|
|
740
782
|
// FLAGGED are the words WorkBuddy refuses a chat for, "Illegal API
|
|
@@ -2510,7 +2552,8 @@ function makePlugin(site) {
|
|
|
2510
2552
|
const completion = !native && isCompletion(req ? req.url : input, chat)
|
|
2511
2553
|
if (completion && chat && !namesEffort(chat) && withDefaultEffort(chat, await effortList(a))) changed = true
|
|
2512
2554
|
chatHeaders(site, headers)
|
|
2513
|
-
|
|
2555
|
+
let who = scopeOf(a)
|
|
2556
|
+
let ids = attendChat(headers, chat, session, who)
|
|
2514
2557
|
const post = (b) => {
|
|
2515
2558
|
// a chat goes gzipped, as WorkBuddy's client sends it
|
|
2516
2559
|
// (gzipped); its size on the wire is what unanswered weighs
|
|
@@ -2557,6 +2600,7 @@ function makePlugin(site) {
|
|
|
2557
2600
|
renewed = true
|
|
2558
2601
|
a = r.a
|
|
2559
2602
|
sign(site, a, headers)
|
|
2603
|
+
ids = reattend(headers, ids, who, (who = scopeOf(a)))
|
|
2560
2604
|
const again = await post(b)
|
|
2561
2605
|
if (again.status !== 401) return again
|
|
2562
2606
|
return out("it refused the token renewed for it too", invalidToken(again), again)
|
|
@@ -2805,4 +2849,4 @@ export const WorkBuddyAuthPlugin = makePlugin(SITES.workbuddy)
|
|
|
2805
2849
|
export const WorkBuddyAIAuthPlugin = makePlugin(SITES["workbuddy-ai"])
|
|
2806
2850
|
|
|
2807
2851
|
// for tests
|
|
2808
|
-
export const _internal = { idFor, replyAfterToolsOn, withDefaultEffort, defaultEffortOf, gzipped, FREE_ONLY, PRICE_TTL, keyAccount, remoteConfig, cycleOf, typeUnions, systemAsUser, systemKey, DEFAULT_SYSTEM, EDGE_READS, fitShape, replyAfterTools, AFTER_TOOLS_REFUSED, enterpriseUsageOf, notDesktop, textOnly, runsOutOf, packagesOf, endOf, enterpriseHeaders, enterpriseOf, liveModels, browserSignIn, withSystem, asReasoning, normalizeToolChoice, fitTools, fitted, renamed, unflagged, usageOf, desktopHeld, explained, REFUSED_HINT, RESTRICTED_HINT, EXHAUSTED_HINT, freeCredits, creditsOf, priceOf, fresh, SITES, renewing, renewed, SESSION, attend, turnKey, conversationKey, signatureOf, isMessages, withoutUnsigned, withoutSignedThinking, prepared, answeredBefore, nativeOf, modelOf, configModels, API_MESSAGES: NPM_MESSAGES, API_CHAT: NPM }
|
|
2852
|
+
export const _internal = { idFor, replyAfterToolsOn, withDefaultEffort, defaultEffortOf, gzipped, FREE_ONLY, PRICE_TTL, keyAccount, remoteConfig, cycleOf, typeUnions, systemAsUser, systemKey, DEFAULT_SYSTEM, EDGE_READS, fitShape, replyAfterTools, AFTER_TOOLS_REFUSED, enterpriseUsageOf, notDesktop, textOnly, runsOutOf, packagesOf, endOf, enterpriseHeaders, enterpriseOf, liveModels, browserSignIn, withSystem, asReasoning, normalizeToolChoice, fitTools, fitted, renamed, unflagged, usageOf, desktopHeld, explained, REFUSED_HINT, RESTRICTED_HINT, EXHAUSTED_HINT, freeCredits, creditsOf, priceOf, fresh, SITES, renewing, renewed, SESSION, attend, scopeOf, turnKey, conversationKey, signatureOf, isMessages, withoutUnsigned, withoutSignedThinking, prepared, answeredBefore, nativeOf, modelOf, configModels, API_MESSAGES: NPM_MESSAGES, API_CHAT: NPM }
|
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.47",
|
|
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",
|