@magpie-community/opencode-cursor-auth 0.2.24 → 0.2.26
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 +11 -1
- package/index.mjs +48 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -203,7 +203,17 @@ minutes), the way pi-cursor-sdk lists Cursor's catalog:
|
|
|
203
203
|
(`claude-opus-5-5`), its efforts as variants, and goes as the usable id
|
|
204
204
|
those parameters pick, never as the family id Cursor doesn't know. A
|
|
205
205
|
picker model whose chosen variant isn't one the account can use goes as
|
|
206
|
-
its family's nearest usable id the same way.
|
|
206
|
+
its family's nearest usable id the same way. Such a family is named
|
|
207
|
+
without the tier Cursor's names carry ("Claude Opus 5 1M Medium
|
|
208
|
+
Thinking" is listed as Claude Opus 5 Thinking): the tier is the
|
|
209
|
+
reasoning level the agent asks for (low to max, as the account has
|
|
210
|
+
them), fast the request's `service_tier`.
|
|
211
|
+
- An id for a model with thinking that the account lists only without it
|
|
212
|
+
(`claude-haiku-5-5-thinking` when the list has Claude Haiku 5.5 alone),
|
|
213
|
+
or the other way round, runs as the model the account has. So does a
|
|
214
|
+
picker model whose default thinks while the account lists it only
|
|
215
|
+
without thinking (`claude-haiku-5-5`), or the other way round: each of
|
|
216
|
+
its variant ids goes as the id the account lists.
|
|
207
217
|
- An `@<size>` id the list no longer has (`claude-opus-5-5@1m` when only
|
|
208
218
|
300k is listed, or the model is listed unsized) runs at the model's
|
|
209
219
|
nearest size, in Max Mode when the size asked for is over the model's
|
package/index.mjs
CHANGED
|
@@ -773,14 +773,31 @@ function fromUsable(fam, effort, fast) {
|
|
|
773
773
|
return (at && vs.find((u) => u.effort === at)) || vs.find((u) => u.effort === "") || vs.find((u) => u.effort === "medium") || vs[0]
|
|
774
774
|
}
|
|
775
775
|
|
|
776
|
-
// usableTitle is a usable id's name without what the id says apart:
|
|
776
|
+
// usableTitle is a usable id's name without what the id says apart: its
|
|
777
777
|
// effort, fast, and the 1M Cursor names every Max-capable Claude with
|
|
778
|
-
// ("Claude Opus 5.5 1M Low" is Claude Opus 5.5)
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
778
|
+
// ("Claude Opus 5.5 1M Low" is Claude Opus 5.5), wherever Cursor puts
|
|
779
|
+
// them: "Claude Opus 5 1M Medium Thinking" is Claude Opus 5 Thinking, as
|
|
780
|
+
// its efforts are magpie's reasoning levels and not models of their own
|
|
781
|
+
// (ysm119 on Discord read "Medium" in the name as the only tier). A word
|
|
782
|
+
// of the model's own name stays: GPT-5.1 Codex Max at high is "GPT-5.1
|
|
783
|
+
// Codex Max".
|
|
784
|
+
const EFFORT_WORDS = { none: ["None"], minimal: ["Minimal"], low: ["Low"], medium: ["Medium"], high: ["High"], xhigh: ["Extra High", "XHigh"], max: ["Max"] }
|
|
785
|
+
function usableTitle(u) {
|
|
786
|
+
const ws = u.name.split(" ")
|
|
787
|
+
// the last time a phrase is said, past the name's first word
|
|
788
|
+
const cutLast = (phrase) => {
|
|
789
|
+
const p = phrase.toLowerCase().split(" ")
|
|
790
|
+
for (let i = ws.length - p.length; i >= 1; i--) {
|
|
791
|
+
if (p.every((w, k) => ws[i + k].toLowerCase() === w)) {
|
|
792
|
+
ws.splice(i, p.length)
|
|
793
|
+
return true
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
return false
|
|
797
|
+
}
|
|
798
|
+
for (const p of EFFORT_WORDS[u.effort] ?? []) if (cutLast(p)) break
|
|
799
|
+
if (u.fast) cutLast("fast")
|
|
800
|
+
return ws.filter((w, i) => i === 0 || !/^\(?1m\)?$/i.test(w)).join(" ") || u.name
|
|
784
801
|
}
|
|
785
802
|
|
|
786
803
|
// modelsOf is the picker's models as offered: one entry for each context
|
|
@@ -810,7 +827,14 @@ function modelsOf(picker, ids, listed = []) {
|
|
|
810
827
|
const def = defaultVariant({ variants })
|
|
811
828
|
const { pid, levels: all } = effortsOf(defs)
|
|
812
829
|
const levels = Object.fromEntries(Object.entries(all).filter(([, value]) => has(pid, value)))
|
|
813
|
-
|
|
830
|
+
// the usable ids of its default's family, else of the same model with
|
|
831
|
+
// thinking or without it: a Team's picker can default Claude Haiku 5.5
|
|
832
|
+
// to thinking while cursor-agent lists it as claude-haiku-5-5 alone
|
|
833
|
+
// (ysm119 on Discord, after 0.2.25), and a variant id it lacks is then
|
|
834
|
+
// asked as that one, as named() takes such an id
|
|
835
|
+
const own = familyOf(def?.legacySlug || m.name).family
|
|
836
|
+
const bare = own.replace(/-thinking$/, "")
|
|
837
|
+
const fam = fams.get(own) ?? fams.get(bare) ?? fams.get(bare + "-thinking") ?? []
|
|
814
838
|
const base = { run: m.name, title: clean(m.clientDisplayName || m.name), pid, levels, fast: !!defs.fast?.length, variants, def, partial, model: m, fam, ids }
|
|
815
839
|
const contexts = (defs.context ?? []).filter((c) => has("context", c))
|
|
816
840
|
if (contexts.length) {
|
|
@@ -833,7 +857,7 @@ function modelsOf(picker, ids, listed = []) {
|
|
|
833
857
|
const def = fromUsable(fam, "", false)
|
|
834
858
|
// Cursor's context for it isn't known: its default's, as for a model
|
|
835
859
|
// the picker gives no limit for
|
|
836
|
-
out.push({ id: family, run: family, name: usableTitle(def
|
|
860
|
+
out.push({ id: family, run: family, name: usableTitle(def), title: usableTitle(def), pid: "", levels, fast: false, variants: [], def: undefined, partial: false, model: { name: family }, fam, ids, usableOnly: true, context: DEFAULT_CONTEXT, size: "", offersFast: fam.some((u) => u.fast) })
|
|
837
861
|
}
|
|
838
862
|
return out
|
|
839
863
|
}
|
|
@@ -1014,6 +1038,21 @@ function named(raw, id) {
|
|
|
1014
1038
|
if (u) return { entry: e, seed: undefined, effort: u.effort, fast: u.fast }
|
|
1015
1039
|
if (e.id === of.family) return { entry: e, seed: undefined, effort: of.effort, fast: of.fast }
|
|
1016
1040
|
}
|
|
1041
|
+
// a family neither has, where the account has the same model with
|
|
1042
|
+
// thinking or without it (claude-haiku-5-5-thinking, which 0.1.x listed,
|
|
1043
|
+
// on a Team account whose list has Claude Haiku 5.5 without a thinking
|
|
1044
|
+
// id; ysm119 on Discord): that one, at the id's effort, never the id as
|
|
1045
|
+
// it is, which Cursor answers "AI Model Not Found"
|
|
1046
|
+
const loose = (f) => f.replace(/-thinking$/, "")
|
|
1047
|
+
const key = loose(of.family)
|
|
1048
|
+
for (const e of models) {
|
|
1049
|
+
if (e.usableOnly) {
|
|
1050
|
+
if (loose(e.id) === key) return { entry: e, seed: undefined, effort: of.effort, fast: of.fast }
|
|
1051
|
+
continue
|
|
1052
|
+
}
|
|
1053
|
+
const vs = e.variants.filter((v) => v.legacySlug && loose(familyOf(v.legacySlug).family) === key)
|
|
1054
|
+
if (vs.length) return as(e, vs, of.effort)
|
|
1055
|
+
}
|
|
1017
1056
|
// an id at a context size the list no longer has (claude-opus-5-5@1m,
|
|
1018
1057
|
// picked from an earlier list, or from another account's): the model at
|
|
1019
1058
|
// the nearest size it has; a model listed without sizes, in Max Mode for
|
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.26",
|
|
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",
|