@magpie-community/opencode-cursor-auth 0.2.39 → 0.2.41
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 +22 -5
- package/index.mjs +96 -11
- package/native-session.mjs +41 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -99,7 +99,14 @@ plugin's `fetch` answers them on Cursor's agent API:
|
|
|
99
99
|
|
|
100
100
|
Tool results can continue a retained Run in the same plugin process. The owner
|
|
101
101
|
uses the same session/cache key and first user message as `conversation_id`, so
|
|
102
|
-
Task subagents sharing their parent's session can run independently.
|
|
102
|
+
Task subagents sharing their parent's session can run independently. A new
|
|
103
|
+
user turn whose earlier native calls all have their results gets a retained Run
|
|
104
|
+
of its own, with those calls as imported history; while any of them is still
|
|
105
|
+
pending, the turn goes stateless. New input after results already given (a
|
|
106
|
+
reminder Claude Code sends beside a tool result reaches the plugin as a user
|
|
107
|
+
message after it) also gets a retained Run of its own while a parent Run of
|
|
108
|
+
the conversation still awaits results. That Run takes no reservation and
|
|
109
|
+
leaves the parent alone; only its own calls' results resume it. Retention
|
|
103
110
|
waits at most 120 seconds for a result batch and 15 minutes for a Run's total
|
|
104
111
|
lifetime. A continuation arriving with less than 10 minutes of that lifetime
|
|
105
112
|
left rebuilds from supplied history on a fresh Run before submitting results
|
|
@@ -134,8 +141,8 @@ given also ends the step (#550). The step's calls are the rest.
|
|
|
134
141
|
|
|
135
142
|
These are retention limits. A missing, expired, restarted, busy, incompatible,
|
|
136
143
|
or full owner uses the original history reconstruction and stateless decoder
|
|
137
|
-
on a new Run. Pending parent calls
|
|
138
|
-
|
|
144
|
+
on a new Run. Pending parent calls can take that path without cancelling the
|
|
145
|
+
parent's owner. Already supplied client tool results become
|
|
139
146
|
history; the plugin never executes those external tools. A failed native result
|
|
140
147
|
write is reported to that request because its outcome may be uncertain. A later
|
|
141
148
|
request can rebuild from its supplied history without submitting the result to
|
|
@@ -152,12 +159,22 @@ stateless debt as `usage.magpie_deferred`, separately from its own prompt total.
|
|
|
152
159
|
If a started native Run is abandoned after a pending handoff, its dashboard
|
|
153
160
|
count is owed once to the same account and conversation. Successful final
|
|
154
161
|
snapshots, including explicit zero, and cached replays do not enroll that debt.
|
|
162
|
+
A Run still awaiting results when a later native Run of its conversation
|
|
163
|
+
starts owes that count at once, for the later Run to collect, rather than at
|
|
164
|
+
abandonment; what it had collected and not given out goes along. Cursor adds
|
|
165
|
+
each step to a Run's one event as the step ends, so that event is looked for
|
|
166
|
+
only `owedAt` (5 seconds) after the handover; a final waits for it. If its own
|
|
167
|
+
results resume it after all, a count not collected yet is withdrawn, and one
|
|
168
|
+
already collected comes off its final (from the earlier calls' share first),
|
|
169
|
+
so the event is billed once.
|
|
155
170
|
|
|
156
171
|
Dashboard attribution uses event timestamps, rather than when events arrive.
|
|
157
172
|
Older debt is bounded strictly before the native Run's start, and keeps that
|
|
158
173
|
bound across later stateless Runs so an authoritative native event is not
|
|
159
|
-
billed again.
|
|
160
|
-
|
|
174
|
+
billed again. A Run abandoned after a later native Run of its conversation
|
|
175
|
+
started owes with the same bound, before that later start. An earlier event
|
|
176
|
+
stamped on or after that boundary cannot be identified reliably and stays
|
|
177
|
+
unknown. Missing or ambiguous debt expires after
|
|
161
178
|
10 minutes; at most 64 distinct bounded debt groups are kept per account and
|
|
162
179
|
conversation, dropping the oldest on overflow. These counts are never guessed
|
|
163
180
|
as prior usage. Stateless Runs otherwise keep the dashboard accounting above.
|
package/index.mjs
CHANGED
|
@@ -2014,11 +2014,13 @@ function addUsage(a, b) {
|
|
|
2014
2014
|
// event timestamps before its start: its authoritative final must never be
|
|
2015
2015
|
// collected as an earlier Run. Keep that bound when a later stateless Run
|
|
2016
2016
|
// adds unbounded debt. Ordinary stateless debt retains its original shape.
|
|
2017
|
+
// A debt owed with a tag is one Run's event, kept in a group of its own: the
|
|
2018
|
+
// tag says whether a step collected it (and what) or the Run withdrew it.
|
|
2017
2019
|
const DEBT_GROUP_LIMIT = 64
|
|
2018
|
-
function owe(key, { since = Date.now(), n = 0, ready = Date.now(), carry = null, before }) {
|
|
2020
|
+
function owe(key, { since = Date.now(), n = 0, ready = Date.now(), carry = null, before, tag }) {
|
|
2019
2021
|
for (const [k, d] of owed) {
|
|
2020
2022
|
if (d.groups) {
|
|
2021
|
-
d.groups = d.groups.filter((g) => Date.now() - g.since <= STEP_WAIT.owedFor)
|
|
2023
|
+
d.groups = d.groups.filter((g) => Date.now() - g.since <= STEP_WAIT.owedFor && g.tag?.state !== "withdrawn")
|
|
2022
2024
|
d.n = d.groups.reduce((sum, g) => sum + g.n, 0)
|
|
2023
2025
|
if (Date.now() - d.since > STEP_WAIT.owedFor) d.carry = null
|
|
2024
2026
|
if (!d.n && !d.carry) owed.delete(k)
|
|
@@ -2027,15 +2029,16 @@ function owe(key, { since = Date.now(), n = 0, ready = Date.now(), carry = null,
|
|
|
2027
2029
|
}
|
|
2028
2030
|
if (n <= 0 && !carry) return
|
|
2029
2031
|
const d = owed.get(key)
|
|
2032
|
+
if (!d && tag) return void owed.set(key, { since, n, ready, carry: carry && { ...carry }, groups: [{ since, n, ready, before, tag }] })
|
|
2030
2033
|
if (!d) return void owed.set(key, { since, n, ready, carry: carry && { ...carry }, ...(before !== undefined ? { before } : {}) })
|
|
2031
|
-
if (n > 0 && (d.groups || d.before !== undefined || before !== undefined)) {
|
|
2034
|
+
if (n > 0 && (d.groups || d.before !== undefined || before !== undefined || tag)) {
|
|
2032
2035
|
const groups = d.groups ?? (d.n > 0 ? [{ since: d.since, n: d.n, ready: d.ready, before: d.before }] : [])
|
|
2033
|
-
const same = groups.find((g) => g.before === before)
|
|
2036
|
+
const same = !tag && groups.find((g) => !g.tag && g.before === before)
|
|
2034
2037
|
if (same) {
|
|
2035
2038
|
same.since = Math.min(same.since, since)
|
|
2036
2039
|
same.n += n
|
|
2037
2040
|
same.ready = Math.min(same.ready, ready)
|
|
2038
|
-
} else groups.push({ since, n, ready, before })
|
|
2041
|
+
} else groups.push({ since, n, ready, before, ...(tag ? { tag } : {}) })
|
|
2039
2042
|
// As with expired dashboard debt, overflow stays unknown, never estimated
|
|
2040
2043
|
// or merged across bounds into an authoritative native Run's event.
|
|
2041
2044
|
groups.sort((a, b) => a.since - b.since)
|
|
@@ -2051,6 +2054,19 @@ function owe(key, { since = Date.now(), n = 0, ready = Date.now(), carry = null,
|
|
|
2051
2054
|
d.carry = addUsage(d.carry, carry)
|
|
2052
2055
|
}
|
|
2053
2056
|
|
|
2057
|
+
// withdraw takes back the debt owed with tag while no step has collected it:
|
|
2058
|
+
// its Run was resumed after all, and its own final counts its event.
|
|
2059
|
+
function withdraw(key, tag) {
|
|
2060
|
+
if (tag.state !== "owed") return
|
|
2061
|
+
tag.state = "withdrawn"
|
|
2062
|
+
const d = owed.get(key)
|
|
2063
|
+
if (!d?.groups) return
|
|
2064
|
+
d.groups = d.groups.filter((g) => g.tag !== tag)
|
|
2065
|
+
d.n = d.groups.reduce((sum, g) => sum + g.n, 0)
|
|
2066
|
+
if (!d.n && !d.carry) owed.delete(key)
|
|
2067
|
+
else if (d.groups.length) d.since = Math.min(...d.groups.map((g) => g.since))
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2054
2070
|
// usageEvents are the dashboard's events of conversation conv from since
|
|
2055
2071
|
// on, the `want` oldest not counted yet, summed: usage (null when none),
|
|
2056
2072
|
// each with its time (events), how many were found (got), and refused
|
|
@@ -2094,12 +2110,17 @@ async function usageEvents(tok, conv, since, want, { poll = false, first = STEP_
|
|
|
2094
2110
|
// found already excludes timestamps claimed by earlier fetches. Two
|
|
2095
2111
|
// distinct events in this response may share a millisecond; count both.
|
|
2096
2112
|
if (at >= before()) continue
|
|
2097
|
-
const group = groups?.findIndex((g, i) => counts[i] < g.n && at >= g.since - 1000 && at < (g.before ?? Infinity))
|
|
2113
|
+
const group = groups?.findIndex((g, i) => counts[i] < g.n && g.tag?.state !== "withdrawn" && at >= g.since - 1000 && at < (g.before ?? Infinity))
|
|
2098
2114
|
if (groups && group === -1) continue
|
|
2099
2115
|
if (groups) counts[group]++
|
|
2100
2116
|
claimed.set(key + "\0" + ev.timestamp, Date.now())
|
|
2101
2117
|
const t = ev.tokenUsage
|
|
2102
2118
|
const u = { input: num(t.inputTokens), output: num(t.outputTokens), cacheRead: num(t.cacheReadTokens), cacheWrite: num(t.cacheWriteTokens), reasoning: 0 }
|
|
2119
|
+
const tag = groups?.[group].tag
|
|
2120
|
+
if (tag) {
|
|
2121
|
+
tag.state = "collected"
|
|
2122
|
+
tag.usage = addUsage(tag.usage, u)
|
|
2123
|
+
}
|
|
2103
2124
|
usage = addUsage(usage ?? ZERO(), u)
|
|
2104
2125
|
events.push({ at: num(ev.timestamp), usage: u })
|
|
2105
2126
|
got++
|
|
@@ -2128,8 +2149,15 @@ function collect(tok, conv, { poll = false, first, signal, over = () => false, a
|
|
|
2128
2149
|
const d = owed.get(key)
|
|
2129
2150
|
if (!d) return Promise.resolve({ usage: null, carry: null, events: [], short: false })
|
|
2130
2151
|
owed.delete(key)
|
|
2152
|
+
// A handed-over Run's event still grows by the step that Run just ended
|
|
2153
|
+
// (Cursor adds each step to a Run's one event as the step ends). It is
|
|
2154
|
+
// looked for only from its own ready on, whatever else is owed with it
|
|
2155
|
+
// sooner: until then it stays owed.
|
|
2156
|
+
const now = Date.now()
|
|
2157
|
+
const held = d.groups?.filter((g) => g.tag?.state === "owed" && g.ready > now) ?? []
|
|
2158
|
+
for (const g of held) owe(key, { since: g.since, n: g.n, ready: g.ready, before: g.before, tag: g.tag })
|
|
2131
2159
|
const p = (async () => {
|
|
2132
|
-
const groups = (d.groups ?? [d]).filter((g) => (g.before === undefined && !d.groups) || Date.now() - g.since <= STEP_WAIT.owedFor)
|
|
2160
|
+
const groups = (d.groups ?? [d]).filter((g) => !held.includes(g) && g.tag?.state !== "withdrawn" && ((g.before === undefined && !d.groups) || Date.now() - g.since <= STEP_WAIT.owedFor))
|
|
2133
2161
|
const want = groups.reduce((sum, g) => sum + g.n, 0)
|
|
2134
2162
|
let r = { usage: null, events: [], got: 0 }
|
|
2135
2163
|
if (want > 0 && canRead(tok)) r = await usageEvents(tok, conv, Math.min(...groups.map((g) => g.since)), want, {
|
|
@@ -2138,9 +2166,10 @@ function collect(tok, conv, { poll = false, first, signal, over = () => false, a
|
|
|
2138
2166
|
let short = false
|
|
2139
2167
|
for (const [i, g] of groups.entries()) {
|
|
2140
2168
|
const remaining = g.n - (d.groups ? r.counts?.[i] ?? 0 : r.got)
|
|
2141
|
-
|
|
2169
|
+
// a tag withdrawn while this was asked is its Run's own again
|
|
2170
|
+
if (remaining > 0 && canRead(tok) && g.tag?.state !== "withdrawn") {
|
|
2142
2171
|
short = true
|
|
2143
|
-
owe(key, { since: g.since, n: remaining, ready: g.ready, before: g.before })
|
|
2172
|
+
owe(key, { since: g.since, n: remaining, ready: g.ready, before: g.before, tag: g.tag })
|
|
2144
2173
|
}
|
|
2145
2174
|
}
|
|
2146
2175
|
const carry = d.carry && { ...d.carry }
|
|
@@ -2200,10 +2229,21 @@ function ledger(tok, conv, since, signal, kept, { before } = {}) {
|
|
|
2200
2229
|
}
|
|
2201
2230
|
return r
|
|
2202
2231
|
})
|
|
2232
|
+
// heldUntil is when the latest handed-over event still held back
|
|
2233
|
+
// (collect) becomes ready; 0 when none is
|
|
2234
|
+
const heldUntil = () => {
|
|
2235
|
+
const now = Date.now()
|
|
2236
|
+
return Math.max(0, ...(owed.get(debtKey)?.groups ?? []).filter((g) => g.tag?.state === "owed" && g.ready > now).map((g) => g.ready))
|
|
2237
|
+
}
|
|
2203
2238
|
let collecting = null
|
|
2204
2239
|
const debt = kept ? owed.get(debtKey) : undefined
|
|
2205
2240
|
const timer = debt ? setTimeout(() => (collecting = gather()), Math.max(0, debt.ready - Date.now())) : null
|
|
2206
2241
|
timer?.unref?.()
|
|
2242
|
+
const sleep = (ms) => new Promise((r) => {
|
|
2243
|
+
if (signal?.aborted) return r()
|
|
2244
|
+
const t = setTimeout(r, ms)
|
|
2245
|
+
signal?.addEventListener("abort", () => (clearTimeout(t), r()), { once: true })
|
|
2246
|
+
})
|
|
2207
2247
|
const takeMine = () => {
|
|
2208
2248
|
const u = mine
|
|
2209
2249
|
mine = null
|
|
@@ -2239,10 +2279,27 @@ function ledger(tok, conv, since, signal, kept, { before } = {}) {
|
|
|
2239
2279
|
if (final) {
|
|
2240
2280
|
await collecting
|
|
2241
2281
|
await Promise.all([...(flights.get(debtKey) ?? [])])
|
|
2282
|
+
// a handed-over event held back is waited for, up to its ready
|
|
2283
|
+
const until = heldUntil()
|
|
2284
|
+
if (until) await sleep(until - Date.now())
|
|
2285
|
+
await Promise.all([...(flights.get(debtKey) ?? [])])
|
|
2242
2286
|
if (owed.has(debtKey)) await gather({ poll: owed.get(debtKey).n > 0, first: 0, signal })
|
|
2243
2287
|
}
|
|
2244
2288
|
return take()
|
|
2245
2289
|
},
|
|
2290
|
+
// handover: a later Run of the conversation began while this one waits
|
|
2291
|
+
// on the caller's results. That Run collects from here on: what this one
|
|
2292
|
+
// collected and has not given out goes to it, as does what an ask still
|
|
2293
|
+
// going brings. A step that ends this Run after all still collects.
|
|
2294
|
+
handover() {
|
|
2295
|
+
clearTimeout(timer)
|
|
2296
|
+
const give = () => {
|
|
2297
|
+
const u = take()
|
|
2298
|
+
if (u) owe(debtKey, { carry: u })
|
|
2299
|
+
}
|
|
2300
|
+
give()
|
|
2301
|
+
collecting?.then(give, () => {})
|
|
2302
|
+
},
|
|
2246
2303
|
done() {
|
|
2247
2304
|
over = true
|
|
2248
2305
|
clearTimeout(timer)
|
|
@@ -2700,8 +2757,32 @@ async function runNative({ tok, base, id, tools, conv, convID, signal, maxMode,
|
|
|
2700
2757
|
const book = ledger(tok, cid, since, accounting.signal, !!convID, { before: since })
|
|
2701
2758
|
const debtKey = usageKey(tok, cid)
|
|
2702
2759
|
let started = false, settled = false, deferred = null
|
|
2760
|
+
// handed is this Run's step owed at a later Run's start while this one
|
|
2761
|
+
// waited on results (handover): owed, collected (and what), or withdrawn
|
|
2762
|
+
let handed = null
|
|
2763
|
+
const owes = () => started && native.segments > 0 && !native.finalUsage && convID && canRead(tok)
|
|
2703
2764
|
native.accounting = {
|
|
2704
2765
|
started() { started = true },
|
|
2766
|
+
// A later Run of the conversation began (NativeSessionPool.create) while
|
|
2767
|
+
// this one waits on the caller's results. Its step's event is owed now,
|
|
2768
|
+
// bounded before that start, for the later Run to collect, rather than
|
|
2769
|
+
// when this one is abandoned at resultWait. Cursor stamps a Run's one
|
|
2770
|
+
// event at its start and adds each step to it as the step ends.
|
|
2771
|
+
handover() {
|
|
2772
|
+
if (settled || handed && handed.state !== "withdrawn" || !owes()) return
|
|
2773
|
+
handed = { state: "owed" }
|
|
2774
|
+
owe(debtKey, { since, n: 1, ready: Date.now() + STEP_WAIT.owedAt, before: native.laterRunAt, tag: handed })
|
|
2775
|
+
book.handover()
|
|
2776
|
+
},
|
|
2777
|
+
// resumed by its own results after all: a step not collected yet is this
|
|
2778
|
+
// Run's to count again, in its final; one collected is counted (below)
|
|
2779
|
+
resumed() {
|
|
2780
|
+
if (handed?.state === "owed") withdraw(debtKey, handed)
|
|
2781
|
+
},
|
|
2782
|
+
// what a later Run collected of this Run's event: its final leaves it out
|
|
2783
|
+
counted() {
|
|
2784
|
+
return handed?.state === "collected" ? handed.usage : null
|
|
2785
|
+
},
|
|
2705
2786
|
async settle() {
|
|
2706
2787
|
const more = await book.owed(true)
|
|
2707
2788
|
if (settled) {
|
|
@@ -2725,10 +2806,14 @@ async function runNative({ tok, base, id, tools, conv, convID, signal, maxMode,
|
|
|
2725
2806
|
accounting.abort()
|
|
2726
2807
|
if (deferred) owe(debtKey, { carry: deferred })
|
|
2727
2808
|
deferred = null
|
|
2809
|
+
// a step handed over is owed already, or was collected
|
|
2810
|
+
if (handed && handed.state !== "withdrawn") return
|
|
2728
2811
|
// Every handoff of this owner belongs to one Run. Only an abandoned
|
|
2729
2812
|
// started/pending Run is owed; a final snapshot (including zero) is not.
|
|
2730
|
-
if (
|
|
2731
|
-
|
|
2813
|
+
if (owes()) {
|
|
2814
|
+
// laterRunAt: a later Run of this conversation began while this one
|
|
2815
|
+
// was live (NativeSessionPool.create); its events are not this debt
|
|
2816
|
+
owe(debtKey, { since, n: 1, ready: Date.now() + STEP_WAIT.owedAt, before: native.laterRunAt })
|
|
2732
2817
|
}
|
|
2733
2818
|
},
|
|
2734
2819
|
}
|
package/native-session.mjs
CHANGED
|
@@ -796,8 +796,24 @@ export class NativeSessionPool {
|
|
|
796
796
|
}
|
|
797
797
|
// Pending ancestors, new input, and terminal old handles are ordinary
|
|
798
798
|
// imported history, even while a parent Run is still awaiting its results.
|
|
799
|
-
|
|
800
|
-
|
|
799
|
+
// A fresh user turn whose old native calls all have results imports them
|
|
800
|
+
// into a NEW owner; those results are never submitted to their old exec.
|
|
801
|
+
const historical = chat.messages.flatMap((m) => (m?.tool_calls ?? []).filter((c) => HANDLE.test(c?.id ?? "")))
|
|
802
|
+
if (historical.length) {
|
|
803
|
+
const answered = new Set(chat.messages.filter((m) => m?.role === "tool").map((m) => m.tool_call_id))
|
|
804
|
+
const last = chat.messages.at(-1)
|
|
805
|
+
const freshTurn = last?.role === "user" && !toolAttachment(last)
|
|
806
|
+
if (!freshTurn || historical.some((c) => !answered.has(c.id))) return fallback("historical native calls")
|
|
807
|
+
}
|
|
808
|
+
if (selector && this.selectors.has(account + ":" + selector)) {
|
|
809
|
+
if (!historical.length) return fallback("owner busy")
|
|
810
|
+
// New input after results the caller already gave its native calls
|
|
811
|
+
// (Claude Code sends a reminder beside a tool result, which a chat
|
|
812
|
+
// request carries as a user message after the tool message). The
|
|
813
|
+
// reservation's holder, a parent awaiting results, is left as it is:
|
|
814
|
+
// this Run takes no reservation, and only its own calls resume it.
|
|
815
|
+
return { account, selector, controls, selected: false, chat }
|
|
816
|
+
}
|
|
801
817
|
return { account, selector, controls, selected: !!selector, chat }
|
|
802
818
|
}
|
|
803
819
|
create(prepared, resolution, wire) {
|
|
@@ -815,6 +831,17 @@ export class NativeSessionPool {
|
|
|
815
831
|
if (!(e instanceof NativeSessionError)) throw e
|
|
816
832
|
return null
|
|
817
833
|
}
|
|
834
|
+
// A Run of this conversation still live may be abandoned after this one
|
|
835
|
+
// starts: what it then owes is bounded before this start, so this Run's
|
|
836
|
+
// own dashboard events are never collected as its debt.
|
|
837
|
+
// One that waits on the caller's results owes its step now, for this
|
|
838
|
+
// Run to collect, rather than when it is abandoned at resultWait.
|
|
839
|
+
const at = Date.now()
|
|
840
|
+
for (const e of this.entries) {
|
|
841
|
+
if (e.account !== owner.account || !e.selector || e.selector !== owner.selector) continue
|
|
842
|
+
e.laterRunAt ??= at
|
|
843
|
+
if (e.state === "awaiting-results") e.accounting?.handover()
|
|
844
|
+
}
|
|
818
845
|
this.entries.add(owner)
|
|
819
846
|
if (prepared.selected) this.selectors.set(owner.account + ":" + owner.selector, owner)
|
|
820
847
|
return owner
|
|
@@ -996,6 +1023,9 @@ class NativeSession {
|
|
|
996
1023
|
batch.next = next
|
|
997
1024
|
this.segment = next
|
|
998
1025
|
this.state = "submitting"
|
|
1026
|
+
// a step owed at a later Run's start and not collected yet is this Run's
|
|
1027
|
+
// to count again, in its own final
|
|
1028
|
+
this.accounting?.resumed()
|
|
999
1029
|
clearTimeout(this.resultTimer)
|
|
1000
1030
|
clearTimeout(this.batchTimer)
|
|
1001
1031
|
this.batchTimer = null
|
|
@@ -1257,6 +1287,15 @@ class NativeSession {
|
|
|
1257
1287
|
earlier = { input: u.input - own.input, cacheRead: u.cacheRead - own.cacheRead, cacheWrite: u.cacheWrite - own.cacheWrite, output: u.output - own.output }
|
|
1258
1288
|
Object.assign(u, own)
|
|
1259
1289
|
}
|
|
1290
|
+
// What a later Run collected of this Run's event while this one waited on
|
|
1291
|
+
// results (handover) is in the turn's totals too: it comes off them, from
|
|
1292
|
+
// the earlier steps' share first, so the event counts once.
|
|
1293
|
+
const counted = this.accounting?.counted?.()
|
|
1294
|
+
if (counted) for (const k of ["input", "cacheRead", "cacheWrite", "output"]) {
|
|
1295
|
+
const off = Math.min(earlier?.[k] ?? 0, counted[k] ?? 0)
|
|
1296
|
+
if (earlier) earlier[k] -= off
|
|
1297
|
+
u[k] = Math.max(0, u[k] - ((counted[k] ?? 0) - off))
|
|
1298
|
+
}
|
|
1260
1299
|
const prompt = u.input + u.cacheRead + u.cacheWrite
|
|
1261
1300
|
this.finalUsage = {
|
|
1262
1301
|
prompt_tokens: prompt, completion_tokens: u.output, total_tokens: prompt + u.output,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magpie-community/opencode-cursor-auth",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.41",
|
|
4
4
|
"description": "Cursor subscriptions (Pro, Pro+, Ultra, Teams) in OpenCode and magpie, through the API cursor-agent talks to",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./opencode.mjs",
|