mslxdff 0.1.80 → 0.1.82
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/package.json
CHANGED
|
@@ -29,11 +29,10 @@ async function clineBenchOne({ baseUrl, model, accessToken, prompt, maxTokens, t
|
|
|
29
29
|
const reader = res.body.getReader();
|
|
30
30
|
const decoder = new TextDecoder();
|
|
31
31
|
let buf = "";
|
|
32
|
-
const firstChunkAt = performance.now();
|
|
33
32
|
for (;;) {
|
|
34
33
|
const { done, value } = await reader.read();
|
|
35
34
|
if (done) break;
|
|
36
|
-
if (ttfbMs === null) ttfbMs = Math.round(performance.now() -
|
|
35
|
+
if (ttfbMs === null) ttfbMs = Math.round(performance.now() - t0);
|
|
37
36
|
buf += decoder.decode(value, { stream: true });
|
|
38
37
|
let idx;
|
|
39
38
|
while ((idx = buf.indexOf("\n")) >= 0) {
|
|
@@ -174,7 +173,7 @@ async function handleVia({ providerId, opts, fetchImpl, loadConfigs, loadKeys, l
|
|
|
174
173
|
const aIdx = Math.min(kIdx, Math.max(auths.length - 1, 0));
|
|
175
174
|
const key = keys[kIdx] || keys[0] || "";
|
|
176
175
|
const auth = auths[aIdx] || auths[0] || null;
|
|
177
|
-
const cKeys = keys.filter((k) => isRefreshToken(k));
|
|
176
|
+
const cKeys = keys.filter((k) => isRefreshToken(k, p));
|
|
178
177
|
if (cKeys.length) {
|
|
179
178
|
const normBase = String(baseUrl).replace(/\/+$/, "");
|
|
180
179
|
const chatBase = normBase.endsWith("/api/v1") ? normBase.slice(0, -7) : normBase;
|
|
@@ -197,10 +196,20 @@ async function handleVia({ providerId, opts, fetchImpl, loadConfigs, loadKeys, l
|
|
|
197
196
|
const aIdx = Math.min(kIdx, Math.max(auths.length - 1, 0));
|
|
198
197
|
const key = keys[kIdx] || keys[0] || "";
|
|
199
198
|
const auth = auths[aIdx] || auths[0] || null;
|
|
200
|
-
const cKeys = keys.filter((k) => isRefreshToken(k));
|
|
199
|
+
const cKeys = keys.filter((k) => isRefreshToken(k, p));
|
|
201
200
|
if (cKeys.length) {
|
|
202
|
-
|
|
203
|
-
|
|
201
|
+
const normBase = String(baseUrl).replace(/\/+$/, "");
|
|
202
|
+
const chatBase = normBase.endsWith("/api/v1") ? normBase.slice(0, -7) : normBase;
|
|
203
|
+
const rt = cKeys[0];
|
|
204
|
+
const at = await refreshTokenForBase({ refreshToken: rt, baseUrl: normBase, fetchImpl });
|
|
205
|
+
if (!at) return { ok: false, label: "鉴权失败", error: "refresh failed", ttfbMs: null, totalMs: 0 };
|
|
206
|
+
const targetUrl = `${chatBase}/api/v1/chat/completions`;
|
|
207
|
+
const headers = clineHeaders(`sess_bench_via_${Date.now()}`, at);
|
|
208
|
+
const rawModel = String(model).startsWith(`${p}/`) ? String(model).slice(p.length + 1) : String(model);
|
|
209
|
+
const body = { model: rawModel, messages: [{ role: "user", content: "hi" }], stream: true, max_tokens: 5, session_id: `sess_bench_via_${Date.now()}`, reasoning_effort: "high" };
|
|
210
|
+
const peer = peers.find((pe) => pe.url === peerUrl || (pe.name || pe.id) === peerUrl);
|
|
211
|
+
const peerToken = peer?.token || token;
|
|
212
|
+
return viaProbe({ peerUrl, token: peerToken, relayTarget: targetUrl, relayHeaders: headers, relayBody: body, timeoutMs: opts.timeoutMs, fetchImpl });
|
|
204
213
|
}
|
|
205
214
|
const rawModel = String(model).startsWith(`${p}/`) ? String(model).slice(p.length + 1) : String(model);
|
|
206
215
|
const targetUrl = p === "opencode" ? `${process.env.UPSTREAM_BASE_URL || "https://opencode.ai"}/zen/v1/chat/completions` : `${String(baseUrl).replace(/\/+$/, "")}${chatPath}`;
|
|
@@ -280,7 +289,7 @@ export async function handleProviderBench(id, sub, rest, args, deps = {}) {
|
|
|
280
289
|
log(`bench ${providerId}: 共 ${allowed.length} 个已勾选模型,逐个测速(串行,${opts.timeoutMs}ms 超时)...`);
|
|
281
290
|
if (!opts.json) console.log(`prompt="${opts.prompt}" maxTokens=${opts.maxTokens}\n`);
|
|
282
291
|
const chatPath = cfg.chatPath || defaultChatPath(providerId);
|
|
283
|
-
const rtKeys = keys.filter((k) => isRefreshToken(k));
|
|
292
|
+
const rtKeys = keys.filter((k) => isRefreshToken(k, providerId));
|
|
284
293
|
const normBase = String(baseUrl).replace(/\/+$/, "");
|
|
285
294
|
const clineChatBase = normBase.endsWith("/api/v1") ? normBase.slice(0, -7) : normBase;
|
|
286
295
|
const results = [];
|
|
@@ -20,12 +20,18 @@ export function clineHeaders(sessionId, token) {
|
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export function isRefreshToken(key) {
|
|
23
|
+
export function isRefreshToken(key, providerId = "") {
|
|
24
24
|
const s = String(key || "").trim();
|
|
25
25
|
if (!s) return false;
|
|
26
|
-
//
|
|
26
|
+
// 仅 cline 系供应商才有 refreshToken 形态(WorkOS 设备授权);其他一律走传统 Key
|
|
27
|
+
const pid = String(providerId || "").toLowerCase();
|
|
28
|
+
const baseHint = pid;
|
|
29
|
+
const isCline = baseHint.includes("cline");
|
|
30
|
+
if (!isCline) {
|
|
31
|
+
// 非 cline 供应商,即使长串也不视为 refreshToken,默认传统 Key(以后 xxx.bot 再扩展此处白名单)
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
27
34
|
if (s.startsWith("sk_") || s.startsWith("sk-")) return false;
|
|
28
|
-
// refreshToken 通常为 JWT 或长随机串,长度 > 20 且含 . 或 -
|
|
29
35
|
if (s.length > 20) return true;
|
|
30
36
|
return false;
|
|
31
37
|
}
|
|
@@ -45,8 +45,8 @@ export function createClineProvider({
|
|
|
45
45
|
if (alt.length) extraKeys = alt;
|
|
46
46
|
} catch {}
|
|
47
47
|
const allKeys = [...new Set([...rawKeys, ...extraKeys].map((k) => String(k).trim()).filter(Boolean))];
|
|
48
|
-
const hasRefresh = allKeys.some((k) => isRefreshToken(k));
|
|
49
|
-
const ring = createKeyRing(allKeys.filter((k) => !isRefreshToken(k)), { cooldownMs });
|
|
48
|
+
const hasRefresh = allKeys.some((k) => isRefreshToken(k, id));
|
|
49
|
+
const ring = createKeyRing(allKeys.filter((k) => !isRefreshToken(k, id)), { cooldownMs });
|
|
50
50
|
|
|
51
51
|
let dispatcher = null; let agent = null;
|
|
52
52
|
const a = createAgent({ keepAliveTimeout: envInt("MSLXDFF_CLINE_KEEPALIVE_TIMEOUT", 30_000), keepAliveMaxTimeout: envInt("MSLXDFF_CLINE_KEEPALIVE_MAX_TIMEOUT", 60_000), connections: envInt("MSLXDFF_CLINE_KEEPALIVE_CONNECTIONS", 20) });
|
|
@@ -62,7 +62,7 @@ export function createClineProvider({
|
|
|
62
62
|
// 新 refreshToken 模式
|
|
63
63
|
let authPool = null; let newChatSvc = null;
|
|
64
64
|
if (hasRefresh) {
|
|
65
|
-
const refreshTokens = allKeys.filter((k) => isRefreshToken(k));
|
|
65
|
+
const refreshTokens = allKeys.filter((k) => isRefreshToken(k, id));
|
|
66
66
|
authPool = createAuthPool({
|
|
67
67
|
id, keys: refreshTokens, fetchImpl, dispatcher, baseUrl: resolvedBase, file,
|
|
68
68
|
saveFn: async ({ oldRefreshToken, newRefreshToken }) => {
|
|
@@ -94,13 +94,13 @@ export function createClineProvider({
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
async function chatWithKeys(body, keys) {
|
|
97
|
-
const refreshSubset = (keys || []).filter((k) => isRefreshToken(k));
|
|
97
|
+
const refreshSubset = (keys || []).filter((k) => isRefreshToken(k, id));
|
|
98
98
|
if (refreshSubset.length && hasRefresh) {
|
|
99
99
|
const tmpPool = createAuthPool({ id, keys: refreshSubset, fetchImpl, dispatcher, baseUrl: resolvedBase, file });
|
|
100
100
|
const tmpSvc = createChatService({ id, baseUrl: resolvedBase, chatPath: resolvedChatPath, fetchImpl, dispatcher, authPool: tmpPool, connectTimeoutMs, retry });
|
|
101
101
|
return tmpSvc.runChat(body, createKeyRing([], { cooldownMs }), "shared");
|
|
102
102
|
}
|
|
103
|
-
const tmpRing = createKeyRing((keys || []).filter((k) => !isRefreshToken(k)), { cooldownMs });
|
|
103
|
+
const tmpRing = createKeyRing((keys || []).filter((k) => !isRefreshToken(k, id)), { cooldownMs });
|
|
104
104
|
return oldRunner.runChat(body, tmpRing, "shared provider keys");
|
|
105
105
|
}
|
|
106
106
|
|