dsh-opendesign-corouter 0.1.2 → 0.1.3
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/lib/client.d.ts +4 -3
- package/lib/client.js +160 -104
- package/lib/generated/typert.host.js +45 -56
- package/lib/generated/typert.remote-client.js +45 -56
- package/lib/index.js +140 -130
- package/lib/index.js.map +4 -4
- package/lib/login.d.ts +2 -0
- package/lib/model-settings.d.ts +3 -3
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -228,96 +228,59 @@ function inferenceEndpoint(baseURL, protocol) {
|
|
|
228
228
|
return baseURL.trim() === "" ? suffix : `${openAiBaseURL(baseURL.trim())}${suffix}`;
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
// src/util.ts
|
|
232
|
-
function record(value) {
|
|
233
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
234
|
-
}
|
|
235
|
-
function finite(value) {
|
|
236
|
-
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
237
|
-
}
|
|
238
|
-
function safeSecret(raw) {
|
|
239
|
-
const value = raw.trim();
|
|
240
|
-
if (!value || /[^\x20-\x7e]/u.test(value)) throw new Error("\u51ED\u636E\u4E3A\u7A7A\u6216\u542B\u6709\u4E0D\u53EF\u7528\u4E8E HTTP \u8BF7\u6C42\u5934\u7684\u5B57\u7B26");
|
|
241
|
-
return value;
|
|
242
|
-
}
|
|
243
|
-
function combinedSignal(signal, timeoutMs) {
|
|
244
|
-
const deadline = AbortSignal.timeout(timeoutMs);
|
|
245
|
-
return signal ? AbortSignal.any([signal, deadline]) : deadline;
|
|
246
|
-
}
|
|
247
|
-
function sleep(ms, signal) {
|
|
248
|
-
return new Promise((resolve) => {
|
|
249
|
-
if (signal.aborted) return resolve();
|
|
250
|
-
const done = () => {
|
|
251
|
-
clearTimeout(timer);
|
|
252
|
-
signal.removeEventListener("abort", done);
|
|
253
|
-
resolve();
|
|
254
|
-
};
|
|
255
|
-
const timer = setTimeout(done, ms);
|
|
256
|
-
signal.addEventListener("abort", done, { once: true });
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
|
|
260
231
|
// src/model-settings.ts
|
|
261
|
-
var MAX_ENTRIES = 512;
|
|
262
|
-
var MAX_MODEL_ID_LENGTH = 128;
|
|
263
|
-
var MODEL_ID = /^[A-Za-z0-9._:/-]{1,128}$/u;
|
|
264
|
-
var MAX_TEMPERATURE = 2;
|
|
265
|
-
var MAX_TOP_P = 1;
|
|
266
|
-
var MAX_TOKENS = 1e7;
|
|
267
|
-
var MAX_CONTEXT_WINDOW = 1e8;
|
|
268
|
-
var REASONING_EFFORTS = ["none", "minimal", "low", "medium", "high", "xhigh", "ultra", "max"];
|
|
269
232
|
var RESERVED_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
270
|
-
var SETTINGS_FIELDS = /* @__PURE__ */ new Set(["enabled", "temperature", "topP", "maxTokens", "contextWindow", "reasoningEffort"]);
|
|
271
|
-
function flag(value) {
|
|
272
|
-
if (typeof value !== "boolean") throw new Error("\u6A21\u578B\u8BBE\u7F6E\u7684 enabled \u5FC5\u987B\u662F\u5E03\u5C14\u503C");
|
|
273
|
-
return value;
|
|
274
|
-
}
|
|
275
|
-
function bounded(value, max, label) {
|
|
276
|
-
if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > max) throw new Error(`\u6A21\u578B\u8BBE\u7F6E\u7684 ${label} \u5FC5\u987B\u662F 0 \u5230 ${max} \u4E4B\u95F4\u7684\u6709\u9650\u6570\u5B57`);
|
|
277
|
-
return value;
|
|
278
|
-
}
|
|
279
|
-
function capacity(value, max, label) {
|
|
280
|
-
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1 || value > max) throw new Error(`\u6A21\u578B\u8BBE\u7F6E\u7684 ${label} \u5FC5\u987B\u662F 1 \u5230 ${max} \u4E4B\u95F4\u7684\u6574\u6570`);
|
|
281
|
-
return value;
|
|
282
|
-
}
|
|
283
|
-
function effort(value) {
|
|
284
|
-
const hit = REASONING_EFFORTS.find((candidate) => candidate === value);
|
|
285
|
-
if (hit === void 0) throw new Error("\u6A21\u578B\u8BBE\u7F6E\u7684 reasoningEffort \u4E0D\u5728\u5141\u8BB8\u7684\u53D6\u503C\u5185");
|
|
286
|
-
return hit;
|
|
287
|
-
}
|
|
288
|
-
function settingsOf(value) {
|
|
289
|
-
if (!record(value)) throw new Error("\u6BCF\u4E2A\u6A21\u578B\u7684\u8BBE\u7F6E\u5FC5\u987B\u662F\u5BF9\u8C61");
|
|
290
|
-
for (const field of Object.keys(value)) {
|
|
291
|
-
if (!SETTINGS_FIELDS.has(field)) throw new Error("\u6A21\u578B\u8BBE\u7F6E\u542B\u6709\u4E0D\u652F\u6301\u7684\u5B57\u6BB5");
|
|
292
|
-
}
|
|
293
|
-
const out = {};
|
|
294
|
-
if (value.enabled !== void 0) out.enabled = flag(value.enabled);
|
|
295
|
-
if (value.temperature !== void 0) out.temperature = bounded(value.temperature, MAX_TEMPERATURE, "temperature");
|
|
296
|
-
if (value.topP !== void 0) out.topP = bounded(value.topP, MAX_TOP_P, "topP");
|
|
297
|
-
if (value.maxTokens !== void 0) out.maxTokens = capacity(value.maxTokens, MAX_TOKENS, "maxTokens");
|
|
298
|
-
if (value.contextWindow !== void 0) out.contextWindow = capacity(value.contextWindow, MAX_CONTEXT_WINDOW, "contextWindow");
|
|
299
|
-
if (value.reasoningEffort !== void 0) out.reasoningEffort = effort(value.reasoningEffort);
|
|
300
|
-
return out;
|
|
301
|
-
}
|
|
302
233
|
function parseModelSettingsMap(value) {
|
|
303
|
-
if (
|
|
234
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("\u6A21\u578B\u8BBE\u7F6E\u5FC5\u987B\u662F\u5BF9\u8C61");
|
|
304
235
|
const keys = Object.keys(value);
|
|
305
|
-
if (keys.length >
|
|
236
|
+
if (keys.length > 512) throw new Error("\u6A21\u578B\u8BBE\u7F6E\u6700\u591A\u5141\u8BB8 512 \u4E2A\u6A21\u578B");
|
|
237
|
+
const fields = /* @__PURE__ */ new Set(["enabled", "temperature", "topP", "maxTokens", "contextWindow", "reasoningEffort"]);
|
|
238
|
+
const efforts = ["none", "minimal", "low", "medium", "high", "xhigh", "ultra", "max"];
|
|
306
239
|
const out = {};
|
|
307
240
|
for (const id of keys) {
|
|
308
|
-
if (
|
|
309
|
-
if (
|
|
310
|
-
|
|
241
|
+
if (["__proto__", "constructor", "prototype"].includes(id)) throw new Error("\u6A21\u578B\u8BBE\u7F6E\u4E0D\u5141\u8BB8\u4FDD\u7559\u5B57\u6BB5\u540D");
|
|
242
|
+
if (!/^[A-Za-z0-9._:/-]{1,128}$/u.test(id)) throw new Error("\u6A21\u578B ID \u5FC5\u987B\u662F 1\u2013128 \u4F4D\u5B57\u6BCD\u3001\u6570\u5B57\u6216 . _ : / -");
|
|
243
|
+
const entry = value[id];
|
|
244
|
+
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) throw new Error("\u6BCF\u4E2A\u6A21\u578B\u7684\u8BBE\u7F6E\u5FC5\u987B\u662F\u5BF9\u8C61");
|
|
245
|
+
const settings = entry;
|
|
246
|
+
for (const field of Object.keys(settings)) {
|
|
247
|
+
if (!fields.has(field)) throw new Error("\u6A21\u578B\u8BBE\u7F6E\u542B\u6709\u4E0D\u652F\u6301\u7684\u5B57\u6BB5");
|
|
248
|
+
}
|
|
249
|
+
const parsed = {};
|
|
250
|
+
if (settings.enabled !== void 0) {
|
|
251
|
+
if (typeof settings.enabled !== "boolean") throw new Error("\u6A21\u578B\u8BBE\u7F6E\u7684 enabled \u5FC5\u987B\u662F\u5E03\u5C14\u503C");
|
|
252
|
+
parsed.enabled = settings.enabled;
|
|
253
|
+
}
|
|
254
|
+
for (const [field, max] of [["temperature", 2], ["topP", 1]]) {
|
|
255
|
+
const item = settings[field];
|
|
256
|
+
if (item === void 0) continue;
|
|
257
|
+
if (typeof item !== "number" || !Number.isFinite(item) || item < 0 || item > max) throw new Error(`\u6A21\u578B\u8BBE\u7F6E\u7684 ${field} \u5FC5\u987B\u662F 0 \u5230 ${max} \u4E4B\u95F4\u7684\u6709\u9650\u6570\u5B57`);
|
|
258
|
+
parsed[field] = item;
|
|
259
|
+
}
|
|
260
|
+
for (const [field, max] of [["maxTokens", 1e7], ["contextWindow", 1e8]]) {
|
|
261
|
+
const item = settings[field];
|
|
262
|
+
if (item === void 0) continue;
|
|
263
|
+
if (typeof item !== "number" || !Number.isSafeInteger(item) || item < 1 || item > max) throw new Error(`\u6A21\u578B\u8BBE\u7F6E\u7684 ${field} \u5FC5\u987B\u662F 1 \u5230 ${max} \u4E4B\u95F4\u7684\u6574\u6570`);
|
|
264
|
+
parsed[field] = item;
|
|
265
|
+
}
|
|
266
|
+
if (settings.reasoningEffort !== void 0) {
|
|
267
|
+
if (typeof settings.reasoningEffort !== "string" || !efforts.includes(settings.reasoningEffort)) throw new Error("\u6A21\u578B\u8BBE\u7F6E\u7684 reasoningEffort \u4E0D\u5728\u5141\u8BB8\u7684\u53D6\u503C\u5185");
|
|
268
|
+
parsed.reasoningEffort = settings.reasoningEffort;
|
|
269
|
+
}
|
|
270
|
+
if (parsed.maxTokens !== void 0 && parsed.contextWindow !== void 0 && parsed.maxTokens >= parsed.contextWindow) throw new Error("\u6A21\u578B\u8BBE\u7F6E\u7684 maxTokens \u5FC5\u987B\u5C0F\u4E8E contextWindow");
|
|
271
|
+
out[id] = parsed;
|
|
311
272
|
}
|
|
312
273
|
return out;
|
|
313
274
|
}
|
|
314
275
|
function applyModelSettings(row, settings) {
|
|
315
276
|
const { contextWindow, maxTokens } = settings ?? {};
|
|
316
277
|
if (contextWindow === void 0 && maxTokens === void 0) return { ...row };
|
|
278
|
+
if (contextWindow !== void 0) parseModelSettingsMap({ model: { contextWindow } });
|
|
279
|
+
if (maxTokens !== void 0) parseModelSettingsMap({ model: { maxTokens } });
|
|
317
280
|
return {
|
|
318
281
|
...row,
|
|
319
|
-
...contextWindow === void 0 ? {} : { contextWindow
|
|
320
|
-
...maxTokens === void 0 ? {} : { maxOutputTokens:
|
|
282
|
+
...contextWindow === void 0 ? {} : { contextWindow },
|
|
283
|
+
...maxTokens === void 0 ? {} : { maxOutputTokens: maxTokens }
|
|
321
284
|
};
|
|
322
285
|
}
|
|
323
286
|
function isModelEnabled(id, settings = {}) {
|
|
@@ -331,10 +294,10 @@ var PLAN_PROVIDER = "opendesign-corouter-plan";
|
|
|
331
294
|
var PAID_PROVIDER = "opendesign-corouter-paid";
|
|
332
295
|
var DEFAULT_BASE_URL = "https://amr-link.open-design.ai/v1";
|
|
333
296
|
var Config = Schema.object({
|
|
334
|
-
apiKeyEnv: Schema.string().pattern(/^[A-Za-z_][A-Za-z0-9_]*$/u).default("COROUTER_API_KEY").description("CoRouter API Key \u7684\u73AF\u5883\u53D8\u91CF\u6216 DSH \u51ED\u636E\u5F15\u7528\u540D").volatile(),
|
|
335
|
-
baseURL: Schema.transform(Schema.string(),
|
|
297
|
+
apiKeyEnv: Schema.string().max(128).pattern(/^[A-Za-z_][A-Za-z0-9_]*$/u).default("COROUTER_API_KEY").description("CoRouter API Key \u7684\u73AF\u5883\u53D8\u91CF\u6216 DSH \u51ED\u636E\u5F15\u7528\u540D").volatile(),
|
|
298
|
+
baseURL: Schema.transform(Schema.string(), assertBaseURL).default(DEFAULT_BASE_URL).description("CoRouter \u7F51\u5173\u5730\u5740\uFF1B\u4E0D\u7528\u4E8E\u63A7\u5236\u53F0\u767B\u5F55\u6216\u989D\u5EA6\u67E5\u8BE2").volatile(),
|
|
336
299
|
apiProtocol: Schema.union(API_PROTOCOL_IDS).default("chat-completions").description("\u63A8\u7406 API \u534F\u8BAE\uFF1B\u6A21\u578B\u53D1\u73B0\u59CB\u7EC8\u4F7F\u7528 OpenAI models \u63A5\u53E3").volatile(),
|
|
337
|
-
modelSettings: Schema.transform(Schema.dict(Schema.any()),
|
|
300
|
+
modelSettings: Schema.transform(Schema.dict(Schema.any()), parseModelSettingsMap).default({}).description("\u9010\u6A21\u578B\u542F\u7528\u72B6\u6001\u548C\u8BF7\u6C42\u53C2\u6570").volatile(),
|
|
338
301
|
useDesktopCredential: Schema.boolean().default(true).description("\u4F18\u5148\u8BFB\u53D6 OpenDesign \u684C\u9762\u7AEF\u767B\u5F55\u6001\u67E5\u8BE2\u989D\u5EA6").volatile(),
|
|
339
302
|
emptyTurnGuard: Schema.boolean().default(true).description("\u76D1\u63A7\u5957\u9910\u8D60\u9001\u6A21\u578B\u7684\u7A7A\u8F6E/\u534F\u8BAE\u6B8B\u6E23\uFF1B\u7531\u5BBF\u4E3B\u91CD\u8BD5\u7B56\u7565\u5904\u7406\uFF0C\u53EF\u80FD\u989D\u5916\u6D88\u8017\u8D60\u9001\u989D\u5EA6").volatile(),
|
|
340
303
|
quotaRefreshSeconds: Schema.natural().min(5).max(3600).default(60).description("\u989D\u5EA6\u81EA\u52A8\u5237\u65B0\u95F4\u9694\uFF08\u79D2\uFF09").volatile(),
|
|
@@ -342,6 +305,7 @@ var Config = Schema.object({
|
|
|
342
305
|
streamIdleTimeoutMs: Schema.natural().min(1e3).max(18e5).default(3e5).description("\u6D41\u5F0F\u54CD\u5E94\u65E0\u6570\u636E\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09").volatile()
|
|
343
306
|
});
|
|
344
307
|
function assertBaseURL(raw) {
|
|
308
|
+
if (raw.length > 2048) throw new Error("\u63A8\u7406 Base URL \u6700\u591A\u5141\u8BB8 2048 \u5B57\u7B26");
|
|
345
309
|
let url;
|
|
346
310
|
try {
|
|
347
311
|
url = new URL(raw);
|
|
@@ -350,7 +314,9 @@ function assertBaseURL(raw) {
|
|
|
350
314
|
}
|
|
351
315
|
if (!["https:", "http:"].includes(url.protocol) || url.username || url.password || url.search || url.hash) throw new Error("\u63A8\u7406 Base URL \u4E0D\u53EF\u5305\u542B\u51ED\u636E\u3001\u67E5\u8BE2\u4E32\u6216\u7247\u6BB5");
|
|
352
316
|
if (url.protocol === "http:" && !["localhost", "127.0.0.1", "[::1]"].includes(url.hostname)) throw new Error("\u975E\u672C\u673A\u63A8\u7406\u5730\u5740\u5FC5\u987B\u4F7F\u7528 HTTPS");
|
|
353
|
-
|
|
317
|
+
const normalized = url.href.replace(/\/+$/u, "");
|
|
318
|
+
if (normalized.length > 2048) throw new Error("\u63A8\u7406 Base URL \u6700\u591A\u5141\u8BB8 2048 \u5B57\u7B26");
|
|
319
|
+
return normalized;
|
|
354
320
|
}
|
|
355
321
|
function readConfig(config) {
|
|
356
322
|
return {
|
|
@@ -462,6 +428,35 @@ function estimateTokens(value) {
|
|
|
462
428
|
// src/stream.ts
|
|
463
429
|
import { LlmError as LlmError4, ToolCallId } from "@deepseek-ai/dsh-llm";
|
|
464
430
|
|
|
431
|
+
// src/util.ts
|
|
432
|
+
function record(value) {
|
|
433
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
434
|
+
}
|
|
435
|
+
function finite(value) {
|
|
436
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
437
|
+
}
|
|
438
|
+
function safeSecret(raw) {
|
|
439
|
+
const value = raw.trim();
|
|
440
|
+
if (!value || /[^\x20-\x7e]/u.test(value)) throw new Error("\u51ED\u636E\u4E3A\u7A7A\u6216\u542B\u6709\u4E0D\u53EF\u7528\u4E8E HTTP \u8BF7\u6C42\u5934\u7684\u5B57\u7B26");
|
|
441
|
+
return value;
|
|
442
|
+
}
|
|
443
|
+
function combinedSignal(signal, timeoutMs) {
|
|
444
|
+
const deadline = AbortSignal.timeout(timeoutMs);
|
|
445
|
+
return signal ? AbortSignal.any([signal, deadline]) : deadline;
|
|
446
|
+
}
|
|
447
|
+
function sleep(ms, signal) {
|
|
448
|
+
return new Promise((resolve) => {
|
|
449
|
+
if (signal.aborted) return resolve();
|
|
450
|
+
const done = () => {
|
|
451
|
+
clearTimeout(timer);
|
|
452
|
+
signal.removeEventListener("abort", done);
|
|
453
|
+
resolve();
|
|
454
|
+
};
|
|
455
|
+
const timer = setTimeout(done, ms);
|
|
456
|
+
signal.addEventListener("abort", done, { once: true });
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
|
|
465
460
|
// src/protocols/errors.ts
|
|
466
461
|
import {
|
|
467
462
|
ACCOUNT_QUOTA_EXCEEDED_CODE,
|
|
@@ -1130,12 +1125,12 @@ function buildMessagesRequest(ctx) {
|
|
|
1130
1125
|
if (ctx.topP !== void 0) body.top_p = ctx.topP;
|
|
1131
1126
|
if (options.stop?.length) body.stop_sequences = options.stop;
|
|
1132
1127
|
if (options.reasoningEffort !== void 0) {
|
|
1133
|
-
const
|
|
1134
|
-
if (
|
|
1135
|
-
else if (THINKING_EFFORTS.includes(
|
|
1128
|
+
const effort = String(options.reasoningEffort);
|
|
1129
|
+
if (effort === "none") body.thinking = { type: "disabled" };
|
|
1130
|
+
else if (THINKING_EFFORTS.includes(effort)) {
|
|
1136
1131
|
body.thinking = { type: "adaptive" };
|
|
1137
|
-
body.output_config = { effort
|
|
1138
|
-
} else throw new LlmError7(`Anthropic Messages \u534F\u8BAE\u4E0D\u63A5\u53D7\u601D\u8003\u6DF1\u5EA6\u300C${
|
|
1132
|
+
body.output_config = { effort };
|
|
1133
|
+
} else throw new LlmError7(`Anthropic Messages \u534F\u8BAE\u4E0D\u63A5\u53D7\u601D\u8003\u6DF1\u5EA6\u300C${effort}\u300D`, "UNSUPPORTED_OPTION");
|
|
1139
1134
|
}
|
|
1140
1135
|
return { url: messagesURL(ctx.baseURL), headers: streamHeaders(ctx.apiKey, { "anthropic-version": ANTHROPIC_VERSION }), body };
|
|
1141
1136
|
}
|
|
@@ -1330,7 +1325,7 @@ import {
|
|
|
1330
1325
|
LlmError as LlmError8,
|
|
1331
1326
|
ToolCallId as ToolCallId3
|
|
1332
1327
|
} from "@deepseek-ai/dsh-llm";
|
|
1333
|
-
var
|
|
1328
|
+
var REASONING_EFFORTS = ["none", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
1334
1329
|
function userContent(text2, images) {
|
|
1335
1330
|
if (!images.length) return text2;
|
|
1336
1331
|
return [
|
|
@@ -1390,9 +1385,9 @@ function buildResponsesRequest(ctx) {
|
|
|
1390
1385
|
body.max_output_tokens = options.maxTokens;
|
|
1391
1386
|
}
|
|
1392
1387
|
if (options.reasoningEffort !== void 0) {
|
|
1393
|
-
const
|
|
1394
|
-
if (!
|
|
1395
|
-
body.reasoning = { effort
|
|
1388
|
+
const effort = String(options.reasoningEffort);
|
|
1389
|
+
if (!REASONING_EFFORTS.includes(effort)) throw new LlmError8(`Responses \u534F\u8BAE\u4E0D\u63A5\u53D7\u601D\u8003\u6DF1\u5EA6\u300C${effort}\u300D`, "UNSUPPORTED_OPTION");
|
|
1390
|
+
body.reasoning = { effort, summary: "auto" };
|
|
1396
1391
|
}
|
|
1397
1392
|
if (options.stop?.length) throw new LlmError8("Responses \u534F\u8BAE\u4E0D\u652F\u6301 stop \u5E8F\u5217", "UNSUPPORTED_OPTION");
|
|
1398
1393
|
return { url: inferenceEndpoint(ctx.baseURL, "responses"), headers: streamHeaders(ctx.apiKey), body };
|
|
@@ -1485,6 +1480,18 @@ async function* streamResponses(body, signal, idleMs) {
|
|
|
1485
1480
|
}
|
|
1486
1481
|
out.push({ type: "tool-call-delta", index: call.index, id: ToolCallId3(call.id), ...name2, argumentsDelta: delta });
|
|
1487
1482
|
}
|
|
1483
|
+
function completeCall(call, item, out) {
|
|
1484
|
+
const args = item.arguments;
|
|
1485
|
+
let delta = "";
|
|
1486
|
+
if (args !== void 0) {
|
|
1487
|
+
if (typeof args !== "string" || !args.startsWith(call.args)) {
|
|
1488
|
+
throw new LlmError8("OpenDesign\uFF1A\u5DE5\u5177\u8C03\u7528\u5B8C\u6574\u53C2\u6570\u4E0E\u6D41\u5F0F\u589E\u91CF\u4E0D\u4E00\u81F4", "INVALID_RESPONSE");
|
|
1489
|
+
}
|
|
1490
|
+
delta = args.slice(call.args.length);
|
|
1491
|
+
call.args = args;
|
|
1492
|
+
}
|
|
1493
|
+
flushCall(call, delta, out);
|
|
1494
|
+
}
|
|
1488
1495
|
function keyFor(value, kind, outputIndex) {
|
|
1489
1496
|
const itemId = str(value.item_id) ?? (outputIndex === void 0 ? void 0 : keyByOutput.get(outputIndex));
|
|
1490
1497
|
return `${kind}:${itemId ?? `idx:${outputIndex ?? -1}`}`;
|
|
@@ -1496,10 +1503,10 @@ async function* streamResponses(body, signal, idleMs) {
|
|
|
1496
1503
|
if (item.type === "function_call") {
|
|
1497
1504
|
const itemId = str(item.id) ?? str(item.call_id);
|
|
1498
1505
|
const callId = str(item.call_id) ?? itemId;
|
|
1499
|
-
if (!callId
|
|
1500
|
-
const
|
|
1501
|
-
call
|
|
1502
|
-
|
|
1506
|
+
if (!callId) continue;
|
|
1507
|
+
const existing = [...calls].find(([, call2]) => call2.id === callId);
|
|
1508
|
+
const call = callState(existing?.[0] ?? `call:${itemId ?? callId}`, item, out);
|
|
1509
|
+
completeCall(call, item, out);
|
|
1503
1510
|
continue;
|
|
1504
1511
|
}
|
|
1505
1512
|
if (item.type === "message") {
|
|
@@ -1612,11 +1619,7 @@ async function* streamResponses(body, signal, idleMs) {
|
|
|
1612
1619
|
const outputIndex = int(value.output_index);
|
|
1613
1620
|
if (item.type === "function_call") {
|
|
1614
1621
|
const call = callState(keyFor(value, "call", outputIndex), item, out);
|
|
1615
|
-
|
|
1616
|
-
if (args !== void 0 && call.args === "") {
|
|
1617
|
-
call.args = args;
|
|
1618
|
-
flushCall(call, args, out);
|
|
1619
|
-
} else flushCall(call, "", out);
|
|
1622
|
+
completeCall(call, item, out);
|
|
1620
1623
|
} else if (item.type === "message") {
|
|
1621
1624
|
const key = `text:${str(item.id) ?? `idx:${outputIndex ?? -1}`}:0`;
|
|
1622
1625
|
if (!texts.has(key)) {
|
|
@@ -1787,13 +1790,13 @@ var CoRouterAdapter = class extends LlmAdapter {
|
|
|
1787
1790
|
if (room < 1) throw new LlmError10("\u5F53\u524D\u8F93\u5165\u6CA1\u6709\u4E3A\u8F93\u51FA\u7559\u4E0B\u4E0A\u4E0B\u6587\u7A7A\u95F4", "CONTEXT_WINDOW_EXCEEDED");
|
|
1788
1791
|
maxTokens = Math.min(capped, Math.floor(room));
|
|
1789
1792
|
}
|
|
1790
|
-
const
|
|
1791
|
-
if (
|
|
1793
|
+
const effort = options.reasoningEffort ?? (setting.reasoningEffort ? ReasoningEffortId(setting.reasoningEffort) : void 0);
|
|
1794
|
+
if (effort !== void 0 && row.reasoningEfforts && !row.reasoningEfforts.includes(effort)) throw new LlmError10("\u8BE5\u6A21\u578B\u4E0D\u652F\u6301\u6240\u9009\u601D\u8003\u6DF1\u5EA6", "UNSUPPORTED_OPTION");
|
|
1792
1795
|
const effective = {
|
|
1793
1796
|
...projectedOptions,
|
|
1794
1797
|
...(options.temperature ?? setting.temperature) === void 0 ? {} : { temperature: options.temperature ?? setting.temperature },
|
|
1795
1798
|
...maxTokens === void 0 ? {} : { maxTokens },
|
|
1796
|
-
...
|
|
1799
|
+
...effort === void 0 ? {} : { reasoningEffort: effort }
|
|
1797
1800
|
};
|
|
1798
1801
|
const protocol = protocolFor(protocolId);
|
|
1799
1802
|
const request = protocol.build({ baseURL: config.baseURL, apiKey: key, model: row, options: effective, images, ...setting.topP === void 0 ? {} : { topP: setting.topP } });
|
|
@@ -1859,7 +1862,7 @@ var DISCOVERY_TIMEOUT_MS = 2e4;
|
|
|
1859
1862
|
var MAX_DISCOVERY_BODY_BYTES = 2 * 1024 * 1024;
|
|
1860
1863
|
var MAX_MODELS = 512;
|
|
1861
1864
|
var MAX_MODEL_NAME_LENGTH = 128;
|
|
1862
|
-
var
|
|
1865
|
+
var MODEL_ID = /^[A-Za-z0-9._:/-]{1,128}$/u;
|
|
1863
1866
|
var MEDIA_MODEL_ID = /^(?:gpt-image-|nano-banana-|seedream-|imagen-|veo-|doubao-seedance-|sora-)/u;
|
|
1864
1867
|
var MESSAGES2 = {
|
|
1865
1868
|
url: "\u6A21\u578B\u53D1\u73B0\u5730\u5740\u65E0\u6548\uFF1A\u5FC5\u987B\u662F\u7EDD\u5BF9 HTTP(S) \u5730\u5740\uFF0C\u4E14\u4E0D\u542B\u51ED\u636E\u3001\u67E5\u8BE2\u4E32\u6216\u7247\u6BB5",
|
|
@@ -1933,7 +1936,7 @@ function normalize(body) {
|
|
|
1933
1936
|
const seen = /* @__PURE__ */ new Set();
|
|
1934
1937
|
const rows = [];
|
|
1935
1938
|
for (const value of body.data) {
|
|
1936
|
-
if (!record(value) || typeof value.id !== "string" || !
|
|
1939
|
+
if (!record(value) || typeof value.id !== "string" || !MODEL_ID.test(value.id) || ["__proto__", "constructor", "prototype"].includes(value.id)) continue;
|
|
1937
1940
|
if (MEDIA_MODEL_ID.test(value.id) || seen.has(value.id)) continue;
|
|
1938
1941
|
seen.add(value.id);
|
|
1939
1942
|
const known = findModel(value.id);
|
|
@@ -2249,7 +2252,7 @@ var ConsoleLogin = class {
|
|
|
2249
2252
|
job.status.jobId = job.id;
|
|
2250
2253
|
job.status.startedAt = job.startedAt;
|
|
2251
2254
|
this.job = job;
|
|
2252
|
-
job.timer = setTimeout(() => this.
|
|
2255
|
+
job.timer = setTimeout(() => this.requestCancellation(job, "\u767B\u5F55\u5DF2\u8D85\u8FC7\u4E94\u5206\u949F\uFF0C\u8BF7\u91CD\u65B0\u5F00\u59CB"), this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
2253
2256
|
job.timer.unref?.();
|
|
2254
2257
|
job.capturedAt = Promise.resolve().then(() => this.callbacks.capture(job.expectedRevision)).then((captured) => {
|
|
2255
2258
|
job.captured = captured;
|
|
@@ -2269,25 +2272,31 @@ var ConsoleLogin = class {
|
|
|
2269
2272
|
cancel(request) {
|
|
2270
2273
|
const job = this.job;
|
|
2271
2274
|
if (!job || job.status.jobId !== request.jobId) return this.status();
|
|
2272
|
-
|
|
2273
|
-
job.cancelRequested = true;
|
|
2274
|
-
job.controller.abort();
|
|
2275
|
-
return this.status();
|
|
2276
|
-
}
|
|
2277
|
-
if (ACTIVE.has(job.status.state)) this.finish(job, "cancelled", "\u767B\u5F55\u5DF2\u53D6\u6D88\uFF0C\u672A\u4FDD\u5B58 Cookie");
|
|
2275
|
+
this.requestCancellation(job, "\u767B\u5F55\u5DF2\u53D6\u6D88\uFF0C\u672A\u4FDD\u5B58 Cookie");
|
|
2278
2276
|
return this.status();
|
|
2279
2277
|
}
|
|
2280
2278
|
/** Plugin teardown: abort the attempt and close the browser. */
|
|
2281
2279
|
dispose() {
|
|
2282
2280
|
const job = this.job;
|
|
2283
|
-
if (job
|
|
2284
|
-
job.cancelRequested = true;
|
|
2285
|
-
job.controller.abort();
|
|
2286
|
-
} else if (job && ACTIVE.has(job.status.state)) {
|
|
2287
|
-
this.finish(job, "cancelled", "\u670D\u52A1\u5DF2\u5378\u8F7D\uFF0C\u767B\u5F55\u5DF2\u53D6\u6D88");
|
|
2288
|
-
}
|
|
2281
|
+
if (job) this.requestCancellation(job, "\u670D\u52A1\u5DF2\u5378\u8F7D\uFF0C\u767B\u5F55\u5DF2\u53D6\u6D88");
|
|
2289
2282
|
this.disposed = true;
|
|
2290
2283
|
}
|
|
2284
|
+
/** Every cancellation source must let an in-flight atomic store decide the final outcome. */
|
|
2285
|
+
requestCancellation(job, message) {
|
|
2286
|
+
if (this.job !== job || !ACTIVE.has(job.status.state)) return;
|
|
2287
|
+
if (!job.committing) {
|
|
2288
|
+
this.finish(job, "cancelled", message);
|
|
2289
|
+
return;
|
|
2290
|
+
}
|
|
2291
|
+
if (!job.cancelRequested) {
|
|
2292
|
+
job.cancellationMessage = message;
|
|
2293
|
+
job.status.message = "\u6B63\u5728\u786E\u8BA4\u4F1A\u8BDD\u4FDD\u5B58\u7ED3\u679C";
|
|
2294
|
+
}
|
|
2295
|
+
job.cancelRequested = true;
|
|
2296
|
+
this.stopTimer(job);
|
|
2297
|
+
job.controller.abort();
|
|
2298
|
+
void this.close(job);
|
|
2299
|
+
}
|
|
2291
2300
|
alive(job) {
|
|
2292
2301
|
if (this.disposed || this.job !== job) return false;
|
|
2293
2302
|
if (job.controller.signal.aborted && !job.committing) return false;
|
|
@@ -2325,7 +2334,7 @@ var ConsoleLogin = class {
|
|
|
2325
2334
|
const browser = await launch(job.controller.signal);
|
|
2326
2335
|
if (!browser) return null;
|
|
2327
2336
|
job.browser = browser;
|
|
2328
|
-
browser.on?.("disconnected", () => this.
|
|
2337
|
+
browser.on?.("disconnected", () => this.requestCancellation(job, "\u767B\u5F55\u7A97\u53E3\u5DF2\u5173\u95ED\uFF0C\u672A\u4FDD\u5B58 Cookie"));
|
|
2329
2338
|
return browser;
|
|
2330
2339
|
}
|
|
2331
2340
|
async run(job) {
|
|
@@ -2342,7 +2351,7 @@ var ConsoleLogin = class {
|
|
|
2342
2351
|
return;
|
|
2343
2352
|
}
|
|
2344
2353
|
const page = await context.newPage();
|
|
2345
|
-
page.on?.("close", () => this.
|
|
2354
|
+
page.on?.("close", () => this.requestCancellation(job, "\u767B\u5F55\u7A97\u53E3\u5DF2\u5173\u95ED\uFF0C\u672A\u4FDD\u5B58 Cookie"));
|
|
2346
2355
|
if (!this.alive(job)) {
|
|
2347
2356
|
await this.close(job);
|
|
2348
2357
|
return;
|
|
@@ -2416,7 +2425,7 @@ var ConsoleLogin = class {
|
|
|
2416
2425
|
} catch (error) {
|
|
2417
2426
|
job.committing = false;
|
|
2418
2427
|
if (job.cancelRequested || job.controller.signal.aborted) {
|
|
2419
|
-
this.finish(job, "cancelled", "\u767B\u5F55\u5DF2\u53D6\u6D88\uFF0C\u672A\u4FDD\u5B58 Cookie");
|
|
2428
|
+
this.finish(job, "cancelled", job.cancellationMessage ?? "\u767B\u5F55\u5DF2\u53D6\u6D88\uFF0C\u672A\u4FDD\u5B58 Cookie");
|
|
2420
2429
|
return "cancelled";
|
|
2421
2430
|
}
|
|
2422
2431
|
if (FATAL_COMMIT_CODES.has(errorCode(error) ?? "")) {
|
|
@@ -2611,6 +2620,7 @@ async function readDesktopQuota(session, signal, runner = runVela, fetcher = fet
|
|
|
2611
2620
|
consoleJson(`${session.apiUrl}/api/v1/wallet/balance`, session, deadline, fetcher),
|
|
2612
2621
|
cli
|
|
2613
2622
|
]);
|
|
2623
|
+
if (wallet.status === "rejected" && wallet.reason instanceof ConsoleError && wallet.reason.kind === "auth") throw wallet.reason;
|
|
2614
2624
|
const walletBalances = wallet.status === "fulfilled" ? normalizeBalances(wallet.value) : {};
|
|
2615
2625
|
const cliBalances = funding.status === "fulfilled" && "balance" in funding.value ? normalizeBalances({ balanceUsd: funding.value.balance }) : {};
|
|
2616
2626
|
const windows = funding.status === "fulfilled" ? funding.value.windows : [];
|
|
@@ -2623,7 +2633,7 @@ async function readDesktopQuota(session, signal, runner = runVela, fetcher = fet
|
|
|
2623
2633
|
}
|
|
2624
2634
|
const tier = (funding.status === "fulfilled" ? funding.value.tier : void 0) ?? session.plan;
|
|
2625
2635
|
const updatedAt = funding.status === "fulfilled" && funding.value.generatedAt || (/* @__PURE__ */ new Date()).toISOString();
|
|
2626
|
-
const note = noSubscription ? "\u684C\u9762\u767B\u5F55\u6001\u663E\u793A\u8BE5\u8D26\u53F7\u6CA1\u6709 Design Plan \u8BA2\u9605\uFF1B\u672A\u8BFB\u5230\u7684\u5206\u6C60\u4FDD\u6301\u672A\u77E5\u3002\
|
|
2636
|
+
const note = noSubscription ? "\u684C\u9762\u767B\u5F55\u6001\u663E\u793A\u8BE5\u8D26\u53F7\u6CA1\u6709 Design Plan \u8BA2\u9605\uFF1B\u672A\u8BFB\u5230\u7684\u5206\u6C60\u4FDD\u6301\u672A\u77E5\u3002\u53EF\u5728\u8FDE\u63A5\u9875\u5B8C\u6210\u72EC\u7ACB\u767B\u5F55\uFF0C\u63D2\u4EF6\u4F1A\u4F18\u5148\u91C7\u7528\u53EF\u8BFB\u53D6\u7684\u5B8C\u6574\u989D\u5EA6\u3002" : !windows.length ? "\u684C\u9762\u767B\u5F55\u6001\u672A\u8FD4\u56DE\u5957\u9910\u7A97\u53E3\uFF1B\u5DF2\u8BFB\u5230\u7684\u94B1\u5305\u4F59\u989D\u7167\u5E38\u663E\u793A\uFF0C\u672A\u8BFB\u5230\u7684\u5206\u6C60\u4FDD\u6301\u672A\u77E5\u3002\u53EF\u5728\u8FDE\u63A5\u9875\u5B8C\u6210\u72EC\u7ACB\u767B\u5F55\uFF0C\u63D2\u4EF6\u4F1A\u4F18\u5148\u91C7\u7528\u53EF\u8BFB\u53D6\u7684\u5B8C\u6574\u989D\u5EA6\u3002" : "\u684C\u9762\u767B\u5F55\u6001\u90E8\u5206\u63A5\u53E3\u6743\u9650\u53D7\u9650\uFF1B\u672A\u8BFB\u5230\u7684\u5206\u6C60\u663E\u793A\u672A\u77E5\u3002\u53EF\u5728\u8FDE\u63A5\u9875\u5B8C\u6210\u72EC\u7ACB\u767B\u5F55\uFF0C\u63D2\u4EF6\u4F1A\u4F18\u5148\u91C7\u7528\u53EF\u8BFB\u53D6\u7684\u5B8C\u6574\u989D\u5EA6\u3002";
|
|
2627
2637
|
return {
|
|
2628
2638
|
state: "partial",
|
|
2629
2639
|
source: "desktop",
|
|
@@ -2649,7 +2659,7 @@ var MAX_WINDOWS = 64;
|
|
|
2649
2659
|
var MAX_API_KEY = 16384;
|
|
2650
2660
|
var HTTP_ASCII = /^[\x21-\x7e]+$/u;
|
|
2651
2661
|
var ENV_REF = /^[A-Za-z_][A-Za-z0-9_]*$/u;
|
|
2652
|
-
var
|
|
2662
|
+
var MODEL_ID2 = /^[A-Za-z0-9._:/-]{1,128}$/u;
|
|
2653
2663
|
var LOGIN_PHASES = ["idle", "launching", "waiting", "verifying", "success", "cancelled", "error"];
|
|
2654
2664
|
var QUOTA_STATES = ["ok", "partial", "need-login", "error"];
|
|
2655
2665
|
var SESSION_SOURCES = ["desktop", "login", "environment"];
|
|
@@ -2663,7 +2673,7 @@ function isoTime(value, label) {
|
|
|
2663
2673
|
if (!Number.isFinite(Date.parse(time))) throw new Error(`${label} \u5FC5\u987B\u662F ISO \u65F6\u95F4\u5B57\u7B26\u4E32`);
|
|
2664
2674
|
return time;
|
|
2665
2675
|
}
|
|
2666
|
-
function
|
|
2676
|
+
function flag(value, label) {
|
|
2667
2677
|
if (typeof value !== "boolean") throw new Error(`${label} \u5FC5\u987B\u662F\u5E03\u5C14\u503C`);
|
|
2668
2678
|
return value;
|
|
2669
2679
|
}
|
|
@@ -2719,11 +2729,11 @@ function parseQuotaSnapshot(value) {
|
|
|
2719
2729
|
...value.subscriptionPeriodStart === void 0 ? {} : { subscriptionPeriodStart: isoTime(value.subscriptionPeriodStart, "\u8BA2\u9605\u5468\u671F\u5F00\u59CB\u65F6\u95F4") },
|
|
2720
2730
|
...value.subscriptionPeriodEnd === void 0 ? {} : { subscriptionPeriodEnd: isoTime(value.subscriptionPeriodEnd, "\u8BA2\u9605\u5468\u671F\u7ED3\u675F\u65F6\u95F4") },
|
|
2721
2731
|
...value.nextRefreshAt === void 0 ? {} : { nextRefreshAt: isoTime(value.nextRefreshAt, "\u4E0B\u6B21\u81EA\u52A8\u5237\u65B0\u65F6\u95F4") },
|
|
2722
|
-
...value.stale === void 0 ? {} : { stale:
|
|
2732
|
+
...value.stale === void 0 ? {} : { stale: flag(value.stale, "\u5386\u53F2\u989D\u5EA6\u8BFB\u6570") },
|
|
2723
2733
|
...value.refreshFailures === void 0 ? {} : { refreshFailures: count(value.refreshFailures, "\u8FDE\u7EED\u5237\u65B0\u5931\u8D25\u6B21\u6570") },
|
|
2724
|
-
...value.autoRefreshPaused === void 0 ? {} : { autoRefreshPaused:
|
|
2734
|
+
...value.autoRefreshPaused === void 0 ? {} : { autoRefreshPaused: flag(value.autoRefreshPaused, "\u81EA\u52A8\u5237\u65B0\u6682\u505C\u72B6\u6001") },
|
|
2725
2735
|
...value.tier === void 0 ? {} : { tier: text(value.tier, "\u5957\u9910\u540D", MAX_TIER) },
|
|
2726
|
-
...value.eligible === void 0 ? {} : { eligible:
|
|
2736
|
+
...value.eligible === void 0 ? {} : { eligible: flag(value.eligible, "\u5957\u9910\u8D44\u683C") },
|
|
2727
2737
|
windows: windows.map(parseQuotaWindow),
|
|
2728
2738
|
balances: {
|
|
2729
2739
|
...balances.subscriptionUsd === void 0 ? {} : { subscriptionUsd: amount(balances.subscriptionUsd, "\u8BA2\u9605\u4F59\u989D") },
|
|
@@ -2748,12 +2758,12 @@ function parseLoginState(value) {
|
|
|
2748
2758
|
function parseStatusModel(value) {
|
|
2749
2759
|
if (!record(value)) throw new Error("\u6A21\u578B\u6761\u76EE\u5FC5\u987B\u662F\u5BF9\u8C61");
|
|
2750
2760
|
const id = text(value.id, "\u6A21\u578B id", 128);
|
|
2751
|
-
if (!
|
|
2761
|
+
if (!MODEL_ID2.test(id)) throw new Error("\u6A21\u578B id \u542B\u4E0D\u5141\u8BB8\u7684\u5B57\u7B26");
|
|
2752
2762
|
return {
|
|
2753
2763
|
id,
|
|
2754
2764
|
name: text(value.name, "\u6A21\u578B\u540D", 128),
|
|
2755
2765
|
group: member(value.group, MODEL_GROUPS, "\u6A21\u578B\u5206\u7EC4"),
|
|
2756
|
-
...value.enabled === void 0 ? {} : { enabled:
|
|
2766
|
+
...value.enabled === void 0 ? {} : { enabled: flag(value.enabled, "\u6A21\u578B\u542F\u7528\u72B6\u6001") },
|
|
2757
2767
|
...value.contextWindow === void 0 ? {} : { contextWindow: positiveInteger(value.contextWindow, "\u4E0A\u4E0B\u6587\u9884\u7B97", 1e8) },
|
|
2758
2768
|
...value.maxOutputTokens === void 0 ? {} : { maxOutputTokens: positiveInteger(value.maxOutputTokens, "\u6700\u5927\u8F93\u51FA", 1e7) },
|
|
2759
2769
|
...value.reasoningEfforts === void 0 ? {} : { reasoningEfforts: parseEfforts(value.reasoningEfforts) }
|
|
@@ -2764,8 +2774,8 @@ function parseStatusConfig(value) {
|
|
|
2764
2774
|
const apiKeyEnv = text(value.apiKeyEnv, "\u51ED\u636E\u5F15\u7528\u540D", MAX_ENV_REF);
|
|
2765
2775
|
if (!ENV_REF.test(apiKeyEnv)) throw new Error("\u51ED\u636E\u5F15\u7528\u540D\u5FC5\u987B\u662F\u5408\u6CD5\u6807\u8BC6\u7B26");
|
|
2766
2776
|
return {
|
|
2767
|
-
emptyTurnGuard:
|
|
2768
|
-
useDesktopCredential:
|
|
2777
|
+
emptyTurnGuard: flag(value.emptyTurnGuard, "\u7A7A\u8F6E\u4FDD\u62A4\u5F00\u5173"),
|
|
2778
|
+
useDesktopCredential: flag(value.useDesktopCredential, "\u684C\u9762\u767B\u5F55\u6001\u5F00\u5173"),
|
|
2769
2779
|
baseURL: text(value.baseURL, "\u63A8\u7406\u5730\u5740", MAX_BASE_URL),
|
|
2770
2780
|
apiKeyEnv,
|
|
2771
2781
|
...value.apiProtocol === void 0 ? {} : { apiProtocol: member(value.apiProtocol, API_PROTOCOL_IDS, "\u63A8\u7406\u534F\u8BAE") },
|
|
@@ -2787,7 +2797,7 @@ function parseStatus(value) {
|
|
|
2787
2797
|
}
|
|
2788
2798
|
return {
|
|
2789
2799
|
revision: text(value.revision, "\u914D\u7F6E\u7248\u672C", MAX_REVISION),
|
|
2790
|
-
apiKeyConfigured:
|
|
2800
|
+
apiKeyConfigured: flag(value.apiKeyConfigured, "\u51ED\u636E\u662F\u5426\u5C31\u7EEA"),
|
|
2791
2801
|
...value.sessionSource === void 0 ? {} : { sessionSource: member(value.sessionSource, SESSION_SOURCES, "\u767B\u5F55\u6001\u6765\u6E90") },
|
|
2792
2802
|
quota: parseQuotaSnapshot(value.quota),
|
|
2793
2803
|
login: parseLoginState(value.login),
|