@magpie-community/opencode-cursor-auth 0.2.35 → 0.2.36
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 +45 -2
- package/native-session.mjs +14 -0
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -2853,7 +2853,7 @@ async function runOnce({ tok, base, id, tools, conv, convID, signal, maxMode, pa
|
|
|
2853
2853
|
|
|
2854
2854
|
// decode follows the server's messages into the answer's pieces until the
|
|
2855
2855
|
// turn ends, or the model has made its tool calls.
|
|
2856
|
-
async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage, owedUsage, note }) {
|
|
2856
|
+
async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage, owedUsage, note, countWait = NATIVE_LIMITS.countWait }) {
|
|
2857
2857
|
let calls = 0
|
|
2858
2858
|
// answered: the step's calls answered here (a refusal, the MCP tool
|
|
2859
2859
|
// list), which Cursor's count of the step's calls takes in too (#142)
|
|
@@ -2937,8 +2937,48 @@ async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage,
|
|
|
2937
2937
|
return finish(owedUsage ? await owedUsage(calls === 0).catch(() => null) : null)
|
|
2938
2938
|
}
|
|
2939
2939
|
const closeExec = (id) => send(pb().bytes(5, pb().bytes(1, pb().varint(1, id))).done())
|
|
2940
|
+
// A step whose calls came and whose count never does: Cursor sent the
|
|
2941
|
+
// calls and then only heartbeats (plugins#550, the fifth trace: two
|
|
2942
|
+
// calls, no count, 240 s of heartbeats until quiet). Once countWait has
|
|
2943
|
+
// passed since Cursor's last frame that wasn't a heartbeat, with no call
|
|
2944
|
+
// still being written, the calls that came are the step's. Heartbeats
|
|
2945
|
+
// never move the deadline: they are all such a Run sends.
|
|
2946
|
+
const it = (stream[Symbol.asyncIterator] ?? stream[Symbol.iterator]).call(stream)
|
|
2947
|
+
let heardAt = Date.now()
|
|
2948
|
+
const read = async () => {
|
|
2949
|
+
const next = Promise.resolve(it.next())
|
|
2950
|
+
if (!calls || listed || step.writing) return next
|
|
2951
|
+
next.catch(() => {}) // a read left behind by the cut fails unheard
|
|
2952
|
+
let timer
|
|
2953
|
+
const cut = new Promise((r) => {
|
|
2954
|
+
timer = setTimeout(() => r({ cut: true }), Math.max(0, heardAt + countWait - Date.now()))
|
|
2955
|
+
timer.unref?.()
|
|
2956
|
+
})
|
|
2957
|
+
try {
|
|
2958
|
+
return await Promise.race([next, cut])
|
|
2959
|
+
} finally {
|
|
2960
|
+
clearTimeout(timer)
|
|
2961
|
+
}
|
|
2962
|
+
}
|
|
2963
|
+
const beat = (data) => {
|
|
2964
|
+
try {
|
|
2965
|
+
const ms = fields(data)
|
|
2966
|
+
return ms.length > 0 && ms.every((m) => m.num === 1 && fields(m.data).every((u) => u.num === 13))
|
|
2967
|
+
} catch {
|
|
2968
|
+
return false
|
|
2969
|
+
}
|
|
2970
|
+
}
|
|
2940
2971
|
try {
|
|
2941
|
-
for
|
|
2972
|
+
for (;;) {
|
|
2973
|
+
const r = await read()
|
|
2974
|
+
if (r.cut) {
|
|
2975
|
+
note?.("no count")
|
|
2976
|
+
yield await settled()
|
|
2977
|
+
return
|
|
2978
|
+
}
|
|
2979
|
+
if (r.done) break
|
|
2980
|
+
const f = r.value
|
|
2981
|
+
if (f.end || !beat(f.data)) heardAt = Date.now()
|
|
2942
2982
|
if (f.end) {
|
|
2943
2983
|
const e = failure(200, f.data)
|
|
2944
2984
|
if (e.status < 200 || e.status > 299) yield { error: e }
|
|
@@ -3072,6 +3112,9 @@ async function* decode(stream, { send, blobs, tools, estimate, close, stepUsage,
|
|
|
3072
3112
|
return
|
|
3073
3113
|
}
|
|
3074
3114
|
yield { error: { status: 502, message: "the reply broke off: " + (e?.message ?? e) } }
|
|
3115
|
+
} finally {
|
|
3116
|
+
// not waited for: after a cut, the read left behind ends with the Run
|
|
3117
|
+
Promise.resolve(it.return?.()).catch(() => {})
|
|
3075
3118
|
}
|
|
3076
3119
|
}
|
|
3077
3120
|
|
package/native-session.mjs
CHANGED
|
@@ -9,6 +9,12 @@ export const NATIVE_LIMITS = {
|
|
|
9
9
|
resultWait: 120_000,
|
|
10
10
|
lifetime: 15 * 60_000,
|
|
11
11
|
batchWait: 30_000,
|
|
12
|
+
// How long a stateless step whose calls came waits for Cursor's count of
|
|
13
|
+
// them (update 27) with nothing but heartbeats before it hands the calls
|
|
14
|
+
// that came to the caller (plugins#550). A count comes within ms of the
|
|
15
|
+
// step's last call; a Run that sent calls and then only heartbeats has
|
|
16
|
+
// stopped, and the caller's next request goes on from the calls' results.
|
|
17
|
+
countWait: 60_000,
|
|
12
18
|
drain: 6000,
|
|
13
19
|
replayWait: 120_000,
|
|
14
20
|
blobBytes: 64 << 20,
|
|
@@ -511,6 +517,14 @@ export class StepCalls {
|
|
|
511
517
|
get completed() {
|
|
512
518
|
return this.byCursor.size
|
|
513
519
|
}
|
|
520
|
+
// writing is how many calls the step wrote (7) that are neither started
|
|
521
|
+
// on the client, sent as an exec, nor completed by Cursor: a call of
|
|
522
|
+
// Cursor's own still running, or one still to be sent
|
|
523
|
+
get writing() {
|
|
524
|
+
let n = 0
|
|
525
|
+
for (const id of this.partial) if (!this.started.has(id) && !this.execs.has(id) && !this.byCursor.has(id)) n++
|
|
526
|
+
return n
|
|
527
|
+
}
|
|
514
528
|
// nextStep starts the next step's count
|
|
515
529
|
nextStep() {
|
|
516
530
|
this.partial.clear()
|
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.36",
|
|
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": "./index.mjs",
|