dsh-opendesign-corouter 0.1.1 → 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/README.md +6 -4
- package/lib/adapter.d.ts +3 -0
- package/lib/client.d.ts +118 -12
- package/lib/client.js +904 -137
- package/lib/config.d.ts +11 -0
- package/lib/generated/typert.host.js +83 -5
- package/lib/generated/typert.remote-client.d.ts +2 -0
- package/lib/generated/typert.remote-client.js +83 -5
- package/lib/index.d.ts +16 -0
- package/lib/index.js +1531 -192
- package/lib/index.js.map +4 -4
- package/lib/login.d.ts +2 -0
- package/lib/model-discovery.d.ts +39 -0
- package/lib/model-settings.d.ts +45 -0
- package/lib/protocol-options.d.ts +11 -0
- package/lib/protocols/chat-completions.d.ts +10 -0
- package/lib/protocols/errors.d.ts +45 -0
- package/lib/protocols/headers.d.ts +14 -0
- package/lib/protocols/index.d.ts +17 -0
- package/lib/protocols/messages.d.ts +29 -0
- package/lib/protocols/parts.d.ts +22 -0
- package/lib/protocols/responses.d.ts +32 -0
- package/lib/protocols/sse.d.ts +25 -0
- package/lib/protocols/types.d.ts +39 -0
- package/lib/protocols/usage.d.ts +34 -0
- package/lib/quota.d.ts +21 -1
- package/lib/remote.d.ts +14 -0
- package/lib/stream.d.ts +11 -3
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -31,13 +31,27 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
// src/client.ts
|
|
32
32
|
var client_exports = {};
|
|
33
33
|
__export(client_exports, {
|
|
34
|
+
Advanced: () => Advanced,
|
|
35
|
+
ModelRow: () => ModelRow,
|
|
36
|
+
Models: () => Models,
|
|
37
|
+
Overview: () => Overview,
|
|
34
38
|
QuotaView: () => QuotaView,
|
|
35
39
|
SettingsPage: () => SettingsPage,
|
|
36
40
|
apply: () => apply,
|
|
41
|
+
formatTime: () => formatTime,
|
|
42
|
+
formatTokens: () => formatTokens,
|
|
37
43
|
formatUsd: () => formatUsd,
|
|
38
44
|
inject: () => inject,
|
|
45
|
+
modelEnabled: () => modelEnabled,
|
|
46
|
+
modelSettingsEntry: () => modelSettingsEntry,
|
|
39
47
|
name: () => name,
|
|
40
|
-
|
|
48
|
+
nextWindowResetAt: () => nextWindowResetAt,
|
|
49
|
+
normaliseQuotaRefreshSeconds: () => normaliseQuotaRefreshSeconds,
|
|
50
|
+
parseNumberInput: () => parseNumberInput,
|
|
51
|
+
protocolEndpoint: () => protocolEndpoint,
|
|
52
|
+
quotaAutoRefresh: () => quotaAutoRefresh,
|
|
53
|
+
tabAfter: () => tabAfter,
|
|
54
|
+
writeModelSettings: () => writeModelSettings
|
|
41
55
|
});
|
|
42
56
|
module.exports = __toCommonJS(client_exports);
|
|
43
57
|
var React = __toESM(require("react"), 1);
|
|
@@ -19911,6 +19925,66 @@ function record2(value) {
|
|
|
19911
19925
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
19912
19926
|
}
|
|
19913
19927
|
|
|
19928
|
+
// src/protocol-options.ts
|
|
19929
|
+
var API_PROTOCOL_IDS = ["chat-completions", "responses", "messages"];
|
|
19930
|
+
function openAiBaseURL(baseURL) {
|
|
19931
|
+
const base = baseURL.replace(/\/+$/u, "");
|
|
19932
|
+
return new URL(base).pathname === "/" ? `${base}/v1` : base;
|
|
19933
|
+
}
|
|
19934
|
+
function inferenceEndpoint(baseURL, protocol) {
|
|
19935
|
+
const suffix = protocol === "responses" ? "/responses" : protocol === "messages" ? "/messages" : "/chat/completions";
|
|
19936
|
+
return baseURL.trim() === "" ? suffix : `${openAiBaseURL(baseURL.trim())}${suffix}`;
|
|
19937
|
+
}
|
|
19938
|
+
var API_PROTOCOL_OPTIONS = [
|
|
19939
|
+
{ id: "chat-completions", name: "OpenAI Chat Completions", description: "\u4F7F\u7528 Chat Completions \u8BF7\u6C42\u4E0E\u6D41\u5F0F\u54CD\u5E94\u3002" },
|
|
19940
|
+
{ id: "responses", name: "OpenAI Responses", description: "\u4F7F\u7528 Responses \u8BF7\u6C42\u4E0E\u6D41\u5F0F\u54CD\u5E94\u3002" },
|
|
19941
|
+
{ id: "messages", name: "Anthropic Messages", description: "\u4F7F\u7528 Messages \u8BF7\u6C42\u4E0E\u6D41\u5F0F\u54CD\u5E94\u3002" }
|
|
19942
|
+
];
|
|
19943
|
+
|
|
19944
|
+
// src/model-settings.ts
|
|
19945
|
+
function parseModelSettingsMap(value) {
|
|
19946
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("\u6A21\u578B\u8BBE\u7F6E\u5FC5\u987B\u662F\u5BF9\u8C61");
|
|
19947
|
+
const keys = Object.keys(value);
|
|
19948
|
+
if (keys.length > 512) throw new Error("\u6A21\u578B\u8BBE\u7F6E\u6700\u591A\u5141\u8BB8 512 \u4E2A\u6A21\u578B");
|
|
19949
|
+
const fields = /* @__PURE__ */ new Set(["enabled", "temperature", "topP", "maxTokens", "contextWindow", "reasoningEffort"]);
|
|
19950
|
+
const efforts = ["none", "minimal", "low", "medium", "high", "xhigh", "ultra", "max"];
|
|
19951
|
+
const out = {};
|
|
19952
|
+
for (const id of keys) {
|
|
19953
|
+
if (["__proto__", "constructor", "prototype"].includes(id)) throw new Error("\u6A21\u578B\u8BBE\u7F6E\u4E0D\u5141\u8BB8\u4FDD\u7559\u5B57\u6BB5\u540D");
|
|
19954
|
+
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 . _ : / -");
|
|
19955
|
+
const entry = value[id];
|
|
19956
|
+
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) throw new Error("\u6BCF\u4E2A\u6A21\u578B\u7684\u8BBE\u7F6E\u5FC5\u987B\u662F\u5BF9\u8C61");
|
|
19957
|
+
const settings = entry;
|
|
19958
|
+
for (const field of Object.keys(settings)) {
|
|
19959
|
+
if (!fields.has(field)) throw new Error("\u6A21\u578B\u8BBE\u7F6E\u542B\u6709\u4E0D\u652F\u6301\u7684\u5B57\u6BB5");
|
|
19960
|
+
}
|
|
19961
|
+
const parsed = {};
|
|
19962
|
+
if (settings.enabled !== void 0) {
|
|
19963
|
+
if (typeof settings.enabled !== "boolean") throw new Error("\u6A21\u578B\u8BBE\u7F6E\u7684 enabled \u5FC5\u987B\u662F\u5E03\u5C14\u503C");
|
|
19964
|
+
parsed.enabled = settings.enabled;
|
|
19965
|
+
}
|
|
19966
|
+
for (const [field, max] of [["temperature", 2], ["topP", 1]]) {
|
|
19967
|
+
const item = settings[field];
|
|
19968
|
+
if (item === void 0) continue;
|
|
19969
|
+
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`);
|
|
19970
|
+
parsed[field] = item;
|
|
19971
|
+
}
|
|
19972
|
+
for (const [field, max] of [["maxTokens", 1e7], ["contextWindow", 1e8]]) {
|
|
19973
|
+
const item = settings[field];
|
|
19974
|
+
if (item === void 0) continue;
|
|
19975
|
+
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`);
|
|
19976
|
+
parsed[field] = item;
|
|
19977
|
+
}
|
|
19978
|
+
if (settings.reasoningEffort !== void 0) {
|
|
19979
|
+
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");
|
|
19980
|
+
parsed.reasoningEffort = settings.reasoningEffort;
|
|
19981
|
+
}
|
|
19982
|
+
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");
|
|
19983
|
+
out[id] = parsed;
|
|
19984
|
+
}
|
|
19985
|
+
return out;
|
|
19986
|
+
}
|
|
19987
|
+
|
|
19914
19988
|
// src/remote.ts
|
|
19915
19989
|
var MAX_REVISION = 256;
|
|
19916
19990
|
var MAX_JOB_ID = 128;
|
|
@@ -19924,7 +19998,7 @@ var MAX_WINDOWS = 64;
|
|
|
19924
19998
|
var MAX_API_KEY = 16384;
|
|
19925
19999
|
var HTTP_ASCII = /^[\x21-\x7e]+$/u;
|
|
19926
20000
|
var ENV_REF = /^[A-Za-z_][A-Za-z0-9_]*$/u;
|
|
19927
|
-
var MODEL_ID = /^[A-Za-z0-9._
|
|
20001
|
+
var MODEL_ID = /^[A-Za-z0-9._:/-]{1,128}$/u;
|
|
19928
20002
|
var LOGIN_PHASES = ["idle", "launching", "waiting", "verifying", "success", "cancelled", "error"];
|
|
19929
20003
|
var QUOTA_STATES = ["ok", "partial", "need-login", "error"];
|
|
19930
20004
|
var SESSION_SOURCES = ["desktop", "login", "environment"];
|
|
@@ -19950,6 +20024,15 @@ function amount(value, label, negative = false) {
|
|
|
19950
20024
|
if (typeof value !== "number" || !Number.isFinite(value) || !negative && value < 0) throw new Error(`${label} \u5FC5\u987B\u662F${negative ? "" : "\u975E\u8D1F"}\u6709\u9650\u6570\u5B57`);
|
|
19951
20025
|
return value;
|
|
19952
20026
|
}
|
|
20027
|
+
function positiveInteger(value, label, max) {
|
|
20028
|
+
const result = count(value, label);
|
|
20029
|
+
if (result === 0 || result > max) throw new Error(`${label} \u8D85\u51FA\u8303\u56F4`);
|
|
20030
|
+
return result;
|
|
20031
|
+
}
|
|
20032
|
+
function parseEfforts(value) {
|
|
20033
|
+
if (!Array.isArray(value) || value.length > 16) throw new Error("\u6A21\u578B\u601D\u8003\u6863\u4F4D\u683C\u5F0F\u65E0\u6548");
|
|
20034
|
+
return value.map((item) => text(item, "\u601D\u8003\u6863\u4F4D", 32));
|
|
20035
|
+
}
|
|
19953
20036
|
function member(value, allowed, label) {
|
|
19954
20037
|
const hit = allowed.find((candidate) => candidate === value);
|
|
19955
20038
|
if (hit === void 0) throw new Error(`${label} \u4E0D\u5728\u5141\u8BB8\u7684\u53D6\u503C\u5185`);
|
|
@@ -19967,7 +20050,9 @@ function parseQuotaWindow(value) {
|
|
|
19967
20050
|
limit,
|
|
19968
20051
|
...value.remaining === void 0 ? {} : { remaining: amount(value.remaining, "\u5269\u4F59\u989D\u5EA6") },
|
|
19969
20052
|
percent: Math.min(100, Math.max(0, amount(value.percent, "\u5DF2\u7528\u767E\u5206\u6BD4"))),
|
|
19970
|
-
...value.resetsAt === void 0 ? {} : { resetsAt: isoTime(value.resetsAt, "\u989D\u5EA6\u91CD\u7F6E\u65F6\u95F4") }
|
|
20053
|
+
...value.resetsAt === void 0 ? {} : { resetsAt: isoTime(value.resetsAt, "\u989D\u5EA6\u91CD\u7F6E\u65F6\u95F4") },
|
|
20054
|
+
...value.windowStart === void 0 ? {} : { windowStart: isoTime(value.windowStart, "\u989D\u5EA6\u7A97\u53E3\u5F00\u59CB\u65F6\u95F4") },
|
|
20055
|
+
...value.resetMode === void 0 ? {} : { resetMode: text(value.resetMode, "\u989D\u5EA6\u5237\u65B0\u65B9\u5F0F", 128) }
|
|
19971
20056
|
};
|
|
19972
20057
|
}
|
|
19973
20058
|
function parseQuotaSnapshot(value) {
|
|
@@ -19980,6 +20065,12 @@ function parseQuotaSnapshot(value) {
|
|
|
19980
20065
|
state: member(value.state, QUOTA_STATES, "\u989D\u5EA6\u72B6\u6001"),
|
|
19981
20066
|
...value.source === void 0 ? {} : { source: member(value.source, SESSION_SOURCES, "\u989D\u5EA6\u6765\u6E90") },
|
|
19982
20067
|
updatedAt: isoTime(value.updatedAt, "\u989D\u5EA6\u66F4\u65B0\u65F6\u95F4"),
|
|
20068
|
+
...value.subscriptionPeriodStart === void 0 ? {} : { subscriptionPeriodStart: isoTime(value.subscriptionPeriodStart, "\u8BA2\u9605\u5468\u671F\u5F00\u59CB\u65F6\u95F4") },
|
|
20069
|
+
...value.subscriptionPeriodEnd === void 0 ? {} : { subscriptionPeriodEnd: isoTime(value.subscriptionPeriodEnd, "\u8BA2\u9605\u5468\u671F\u7ED3\u675F\u65F6\u95F4") },
|
|
20070
|
+
...value.nextRefreshAt === void 0 ? {} : { nextRefreshAt: isoTime(value.nextRefreshAt, "\u4E0B\u6B21\u81EA\u52A8\u5237\u65B0\u65F6\u95F4") },
|
|
20071
|
+
...value.stale === void 0 ? {} : { stale: flag(value.stale, "\u5386\u53F2\u989D\u5EA6\u8BFB\u6570") },
|
|
20072
|
+
...value.refreshFailures === void 0 ? {} : { refreshFailures: count(value.refreshFailures, "\u8FDE\u7EED\u5237\u65B0\u5931\u8D25\u6B21\u6570") },
|
|
20073
|
+
...value.autoRefreshPaused === void 0 ? {} : { autoRefreshPaused: flag(value.autoRefreshPaused, "\u81EA\u52A8\u5237\u65B0\u6682\u505C\u72B6\u6001") },
|
|
19983
20074
|
...value.tier === void 0 ? {} : { tier: text(value.tier, "\u5957\u9910\u540D", MAX_TIER) },
|
|
19984
20075
|
...value.eligible === void 0 ? {} : { eligible: flag(value.eligible, "\u5957\u9910\u8D44\u683C") },
|
|
19985
20076
|
windows: windows.map(parseQuotaWindow),
|
|
@@ -20010,7 +20101,11 @@ function parseStatusModel(value) {
|
|
|
20010
20101
|
return {
|
|
20011
20102
|
id,
|
|
20012
20103
|
name: text(value.name, "\u6A21\u578B\u540D", 128),
|
|
20013
|
-
group: member(value.group, MODEL_GROUPS, "\u6A21\u578B\u5206\u7EC4")
|
|
20104
|
+
group: member(value.group, MODEL_GROUPS, "\u6A21\u578B\u5206\u7EC4"),
|
|
20105
|
+
...value.enabled === void 0 ? {} : { enabled: flag(value.enabled, "\u6A21\u578B\u542F\u7528\u72B6\u6001") },
|
|
20106
|
+
...value.contextWindow === void 0 ? {} : { contextWindow: positiveInteger(value.contextWindow, "\u4E0A\u4E0B\u6587\u9884\u7B97", 1e8) },
|
|
20107
|
+
...value.maxOutputTokens === void 0 ? {} : { maxOutputTokens: positiveInteger(value.maxOutputTokens, "\u6700\u5927\u8F93\u51FA", 1e7) },
|
|
20108
|
+
...value.reasoningEfforts === void 0 ? {} : { reasoningEfforts: parseEfforts(value.reasoningEfforts) }
|
|
20014
20109
|
};
|
|
20015
20110
|
}
|
|
20016
20111
|
function parseStatusConfig(value) {
|
|
@@ -20021,7 +20116,12 @@ function parseStatusConfig(value) {
|
|
|
20021
20116
|
emptyTurnGuard: flag(value.emptyTurnGuard, "\u7A7A\u8F6E\u4FDD\u62A4\u5F00\u5173"),
|
|
20022
20117
|
useDesktopCredential: flag(value.useDesktopCredential, "\u684C\u9762\u767B\u5F55\u6001\u5F00\u5173"),
|
|
20023
20118
|
baseURL: text(value.baseURL, "\u63A8\u7406\u5730\u5740", MAX_BASE_URL),
|
|
20024
|
-
apiKeyEnv
|
|
20119
|
+
apiKeyEnv,
|
|
20120
|
+
...value.apiProtocol === void 0 ? {} : { apiProtocol: member(value.apiProtocol, API_PROTOCOL_IDS, "\u63A8\u7406\u534F\u8BAE") },
|
|
20121
|
+
...value.modelSettings === void 0 ? {} : { modelSettings: parseModelSettingsMap(value.modelSettings) },
|
|
20122
|
+
...value.requestTimeoutMs === void 0 ? {} : { requestTimeoutMs: positiveInteger(value.requestTimeoutMs, "\u8BF7\u6C42\u8D85\u65F6", 36e5) },
|
|
20123
|
+
...value.streamIdleTimeoutMs === void 0 ? {} : { streamIdleTimeoutMs: positiveInteger(value.streamIdleTimeoutMs, "\u6D41\u7A7A\u95F2\u8D85\u65F6", 18e5) },
|
|
20124
|
+
...value.quotaRefreshSeconds === void 0 ? {} : { quotaRefreshSeconds: positiveInteger(value.quotaRefreshSeconds, "\u81EA\u52A8\u5237\u65B0\u95F4\u9694", 3600) }
|
|
20025
20125
|
};
|
|
20026
20126
|
}
|
|
20027
20127
|
function parseStatus(value) {
|
|
@@ -20042,7 +20142,10 @@ function parseStatus(value) {
|
|
|
20042
20142
|
login: parseLoginState(value.login),
|
|
20043
20143
|
config: parseStatusConfig(value.config),
|
|
20044
20144
|
guardedTurns: count(value.guardedTurns, "\u5DF2\u62E6\u622A\u7A7A\u8F6E\u6570"),
|
|
20045
|
-
models: parsed
|
|
20145
|
+
models: parsed,
|
|
20146
|
+
...value.modelsSource === void 0 ? {} : { modelsSource: member(value.modelsSource, ["builtin", "openai"], "\u6A21\u578B\u76EE\u5F55\u6765\u6E90") },
|
|
20147
|
+
...value.modelsUpdatedAt === void 0 ? {} : { modelsUpdatedAt: isoTime(value.modelsUpdatedAt, "\u6A21\u578B\u66F4\u65B0\u65F6\u95F4") },
|
|
20148
|
+
...value.modelsError === void 0 ? {} : { modelsError: text(value.modelsError, "\u6A21\u578B\u66F4\u65B0\u63D0\u793A", MAX_MESSAGE) }
|
|
20046
20149
|
};
|
|
20047
20150
|
}
|
|
20048
20151
|
function parseStartLoginRequest(value) {
|
|
@@ -20071,7 +20174,9 @@ var CancelLoginRequestCodec = { mode: "strict", typeSymbol: "dsh-opendesign-coro
|
|
|
20071
20174
|
var SaveApiKeyRequestCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#SaveApiKeyRequest", create: () => external_exports.unknown().transform((value) => parseSaveApiKeyRequest(value)) };
|
|
20072
20175
|
var TYPERT_REMOTE = createTypertRemoteInfo({ package: "dsh-opendesign-corouter", methods: {
|
|
20073
20176
|
"openDesignCoRouter/status": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [], result: StatusCodec },
|
|
20177
|
+
"openDesignCoRouter/refreshModels": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [], result: StatusCodec },
|
|
20074
20178
|
"openDesignCoRouter/refreshQuota": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [], result: QuotaSnapshotCodec },
|
|
20179
|
+
"openDesignCoRouter/refreshQuotaNow": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [], result: QuotaSnapshotCodec },
|
|
20075
20180
|
"openDesignCoRouter/startLogin": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [{ name: "input", source: "json", codec: StartLoginRequestCodec, strictCodec: StartLoginRequestCodec }], result: LoginStateCodec },
|
|
20076
20181
|
"openDesignCoRouter/loginStatus": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [], result: LoginStateCodec },
|
|
20077
20182
|
"openDesignCoRouter/cancelLogin": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [{ name: "input", source: "json", codec: CancelLoginRequestCodec, strictCodec: CancelLoginRequestCodec }], result: LoginStateCodec },
|
|
@@ -20089,6 +20194,17 @@ var TABS = [
|
|
|
20089
20194
|
{ id: "connection", label: "\u8FDE\u63A5\u4E0E\u767B\u5F55" },
|
|
20090
20195
|
{ id: "advanced", label: "\u9AD8\u7EA7" }
|
|
20091
20196
|
];
|
|
20197
|
+
var DEFAULT_QUOTA_REFRESH_SECONDS = 60;
|
|
20198
|
+
var MIN_QUOTA_REFRESH_SECONDS = 5;
|
|
20199
|
+
var MAX_QUOTA_REFRESH_SECONDS = 3600;
|
|
20200
|
+
var DEFAULT_REQUEST_TIMEOUT_MS = 18e5;
|
|
20201
|
+
var MIN_REQUEST_TIMEOUT_MS = 1e3;
|
|
20202
|
+
var MAX_REQUEST_TIMEOUT_MS = 36e5;
|
|
20203
|
+
var DEFAULT_STREAM_IDLE_TIMEOUT_MS = 3e5;
|
|
20204
|
+
var MIN_STREAM_IDLE_TIMEOUT_MS = 1e3;
|
|
20205
|
+
var MAX_STREAM_IDLE_TIMEOUT_MS = 18e5;
|
|
20206
|
+
var MAX_OUTPUT_TOKENS = 1e7;
|
|
20207
|
+
var MAX_CONTEXT_WINDOW = 1e8;
|
|
20092
20208
|
var GENERIC_ERROR = "\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002";
|
|
20093
20209
|
var LOGIN_LABELS = {
|
|
20094
20210
|
idle: "\u5C1A\u672A\u5F00\u59CB\u72EC\u7ACB\u767B\u5F55",
|
|
@@ -20114,13 +20230,18 @@ function installStyles() {
|
|
|
20114
20230
|
.odc-intro{margin:6px 0 18px!important;color:var(--dsw-alias-label-secondary,inherit);font-size:12px}.odc-tabs{display:flex;gap:4px;overflow-x:auto;margin:0 0 16px;padding:0 0 8px;border-bottom:1px solid var(--dsw-alias-border-l4,transparent)}
|
|
20115
20231
|
.odc-tab{flex:none;border:1px solid transparent;border-radius:8px;padding:7px 13px;background:transparent;color:var(--dsw-alias-label-secondary,inherit);font:inherit;cursor:pointer}.odc-tab:hover{background:var(--dsw-alias-bg-layer-1,transparent)}.odc-tab[aria-selected=true]{color:var(--dsw-alias-label-primary,inherit);border-color:var(--dsw-alias-border-l3,transparent);background:var(--dsw-alias-bg-layer-1,transparent)}
|
|
20116
20232
|
.odc-panel{display:grid;gap:14px}.odc-card{min-width:0;padding:15px;border:1px solid var(--dsw-alias-border-l4,transparent);border-radius:12px;background:var(--dsw-alias-bg-layer-1,transparent)}.odc-card>p{margin-top:6px}.odc-card-head,.odc-row{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.odc-card-head{margin-bottom:12px}
|
|
20117
|
-
.odc-quota-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}.odc-metric{display:grid;align-content:start;gap:5px;min-height:96px}.odc-metric-value{font-size:20px;font-weight:650;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.odc-
|
|
20118
|
-
.odc-
|
|
20233
|
+
.odc-quota-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}.odc-metric{display:grid;align-content:start;gap:5px;min-height:96px}.odc-metric-value{font-size:20px;font-weight:650;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.odc-metric-value.odc-metric-text{font-size:13px;font-weight:600;line-height:1.55}.odc-quota-grid+.odc-quota-grid{margin-top:10px}
|
|
20234
|
+
.odc-label,.odc-hint,.odc-meta{color:var(--dsw-alias-label-secondary,inherit);font-size:11px;line-height:1.6}.odc-meta{margin-top:10px!important}.odc-window{display:grid;gap:7px;margin-top:10px}.odc-window progress{width:100%;height:7px;accent-color:var(--dsw-alias-brand-primary,Highlight)}
|
|
20235
|
+
.odc-button{display:inline-flex;align-items:center;justify-content:center;min-height:32px;padding:6px 12px;border:1px solid var(--dsw-alias-border-l3,transparent);border-radius:8px;background:var(--dsw-alias-bg-layer-2,transparent);color:var(--dsw-alias-label-primary,inherit);font:inherit;font-size:12px;cursor:pointer}.odc-button:hover:not(:disabled){border-color:var(--dsw-alias-brand-primary,Highlight)}.odc-button-primary{background:var(--dsw-alias-button-primary-fill,var(--dsw-alias-brand-primary,Highlight));color:var(--dsw-alias-label-primary-foreground,HighlightText);border-color:transparent}.odc-button-primary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover,var(--dsw-alias-brand-primary,Highlight))}.odc-button:disabled{opacity:.55;cursor:not-allowed}.odc-button-small{min-height:26px;padding:3px 9px;font-size:11px}.odc-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
|
20119
20236
|
.odc-notice{padding:9px 11px;border-radius:8px;background:var(--dsw-alias-bg-layer-2,transparent);font-size:12px;line-height:1.6}.odc-notice[data-kind=error]{color:var(--dsw-alias-state-error-primary,inherit);color:color-mix(in srgb,var(--dsw-alias-state-error-primary,CanvasText) 85%,var(--dsw-alias-label-primary,CanvasText))}
|
|
20120
|
-
.odc-model-groups{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.odc-model-list{display:grid;gap:6px;margin:10px 0 0;padding:0;list-style:none}.odc-model-item{padding:9px 10px;border-radius:8px;background:var(--dsw-alias-bg-layer-2,transparent);min-width:0}.odc-model-item strong,.odc-model-item code{display:block;overflow-wrap:anywhere}.odc-model-item code{margin-top:2px;color:var(--dsw-alias-label-secondary,inherit);font-size:11px}.odc-model-count{color:var(--dsw-alias-label-secondary,inherit);font-size:11px;font-weight:400}
|
|
20121
|
-
.odc-
|
|
20122
|
-
.odc-
|
|
20123
|
-
.odc-
|
|
20237
|
+
.odc-model-groups{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:12px}.odc-model-list{display:grid;gap:6px;margin:10px 0 0;padding:0;list-style:none}.odc-model-item{padding:9px 10px;border-radius:8px;background:var(--dsw-alias-bg-layer-2,transparent);min-width:0}.odc-model-head{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;flex-wrap:wrap}.odc-model-switch{min-width:0;flex:1 1 190px}.odc-model-item strong,.odc-model-item code{display:block;overflow-wrap:anywhere}.odc-model-item strong{font-size:12px;font-weight:600}.odc-model-item code{margin-top:2px;color:var(--dsw-alias-label-secondary,inherit);font-size:11px}.odc-model-meta{margin-top:6px!important;color:var(--dsw-alias-label-secondary,inherit);font-size:11px;overflow-wrap:anywhere}.odc-model-count{color:var(--dsw-alias-label-secondary,inherit);font-size:11px;font-weight:400}.odc-chip{display:inline-flex;align-items:center;padding:1px 7px;border:1px solid var(--dsw-alias-border-l3,transparent);border-radius:999px;color:var(--dsw-alias-label-secondary,inherit);font-size:10px;line-height:1.6}
|
|
20238
|
+
.odc-model-details{margin-top:8px}.odc-model-details>summary{cursor:pointer;color:var(--dsw-alias-label-secondary,inherit);font-size:11px;line-height:1.7}.odc-model-editor{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2px 10px;margin-top:8px}
|
|
20239
|
+
.odc-field{display:grid;gap:6px;margin-top:14px}.odc-field-compact{margin-top:8px}.odc-field label,.odc-switch-text{font-size:12px;font-weight:550}.odc-input{width:100%;min-width:0;min-height:34px;padding:7px 9px;border:1px solid var(--dsw-alias-border-l3,transparent);border-radius:8px;background:var(--dsw-alias-bg-layer-2,transparent);color:var(--dsw-alias-label-primary,inherit);font:inherit;font-size:12px}.odc-field-compact .odc-input{min-height:30px;padding:5px 8px;font-size:11px}.odc-input::placeholder{color:var(--dsw-alias-label-secondary,inherit);opacity:1}.odc-input:disabled{opacity:.55}
|
|
20240
|
+
.odc-switch{display:flex;align-items:center;gap:12px;min-height:44px;padding:6px 2px;cursor:pointer}.odc-switch input{appearance:auto;width:20px;height:20px;flex:none;margin:0;cursor:inherit;accent-color:var(--dsw-alias-brand-primary,Highlight)}.odc-switch>span{display:grid;gap:4px;min-width:0}.odc-switch:has(input:disabled){cursor:not-allowed;opacity:.6}.odc-divider{height:1px;border:0;background:var(--dsw-alias-border-l4,transparent);margin:2px 0}.odc-link{color:var(--dsw-alias-brand-primary,inherit);text-underline-offset:3px}
|
|
20241
|
+
.odc-readonly{display:grid;gap:10px;margin-top:14px;padding:10px 12px;border-radius:8px;background:var(--dsw-alias-bg-layer-2,transparent)}.odc-code{display:block;min-width:0;color:var(--dsw-alias-label-primary,inherit);font-family:ui-monospace,'Cascadia Mono',Consolas,monospace;font-size:11px;line-height:1.6;overflow-wrap:anywhere}
|
|
20242
|
+
.odc-timing{padding:12px 0;border-top:1px solid var(--dsw-alias-border-l4,transparent)}.odc-timing .odc-metric{min-height:0}.odc-settings>.odc-notice{margin-bottom:14px}.odc-model-details>summary{min-height:32px;padding:6px 0}
|
|
20243
|
+
.odc-field-error{color:var(--dsw-alias-state-error-primary,inherit);color:color-mix(in srgb,var(--dsw-alias-state-error-primary,CanvasText) 85%,var(--dsw-alias-label-primary,CanvasText))}
|
|
20244
|
+
.odc-settings :focus-visible{outline:2px solid var(--dsw-alias-brand-primary,Highlight);outline-offset:3px}@media(max-width:680px){.odc-quota-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.odc-model-groups{grid-template-columns:1fr}.odc-model-editor{grid-template-columns:1fr}}@media(max-width:380px){.odc-quota-grid{grid-template-columns:1fr}.odc-card{padding:12px}}
|
|
20124
20245
|
`;
|
|
20125
20246
|
document.head.append(style);
|
|
20126
20247
|
return () => style.remove();
|
|
@@ -20218,19 +20339,65 @@ function formatTime(value) {
|
|
|
20218
20339
|
const date5 = new Date(value);
|
|
20219
20340
|
return Number.isFinite(date5.getTime()) ? date5.toLocaleString("zh-CN", { hour12: false }) : "\u2014";
|
|
20220
20341
|
}
|
|
20342
|
+
function formatTokens(value) {
|
|
20343
|
+
if (value === void 0 || !Number.isFinite(value)) return "\u2014";
|
|
20344
|
+
return new Intl.NumberFormat("zh-CN").format(value);
|
|
20345
|
+
}
|
|
20221
20346
|
function windowLabel(seconds) {
|
|
20222
20347
|
if (seconds % 86400 === 0) return `${seconds / 86400} \u5929\u8D60\u9001\u7A97\u53E3`;
|
|
20223
20348
|
if (seconds % 3600 === 0) return `${seconds / 3600} \u5C0F\u65F6\u8D60\u9001\u7A97\u53E3`;
|
|
20224
20349
|
if (seconds % 60 === 0) return `${seconds / 60} \u5206\u949F\u8D60\u9001\u7A97\u53E3`;
|
|
20225
20350
|
return `${seconds} \u79D2\u8D60\u9001\u7A97\u53E3`;
|
|
20226
20351
|
}
|
|
20227
|
-
function
|
|
20352
|
+
function nextWindowResetAt(windows, now) {
|
|
20353
|
+
let earliest;
|
|
20354
|
+
let earliestMs = Number.POSITIVE_INFINITY;
|
|
20355
|
+
for (const window of windows) {
|
|
20356
|
+
if (window.resetsAt === void 0) continue;
|
|
20357
|
+
const ms = Date.parse(window.resetsAt);
|
|
20358
|
+
if (!Number.isFinite(ms) || ms <= now || ms >= earliestMs) continue;
|
|
20359
|
+
earliest = window.resetsAt;
|
|
20360
|
+
earliestMs = ms;
|
|
20361
|
+
}
|
|
20362
|
+
return earliest;
|
|
20363
|
+
}
|
|
20364
|
+
var SOURCE_LABELS = {
|
|
20365
|
+
desktop: "\u684C\u9762\u767B\u5F55\u6001",
|
|
20366
|
+
login: "\u72EC\u7ACB\u767B\u5F55",
|
|
20367
|
+
environment: "\u73AF\u5883\u51ED\u636E"
|
|
20368
|
+
};
|
|
20369
|
+
var RESET_MODE_LABELS = {
|
|
20370
|
+
activity_triggered: "\u6309\u4F7F\u7528\u89E6\u53D1",
|
|
20371
|
+
anchored_recurring: "\u56FA\u5B9A\u5468\u671F"
|
|
20372
|
+
};
|
|
20373
|
+
function QuotaView({ quota, nextAutoRefreshAt, refreshIntervalSeconds }) {
|
|
20228
20374
|
if (quota === void 0) return h("p", { className: "odc-hint", role: "status" }, "\u6B63\u5728\u8BFB\u53D6\u989D\u5EA6\u2026");
|
|
20229
20375
|
const metrics = [
|
|
20230
20376
|
{ label: "\u5957\u9910\u4F59\u989D", value: formatUsd(quota.balances.subscriptionUsd), hint: "\u8BA2\u9605\u5269\u4F59\u53EF\u7528\u91D1\u989D" },
|
|
20231
20377
|
{ label: "\u5145\u503C / \u8D60\u9001\u91D1\u989D", value: formatUsd(quota.balances.rechargeUsd), hint: "\u5145\u503C\u4E0E\u8D60\u9001\u7684\u53EF\u7528\u91D1\u989D" },
|
|
20232
20378
|
{ label: "\u603B\u989D\u5EA6", value: formatUsd(quota.balances.totalUsd), hint: "\u94B1\u5305\u5F53\u524D\u53EF\u7528\u603B\u989D" }
|
|
20233
20379
|
];
|
|
20380
|
+
const timing = [
|
|
20381
|
+
{
|
|
20382
|
+
label: "\u8BA2\u9605\u8D26\u671F\u7ED3\u675F",
|
|
20383
|
+
value: formatTime(quota.subscriptionPeriodEnd),
|
|
20384
|
+
hint: `\u8D26\u671F\u5F00\u59CB\uFF1A${formatTime(quota.subscriptionPeriodStart)}`
|
|
20385
|
+
},
|
|
20386
|
+
{
|
|
20387
|
+
label: "\u4E0B\u6B21\u989D\u5EA6\u6062\u590D",
|
|
20388
|
+
value: formatTime(nextWindowResetAt(quota.windows, Date.now())),
|
|
20389
|
+
hint: "\u6700\u65E9\u6062\u590D\u7684\u8D60\u9001\u7A97\u53E3\uFF1B\u4E0D\u4EE3\u8868\u94B1\u5305\u5230\u8D26\u65F6\u95F4"
|
|
20390
|
+
},
|
|
20391
|
+
{
|
|
20392
|
+
label: "\u4E0B\u6B21\u81EA\u52A8\u5237\u65B0",
|
|
20393
|
+
value: formatTime(quota.state === "need-login" || quota.autoRefreshPaused ? void 0 : nextAutoRefreshAt),
|
|
20394
|
+
hint: quota.state === "need-login" ? "\u767B\u5F55\u540E\u81EA\u52A8\u5237\u65B0" : quota.autoRefreshPaused ? "\u8FDE\u7EED\u5931\u8D25\uFF0C\u81EA\u52A8\u91CD\u8BD5\u5DF2\u6682\u505C\uFF1B\u70B9\u51FB\u5237\u65B0\u989D\u5EA6\u91CD\u8BD5" : refreshIntervalSeconds === void 0 ? "\u672A\u542F\u7528\u81EA\u52A8\u5237\u65B0" : quota.refreshFailures ? `\u5237\u65B0\u5931\u8D25 ${quota.refreshFailures} \u6B21\uFF0C\u6B63\u5728\u5EF6\u8FDF\u91CD\u8BD5` : `\u6BCF ${refreshIntervalSeconds} \u79D2\u81EA\u52A8\u5237\u65B0`
|
|
20395
|
+
}
|
|
20396
|
+
];
|
|
20397
|
+
const tierLine = [
|
|
20398
|
+
quota.tier === void 0 ? void 0 : `\u5F53\u524D\u5957\u9910\uFF1A${quota.tier}`,
|
|
20399
|
+
quota.eligible === void 0 ? void 0 : `\u5957\u9910\u8D44\u683C\uFF1A${quota.eligible ? "\u5DF2\u5F00\u901A" : "\u672A\u5F00\u901A"}`
|
|
20400
|
+
].filter((value) => value !== void 0).join(" \xB7 ");
|
|
20234
20401
|
return h(
|
|
20235
20402
|
React.Fragment,
|
|
20236
20403
|
null,
|
|
@@ -20240,10 +20407,25 @@ function QuotaView({ quota }) {
|
|
|
20240
20407
|
h(
|
|
20241
20408
|
"div",
|
|
20242
20409
|
{ className: "odc-card-head" },
|
|
20243
|
-
h(
|
|
20244
|
-
|
|
20410
|
+
h(
|
|
20411
|
+
"div",
|
|
20412
|
+
null,
|
|
20413
|
+
h("h3", null, "\u5957\u9910\u8D60\u9001\u7A97\u53E3"),
|
|
20414
|
+
tierLine === "" ? null : h("p", { className: "odc-hint" }, tierLine)
|
|
20415
|
+
),
|
|
20416
|
+
h(
|
|
20417
|
+
"div",
|
|
20418
|
+
{ className: "odc-actions" },
|
|
20419
|
+
h("span", { className: "odc-label" }, QUOTA_LABELS[quota.state]),
|
|
20420
|
+
quota.stale ? h("span", { className: "odc-chip" }, "\u4E0A\u6B21\u6210\u529F\u8BFB\u6570") : null
|
|
20421
|
+
)
|
|
20245
20422
|
),
|
|
20246
|
-
quota.windows.length === 0 ? h("p", { className: "odc-
|
|
20423
|
+
quota.windows.length === 0 ? quota.eligible === false ? h("p", { className: "odc-hint", role: "status" }, "\u5F53\u524D\u8D26\u53F7\u672A\u5F00\u901A Design Plan\uFF0C\u6CA1\u6709\u8D60\u9001\u989D\u5EA6\u7A97\u53E3\u3002") : h(
|
|
20424
|
+
React.Fragment,
|
|
20425
|
+
null,
|
|
20426
|
+
h("p", { className: "odc-metric-value" }, "\u2014"),
|
|
20427
|
+
h("p", { className: "odc-hint" }, "\u989D\u5EA6\u7A97\u53E3\u6682\u4E0D\u53EF\u786E\u8BA4\uFF1B\u4E0D\u6309 0 \u586B\u5145\u3002")
|
|
20428
|
+
) : quota.windows.map((window, index) => h(
|
|
20247
20429
|
"div",
|
|
20248
20430
|
{ className: "odc-window", key: `${window.durationSeconds}-${index}` },
|
|
20249
20431
|
h(
|
|
@@ -20253,7 +20435,7 @@ function QuotaView({ quota }) {
|
|
|
20253
20435
|
h("span", { className: "odc-label" }, `\u5DF2\u7528 ${window.percent.toFixed(1)}% \xB7 \u5269\u4F59 ${window.remaining ?? "\u2014"}`)
|
|
20254
20436
|
),
|
|
20255
20437
|
h("progress", { max: 100, value: window.percent, "aria-label": `${windowLabel(window.durationSeconds)}\u5DF2\u7528\u989D\u5EA6` }),
|
|
20256
|
-
h("span", { className: "odc-meta" }, `\u5DF2\u7528 ${window.used} / \u4E0A\u9650 ${window.limit} \xB7 \
|
|
20438
|
+
h("span", { className: "odc-meta" }, `\u5DF2\u7528 ${window.used} / \u4E0A\u9650 ${window.limit} \xB7 \u6062\u590D ${formatTime(window.resetsAt)}${window.windowStart === void 0 ? "" : ` \xB7 \u7A97\u53E3\u5F00\u59CB ${formatTime(window.windowStart)}`}${window.resetMode === void 0 ? "" : ` \xB7 \u91CD\u7F6E\u65B9\u5F0F ${RESET_MODE_LABELS[window.resetMode] ?? window.resetMode}`}`)
|
|
20257
20439
|
))
|
|
20258
20440
|
),
|
|
20259
20441
|
h("div", { className: "odc-quota-grid" }, metrics.map((metric) => h(
|
|
@@ -20263,28 +20445,316 @@ function QuotaView({ quota }) {
|
|
|
20263
20445
|
h("strong", { className: "odc-metric-value" }, metric.value),
|
|
20264
20446
|
h("span", { className: "odc-hint" }, metric.hint)
|
|
20265
20447
|
))),
|
|
20266
|
-
h("
|
|
20448
|
+
h("div", { className: "odc-quota-grid odc-timing", "aria-label": "\u989D\u5EA6\u65F6\u95F4\u5B89\u6392" }, timing.map((metric) => h(
|
|
20449
|
+
"div",
|
|
20450
|
+
{ className: "odc-metric", key: metric.label },
|
|
20451
|
+
h("span", { className: "odc-label" }, metric.label),
|
|
20452
|
+
h("strong", { className: "odc-metric-value odc-metric-text" }, metric.value),
|
|
20453
|
+
h("span", { className: "odc-hint" }, metric.hint)
|
|
20454
|
+
))),
|
|
20455
|
+
h("p", { className: "odc-meta" }, `\u66F4\u65B0\u4E8E ${formatTime(quota.updatedAt)}${quota.source !== void 0 ? ` \xB7 \u6765\u6E90\uFF1A${SOURCE_LABELS[quota.source]}\uFF08\u53EA\u8BFB\u5C55\u793A\uFF09` : ""}`),
|
|
20456
|
+
h(
|
|
20457
|
+
"details",
|
|
20458
|
+
{ className: "odc-model-details" },
|
|
20459
|
+
h("summary", null, "\u5982\u4F55\u7406\u89E3\u8FD9\u4E9B\u989D\u5EA6\uFF1F"),
|
|
20460
|
+
h("p", { className: "odc-hint" }, "\u8D60\u9001\u7A97\u53E3\u4E0E\u94B1\u5305\u4F59\u989D\u5206\u522B\u8BA1\u91CF\u3002\u5957\u9910\u4F59\u989D\u6765\u81EA\u8BA2\u9605\uFF0C\u5145\u503C / \u8D60\u9001\u91D1\u989D\u6765\u81EA\u94B1\u5305\uFF1B\u603B\u989D\u5EA6\u662F\u94B1\u5305\u5F53\u524D\u53EF\u7528\u603B\u989D\u3002\u5B9E\u9645\u6263\u6B3E\u7531\u670D\u52A1\u7AEF\u51B3\u5B9A\u3002\u989D\u5EA6\u6570\u636E\u53EA\u8BFB\u5C55\u793A\uFF0C\u672A\u77E5\u91D1\u989D\u663E\u793A \u2014\u3002")
|
|
20461
|
+
),
|
|
20267
20462
|
quota.note !== void 0 ? h("p", { className: "odc-notice", "data-kind": quota.state === "error" ? "error" : "status", role: quota.state === "error" ? "alert" : "status" }, quota.note) : null
|
|
20268
20463
|
);
|
|
20269
20464
|
}
|
|
20270
|
-
function
|
|
20465
|
+
function writeModelSettings(map2, id, next) {
|
|
20466
|
+
const out = { ...map2 ?? {} };
|
|
20467
|
+
if (next === void 0) {
|
|
20468
|
+
delete out[id];
|
|
20469
|
+
return out;
|
|
20470
|
+
}
|
|
20471
|
+
const entry = {};
|
|
20472
|
+
if (next.enabled !== void 0) entry.enabled = next.enabled;
|
|
20473
|
+
if (next.temperature !== void 0) entry.temperature = next.temperature;
|
|
20474
|
+
if (next.topP !== void 0) entry.topP = next.topP;
|
|
20475
|
+
if (next.maxTokens !== void 0) entry.maxTokens = next.maxTokens;
|
|
20476
|
+
if (next.contextWindow !== void 0) entry.contextWindow = next.contextWindow;
|
|
20477
|
+
if (next.reasoningEffort !== void 0) entry.reasoningEffort = next.reasoningEffort;
|
|
20478
|
+
if (Object.keys(entry).length === 0) delete out[id];
|
|
20479
|
+
else out[id] = entry;
|
|
20480
|
+
return out;
|
|
20481
|
+
}
|
|
20482
|
+
function modelSettingsEntry(map2, id) {
|
|
20483
|
+
return { ...map2?.[id] ?? {} };
|
|
20484
|
+
}
|
|
20485
|
+
function modelEnabled(model, settings, authoritative = true) {
|
|
20486
|
+
if (settings?.enabled !== void 0) return settings.enabled;
|
|
20487
|
+
if (authoritative) return true;
|
|
20488
|
+
return model.enabled !== false;
|
|
20489
|
+
}
|
|
20490
|
+
var DECIMAL_TEXT = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/u;
|
|
20491
|
+
function parseNumberInput(raw, spec) {
|
|
20492
|
+
const text2 = raw.trim();
|
|
20493
|
+
if (text2 === "") {
|
|
20494
|
+
return spec.allowEmpty === true ? { ok: true, value: void 0 } : { ok: false, message: `${spec.label}\u4E0D\u80FD\u4E3A\u7A7A\u3002` };
|
|
20495
|
+
}
|
|
20496
|
+
const integral = spec.integer === true;
|
|
20497
|
+
const value = DECIMAL_TEXT.test(text2) ? Number(text2) : Number.NaN;
|
|
20498
|
+
if (!DECIMAL_TEXT.test(text2) || !Number.isFinite(value) || value < spec.min || value > spec.max || integral && !Number.isSafeInteger(value)) {
|
|
20499
|
+
return {
|
|
20500
|
+
ok: false,
|
|
20501
|
+
message: `${spec.label}\u9700\u4E3A ${spec.min} \u5230 ${spec.max} \u4E4B\u95F4\u7684${integral ? "\u6574\u6570" : "\u6570\u5B57"}${spec.allowEmpty === true ? "\uFF0C\u6216\u7559\u7A7A\u7EE7\u627F\u9ED8\u8BA4\u3002" : "\u3002"}`
|
|
20502
|
+
};
|
|
20503
|
+
}
|
|
20504
|
+
return { ok: true, value };
|
|
20505
|
+
}
|
|
20506
|
+
function protocolEndpoint(baseURL, protocol) {
|
|
20507
|
+
return inferenceEndpoint(baseURL, protocol);
|
|
20508
|
+
}
|
|
20509
|
+
function normaliseQuotaRefreshSeconds(value) {
|
|
20510
|
+
if (value === void 0 || !Number.isSafeInteger(value) || value < MIN_QUOTA_REFRESH_SECONDS || value > MAX_QUOTA_REFRESH_SECONDS) return void 0;
|
|
20511
|
+
return value;
|
|
20512
|
+
}
|
|
20513
|
+
function quotaAutoRefresh(secondsRaw, nextRefreshAt, now, backingOff = false) {
|
|
20514
|
+
const intervalSeconds = normaliseQuotaRefreshSeconds(secondsRaw);
|
|
20515
|
+
if (intervalSeconds === void 0) return void 0;
|
|
20516
|
+
const intervalMs = intervalSeconds * 1e3;
|
|
20517
|
+
const planMs = nextRefreshAt === void 0 ? Number.NaN : Date.parse(nextRefreshAt);
|
|
20518
|
+
const planDelay = Number.isFinite(planMs) ? planMs - now : Number.POSITIVE_INFINITY;
|
|
20519
|
+
const plannedDelay = Math.max(1e3, Math.floor(planDelay) + 500);
|
|
20520
|
+
const delayMs = Number.isFinite(planDelay) && planDelay > 0 ? backingOff ? plannedDelay : Math.min(intervalMs, plannedDelay) : intervalMs;
|
|
20521
|
+
return { delayMs, at: new Date(now + delayMs).toISOString(), intervalSeconds };
|
|
20522
|
+
}
|
|
20523
|
+
function Overview({ status, busy, onRefresh, nextAutoRefreshAt, refreshIntervalSeconds, onConnection }) {
|
|
20271
20524
|
return h(
|
|
20272
20525
|
React.Fragment,
|
|
20273
20526
|
null,
|
|
20527
|
+
status !== void 0 && (status.apiKeyConfigured === false || status.quota.state === "need-login") ? h(
|
|
20528
|
+
"section",
|
|
20529
|
+
{ className: "odc-card odc-row", "aria-label": "\u8FDE\u63A5\u5F85\u5B8C\u6210" },
|
|
20530
|
+
h(
|
|
20531
|
+
"div",
|
|
20532
|
+
null,
|
|
20533
|
+
h("h3", null, "\u5148\u5B8C\u6210\u8FDE\u63A5"),
|
|
20534
|
+
h("p", { className: "odc-hint" }, status.apiKeyConfigured === false ? "\u63A8\u7406\u5C1A\u7F3A API Key\uFF1B\u989D\u5EA6\u767B\u5F55\u4E0E\u63A8\u7406\u51ED\u636E\u5206\u522B\u914D\u7F6E\u3002" : "API Key \u5DF2\u914D\u7F6E\uFF1B\u767B\u5F55\u540E\u5373\u53EF\u67E5\u770B\u8D26\u53F7\u989D\u5EA6\u3002")
|
|
20535
|
+
),
|
|
20536
|
+
onConnection === void 0 ? null : h("button", { type: "button", className: "odc-button odc-button-primary", onClick: onConnection }, "\u524D\u5F80\u8FDE\u63A5\u4E0E\u767B\u5F55")
|
|
20537
|
+
) : null,
|
|
20274
20538
|
h(
|
|
20275
20539
|
"div",
|
|
20276
20540
|
{ className: "odc-card-head" },
|
|
20277
20541
|
h("div", null, h("h3", null, "\u989D\u5EA6\u6982\u89C8"), h("p", { className: "odc-hint" }, "\u5957\u9910\u7A97\u53E3\u4E0E\u94B1\u5305\u4F59\u989D\u5206\u5F00\u8BA1\u91CF\uFF1B\u672A\u77E5\u6570\u636E\u4E0D\u505A\u63A8\u7B97\u3002")),
|
|
20278
20542
|
h("button", { className: "odc-button", type: "button", disabled: busy, onClick: onRefresh }, busy ? "\u5237\u65B0\u4E2D\u2026" : "\u5237\u65B0\u989D\u5EA6")
|
|
20279
20543
|
),
|
|
20280
|
-
h(QuotaView, { quota: status?.quota })
|
|
20544
|
+
h(QuotaView, { quota: status?.quota, nextAutoRefreshAt, refreshIntervalSeconds })
|
|
20281
20545
|
);
|
|
20282
20546
|
}
|
|
20283
|
-
|
|
20547
|
+
var NUMERIC_FIELDS = {
|
|
20548
|
+
temperature: { label: "\u6E29\u5EA6", hint: "0\u20132\uFF1B\u7559\u7A7A\u7EE7\u627F\u9ED8\u8BA4\u3002", min: 0, max: 2 },
|
|
20549
|
+
topP: { label: "Top P", hint: "0\u20131\uFF1B\u7559\u7A7A\u7EE7\u627F\u9ED8\u8BA4\u3002", min: 0, max: 1 },
|
|
20550
|
+
maxTokens: { label: "\u6700\u5927\u8F93\u51FA\uFF08tokens\uFF09", hint: "\u6B63\u6574\u6570\uFF1B\u7559\u7A7A\u7EE7\u627F\u76EE\u5F55\u9ED8\u8BA4\u3002", min: 1, max: MAX_OUTPUT_TOKENS, integer: true },
|
|
20551
|
+
contextWindow: { label: "\u4E0A\u4E0B\u6587\u9884\u7B97\uFF08tokens\uFF09", hint: "\u6B63\u6574\u6570\uFF1B\u7559\u7A7A\u7EE7\u627F\u76EE\u5F55\u9ED8\u8BA4\u3002", min: 1, max: MAX_CONTEXT_WINDOW, integer: true }
|
|
20552
|
+
};
|
|
20553
|
+
var NUMERIC_ORDER = ["temperature", "topP", "maxTokens", "contextWindow"];
|
|
20554
|
+
function OptionalNumberField({ id, field, value, disabled, resetToken, onSave }) {
|
|
20555
|
+
const spec = NUMERIC_FIELDS[field];
|
|
20556
|
+
const mounted = useMounted();
|
|
20557
|
+
const [draft, setDraft] = React.useState(void 0);
|
|
20558
|
+
const [error62, setError] = React.useState(void 0);
|
|
20559
|
+
React.useEffect(() => {
|
|
20560
|
+
setDraft(void 0);
|
|
20561
|
+
setError(void 0);
|
|
20562
|
+
}, [value, resetToken]);
|
|
20563
|
+
const commit = async () => {
|
|
20564
|
+
if (disabled || draft === void 0) return;
|
|
20565
|
+
const result = parseNumberInput(draft, {
|
|
20566
|
+
label: spec.label,
|
|
20567
|
+
min: spec.min,
|
|
20568
|
+
max: spec.max,
|
|
20569
|
+
...spec.integer === true ? { integer: true } : {},
|
|
20570
|
+
allowEmpty: true
|
|
20571
|
+
});
|
|
20572
|
+
if (!result.ok) {
|
|
20573
|
+
setError(result.message);
|
|
20574
|
+
return;
|
|
20575
|
+
}
|
|
20576
|
+
if (result.value === value) {
|
|
20577
|
+
setDraft(void 0);
|
|
20578
|
+
setError(void 0);
|
|
20579
|
+
return;
|
|
20580
|
+
}
|
|
20581
|
+
const saved = await onSave(result.value);
|
|
20582
|
+
if (!mounted.current) return;
|
|
20583
|
+
if (saved) {
|
|
20584
|
+
setDraft(void 0);
|
|
20585
|
+
setError(void 0);
|
|
20586
|
+
} else setError("\u8BBE\u7F6E\u672A\u4FDD\u5B58\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
20587
|
+
};
|
|
20588
|
+
return h(
|
|
20589
|
+
"div",
|
|
20590
|
+
{ className: "odc-field odc-field-compact" },
|
|
20591
|
+
h("label", { htmlFor: id }, spec.label),
|
|
20592
|
+
h("input", {
|
|
20593
|
+
id,
|
|
20594
|
+
className: "odc-input",
|
|
20595
|
+
type: "number",
|
|
20596
|
+
inputMode: "decimal",
|
|
20597
|
+
min: spec.min,
|
|
20598
|
+
max: spec.max,
|
|
20599
|
+
step: spec.integer === true ? 1 : 0.1,
|
|
20600
|
+
value: draft ?? (value === void 0 ? "" : String(value)),
|
|
20601
|
+
disabled,
|
|
20602
|
+
"aria-invalid": error62 !== void 0,
|
|
20603
|
+
"aria-describedby": `${id}-hint`,
|
|
20604
|
+
onChange: (event) => setDraft(event.target.value),
|
|
20605
|
+
onBlur: () => {
|
|
20606
|
+
void commit();
|
|
20607
|
+
}
|
|
20608
|
+
}),
|
|
20609
|
+
h("small", {
|
|
20610
|
+
className: error62 === void 0 ? "odc-hint" : "odc-hint odc-field-error",
|
|
20611
|
+
id: `${id}-hint`,
|
|
20612
|
+
...error62 === void 0 ? {} : { role: "alert" }
|
|
20613
|
+
}, error62 ?? spec.hint)
|
|
20614
|
+
);
|
|
20615
|
+
}
|
|
20616
|
+
function EffortField({ id, model, value, disabled, onChange }) {
|
|
20617
|
+
const mounted = useMounted();
|
|
20618
|
+
const [error62, setError] = React.useState(void 0);
|
|
20619
|
+
const listed = model.reasoningEfforts ?? [];
|
|
20620
|
+
const options = value === void 0 || listed.includes(value) ? listed : [...listed, value];
|
|
20621
|
+
const unknown2 = options.length === 0;
|
|
20622
|
+
return h(
|
|
20623
|
+
"div",
|
|
20624
|
+
{ className: "odc-field odc-field-compact" },
|
|
20625
|
+
h("label", { htmlFor: id }, "\u9ED8\u8BA4\u601D\u8003\u6DF1\u5EA6"),
|
|
20626
|
+
h("select", {
|
|
20627
|
+
id,
|
|
20628
|
+
className: "odc-input",
|
|
20629
|
+
value: value ?? "",
|
|
20630
|
+
disabled: disabled || unknown2,
|
|
20631
|
+
"aria-describedby": `${id}-hint`,
|
|
20632
|
+
onChange: (event) => {
|
|
20633
|
+
const next = event.target.value;
|
|
20634
|
+
void (async () => {
|
|
20635
|
+
const saved = await onChange(next);
|
|
20636
|
+
if (mounted.current) setError(saved ? void 0 : "\u8BBE\u7F6E\u672A\u4FDD\u5B58\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
20637
|
+
})();
|
|
20638
|
+
}
|
|
20639
|
+
}, [
|
|
20640
|
+
h("option", { key: "", value: "" }, "\u7EE7\u627F\u9ED8\u8BA4"),
|
|
20641
|
+
...options.map((effort) => h("option", { key: effort, value: effort }, effort))
|
|
20642
|
+
]),
|
|
20643
|
+
h("small", {
|
|
20644
|
+
className: error62 === void 0 ? "odc-hint" : "odc-hint odc-field-error",
|
|
20645
|
+
id: `${id}-hint`,
|
|
20646
|
+
...error62 === void 0 ? {} : { role: "alert" }
|
|
20647
|
+
}, error62 ?? (unknown2 ? "\u8BE5\u6A21\u578B\u76EE\u5F55\u672A\u63D0\u4F9B\u601D\u8003\u6863\u4F4D\uFF0C\u65E0\u6CD5\u8986\u76D6\u3002" : "\u53EA\u5217\u51FA\u8BE5\u6A21\u578B\u5DF2\u77E5\u6863\u4F4D\uFF1B\u7559\u7A7A\u7EE7\u627F\u9ED8\u8BA4\u3002"))
|
|
20648
|
+
);
|
|
20649
|
+
}
|
|
20650
|
+
function ModelRow({ model, settings, authoritative, writable, pending, onCommit }) {
|
|
20651
|
+
const id = React.useId();
|
|
20652
|
+
const mounted = useMounted();
|
|
20653
|
+
const [error62, setError] = React.useState(void 0);
|
|
20654
|
+
const [resetToken, setResetToken] = React.useState(0);
|
|
20655
|
+
const enabled = modelEnabled(model, settings, authoritative);
|
|
20656
|
+
const hasOverrides = Object.keys(settings).length > 0;
|
|
20657
|
+
const commit = async (next) => {
|
|
20658
|
+
const saved = await onCommit(next);
|
|
20659
|
+
if (mounted.current) setError(saved ? void 0 : "\u8BBE\u7F6E\u672A\u4FDD\u5B58\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
20660
|
+
return saved;
|
|
20661
|
+
};
|
|
20662
|
+
const saveField = async (key, value) => {
|
|
20663
|
+
const next = { ...settings };
|
|
20664
|
+
if (value === void 0) delete next[key];
|
|
20665
|
+
else next[key] = value;
|
|
20666
|
+
const output2 = next.maxTokens ?? model.maxOutputTokens;
|
|
20667
|
+
const context = next.contextWindow ?? model.contextWindow;
|
|
20668
|
+
if (output2 !== void 0 && context !== void 0 && output2 >= context) {
|
|
20669
|
+
setError("\u6700\u5927\u8F93\u51FA\u5FC5\u987B\u5C0F\u4E8E\u4E0A\u4E0B\u6587\u9884\u7B97\uFF1B\u8BF7\u5148\u589E\u5927\u4E0A\u4E0B\u6587\u9884\u7B97\u6216\u51CF\u5C0F\u6700\u5927\u8F93\u51FA\u3002");
|
|
20670
|
+
return false;
|
|
20671
|
+
}
|
|
20672
|
+
setError(void 0);
|
|
20673
|
+
return commit(next);
|
|
20674
|
+
};
|
|
20675
|
+
const reset = async () => {
|
|
20676
|
+
setError(void 0);
|
|
20677
|
+
setResetToken((token) => token + 1);
|
|
20678
|
+
await commit(void 0);
|
|
20679
|
+
};
|
|
20680
|
+
const facts = [
|
|
20681
|
+
`\u4E0A\u4E0B\u6587 ${formatTokens(model.contextWindow)}`,
|
|
20682
|
+
`\u6700\u5927\u8F93\u51FA ${formatTokens(model.maxOutputTokens)}`,
|
|
20683
|
+
...model.reasoningEfforts === void 0 || model.reasoningEfforts.length === 0 ? [] : [`\u601D\u8003\u6863\u4F4D ${model.reasoningEfforts.join(" / ")}`]
|
|
20684
|
+
].join(" \xB7 ");
|
|
20685
|
+
return h(
|
|
20686
|
+
"li",
|
|
20687
|
+
{ className: "odc-model-item" },
|
|
20688
|
+
h(
|
|
20689
|
+
"div",
|
|
20690
|
+
{ className: "odc-model-head" },
|
|
20691
|
+
h(
|
|
20692
|
+
"label",
|
|
20693
|
+
{ className: "odc-switch odc-model-switch" },
|
|
20694
|
+
h("input", {
|
|
20695
|
+
type: "checkbox",
|
|
20696
|
+
checked: enabled,
|
|
20697
|
+
disabled: !writable || pending,
|
|
20698
|
+
onChange: (event) => {
|
|
20699
|
+
void commit({ ...settings, enabled: event.target.checked });
|
|
20700
|
+
}
|
|
20701
|
+
}),
|
|
20702
|
+
h("span", null, h("strong", null, model.name), h("code", null, model.id))
|
|
20703
|
+
),
|
|
20704
|
+
h(
|
|
20705
|
+
"div",
|
|
20706
|
+
{ className: "odc-actions" },
|
|
20707
|
+
enabled ? null : h("span", { className: "odc-chip" }, "\u5DF2\u7981\u7528"),
|
|
20708
|
+
h("button", { className: "odc-button odc-button-small", type: "button", disabled: !writable || pending || !hasOverrides, onClick: () => {
|
|
20709
|
+
void reset();
|
|
20710
|
+
} }, "\u91CD\u7F6E")
|
|
20711
|
+
)
|
|
20712
|
+
),
|
|
20713
|
+
h(
|
|
20714
|
+
"details",
|
|
20715
|
+
{ className: "odc-model-details" },
|
|
20716
|
+
h("summary", { "aria-label": `${model.name} \u53C2\u6570\u8BBE\u7F6E` }, hasOverrides ? "\u53C2\u6570\u8BBE\u7F6E \xB7 \u5DF2\u81EA\u5B9A\u4E49" : "\u53C2\u6570\u8BBE\u7F6E \xB7 \u4F7F\u7528\u9ED8\u8BA4\u503C"),
|
|
20717
|
+
h("p", { className: "odc-model-meta" }, facts),
|
|
20718
|
+
h("p", { className: "odc-hint" }, "\u6570\u503C\u79BB\u5F00\u8F93\u5165\u6846\u540E\u4FDD\u5B58\uFF0C\u7559\u7A7A\u7EE7\u627F\u9ED8\u8BA4\u3002"),
|
|
20719
|
+
h(
|
|
20720
|
+
"div",
|
|
20721
|
+
{ className: "odc-model-editor" },
|
|
20722
|
+
NUMERIC_ORDER.map((key) => h(OptionalNumberField, {
|
|
20723
|
+
key,
|
|
20724
|
+
id: `${id}-${key}`,
|
|
20725
|
+
field: key,
|
|
20726
|
+
value: settings[key],
|
|
20727
|
+
disabled: !writable || pending,
|
|
20728
|
+
resetToken,
|
|
20729
|
+
onSave: (value) => saveField(key, value)
|
|
20730
|
+
})),
|
|
20731
|
+
h(EffortField, {
|
|
20732
|
+
id: `${id}-effort`,
|
|
20733
|
+
model,
|
|
20734
|
+
value: settings.reasoningEffort,
|
|
20735
|
+
disabled: !writable || pending,
|
|
20736
|
+
onChange: async (value) => {
|
|
20737
|
+
const next = { ...settings };
|
|
20738
|
+
if (value === "") delete next.reasoningEffort;
|
|
20739
|
+
else next.reasoningEffort = value;
|
|
20740
|
+
setError(void 0);
|
|
20741
|
+
return commit(next);
|
|
20742
|
+
}
|
|
20743
|
+
})
|
|
20744
|
+
)
|
|
20745
|
+
),
|
|
20746
|
+
error62 !== void 0 ? h("p", { className: "odc-hint odc-field-error", role: "alert" }, error62) : null
|
|
20747
|
+
);
|
|
20748
|
+
}
|
|
20749
|
+
function ModelGroup({ title, group, models, settingsMap, authoritative, writable, pending, onCommit }) {
|
|
20284
20750
|
const [query, setQuery] = React.useState("");
|
|
20751
|
+
const [expanded, setExpanded] = React.useState(false);
|
|
20285
20752
|
const id = React.useId();
|
|
20286
20753
|
const normalized = query.trim().toLocaleLowerCase();
|
|
20287
|
-
const
|
|
20754
|
+
const groupModels = models.filter((model) => model.group === group);
|
|
20755
|
+
const filtered = groupModels.filter((model) => normalized === "" || `${model.name} ${model.id}`.toLocaleLowerCase().includes(normalized));
|
|
20756
|
+
const visible = normalized !== "" || expanded ? filtered : filtered.slice(0, 6);
|
|
20757
|
+
const enabledCount = groupModels.filter((model) => modelEnabled(model, settingsMap[model.id], authoritative)).length;
|
|
20288
20758
|
return h(
|
|
20289
20759
|
"section",
|
|
20290
20760
|
{ className: "odc-card", "aria-labelledby": `${id}-title` },
|
|
@@ -20292,7 +20762,7 @@ function ModelGroup({ title, group, models }) {
|
|
|
20292
20762
|
"div",
|
|
20293
20763
|
{ className: "odc-card-head" },
|
|
20294
20764
|
h("h3", { id: `${id}-title` }, title),
|
|
20295
|
-
h("span", { className: "odc-model-count" }, `${
|
|
20765
|
+
h("span", { className: "odc-model-count" }, `${enabledCount} / ${groupModels.length} \u5DF2\u542F\u7528`)
|
|
20296
20766
|
),
|
|
20297
20767
|
h("label", { className: "odc-label", htmlFor: `${id}-search` }, `\u641C\u7D22${title}`),
|
|
20298
20768
|
h("input", {
|
|
@@ -20300,28 +20770,291 @@ function ModelGroup({ title, group, models }) {
|
|
|
20300
20770
|
className: "odc-input",
|
|
20301
20771
|
type: "search",
|
|
20302
20772
|
value: query,
|
|
20303
|
-
placeholder: "\
|
|
20773
|
+
placeholder: "\u641C\u7D22\u5168\u90E8\u6A21\u578B\u7684\u540D\u79F0\u6216 ID",
|
|
20304
20774
|
onChange: (event) => setQuery(event.target.value)
|
|
20305
20775
|
}),
|
|
20306
|
-
filtered.length === 0 ? h("p", { className: "odc-hint", role: "status" }, "\u6CA1\u6709\u5339\u914D\u7684\u6A21\u578B\u3002") : h("ul", { className: "odc-model-list" },
|
|
20307
|
-
|
|
20308
|
-
|
|
20309
|
-
|
|
20310
|
-
|
|
20311
|
-
|
|
20312
|
-
|
|
20776
|
+
filtered.length === 0 ? h("p", { className: "odc-hint", role: "status" }, "\u6CA1\u6709\u5339\u914D\u7684\u6A21\u578B\u3002") : h("ul", { id: `${id}-list`, className: "odc-model-list" }, visible.map((model) => h(ModelRow, {
|
|
20777
|
+
key: model.id,
|
|
20778
|
+
model,
|
|
20779
|
+
settings: modelSettingsEntry(settingsMap, model.id),
|
|
20780
|
+
authoritative,
|
|
20781
|
+
writable,
|
|
20782
|
+
pending,
|
|
20783
|
+
onCommit: (next) => onCommit(model.id, next)
|
|
20784
|
+
}))),
|
|
20785
|
+
normalized === "" && filtered.length > 6 ? h("button", {
|
|
20786
|
+
type: "button",
|
|
20787
|
+
className: "odc-button",
|
|
20788
|
+
style: { marginTop: 12 },
|
|
20789
|
+
"aria-expanded": expanded,
|
|
20790
|
+
"aria-controls": `${id}-list`,
|
|
20791
|
+
onClick: () => setExpanded((value) => !value)
|
|
20792
|
+
}, expanded ? "\u6536\u8D77\u6A21\u578B\u5217\u8868" : `\u663E\u793A\u5168\u90E8 ${filtered.length} \u4E2A\u6A21\u578B`) : null
|
|
20313
20793
|
);
|
|
20314
20794
|
}
|
|
20315
|
-
function Models({
|
|
20795
|
+
function Models({ status, formSnapshot, setFormField, pendingField, onRefreshModels, refreshingModels, notice }) {
|
|
20796
|
+
const formReady = formSnapshot.status === "ready" && formSnapshot.value !== void 0;
|
|
20797
|
+
const settingsMap = formReady ? formSnapshot.value?.modelSettings ?? {} : status?.config.modelSettings ?? {};
|
|
20798
|
+
const authoritative = formReady || status?.config.modelSettings !== void 0;
|
|
20799
|
+
const writable = formSnapshot.status === "ready" && formSnapshot.value !== void 0 && formSnapshot.writable;
|
|
20800
|
+
const pending = pendingField.includes("modelSettings");
|
|
20801
|
+
const latestSettings = React.useRef(settingsMap);
|
|
20802
|
+
React.useEffect(() => {
|
|
20803
|
+
latestSettings.current = settingsMap;
|
|
20804
|
+
}, [settingsMap]);
|
|
20805
|
+
const saving = React.useRef(false);
|
|
20806
|
+
const commit = async (id, next) => {
|
|
20807
|
+
if (!writable || saving.current) return false;
|
|
20808
|
+
saving.current = true;
|
|
20809
|
+
try {
|
|
20810
|
+
return await setFormField("modelSettings", writeModelSettings(latestSettings.current, id, next));
|
|
20811
|
+
} finally {
|
|
20812
|
+
saving.current = false;
|
|
20813
|
+
}
|
|
20814
|
+
};
|
|
20815
|
+
const source = status?.modelsSource === "openai" ? "OpenAI /models \u53D1\u73B0" : status?.modelsSource === "builtin" ? "\u5185\u7F6E\u76EE\u5F55" : "\u5C1A\u672A\u786E\u8BA4";
|
|
20816
|
+
const updated = status?.modelsUpdatedAt === void 0 ? "" : ` \xB7 \u66F4\u65B0\u4E8E ${formatTime(status.modelsUpdatedAt)}`;
|
|
20817
|
+
const models = status?.models ?? [];
|
|
20316
20818
|
return h(
|
|
20317
20819
|
React.Fragment,
|
|
20318
20820
|
null,
|
|
20319
|
-
h("div", null, h("h3", null, "\u53EF\u7528\u6A21\u578B"), h("p", { className: "odc-hint" }, "\u4E24\u4E2A Provider \u72EC\u7ACB\u7B5B\u9009\u3002\u8FD9\u91CC\u4EC5\u5C55\u793A\u76EE\u5F55\uFF0C\u4E0D\u4FEE\u6539 API \u6216\u5F53\u524D\u4F1A\u8BDD\u6A21\u578B\u3002")),
|
|
20320
20821
|
h(
|
|
20822
|
+
"div",
|
|
20823
|
+
{ className: "odc-card-head" },
|
|
20824
|
+
h(
|
|
20825
|
+
"div",
|
|
20826
|
+
null,
|
|
20827
|
+
h("h3", null, "\u53EF\u7528\u6A21\u578B"),
|
|
20828
|
+
h("p", { className: "odc-hint" }, "\u4E24\u4E2A Provider \u72EC\u7ACB\u7B5B\u9009\u3002\u9010\u6A21\u578B\u7684\u542F\u7528\u4E0E\u53C2\u6570\u4F1A\u4FDD\u5B58\u5230\u63D2\u4EF6\u8BBE\u7F6E\uFF0C\u53EA\u5F71\u54CD\u672C\u63D2\u4EF6\u7684\u6A21\u578B\u9009\u62E9\u4E0E\u8BF7\u6C42\u3002")
|
|
20829
|
+
),
|
|
20830
|
+
h(
|
|
20831
|
+
"div",
|
|
20832
|
+
{ className: "odc-actions" },
|
|
20833
|
+
h("span", { className: "odc-label", role: "status" }, `\u6765\u6E90\uFF1A${source}${updated}`),
|
|
20834
|
+
h("button", {
|
|
20835
|
+
className: "odc-button",
|
|
20836
|
+
type: "button",
|
|
20837
|
+
disabled: refreshingModels || status === void 0 || status.apiKeyConfigured === false,
|
|
20838
|
+
onClick: onRefreshModels
|
|
20839
|
+
}, refreshingModels ? "\u6B63\u5728\u5237\u65B0\u6A21\u578B\u2026" : "\u4ECE OpenAI \u5237\u65B0\u6A21\u578B")
|
|
20840
|
+
)
|
|
20841
|
+
),
|
|
20842
|
+
status?.apiKeyConfigured === false ? h("p", { className: "odc-hint" }, "\u5237\u65B0\u6A21\u578B\u9700\u8981\u53EF\u7528\u7684 API Key\uFF1B\u4FDD\u5B58 Key \u540E\u91CD\u8BD5\u3002") : null,
|
|
20843
|
+
status?.modelsError !== void 0 ? h("p", { className: "odc-notice", "data-kind": "error", role: "alert" }, status.modelsError) : null,
|
|
20844
|
+
h(NoticeView, { notice }),
|
|
20845
|
+
models.length === 0 ? h("p", { className: "odc-hint", role: "status" }, "\u6682\u65E0\u53EF\u7528\u6A21\u578B\uFF1B\u53EF\u5237\u65B0\u6A21\u578B\u5217\u8868\u540E\u91CD\u8BD5\u3002") : h(
|
|
20321
20846
|
"div",
|
|
20322
20847
|
{ className: "odc-model-groups" },
|
|
20323
|
-
h(ModelGroup, { title: "\u5957\u9910\u8D60\u9001 Provider", group: "plan", models
|
|
20324
|
-
h(ModelGroup, { title: "\u4ED8\u8D39 Provider", group: "paid", models
|
|
20848
|
+
h(ModelGroup, { title: "\u5957\u9910\u8D60\u9001 Provider", group: "plan", models, settingsMap, authoritative, writable, pending, onCommit: commit }),
|
|
20849
|
+
h(ModelGroup, { title: "\u4ED8\u8D39 Provider", group: "paid", models, settingsMap, authoritative, writable, pending, onCommit: commit })
|
|
20850
|
+
)
|
|
20851
|
+
);
|
|
20852
|
+
}
|
|
20853
|
+
function NumberField({ id, label, hint, value, min, max, integer: integer2, disabled, onCommit }) {
|
|
20854
|
+
const mounted = useMounted();
|
|
20855
|
+
const [draft, setDraft] = React.useState(String(value));
|
|
20856
|
+
const [error62, setError] = React.useState(void 0);
|
|
20857
|
+
React.useEffect(() => {
|
|
20858
|
+
setDraft(String(value));
|
|
20859
|
+
setError(void 0);
|
|
20860
|
+
}, [value]);
|
|
20861
|
+
const commit = async () => {
|
|
20862
|
+
const result = parseNumberInput(draft, { label, min, max, ...integer2 ? { integer: true } : {} });
|
|
20863
|
+
if (!result.ok) {
|
|
20864
|
+
setError(result.message);
|
|
20865
|
+
return;
|
|
20866
|
+
}
|
|
20867
|
+
if (result.value === void 0 || result.value === value) {
|
|
20868
|
+
setDraft(String(value));
|
|
20869
|
+
setError(void 0);
|
|
20870
|
+
return;
|
|
20871
|
+
}
|
|
20872
|
+
const saved = await onCommit(result.value);
|
|
20873
|
+
if (!mounted.current) return;
|
|
20874
|
+
if (saved) setError(void 0);
|
|
20875
|
+
else setError("\u8BBE\u7F6E\u672A\u4FDD\u5B58\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
20876
|
+
};
|
|
20877
|
+
return h(
|
|
20878
|
+
"div",
|
|
20879
|
+
{ className: "odc-field" },
|
|
20880
|
+
h("label", { htmlFor: id }, label),
|
|
20881
|
+
h("input", {
|
|
20882
|
+
id,
|
|
20883
|
+
className: "odc-input",
|
|
20884
|
+
type: "number",
|
|
20885
|
+
inputMode: "numeric",
|
|
20886
|
+
min,
|
|
20887
|
+
max,
|
|
20888
|
+
step: integer2 ? 1 : 0.1,
|
|
20889
|
+
value: draft,
|
|
20890
|
+
disabled,
|
|
20891
|
+
"aria-invalid": error62 !== void 0,
|
|
20892
|
+
"aria-describedby": `${id}-hint`,
|
|
20893
|
+
onChange: (event) => setDraft(event.target.value),
|
|
20894
|
+
onBlur: () => {
|
|
20895
|
+
void commit();
|
|
20896
|
+
}
|
|
20897
|
+
}),
|
|
20898
|
+
h("small", {
|
|
20899
|
+
className: error62 === void 0 ? "odc-hint" : "odc-hint odc-field-error",
|
|
20900
|
+
id: `${id}-hint`,
|
|
20901
|
+
...error62 === void 0 ? {} : { role: "alert" }
|
|
20902
|
+
}, error62 ?? hint)
|
|
20903
|
+
);
|
|
20904
|
+
}
|
|
20905
|
+
function Advanced({ status, formSnapshot, setFormField, pendingField }) {
|
|
20906
|
+
const [apiKeyEnv, setApiKeyEnv] = React.useState(status?.config.apiKeyEnv ?? "");
|
|
20907
|
+
const [keyNotice, setKeyNotice] = React.useState(null);
|
|
20908
|
+
const mounted = useMounted();
|
|
20909
|
+
React.useEffect(() => {
|
|
20910
|
+
setApiKeyEnv(formSnapshot.value?.apiKeyEnv ?? status?.config.apiKeyEnv ?? "");
|
|
20911
|
+
}, [formSnapshot.value?.apiKeyEnv, status?.config.apiKeyEnv]);
|
|
20912
|
+
const writable = formSnapshot.status === "ready" && formSnapshot.value !== void 0 && formSnapshot.writable;
|
|
20913
|
+
const configuredProtocol = formSnapshot.value?.apiProtocol ?? status?.config.apiProtocol;
|
|
20914
|
+
const protocol = configuredProtocol !== void 0 && API_PROTOCOL_OPTIONS.some((option) => option.id === configuredProtocol) ? configuredProtocol : "chat-completions";
|
|
20915
|
+
const baseURL = formSnapshot.value?.baseURL ?? status?.config.baseURL ?? "";
|
|
20916
|
+
const requestTimeout = formSnapshot.value?.requestTimeoutMs ?? status?.config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
20917
|
+
const streamIdleTimeout = formSnapshot.value?.streamIdleTimeoutMs ?? status?.config.streamIdleTimeoutMs ?? DEFAULT_STREAM_IDLE_TIMEOUT_MS;
|
|
20918
|
+
const refreshSeconds = formSnapshot.value?.quotaRefreshSeconds ?? status?.config.quotaRefreshSeconds ?? DEFAULT_QUOTA_REFRESH_SECONDS;
|
|
20919
|
+
const selected = API_PROTOCOL_OPTIONS.find((option) => option.id === protocol);
|
|
20920
|
+
const saveKeyRef = async () => {
|
|
20921
|
+
const value = apiKeyEnv.trim();
|
|
20922
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]{0,127}$/u.test(value)) {
|
|
20923
|
+
setKeyNotice({ kind: "error", text: "\u5F15\u7528\u540D\u9700\u4E3A 1\u2013128 \u4F4D\u5B57\u6BCD\u3001\u6570\u5B57\u6216\u4E0B\u5212\u7EBF\uFF0C\u4E14\u4E0D\u80FD\u4EE5\u6570\u5B57\u5F00\u5934\u3002" });
|
|
20924
|
+
return;
|
|
20925
|
+
}
|
|
20926
|
+
setKeyNotice(null);
|
|
20927
|
+
try {
|
|
20928
|
+
const accepted = await setFormField("apiKeyEnv", value);
|
|
20929
|
+
if (mounted.current) setKeyNotice(accepted ? { kind: "status", text: "\u914D\u7F6E\u5DF2\u4FDD\u5B58\u3002" } : { kind: "error", text: "\u914D\u7F6E\u672A\u4FDD\u5B58\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5\u3002" });
|
|
20930
|
+
} catch {
|
|
20931
|
+
if (mounted.current) setKeyNotice({ kind: "error", text: GENERIC_ERROR });
|
|
20932
|
+
}
|
|
20933
|
+
};
|
|
20934
|
+
return h(
|
|
20935
|
+
React.Fragment,
|
|
20936
|
+
null,
|
|
20937
|
+
h(
|
|
20938
|
+
"section",
|
|
20939
|
+
{ className: "odc-card" },
|
|
20940
|
+
h("h3", null, "\u7A7A\u8F6E\u76D1\u63A7"),
|
|
20941
|
+
h("p", { className: "odc-hint" }, "\u72EC\u7ACB\u76D1\u63A7\u5957\u9910\u8D60\u9001\u6A21\u578B\u7684\u7A7A\u8F6E\u6216\u534F\u8BAE\u6B8B\u6E23\uFF1B\u4E0D\u5F71\u54CD\u4ED8\u8D39 Provider \u7684\u5F00\u5173\u3002"),
|
|
20942
|
+
h("div", { style: { marginTop: 14 } }, h(Switch, {
|
|
20943
|
+
checked: formSnapshot.value?.emptyTurnGuard ?? status?.config.emptyTurnGuard ?? true,
|
|
20944
|
+
disabled: !writable || pendingField.includes("emptyTurnGuard"),
|
|
20945
|
+
label: "\u542F\u7528\u7A7A\u8F6E\u76D1\u63A7",
|
|
20946
|
+
hint: `\u672C\u6B21\u8FD0\u884C\u5DF2\u62E6\u622A ${status?.guardedTurns ?? "\u2014"} \u8F6E\u3002\u68C0\u6D4B\u540E\u7531\u5BBF\u4E3B\u91CD\u8BD5\u7B56\u7565\u5904\u7406\uFF0C\u5BBF\u4E3B\u91CD\u8BD5\u4F1A\u989D\u5916\u6D88\u8017\u989D\u5EA6\u3002`,
|
|
20947
|
+
onChange: (checked) => {
|
|
20948
|
+
void setFormField("emptyTurnGuard", checked);
|
|
20949
|
+
}
|
|
20950
|
+
}))
|
|
20951
|
+
),
|
|
20952
|
+
h(
|
|
20953
|
+
"section",
|
|
20954
|
+
{ className: "odc-card" },
|
|
20955
|
+
h("h3", null, "\u63A8\u7406\u534F\u8BAE"),
|
|
20956
|
+
h("p", { className: "odc-hint" }, "\u63D2\u4EF6\u6309\u6240\u9009\u534F\u8BAE\u7EC4\u88C5\u8BF7\u6C42\uFF1B\u6A21\u578B\u53D1\u73B0\u59CB\u7EC8\u8BFB\u53D6 OpenAI /models\uFF0C\u4E0E\u8FD9\u91CC\u7684\u9009\u62E9\u65E0\u5173\u3002"),
|
|
20957
|
+
h(
|
|
20958
|
+
"div",
|
|
20959
|
+
{ className: "odc-field" },
|
|
20960
|
+
h("label", { htmlFor: "odc-api-protocol" }, "API \u534F\u8BAE"),
|
|
20961
|
+
h("select", {
|
|
20962
|
+
id: "odc-api-protocol",
|
|
20963
|
+
className: "odc-input",
|
|
20964
|
+
value: protocol,
|
|
20965
|
+
disabled: !writable || pendingField.includes("apiProtocol"),
|
|
20966
|
+
onChange: (event) => {
|
|
20967
|
+
void setFormField("apiProtocol", event.target.value);
|
|
20968
|
+
}
|
|
20969
|
+
}, API_PROTOCOL_OPTIONS.map((option) => h("option", { key: option.id, value: option.id }, option.name))),
|
|
20970
|
+
h("small", { className: "odc-hint" }, selected?.description ?? "\u9009\u62E9\u4E0E\u7F51\u5173\u517C\u5BB9\u7684\u63A8\u7406\u534F\u8BAE\u3002")
|
|
20971
|
+
),
|
|
20972
|
+
h(
|
|
20973
|
+
"div",
|
|
20974
|
+
{ className: "odc-readonly" },
|
|
20975
|
+
h(
|
|
20976
|
+
"div",
|
|
20977
|
+
null,
|
|
20978
|
+
h("span", { className: "odc-label" }, "\u5F53\u524D\u7F51\u5173\u5730\u5740\uFF08\u53EA\u8BFB\uFF09"),
|
|
20979
|
+
h("code", { className: "odc-code" }, baseURL === "" ? "\u2014" : baseURL)
|
|
20980
|
+
),
|
|
20981
|
+
h(
|
|
20982
|
+
"div",
|
|
20983
|
+
null,
|
|
20984
|
+
h("span", { className: "odc-label" }, "\u5F53\u524D\u63A8\u7406\u8DEF\u5F84\uFF08\u53EA\u8BFB\uFF09"),
|
|
20985
|
+
h("code", { className: "odc-code" }, protocolEndpoint(baseURL, protocol))
|
|
20986
|
+
),
|
|
20987
|
+
h("small", { className: "odc-hint" }, "\u5730\u5740\u7531\u63D2\u4EF6\u914D\u7F6E\u63D0\u4F9B\uFF0C\u65E0\u9700\u5728\u6B64\u586B\u5199\uFF1B\u5207\u6362\u534F\u8BAE\u53EA\u6539\u53D8\u8BF7\u6C42\u8DEF\u5F84\u4E0E\u62A5\u6587\u683C\u5F0F\u3002")
|
|
20988
|
+
)
|
|
20989
|
+
),
|
|
20990
|
+
h(
|
|
20991
|
+
"section",
|
|
20992
|
+
{ className: "odc-card" },
|
|
20993
|
+
h("h3", null, "\u51ED\u636E\u4E0E\u7F51\u5173"),
|
|
20994
|
+
h("p", { className: "odc-hint" }, "\u8FD9\u91CC\u53EA\u4FDD\u5B58\u51ED\u636E\u5F15\u7528\u540D\u79F0\uFF0C\u4E0D\u586B\u5199 Key \u672C\u8EAB\uFF1B\u7F51\u5173\u5730\u5740\u7531\u63D2\u4EF6\u914D\u7F6E\u6258\u7BA1\u3002"),
|
|
20995
|
+
h(
|
|
20996
|
+
"div",
|
|
20997
|
+
{ className: "odc-field" },
|
|
20998
|
+
h("label", { htmlFor: "odc-api-key-env" }, "API Key \u73AF\u5883\u53D8\u91CF / \u51ED\u636E\u5F15\u7528\u540D"),
|
|
20999
|
+
h("input", {
|
|
21000
|
+
id: "odc-api-key-env",
|
|
21001
|
+
className: "odc-input",
|
|
21002
|
+
type: "text",
|
|
21003
|
+
value: apiKeyEnv,
|
|
21004
|
+
disabled: !writable,
|
|
21005
|
+
autoCapitalize: "off",
|
|
21006
|
+
spellCheck: false,
|
|
21007
|
+
onChange: (event) => setApiKeyEnv(event.target.value)
|
|
21008
|
+
}),
|
|
21009
|
+
h("small", { className: "odc-hint" }, "\u5F15\u7528\u540D\u5BF9\u5E94\u7684\u51ED\u636E\u4ECD\u4F18\u5148\u4E8E\u672C\u63D2\u4EF6\u4FDD\u5B58\u7684 Key\u3002")
|
|
21010
|
+
),
|
|
21011
|
+
h(
|
|
21012
|
+
"div",
|
|
21013
|
+
{ className: "odc-actions", style: { marginTop: 10 } },
|
|
21014
|
+
h("button", { className: "odc-button", type: "button", disabled: !writable || pendingField.includes("apiKeyEnv"), onClick: () => {
|
|
21015
|
+
void saveKeyRef();
|
|
21016
|
+
} }, "\u4FDD\u5B58\u5F15\u7528\u540D")
|
|
21017
|
+
),
|
|
21018
|
+
h(NoticeView, { notice: keyNotice })
|
|
21019
|
+
),
|
|
21020
|
+
h(
|
|
21021
|
+
"section",
|
|
21022
|
+
{ className: "odc-card" },
|
|
21023
|
+
h("h3", null, "\u8BF7\u6C42\u65F6\u9650\u4E0E\u81EA\u52A8\u5237\u65B0"),
|
|
21024
|
+
h("p", { className: "odc-hint" }, "\u6570\u503C\u5728\u79BB\u5F00\u8F93\u5165\u6846\u65F6\u6821\u9A8C\u5E76\u4FDD\u5B58\uFF1B\u7559\u7A7A\u6216\u8D8A\u754C\u4E0D\u4F1A\u5199\u5165\u3002"),
|
|
21025
|
+
h(NumberField, {
|
|
21026
|
+
id: "odc-request-timeout",
|
|
21027
|
+
label: "\u8BF7\u6C42\u603B\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09",
|
|
21028
|
+
hint: "\u4ECE\u53D1\u51FA\u8BF7\u6C42\u5230\u54CD\u5E94\u7ED3\u675F\u7684\u4E0A\u9650\uFF0C1000\u20133600000\u3002",
|
|
21029
|
+
value: requestTimeout,
|
|
21030
|
+
min: MIN_REQUEST_TIMEOUT_MS,
|
|
21031
|
+
max: MAX_REQUEST_TIMEOUT_MS,
|
|
21032
|
+
integer: true,
|
|
21033
|
+
disabled: !writable || pendingField.includes("requestTimeoutMs"),
|
|
21034
|
+
onCommit: (value) => setFormField("requestTimeoutMs", value)
|
|
21035
|
+
}),
|
|
21036
|
+
h(NumberField, {
|
|
21037
|
+
id: "odc-stream-idle-timeout",
|
|
21038
|
+
label: "\u6D41\u5F0F\u7A7A\u95F2\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09",
|
|
21039
|
+
hint: "\u6D41\u5F0F\u54CD\u5E94\u65E0\u65B0\u6570\u636E\u7684\u6700\u957F\u7B49\u5F85\uFF0C1000\u20131800000\u3002",
|
|
21040
|
+
value: streamIdleTimeout,
|
|
21041
|
+
min: MIN_STREAM_IDLE_TIMEOUT_MS,
|
|
21042
|
+
max: MAX_STREAM_IDLE_TIMEOUT_MS,
|
|
21043
|
+
integer: true,
|
|
21044
|
+
disabled: !writable || pendingField.includes("streamIdleTimeoutMs"),
|
|
21045
|
+
onCommit: (value) => setFormField("streamIdleTimeoutMs", value)
|
|
21046
|
+
}),
|
|
21047
|
+
h(NumberField, {
|
|
21048
|
+
id: "odc-quota-refresh",
|
|
21049
|
+
label: "\u989D\u5EA6\u81EA\u52A8\u5237\u65B0\u95F4\u9694\uFF08\u79D2\uFF09",
|
|
21050
|
+
hint: `5\u20133600\uFF1B\u9ED8\u8BA4 ${DEFAULT_QUOTA_REFRESH_SECONDS} \u79D2\uFF0C\u9875\u9762\u5173\u95ED\u540E\u505C\u6B62\u3002`,
|
|
21051
|
+
value: refreshSeconds,
|
|
21052
|
+
min: MIN_QUOTA_REFRESH_SECONDS,
|
|
21053
|
+
max: MAX_QUOTA_REFRESH_SECONDS,
|
|
21054
|
+
integer: true,
|
|
21055
|
+
disabled: !writable || pendingField.includes("quotaRefreshSeconds"),
|
|
21056
|
+
onCommit: (value) => setFormField("quotaRefreshSeconds", value)
|
|
21057
|
+
})
|
|
20325
21058
|
)
|
|
20326
21059
|
);
|
|
20327
21060
|
}
|
|
@@ -20350,7 +21083,7 @@ function Connection({ status, formSnapshot, setFormField, pendingField, caller,
|
|
|
20350
21083
|
const state = login?.state ?? "idle";
|
|
20351
21084
|
const inFlight = loginInFlight(state);
|
|
20352
21085
|
const startLogin = async () => {
|
|
20353
|
-
if (status === void 0 || busy) return;
|
|
21086
|
+
if (status === void 0 || busy || keyBusy) return;
|
|
20354
21087
|
const version2 = ++actionVersion.current;
|
|
20355
21088
|
setBusy(true);
|
|
20356
21089
|
setNotice({ kind: "status", text: "\u6B63\u5728\u542F\u52A8\u5B98\u65B9\u767B\u5F55\u2026" });
|
|
@@ -20366,7 +21099,7 @@ function Connection({ status, formSnapshot, setFormField, pendingField, caller,
|
|
|
20366
21099
|
}
|
|
20367
21100
|
};
|
|
20368
21101
|
const cancelLogin = async () => {
|
|
20369
|
-
if (login?.jobId == null || busy) return;
|
|
21102
|
+
if (login?.jobId == null || busy || keyBusy) return;
|
|
20370
21103
|
const version2 = ++actionVersion.current;
|
|
20371
21104
|
setBusy(true);
|
|
20372
21105
|
try {
|
|
@@ -20382,7 +21115,7 @@ function Connection({ status, formSnapshot, setFormField, pendingField, caller,
|
|
|
20382
21115
|
};
|
|
20383
21116
|
const saveKey = async (event) => {
|
|
20384
21117
|
event.preventDefault();
|
|
20385
|
-
if (status === void 0 || keyBusy || apiKey.trim() === "") {
|
|
21118
|
+
if (status === void 0 || busy || inFlight || keyBusy || apiKey.trim() === "") {
|
|
20386
21119
|
if (apiKey.trim() === "") setNotice({ kind: "error", text: "\u8BF7\u8F93\u5165 API Key \u540E\u518D\u4FDD\u5B58\u3002" });
|
|
20387
21120
|
return;
|
|
20388
21121
|
}
|
|
@@ -20417,7 +21150,7 @@ function Connection({ status, formSnapshot, setFormField, pendingField, caller,
|
|
|
20417
21150
|
{ style: { marginTop: 14 } },
|
|
20418
21151
|
h(Switch, {
|
|
20419
21152
|
checked: desktopChecked,
|
|
20420
|
-
disabled: !formSnapshot.writable || pendingField
|
|
21153
|
+
disabled: formSnapshot.status !== "ready" || formSnapshot.value === void 0 || !formSnapshot.writable || pendingField.includes("useDesktopCredential"),
|
|
20421
21154
|
label: "\u4F18\u5148\u4F7F\u7528\u684C\u9762\u767B\u5F55\u6001",
|
|
20422
21155
|
hint: "\u4EC5\u63A7\u5236\u8BFB\u53D6\u4F18\u5148\u7EA7\uFF0C\u4E0D\u4F1A\u4FEE\u6539\u6216\u5199\u56DE\u684C\u9762\u7AEF\u767B\u5F55\u6587\u4EF6\u3002",
|
|
20423
21156
|
onChange: (checked) => {
|
|
@@ -20435,10 +21168,10 @@ function Connection({ status, formSnapshot, setFormField, pendingField, caller,
|
|
|
20435
21168
|
h(
|
|
20436
21169
|
"div",
|
|
20437
21170
|
{ className: "odc-actions", style: { marginTop: 14 } },
|
|
20438
|
-
h("button", { className: "odc-button odc-button-primary", type: "button", disabled: status === void 0 || busy || inFlight, onClick: () => {
|
|
21171
|
+
h("button", { className: "odc-button odc-button-primary", type: "button", disabled: status === void 0 || busy || keyBusy || inFlight, onClick: () => {
|
|
20439
21172
|
void startLogin();
|
|
20440
21173
|
} }, "\u767B\u5F55\u5E76\u4FDD\u5B58\u4F1A\u8BDD"),
|
|
20441
|
-
inFlight ? h("button", { className: "odc-button", type: "button", disabled: busy || login?.jobId == null, onClick: () => {
|
|
21174
|
+
inFlight ? h("button", { className: "odc-button", type: "button", disabled: busy || keyBusy || login?.jobId == null, onClick: () => {
|
|
20442
21175
|
void cancelLogin();
|
|
20443
21176
|
} }, "\u53D6\u6D88\u767B\u5F55") : null,
|
|
20444
21177
|
h("a", { className: "odc-link", href: OFFICIAL_SITE, target: "_blank", rel: "noreferrer noopener" }, "\u6253\u5F00 CoRouter \u5B98\u7F51")
|
|
@@ -20468,7 +21201,7 @@ function Connection({ status, formSnapshot, setFormField, pendingField, caller,
|
|
|
20468
21201
|
autoComplete: "new-password",
|
|
20469
21202
|
autoCapitalize: "off",
|
|
20470
21203
|
spellCheck: false,
|
|
20471
|
-
disabled: status === void 0 || keyBusy,
|
|
21204
|
+
disabled: status === void 0 || busy || inFlight || keyBusy,
|
|
20472
21205
|
placeholder: "\u4EC5\u7528\u4E8E\u672C\u6B21\u4FDD\u5B58\uFF0C\u4E0D\u4F1A\u56DE\u586B",
|
|
20473
21206
|
onChange: (event) => setApiKey(event.target.value)
|
|
20474
21207
|
}),
|
|
@@ -20477,85 +21210,12 @@ function Connection({ status, formSnapshot, setFormField, pendingField, caller,
|
|
|
20477
21210
|
h(
|
|
20478
21211
|
"div",
|
|
20479
21212
|
{ className: "odc-actions", style: { marginTop: 12 } },
|
|
20480
|
-
h("button", { className: "odc-button", type: "submit", disabled: status === void 0 || keyBusy || apiKey.trim() === "" }, keyBusy ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58 API Key")
|
|
21213
|
+
h("button", { className: "odc-button", type: "submit", disabled: status === void 0 || busy || inFlight || keyBusy || apiKey.trim() === "" }, keyBusy ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58 API Key")
|
|
20481
21214
|
)
|
|
20482
21215
|
)
|
|
20483
21216
|
)
|
|
20484
21217
|
);
|
|
20485
21218
|
}
|
|
20486
|
-
function Advanced({ status, formSnapshot, setFormField, pendingField }) {
|
|
20487
|
-
const [baseURL, setBaseURL] = React.useState(status?.config.baseURL ?? "");
|
|
20488
|
-
const [apiKeyEnv, setApiKeyEnv] = React.useState(status?.config.apiKeyEnv ?? "");
|
|
20489
|
-
const [notice, setNotice] = React.useState(null);
|
|
20490
|
-
const mounted = useMounted();
|
|
20491
|
-
React.useEffect(() => {
|
|
20492
|
-
setBaseURL(formSnapshot.value?.baseURL ?? status?.config.baseURL ?? "");
|
|
20493
|
-
}, [formSnapshot.value?.baseURL, status?.config.baseURL]);
|
|
20494
|
-
React.useEffect(() => {
|
|
20495
|
-
setApiKeyEnv(formSnapshot.value?.apiKeyEnv ?? status?.config.apiKeyEnv ?? "");
|
|
20496
|
-
}, [formSnapshot.value?.apiKeyEnv, status?.config.apiKeyEnv]);
|
|
20497
|
-
const saveText = async (field) => {
|
|
20498
|
-
const value = field === "baseURL" ? baseURL.trim() : apiKeyEnv.trim();
|
|
20499
|
-
if (value === "") {
|
|
20500
|
-
setNotice({ kind: "error", text: "\u914D\u7F6E\u503C\u4E0D\u80FD\u4E3A\u7A7A\u3002" });
|
|
20501
|
-
return;
|
|
20502
|
-
}
|
|
20503
|
-
setNotice(null);
|
|
20504
|
-
try {
|
|
20505
|
-
const accepted = await setFormField(field, value);
|
|
20506
|
-
if (mounted.current) setNotice(accepted ? { kind: "status", text: "\u914D\u7F6E\u5DF2\u4FDD\u5B58\u3002" } : { kind: "error", text: "\u914D\u7F6E\u672A\u4FDD\u5B58\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5\u3002" });
|
|
20507
|
-
} catch {
|
|
20508
|
-
if (mounted.current) setNotice({ kind: "error", text: GENERIC_ERROR });
|
|
20509
|
-
}
|
|
20510
|
-
};
|
|
20511
|
-
const disabled = !formSnapshot.writable;
|
|
20512
|
-
return h(
|
|
20513
|
-
React.Fragment,
|
|
20514
|
-
null,
|
|
20515
|
-
h(
|
|
20516
|
-
"section",
|
|
20517
|
-
{ className: "odc-card" },
|
|
20518
|
-
h("h3", null, "\u7A7A\u8F6E\u76D1\u63A7"),
|
|
20519
|
-
h("p", { className: "odc-hint" }, "\u72EC\u7ACB\u76D1\u63A7\u5957\u9910\u8D60\u9001\u6A21\u578B\u7684\u7A7A\u8F6E\u6216\u534F\u8BAE\u6B8B\u6E23\uFF1B\u4E0D\u5F71\u54CD\u4ED8\u8D39 Provider \u7684\u5F00\u5173\u3002"),
|
|
20520
|
-
h("div", { style: { marginTop: 14 } }, h(Switch, {
|
|
20521
|
-
checked: formSnapshot.value?.emptyTurnGuard ?? status?.config.emptyTurnGuard ?? true,
|
|
20522
|
-
disabled: disabled || pendingField === "emptyTurnGuard",
|
|
20523
|
-
label: "\u542F\u7528\u7A7A\u8F6E\u76D1\u63A7",
|
|
20524
|
-
hint: `\u672C\u6B21\u8FD0\u884C\u5DF2\u62E6\u622A ${status?.guardedTurns ?? "\u2014"} \u8F6E\u3002\u68C0\u6D4B\u540E\u7531\u5BBF\u4E3B\u91CD\u8BD5\u7B56\u7565\u5904\u7406\uFF0C\u5BBF\u4E3B\u91CD\u8BD5\u4F1A\u989D\u5916\u6D88\u8017\u989D\u5EA6\u3002`,
|
|
20525
|
-
onChange: (checked) => {
|
|
20526
|
-
void setFormField("emptyTurnGuard", checked);
|
|
20527
|
-
}
|
|
20528
|
-
}))
|
|
20529
|
-
),
|
|
20530
|
-
h(
|
|
20531
|
-
"section",
|
|
20532
|
-
{ className: "odc-card" },
|
|
20533
|
-
h("h3", null, "\u63A8\u7406\u8FDE\u63A5"),
|
|
20534
|
-
h("p", { className: "odc-hint" }, formSnapshot.status === "unavailable" ? "\u5BBF\u4E3B\u672A\u5F00\u653E\u6B64\u914D\u7F6E\u8868\u5355\u3002" : "\u5B57\u6BB5\u7531\u5BBF\u4E3B\u914D\u7F6E\u8868\u5355\u6821\u9A8C\u5E76\u6301\u4E45\u5316\uFF1B\u65E0\u9700\u989D\u5916\u7684\u4FDD\u5B58\u63A5\u53E3\u3002"),
|
|
20535
|
-
h(
|
|
20536
|
-
"div",
|
|
20537
|
-
{ className: "odc-field" },
|
|
20538
|
-
h("label", { htmlFor: "odc-base-url" }, "Base URL"),
|
|
20539
|
-
h("input", { id: "odc-base-url", className: "odc-input", type: "url", value: baseURL, disabled, onChange: (event) => setBaseURL(event.target.value) }),
|
|
20540
|
-
h("small", { className: "odc-hint" }, "\u4EC5\u7528\u4E8E OpenAI \u517C\u5BB9\u63A8\u7406\uFF0C\u4E0D\u7528\u4E8E\u63A7\u5236\u53F0\u767B\u5F55\u6216\u989D\u5EA6\u67E5\u8BE2\u3002")
|
|
20541
|
-
),
|
|
20542
|
-
h("div", { className: "odc-actions", style: { marginTop: 10 } }, h("button", { className: "odc-button", type: "button", disabled: disabled || pendingField === "baseURL", onClick: () => {
|
|
20543
|
-
void saveText("baseURL");
|
|
20544
|
-
} }, "\u4FDD\u5B58 Base URL")),
|
|
20545
|
-
h(
|
|
20546
|
-
"div",
|
|
20547
|
-
{ className: "odc-field" },
|
|
20548
|
-
h("label", { htmlFor: "odc-api-key-env" }, "API Key \u73AF\u5883\u53D8\u91CF / \u51ED\u636E\u5F15\u7528\u540D"),
|
|
20549
|
-
h("input", { id: "odc-api-key-env", className: "odc-input", type: "text", value: apiKeyEnv, disabled, autoCapitalize: "off", spellCheck: false, onChange: (event) => setApiKeyEnv(event.target.value) }),
|
|
20550
|
-
h("small", { className: "odc-hint" }, "\u8FD9\u91CC\u53EA\u4FDD\u5B58\u5F15\u7528\u540D\u79F0\uFF0C\u4E0D\u586B\u5199 Key \u672C\u8EAB\u3002")
|
|
20551
|
-
),
|
|
20552
|
-
h("div", { className: "odc-actions", style: { marginTop: 10 } }, h("button", { className: "odc-button", type: "button", disabled: disabled || pendingField === "apiKeyEnv", onClick: () => {
|
|
20553
|
-
void saveText("apiKeyEnv");
|
|
20554
|
-
} }, "\u4FDD\u5B58\u5F15\u7528\u540D")),
|
|
20555
|
-
h(NoticeView, { notice })
|
|
20556
|
-
)
|
|
20557
|
-
);
|
|
20558
|
-
}
|
|
20559
21219
|
function tabAfter(current, key) {
|
|
20560
21220
|
const index = TABS.findIndex((tab) => tab.id === current);
|
|
20561
21221
|
if (key === "Home") return TABS[0].id;
|
|
@@ -20571,14 +21231,27 @@ function SettingsPage({ caller, form }) {
|
|
|
20571
21231
|
const [error62, setError] = React.useState();
|
|
20572
21232
|
const [loading, setLoading] = React.useState(true);
|
|
20573
21233
|
const [refreshing, setRefreshing] = React.useState(false);
|
|
20574
|
-
const [
|
|
21234
|
+
const [refreshingModels, setRefreshingModels] = React.useState(false);
|
|
21235
|
+
const [modelsNotice, setModelsNotice] = React.useState(null);
|
|
21236
|
+
const [pendingField, setPendingField] = React.useState([]);
|
|
21237
|
+
const writeTail = React.useRef(Promise.resolve());
|
|
20575
21238
|
const [formNotice, setFormNotice] = React.useState(null);
|
|
21239
|
+
const [scheduleTick, setScheduleTick] = React.useState(0);
|
|
20576
21240
|
const statusVersion = React.useRef(0);
|
|
20577
21241
|
const quotaVersion = React.useRef(0);
|
|
20578
21242
|
const loginVersion = React.useRef(0);
|
|
21243
|
+
const modelsVersion = React.useRef(0);
|
|
20579
21244
|
const tabRefs = React.useRef([]);
|
|
20580
21245
|
const baseId = React.useId();
|
|
20581
|
-
const
|
|
21246
|
+
const acceptedFormSnapshot = useFormSnapshot(form);
|
|
21247
|
+
const [pendingValues, setPendingValues] = React.useState({});
|
|
21248
|
+
const writeVersions = React.useRef(/* @__PURE__ */ new Map());
|
|
21249
|
+
const nextWriteVersion = React.useRef(0);
|
|
21250
|
+
const batchWriteFailed = React.useRef(false);
|
|
21251
|
+
const formSnapshot = React.useMemo(() => ({
|
|
21252
|
+
...acceptedFormSnapshot,
|
|
21253
|
+
value: acceptedFormSnapshot.value === void 0 ? void 0 : { ...acceptedFormSnapshot.value, ...pendingValues }
|
|
21254
|
+
}), [acceptedFormSnapshot, pendingValues]);
|
|
20582
21255
|
const loadStatus = React.useCallback(async () => {
|
|
20583
21256
|
const version2 = ++statusVersion.current;
|
|
20584
21257
|
try {
|
|
@@ -20593,14 +21266,18 @@ function SettingsPage({ caller, form }) {
|
|
|
20593
21266
|
}
|
|
20594
21267
|
}, [caller, mounted]);
|
|
20595
21268
|
const refreshBusy = React.useRef(false);
|
|
20596
|
-
const
|
|
20597
|
-
|
|
21269
|
+
const forcedRefreshPending = React.useRef(false);
|
|
21270
|
+
const refresh = React.useCallback(async (force = false) => {
|
|
21271
|
+
if (refreshBusy.current) {
|
|
21272
|
+
if (force) forcedRefreshPending.current = true;
|
|
21273
|
+
return;
|
|
21274
|
+
}
|
|
20598
21275
|
refreshBusy.current = true;
|
|
20599
21276
|
const version2 = ++quotaVersion.current;
|
|
20600
21277
|
setRefreshing(true);
|
|
20601
21278
|
setError(void 0);
|
|
20602
21279
|
try {
|
|
20603
|
-
const quota = await caller("refreshQuota");
|
|
21280
|
+
const quota = await caller(force ? "refreshQuotaNow" : "refreshQuota");
|
|
20604
21281
|
if (!mounted.current || version2 !== quotaVersion.current) return;
|
|
20605
21282
|
setStatus((previous) => previous === void 0 ? previous : { ...previous, quota });
|
|
20606
21283
|
await loadStatus();
|
|
@@ -20610,32 +21287,83 @@ function SettingsPage({ caller, form }) {
|
|
|
20610
21287
|
if (mounted.current && version2 === quotaVersion.current) {
|
|
20611
21288
|
refreshBusy.current = false;
|
|
20612
21289
|
setRefreshing(false);
|
|
21290
|
+
if (forcedRefreshPending.current) {
|
|
21291
|
+
forcedRefreshPending.current = false;
|
|
21292
|
+
void refresh(true);
|
|
21293
|
+
}
|
|
20613
21294
|
}
|
|
20614
21295
|
}
|
|
20615
21296
|
}, [caller, loadStatus, mounted]);
|
|
20616
21297
|
React.useEffect(() => {
|
|
21298
|
+
void loadStatus();
|
|
20617
21299
|
void refresh();
|
|
20618
21300
|
return () => {
|
|
20619
21301
|
statusVersion.current += 1;
|
|
20620
21302
|
quotaVersion.current += 1;
|
|
20621
21303
|
loginVersion.current += 1;
|
|
21304
|
+
modelsVersion.current += 1;
|
|
20622
21305
|
refreshBusy.current = false;
|
|
21306
|
+
forcedRefreshPending.current = false;
|
|
20623
21307
|
};
|
|
20624
|
-
}, [refresh]);
|
|
21308
|
+
}, [loadStatus, refresh]);
|
|
20625
21309
|
const setFormField = React.useCallback(async (field, value) => {
|
|
20626
|
-
|
|
20627
|
-
|
|
21310
|
+
const snapshot = form.getSnapshot();
|
|
21311
|
+
if (snapshot.status !== "ready" || snapshot.value === void 0 || !snapshot.writable || writeVersions.current.has(field)) return false;
|
|
21312
|
+
if (writeVersions.current.size === 0) batchWriteFailed.current = false;
|
|
21313
|
+
const version2 = ++nextWriteVersion.current;
|
|
21314
|
+
writeVersions.current.set(field, version2);
|
|
21315
|
+
setPendingField([...writeVersions.current.keys()]);
|
|
21316
|
+
setPendingValues((previous) => ({ ...previous, [field]: value }));
|
|
21317
|
+
setFormNotice({ kind: "status", text: "\u6B63\u5728\u4FDD\u5B58\u8BBE\u7F6E\u2026" });
|
|
20628
21318
|
try {
|
|
20629
|
-
const
|
|
20630
|
-
|
|
21319
|
+
const operation = writeTail.current.then(() => mounted.current ? form.set(field, value) : false);
|
|
21320
|
+
writeTail.current = operation.then(() => {
|
|
21321
|
+
}, () => {
|
|
21322
|
+
});
|
|
21323
|
+
const accepted = await operation;
|
|
21324
|
+
if (!accepted) batchWriteFailed.current = true;
|
|
21325
|
+
if (accepted && mounted.current && (field === "useDesktopCredential" || field === "quotaRefreshSeconds")) void refresh(true);
|
|
20631
21326
|
return accepted;
|
|
20632
21327
|
} catch {
|
|
20633
|
-
|
|
21328
|
+
batchWriteFailed.current = true;
|
|
20634
21329
|
return false;
|
|
20635
21330
|
} finally {
|
|
20636
|
-
if (
|
|
21331
|
+
if (writeVersions.current.get(field) === version2) {
|
|
21332
|
+
writeVersions.current.delete(field);
|
|
21333
|
+
if (mounted.current) {
|
|
21334
|
+
setPendingValues((previous) => {
|
|
21335
|
+
const next = { ...previous };
|
|
21336
|
+
delete next[field];
|
|
21337
|
+
return next;
|
|
21338
|
+
});
|
|
21339
|
+
setPendingField([...writeVersions.current.keys()]);
|
|
21340
|
+
if (writeVersions.current.size === 0) setFormNotice(batchWriteFailed.current ? { kind: "error", text: "\u8BBE\u7F6E\u672A\u4FDD\u5B58\uFF0C\u5DF2\u6062\u590D\u539F\u503C\uFF0C\u8BF7\u91CD\u8BD5\u3002" } : { kind: "status", text: "\u8BBE\u7F6E\u5DF2\u4FDD\u5B58\u3002" });
|
|
21341
|
+
}
|
|
21342
|
+
}
|
|
21343
|
+
}
|
|
21344
|
+
}, [form, mounted, refresh]);
|
|
21345
|
+
const refreshModelsBusy = React.useRef(false);
|
|
21346
|
+
const refreshModels = React.useCallback(async () => {
|
|
21347
|
+
if (refreshModelsBusy.current) return;
|
|
21348
|
+
refreshModelsBusy.current = true;
|
|
21349
|
+
const version2 = ++modelsVersion.current;
|
|
21350
|
+
setRefreshingModels(true);
|
|
21351
|
+
setModelsNotice(null);
|
|
21352
|
+
try {
|
|
21353
|
+
const next = await caller("refreshModels");
|
|
21354
|
+
if (!mounted.current || version2 !== modelsVersion.current) return;
|
|
21355
|
+
setStatus(next);
|
|
21356
|
+
setError(void 0);
|
|
21357
|
+
setModelsNotice(next.modelsError === void 0 ? { kind: "status", text: `\u5DF2\u4ECE OpenAI \u5237\u65B0\u6A21\u578B\u5217\u8868\uFF0C\u5171 ${next.models.length} \u4E2A\u6A21\u578B\u3002` } : null);
|
|
21358
|
+
} catch {
|
|
21359
|
+
if (mounted.current && version2 === modelsVersion.current) setModelsNotice({ kind: "error", text: "\u6A21\u578B\u5237\u65B0\u672A\u5B8C\u6210\uFF0C\u8BF7\u68C0\u67E5\u51ED\u636E\u3001\u7F51\u5173\u4E0E\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002" });
|
|
21360
|
+
} finally {
|
|
21361
|
+
if (mounted.current && version2 === modelsVersion.current) {
|
|
21362
|
+
setRefreshingModels(false);
|
|
21363
|
+
refreshModelsBusy.current = false;
|
|
21364
|
+
}
|
|
20637
21365
|
}
|
|
20638
|
-
}, [
|
|
21366
|
+
}, [caller, mounted]);
|
|
20639
21367
|
const loginState = status?.login.state;
|
|
20640
21368
|
const loginActive = loginState !== void 0 && loginInFlight(loginState);
|
|
20641
21369
|
React.useEffect(() => {
|
|
@@ -20664,17 +21392,55 @@ function SettingsPage({ caller, form }) {
|
|
|
20664
21392
|
loginVersion.current += 1;
|
|
20665
21393
|
};
|
|
20666
21394
|
}, [caller, loadStatus, loginActive, mounted, refresh]);
|
|
21395
|
+
const configuredSeconds = formSnapshot.value?.quotaRefreshSeconds ?? status?.config.quotaRefreshSeconds;
|
|
21396
|
+
const refreshIntervalSeconds = configuredSeconds === void 0 ? DEFAULT_QUOTA_REFRESH_SECONDS : normaliseQuotaRefreshSeconds(configuredSeconds);
|
|
21397
|
+
const quotaNextRefreshAt = status?.quota.nextRefreshAt;
|
|
21398
|
+
const schedule = React.useMemo(
|
|
21399
|
+
() => status?.quota.state === "need-login" || status?.quota.autoRefreshPaused ? void 0 : quotaAutoRefresh(refreshIntervalSeconds, quotaNextRefreshAt, Date.now(), Boolean(status?.quota.refreshFailures)),
|
|
21400
|
+
[refreshIntervalSeconds, quotaNextRefreshAt, status?.quota.state, status?.quota.autoRefreshPaused, status?.quota.refreshFailures, scheduleTick]
|
|
21401
|
+
);
|
|
21402
|
+
React.useEffect(() => {
|
|
21403
|
+
if (schedule === void 0) return;
|
|
21404
|
+
const timer = setTimeout(() => {
|
|
21405
|
+
void refresh().finally(() => {
|
|
21406
|
+
if (mounted.current) setScheduleTick((tick) => tick + 1);
|
|
21407
|
+
});
|
|
21408
|
+
}, schedule.delayMs);
|
|
21409
|
+
return () => clearTimeout(timer);
|
|
21410
|
+
}, [schedule, refresh, mounted]);
|
|
20667
21411
|
const selectTab = (next) => {
|
|
20668
21412
|
setTab(next);
|
|
20669
21413
|
if (next === "overview" && tab !== "overview") void refresh();
|
|
20670
21414
|
};
|
|
20671
21415
|
let content;
|
|
20672
|
-
if (tab === "overview")
|
|
20673
|
-
|
|
20674
|
-
|
|
20675
|
-
|
|
20676
|
-
|
|
20677
|
-
|
|
21416
|
+
if (tab === "overview") {
|
|
21417
|
+
content = h(Overview, {
|
|
21418
|
+
status,
|
|
21419
|
+
busy: refreshing,
|
|
21420
|
+
onRefresh: () => {
|
|
21421
|
+
void refresh(true);
|
|
21422
|
+
},
|
|
21423
|
+
onConnection: () => selectTab("connection"),
|
|
21424
|
+
nextAutoRefreshAt: schedule?.at,
|
|
21425
|
+
refreshIntervalSeconds
|
|
21426
|
+
});
|
|
21427
|
+
} else if (tab === "models") {
|
|
21428
|
+
content = h(Models, {
|
|
21429
|
+
status,
|
|
21430
|
+
formSnapshot,
|
|
21431
|
+
setFormField,
|
|
21432
|
+
pendingField,
|
|
21433
|
+
onRefreshModels: () => {
|
|
21434
|
+
void refreshModels();
|
|
21435
|
+
},
|
|
21436
|
+
refreshingModels,
|
|
21437
|
+
notice: modelsNotice
|
|
21438
|
+
});
|
|
21439
|
+
} else if (tab === "connection") {
|
|
21440
|
+
content = h(Connection, { status, formSnapshot, setFormField, pendingField, caller, loadStatus, refreshAfterLogin: refresh });
|
|
21441
|
+
} else {
|
|
21442
|
+
content = h(Advanced, { status, formSnapshot, setFormField, pendingField });
|
|
21443
|
+
}
|
|
20678
21444
|
return h(
|
|
20679
21445
|
"div",
|
|
20680
21446
|
{ className: "odc-settings" },
|
|
@@ -20701,6 +21467,8 @@ function SettingsPage({ caller, form }) {
|
|
|
20701
21467
|
tabRefs.current[TABS.findIndex((candidate) => candidate.id === next)]?.focus();
|
|
20702
21468
|
}
|
|
20703
21469
|
}, item.label))),
|
|
21470
|
+
acceptedFormSnapshot.status !== "ready" || acceptedFormSnapshot.value === void 0 ? h(NoticeView, { notice: { kind: "status", text: acceptedFormSnapshot.status === "unavailable" ? "\u914D\u7F6E\u6682\u4E0D\u53EF\u7528\uFF0C\u8BF7\u68C0\u67E5\u63D2\u4EF6\u662F\u5426\u5DF2\u542F\u7528\u3002" : "\u6B63\u5728\u8F7D\u5165\u914D\u7F6E\uFF0C\u5B8C\u6210\u540E\u5373\u53EF\u4FEE\u6539\u3002" } }) : !acceptedFormSnapshot.writable ? h(NoticeView, { notice: { kind: "status", text: "\u5F53\u524D\u8BBE\u7F6E\u4E3A\u53EA\u8BFB\uFF0C\u65E0\u6CD5\u4FDD\u5B58\u4FEE\u6539\u3002" } }) : null,
|
|
21471
|
+
h(NoticeView, { notice: formNotice }),
|
|
20704
21472
|
h("div", {
|
|
20705
21473
|
className: "odc-panel",
|
|
20706
21474
|
role: "tabpanel",
|
|
@@ -20709,8 +21477,7 @@ function SettingsPage({ caller, form }) {
|
|
|
20709
21477
|
"aria-labelledby": `${baseId}-tab-${tab}`
|
|
20710
21478
|
}, content),
|
|
20711
21479
|
loading ? h("p", { className: "odc-meta", role: "status" }, "\u6B63\u5728\u8FDE\u63A5\u670D\u52A1\u2026") : null,
|
|
20712
|
-
error62 !== void 0 ? h(NoticeView, { notice: { kind: "error", text: error62 } }) : null
|
|
20713
|
-
h(NoticeView, { notice: formNotice })
|
|
21480
|
+
error62 !== void 0 ? h(NoticeView, { notice: { kind: "error", text: error62 } }) : null
|
|
20714
21481
|
);
|
|
20715
21482
|
}
|
|
20716
21483
|
var name = "dsh-opendesign-corouter";
|