magicrew-auth 0.3.7 → 0.3.13

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.
@@ -1,100 +1,100 @@
1
- // 模型上下文窗口 —— 向 magpie 自己的模型库查
2
- //
3
- // ═══ 为什么不能自己填一个值 ═══════════════════════════════════════════
4
- //
5
- // magicrew 的两个模型接口**都不返回上下文窗口**:
6
- // GET /api/v1/flows/models → value / label / vision / tags / configs
7
- // GET /v1/models → id / object / created_at / owner_by
8
- //
9
- // 早前这里一律填 256_000 当保守值,后果是反的:
10
- // `pi-ai detected context overflow for model "magicrew/deepseek-v4.1-flash"`
11
- // —— agent 拿 256K 判断"放不下了",而实际窗口是 1M,白砍掉四分之三。
12
- //
13
- // magpie 自己有一份模型库(`~/.cache/magpie/models.json`,按厂商分组,
14
- // 每条带 `limit.context`),它本来就随 magpie 更新。**向它查,不要自己编。**
15
- //
16
- // 查不到才退回保守值 —— 宁可保守,不要给出超过真实窗口的数(那会让 agent
17
- // 以为还有余量,请求超了上游才报错)。
18
-
19
- import { readFileSync } from "node:fs"
20
- import { homedir } from "node:os"
21
- import { join } from "node:path"
22
-
23
- /**
24
- * 查不到时的兜底:**1M**。
25
- *
26
- * 优先级从高到低:
27
- * ① 用户在 magpie GUI 里手选的(「上下文窗口」那一行)—— magpie 直接用它,插件的值只是默认
28
- * ② 本文件从 magpie 模型库查到的真实值(models.dev 数据)
29
- * ③ 这个兜底
30
- *
31
- * ⚠ 兜底故意给大的:给 1M 而实际只有 128K 时,上游会在超限时报错,用户看得到;
32
- * 给 256K 而实际有 1M 时,agent 会主动拒绝一段本可以处理的对话 —— 那是静默的能力损失,
33
- * 比报错更难查(`pi-ai detected context overflow` 就是这么来的)。
34
- */
35
- const FALLBACK_CONTEXT = 1_048_576
36
-
37
- let cache = null
38
- let cacheAt = 0
39
-
40
- /** models.json 5-6MB,读一次缓存住;10 分钟内不重复读 */
41
- const CACHE_MS = 10 * 60_000
42
-
43
- function loadLibrary() {
44
- if (cache && Date.now() - cacheAt < CACHE_MS) return cache
45
- const idx = new Map()
46
- try {
47
- const raw = readFileSync(join(homedir(), ".cache", "magpie", "models.json"), "utf8")
48
- const walk = (o) => {
49
- if (Array.isArray(o)) {
50
- for (const v of o) walk(v)
51
- return
52
- }
53
- if (!o || typeof o !== "object") return
54
- const id = typeof o.id === "string" ? o.id : ""
55
- const ctx = o.limit?.context ?? o.context_length ?? o.context_window
56
- if (id && Number(ctx) > 0) {
57
- idx.set(id.toLowerCase(), Number(ctx))
58
- // 同一个模型可能挂在多个厂商下(deepseek-ai/x、Pro/deepseek-ai/x …),
59
- // 只保留最大值 —— 那才是它真能收的
60
- const tail = id.toLowerCase().split("/").pop()
61
- if (tail) {
62
- const prev = idx.get(`~${tail}`) || 0
63
- if (Number(ctx) > prev) idx.set(`~${tail}`, Number(ctx))
64
- }
65
- }
66
- for (const v of Object.values(o)) walk(v)
67
- }
68
- walk(JSON.parse(raw))
69
- } catch {}
70
- cache = idx
71
- cacheAt = Date.now()
72
- return idx
73
- }
74
-
75
- /**
76
- * 这个模型的上下文窗口。
77
- * @param {string} modelId 插件侧的模型 id,如 `deepseek-v4.1-flash`
78
- * @returns {number} 字节按 token 计;查不到给保守值
79
- */
80
- export function contextOf(modelId) {
81
- const id = String(modelId || "").toLowerCase()
82
- if (!id) return FALLBACK_CONTEXT
83
- const idx = loadLibrary()
84
-
85
- // ① 全名命中(插件 id 恰好等于库里的 id)
86
- if (idx.has(id)) return idx.get(id)
87
-
88
- // ② 尾段命中:库里的 `deepseek-ai/deepseek-v4.1-flash` ↔ 我们的 `deepseek-v4.1-flash`
89
- if (idx.has(`~${id}`)) return idx.get(`~${id}`)
90
-
91
- // ③ 同一个模型挂在不同厂商前缀下,取最大的那个(真能收的容量)
92
- let best = 0
93
- for (const [k, v] of idx) {
94
- if (k.startsWith("~")) continue
95
- if (k.endsWith(`/${id}`) && v > best) best = v
96
- }
97
- return best || FALLBACK_CONTEXT
98
- }
99
-
100
- export const _internal = { FALLBACK_CONTEXT, loadLibrary }
1
+ // 模型上下文窗口 —— 向 magpie 自己的模型库查
2
+ //
3
+ // ═══ 为什么不能自己填一个值 ═══════════════════════════════════════════
4
+ //
5
+ // magicrew 的两个模型接口**都不返回上下文窗口**:
6
+ // GET /api/v1/flows/models → value / label / vision / tags / configs
7
+ // GET /v1/models → id / object / created_at / owner_by
8
+ //
9
+ // 早前这里一律填 256_000 当保守值,后果是反的:
10
+ // `pi-ai detected context overflow for model "magicrew/deepseek-v4.1-flash"`
11
+ // —— agent 拿 256K 判断"放不下了",而实际窗口是 1M,白砍掉四分之三。
12
+ //
13
+ // magpie 自己有一份模型库(`~/.cache/magpie/models.json`,按厂商分组,
14
+ // 每条带 `limit.context`),它本来就随 magpie 更新。**向它查,不要自己编。**
15
+ //
16
+ // 查不到才退回保守值 —— 宁可保守,不要给出超过真实窗口的数(那会让 agent
17
+ // 以为还有余量,请求超了上游才报错)。
18
+
19
+ import { readFileSync } from "node:fs"
20
+ import { homedir } from "node:os"
21
+ import { join } from "node:path"
22
+
23
+ /**
24
+ * 查不到时的兜底:**1M**。
25
+ *
26
+ * 优先级从高到低:
27
+ * ① 用户在 magpie GUI 里手选的(「上下文窗口」那一行)—— magpie 直接用它,插件的值只是默认
28
+ * ② 本文件从 magpie 模型库查到的真实值(models.dev 数据)
29
+ * ③ 这个兜底
30
+ *
31
+ * ⚠ 兜底故意给大的:给 1M 而实际只有 128K 时,上游会在超限时报错,用户看得到;
32
+ * 给 256K 而实际有 1M 时,agent 会主动拒绝一段本可以处理的对话 —— 那是静默的能力损失,
33
+ * 比报错更难查(`pi-ai detected context overflow` 就是这么来的)。
34
+ */
35
+ const FALLBACK_CONTEXT = 1_048_576
36
+
37
+ let cache = null
38
+ let cacheAt = 0
39
+
40
+ /** models.json 5-6MB,读一次缓存住;10 分钟内不重复读 */
41
+ const CACHE_MS = 10 * 60_000
42
+
43
+ function loadLibrary() {
44
+ if (cache && Date.now() - cacheAt < CACHE_MS) return cache
45
+ const idx = new Map()
46
+ try {
47
+ const raw = readFileSync(join(homedir(), ".cache", "magpie", "models.json"), "utf8")
48
+ const walk = (o) => {
49
+ if (Array.isArray(o)) {
50
+ for (const v of o) walk(v)
51
+ return
52
+ }
53
+ if (!o || typeof o !== "object") return
54
+ const id = typeof o.id === "string" ? o.id : ""
55
+ const ctx = o.limit?.context ?? o.context_length ?? o.context_window
56
+ if (id && Number(ctx) > 0) {
57
+ idx.set(id.toLowerCase(), Number(ctx))
58
+ // 同一个模型可能挂在多个厂商下(deepseek-ai/x、Pro/deepseek-ai/x …),
59
+ // 只保留最大值 —— 那才是它真能收的
60
+ const tail = id.toLowerCase().split("/").pop()
61
+ if (tail) {
62
+ const prev = idx.get(`~${tail}`) || 0
63
+ if (Number(ctx) > prev) idx.set(`~${tail}`, Number(ctx))
64
+ }
65
+ }
66
+ for (const v of Object.values(o)) walk(v)
67
+ }
68
+ walk(JSON.parse(raw))
69
+ } catch {}
70
+ cache = idx
71
+ cacheAt = Date.now()
72
+ return idx
73
+ }
74
+
75
+ /**
76
+ * 这个模型的上下文窗口。
77
+ * @param {string} modelId 插件侧的模型 id,如 `deepseek-v4.1-flash`
78
+ * @returns {number} 字节按 token 计;查不到给保守值
79
+ */
80
+ export function contextOf(modelId) {
81
+ const id = String(modelId || "").toLowerCase()
82
+ if (!id) return FALLBACK_CONTEXT
83
+ const idx = loadLibrary()
84
+
85
+ // ① 全名命中(插件 id 恰好等于库里的 id)
86
+ if (idx.has(id)) return idx.get(id)
87
+
88
+ // ② 尾段命中:库里的 `deepseek-ai/deepseek-v4.1-flash` ↔ 我们的 `deepseek-v4.1-flash`
89
+ if (idx.has(`~${id}`)) return idx.get(`~${id}`)
90
+
91
+ // ③ 同一个模型挂在不同厂商前缀下,取最大的那个(真能收的容量)
92
+ let best = 0
93
+ for (const [k, v] of idx) {
94
+ if (k.startsWith("~")) continue
95
+ if (k.endsWith(`/${id}`) && v > best) best = v
96
+ }
97
+ return best || FALLBACK_CONTEXT
98
+ }
99
+
100
+ export const _internal = { FALLBACK_CONTEXT, loadLibrary }