dsh-llm-ustc 0.2.0 → 0.3.0
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 +17 -8
- package/lib/adapter.js +28 -24
- package/lib/adapter.js.map +1 -1
- package/lib/client.js +256 -125
- package/lib/config.js +7 -4
- package/lib/config.js.map +1 -1
- package/lib/constants.js +3 -2
- package/lib/constants.js.map +1 -1
- package/lib/index.js +25 -17
- package/lib/index.js.map +1 -1
- package/lib/model-catalog.js +5 -9
- package/lib/model-catalog.js.map +1 -1
- package/lib/state.js +9 -9
- package/lib/state.js.map +1 -1
- package/lib/tokenworks.js +379 -0
- package/lib/tokenworks.js.map +1 -0
- package/lib/types/adapter.d.ts +3 -1
- package/lib/types/adapter.d.ts.map +1 -1
- package/lib/types/client/index.d.ts +24 -6
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/config.d.ts +16 -3
- package/lib/types/config.d.ts.map +1 -1
- package/lib/types/constants.d.ts +3 -2
- package/lib/types/constants.d.ts.map +1 -1
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/model-catalog.d.ts +2 -3
- package/lib/types/model-catalog.d.ts.map +1 -1
- package/lib/types/state.d.ts +1 -1
- package/lib/types/state.d.ts.map +1 -1
- package/lib/types/tokenworks.d.ts +44 -0
- package/lib/types/tokenworks.d.ts.map +1 -0
- package/lib/types/web.d.ts +23 -1
- package/lib/types/web.d.ts.map +1 -1
- package/lib/web.js +80 -51
- package/lib/web.js.map +1 -1
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +63 -43
package/lib/client.js
CHANGED
|
@@ -9,13 +9,16 @@ let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-
|
|
|
9
9
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
10
|
//#region src/client/index.tsx
|
|
11
11
|
const LOCALE_NS = "llm-ustc";
|
|
12
|
-
const SETTINGS_ROUTE = "/
|
|
12
|
+
const SETTINGS_ROUTE = "/api/llm-ustc/settings";
|
|
13
13
|
const en = {
|
|
14
|
-
title: "USTC LLM",
|
|
15
|
-
intro: "Manage the USTC API credential, model catalog, and iWAN access.",
|
|
16
|
-
expand: "Show settings",
|
|
17
|
-
collapse: "Hide settings",
|
|
18
14
|
apiKeyLabel: "USTC API Key",
|
|
15
|
+
keySource: "Key source",
|
|
16
|
+
manualKey: "Enter API Key",
|
|
17
|
+
tokenworksKey: "Tokenworks sign-in",
|
|
18
|
+
beginTokenworks: "Sign in to Tokenworks",
|
|
19
|
+
awaitingLogin: "Waiting for browser sign-in...",
|
|
20
|
+
cancelLogin: "Cancel sign-in",
|
|
21
|
+
signedIn: "Signed in",
|
|
19
22
|
apiKeyPlaceholder: "Enter a new key",
|
|
20
23
|
configured: "Configured",
|
|
21
24
|
readOnly: "The active credential or settings provider is read-only.",
|
|
@@ -42,6 +45,8 @@ const en = {
|
|
|
42
45
|
models: "Model catalog",
|
|
43
46
|
syncModels: "Sync models",
|
|
44
47
|
syncingModels: "Syncing...",
|
|
48
|
+
removeModel: "Remove model",
|
|
49
|
+
modelsEmpty: "No models",
|
|
45
50
|
refreshedAt: "Refreshed",
|
|
46
51
|
never: "Never",
|
|
47
52
|
loading: "Loading...",
|
|
@@ -49,11 +54,14 @@ const en = {
|
|
|
49
54
|
retry: "Retry"
|
|
50
55
|
};
|
|
51
56
|
const zh = {
|
|
52
|
-
title: "科大大模型",
|
|
53
|
-
intro: "管理科大 API 凭据、模型目录和 iWAN 访问。",
|
|
54
|
-
expand: "展开设置",
|
|
55
|
-
collapse: "收起设置",
|
|
56
57
|
apiKeyLabel: "科大 API Key",
|
|
58
|
+
keySource: "Key 来源",
|
|
59
|
+
manualKey: "手动输入 API Key",
|
|
60
|
+
tokenworksKey: "词元工坊登录",
|
|
61
|
+
beginTokenworks: "登录词元工坊",
|
|
62
|
+
awaitingLogin: "等待浏览器登录...",
|
|
63
|
+
cancelLogin: "取消登录",
|
|
64
|
+
signedIn: "已登录",
|
|
57
65
|
apiKeyPlaceholder: "输入新的 Key",
|
|
58
66
|
configured: "已配置",
|
|
59
67
|
readOnly: "当前凭据或设置提供方为只读。",
|
|
@@ -80,6 +88,8 @@ const zh = {
|
|
|
80
88
|
models: "模型目录",
|
|
81
89
|
syncModels: "同步模型",
|
|
82
90
|
syncingModels: "正在同步...",
|
|
91
|
+
removeModel: "删除模型",
|
|
92
|
+
modelsEmpty: "暂无模型",
|
|
83
93
|
refreshedAt: "刷新时间",
|
|
84
94
|
never: "从未",
|
|
85
95
|
loading: "正在加载...",
|
|
@@ -101,6 +111,7 @@ var UstcSettingsController = class {
|
|
|
101
111
|
current = { status: "idle" };
|
|
102
112
|
listeners = /* @__PURE__ */ new Set();
|
|
103
113
|
generation = 0;
|
|
114
|
+
polling = false;
|
|
104
115
|
subscribe = (listener) => {
|
|
105
116
|
this.listeners.add(listener);
|
|
106
117
|
return () => {
|
|
@@ -118,7 +129,8 @@ var UstcSettingsController = class {
|
|
|
118
129
|
...this.current,
|
|
119
130
|
status: "loading",
|
|
120
131
|
action: "load",
|
|
121
|
-
error: void 0
|
|
132
|
+
error: void 0,
|
|
133
|
+
errorAction: void 0
|
|
122
134
|
});
|
|
123
135
|
try {
|
|
124
136
|
const snapshot = await apiRequest();
|
|
@@ -126,7 +138,8 @@ var UstcSettingsController = class {
|
|
|
126
138
|
this.set({
|
|
127
139
|
status: "ready",
|
|
128
140
|
snapshot,
|
|
129
|
-
oidc: this.current.oidc
|
|
141
|
+
oidc: this.current.oidc,
|
|
142
|
+
tokenworksUrl: snapshot.tokenworks.pending ? this.current.tokenworksUrl : void 0
|
|
130
143
|
});
|
|
131
144
|
} catch (error) {
|
|
132
145
|
if (generation !== this.generation) return;
|
|
@@ -134,7 +147,8 @@ var UstcSettingsController = class {
|
|
|
134
147
|
...this.current,
|
|
135
148
|
status: "error",
|
|
136
149
|
action: void 0,
|
|
137
|
-
error: messageOf(error)
|
|
150
|
+
error: messageOf(error),
|
|
151
|
+
errorAction: "load"
|
|
138
152
|
});
|
|
139
153
|
}
|
|
140
154
|
}
|
|
@@ -142,10 +156,12 @@ var UstcSettingsController = class {
|
|
|
142
156
|
if (this.current.status !== "idle" && this.current.action === void 0) this.load();
|
|
143
157
|
}
|
|
144
158
|
async run(action, request, apply) {
|
|
159
|
+
++this.generation;
|
|
145
160
|
this.set({
|
|
146
161
|
...this.current,
|
|
147
162
|
action,
|
|
148
|
-
error: void 0
|
|
163
|
+
error: void 0,
|
|
164
|
+
errorAction: void 0
|
|
149
165
|
});
|
|
150
166
|
try {
|
|
151
167
|
const value = await apiRequest({
|
|
@@ -157,7 +173,8 @@ var UstcSettingsController = class {
|
|
|
157
173
|
this.set({
|
|
158
174
|
...this.current,
|
|
159
175
|
action: void 0,
|
|
160
|
-
error: messageOf(error)
|
|
176
|
+
error: messageOf(error),
|
|
177
|
+
errorAction: action
|
|
161
178
|
});
|
|
162
179
|
}
|
|
163
180
|
}
|
|
@@ -165,7 +182,8 @@ var UstcSettingsController = class {
|
|
|
165
182
|
return this.run(action, request, (snapshot, state) => ({
|
|
166
183
|
status: "ready",
|
|
167
184
|
snapshot,
|
|
168
|
-
oidc: state.oidc
|
|
185
|
+
oidc: state.oidc,
|
|
186
|
+
tokenworksUrl: snapshot.tokenworks.pending ? state.tokenworksUrl : void 0
|
|
169
187
|
}));
|
|
170
188
|
}
|
|
171
189
|
beginOidc() {
|
|
@@ -175,6 +193,37 @@ var UstcSettingsController = class {
|
|
|
175
193
|
oidc
|
|
176
194
|
}));
|
|
177
195
|
}
|
|
196
|
+
beginTokenworks() {
|
|
197
|
+
return this.run("beginTokenworks", {}, (value, state) => ({
|
|
198
|
+
...state,
|
|
199
|
+
status: "ready",
|
|
200
|
+
action: void 0,
|
|
201
|
+
snapshot: value.snapshot,
|
|
202
|
+
tokenworksUrl: value.authUrl
|
|
203
|
+
}));
|
|
204
|
+
}
|
|
205
|
+
async pollLogin() {
|
|
206
|
+
if (this.current.action !== void 0 || this.polling) return;
|
|
207
|
+
this.polling = true;
|
|
208
|
+
const generation = this.generation;
|
|
209
|
+
try {
|
|
210
|
+
const snapshot = await apiRequest();
|
|
211
|
+
if (generation !== this.generation) return;
|
|
212
|
+
this.set({
|
|
213
|
+
...this.current,
|
|
214
|
+
snapshot,
|
|
215
|
+
tokenworksUrl: snapshot.tokenworks.pending ? this.current.tokenworksUrl : void 0
|
|
216
|
+
});
|
|
217
|
+
} catch (error) {
|
|
218
|
+
if (generation === this.generation) this.set({
|
|
219
|
+
...this.current,
|
|
220
|
+
error: messageOf(error),
|
|
221
|
+
errorAction: "beginTokenworks"
|
|
222
|
+
});
|
|
223
|
+
} finally {
|
|
224
|
+
this.polling = false;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
178
227
|
completeOidc(callbackUrl) {
|
|
179
228
|
return this.run("completeOidc", { callbackUrl }, (value) => ({
|
|
180
229
|
status: "ready",
|
|
@@ -185,58 +234,28 @@ var UstcSettingsController = class {
|
|
|
185
234
|
function messageOf(error) {
|
|
186
235
|
return error instanceof Error ? error.message : String(error);
|
|
187
236
|
}
|
|
188
|
-
function
|
|
189
|
-
if (controller === void 0 || t === void 0) return null;
|
|
190
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UstcCard, {
|
|
191
|
-
controller,
|
|
192
|
-
t
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
function UstcCard({ controller, t }) {
|
|
237
|
+
function UstcBundleConfig({ controller, t }) {
|
|
196
238
|
const state = (0, react.useSyncExternalStore)(controller.subscribe, controller.snapshot, controller.snapshot);
|
|
197
|
-
const [open, setOpen] = (0, react.useState)(false);
|
|
198
|
-
(0, react.useEffect)(() => {
|
|
199
|
-
if (state.status === "idle") controller.load();
|
|
200
|
-
}, [controller, state.status]);
|
|
201
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
202
|
-
className: "ulu-card",
|
|
203
|
-
"data-open": open || void 0,
|
|
204
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
205
|
-
type: "button",
|
|
206
|
-
className: "ulu-card-header",
|
|
207
|
-
"aria-expanded": open,
|
|
208
|
-
"aria-label": `${t(open ? "collapse" : "expand")}: ${t("title")}`,
|
|
209
|
-
onClick: () => {
|
|
210
|
-
setOpen((value) => !value);
|
|
211
|
-
},
|
|
212
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
213
|
-
className: "ulu-card-head-text",
|
|
214
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
215
|
-
className: "ulu-card-name",
|
|
216
|
-
children: t("title")
|
|
217
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
218
|
-
className: "ulu-card-description",
|
|
219
|
-
children: t("intro")
|
|
220
|
-
})]
|
|
221
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: "ulu-card-chevron" })]
|
|
222
|
-
}), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
223
|
-
className: "ulu-card-body",
|
|
224
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LoadedSettings, {
|
|
225
|
-
controller,
|
|
226
|
-
t,
|
|
227
|
-
state
|
|
228
|
-
})
|
|
229
|
-
}) : null]
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
function LoadedSettings({ controller, t, state }) {
|
|
233
239
|
const snapshot = state.snapshot;
|
|
234
240
|
const [apiKey, setApiKey] = (0, react.useState)("");
|
|
235
241
|
const [callbackUrl, setCallbackUrl] = (0, react.useState)("");
|
|
236
242
|
const [selectedServerId, setSelectedServerId] = (0, react.useState)("");
|
|
243
|
+
(0, react.useEffect)(() => {
|
|
244
|
+
controller.load();
|
|
245
|
+
}, [controller]);
|
|
237
246
|
(0, react.useEffect)(() => {
|
|
238
247
|
setSelectedServerId(snapshot?.selectedServerId ?? "");
|
|
239
248
|
}, [snapshot?.selectedServerId]);
|
|
249
|
+
(0, react.useEffect)(() => {
|
|
250
|
+
setApiKey("");
|
|
251
|
+
}, [snapshot?.keySource]);
|
|
252
|
+
(0, react.useEffect)(() => {
|
|
253
|
+
if (!snapshot?.tokenworks.pending) return;
|
|
254
|
+
const timer = setInterval(() => {
|
|
255
|
+
controller.pollLogin();
|
|
256
|
+
}, 1500);
|
|
257
|
+
return () => clearInterval(timer);
|
|
258
|
+
}, [controller, snapshot?.tokenworks.pending]);
|
|
240
259
|
if ((state.status === "idle" || state.status === "loading") && snapshot === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
241
260
|
className: "ulu-loading",
|
|
242
261
|
children: t("loading")
|
|
@@ -260,31 +279,7 @@ function LoadedSettings({ controller, t, state }) {
|
|
|
260
279
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
261
280
|
className: "ulu-settings",
|
|
262
281
|
children: [
|
|
263
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
264
|
-
className: "ulu-status-row",
|
|
265
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("route") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
266
|
-
className: "ulu-route-value",
|
|
267
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: snapshot.usingIwan ? t("iwanRoute") : t("directRoute") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
268
|
-
label: t("refreshRoute"),
|
|
269
|
-
side: "top",
|
|
270
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
271
|
-
className: "ulu-route-refresh",
|
|
272
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
273
|
-
type: "button",
|
|
274
|
-
variant: "toolbar",
|
|
275
|
-
size: "sm",
|
|
276
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline14, { className: state.action === "refreshRoute" ? "ulu-spin" : void 0 }),
|
|
277
|
-
"aria-label": t("refreshRoute"),
|
|
278
|
-
disabled: busy,
|
|
279
|
-
onClick: () => {
|
|
280
|
-
controller.mutateSnapshot("refreshRoute");
|
|
281
|
-
}
|
|
282
|
-
})
|
|
283
|
-
})
|
|
284
|
-
})]
|
|
285
|
-
})]
|
|
286
|
-
}),
|
|
287
|
-
!snapshot.writable || !snapshot.apiKey.writable || !snapshot.iwan.writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
282
|
+
!snapshot.writable || !(snapshot.keySource === "manual" ? snapshot.apiKey.writable : snapshot.tokenworks.writable) || !snapshot.iwan.writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
288
283
|
className: "ulu-alert warning",
|
|
289
284
|
children: t("readOnly")
|
|
290
285
|
}) : null,
|
|
@@ -295,17 +290,36 @@ function LoadedSettings({ controller, t, state }) {
|
|
|
295
290
|
className: "ulu-section-title",
|
|
296
291
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("apiKeyLabel") })
|
|
297
292
|
}),
|
|
298
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
293
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
294
|
+
className: "ulu-line-select",
|
|
295
|
+
"aria-label": t("keySource"),
|
|
296
|
+
value: snapshot.keySource,
|
|
297
|
+
disabled: busy || !snapshot.writable,
|
|
298
|
+
onChange: (event) => {
|
|
299
|
+
controller.mutateSnapshot("selectKeySource", {
|
|
300
|
+
keySource: event.target.value,
|
|
301
|
+
expectedRevision: snapshot.revision
|
|
302
|
+
});
|
|
303
|
+
},
|
|
304
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
305
|
+
value: "manual",
|
|
306
|
+
children: t("manualKey")
|
|
307
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
308
|
+
value: "tokenworks",
|
|
309
|
+
children: t("tokenworksKey")
|
|
310
|
+
})]
|
|
311
|
+
}),
|
|
312
|
+
snapshot.keySource === "manual" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
313
|
+
className: "ulu-input",
|
|
299
314
|
type: "password",
|
|
300
|
-
autoComplete: "
|
|
315
|
+
autoComplete: "new-password",
|
|
301
316
|
"aria-label": t("apiKeyLabel"),
|
|
302
317
|
placeholder: snapshot.apiKey.configured ? t("configured") : t("apiKeyPlaceholder"),
|
|
303
318
|
value: apiKey,
|
|
304
319
|
onChange: (event) => {
|
|
305
320
|
setApiKey(event.target.value);
|
|
306
321
|
}
|
|
307
|
-
}),
|
|
308
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
322
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
309
323
|
className: "ulu-actions",
|
|
310
324
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
311
325
|
size: "sm",
|
|
@@ -326,9 +340,80 @@ function LoadedSettings({ controller, t, state }) {
|
|
|
326
340
|
},
|
|
327
341
|
children: t("remove")
|
|
328
342
|
})]
|
|
329
|
-
})
|
|
343
|
+
})] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
344
|
+
className: "ulu-login-row",
|
|
345
|
+
children: snapshot.tokenworks.pending ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [state.tokenworksUrl === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
346
|
+
className: "ulu-login-state",
|
|
347
|
+
children: t("awaitingLogin")
|
|
348
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
349
|
+
className: "ulu-link",
|
|
350
|
+
href: state.tokenworksUrl,
|
|
351
|
+
target: "_blank",
|
|
352
|
+
rel: "noopener noreferrer",
|
|
353
|
+
children: t("openLogin")
|
|
354
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
355
|
+
size: "sm",
|
|
356
|
+
variant: "outline",
|
|
357
|
+
disabled: busy,
|
|
358
|
+
onClick: () => {
|
|
359
|
+
controller.mutateSnapshot("cancelTokenworks");
|
|
360
|
+
},
|
|
361
|
+
children: t("cancelLogin")
|
|
362
|
+
})] }) : snapshot.tokenworks.configured ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
363
|
+
className: "ulu-login-state",
|
|
364
|
+
children: snapshot.tokenworks.name ?? t("signedIn")
|
|
365
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
366
|
+
size: "sm",
|
|
367
|
+
variant: "outline",
|
|
368
|
+
disabled: busy || !snapshot.tokenworks.writable,
|
|
369
|
+
onClick: () => {
|
|
370
|
+
controller.mutateSnapshot("logoutTokenworks");
|
|
371
|
+
},
|
|
372
|
+
children: state.action === "logoutTokenworks" ? t("loggingOut") : t("logoutIwan")
|
|
373
|
+
})] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
374
|
+
size: "sm",
|
|
375
|
+
variant: "primary",
|
|
376
|
+
disabled: busy || !snapshot.tokenworks.writable,
|
|
377
|
+
onClick: () => {
|
|
378
|
+
controller.beginTokenworks();
|
|
379
|
+
},
|
|
380
|
+
children: state.action === "beginTokenworks" ? t("startingOidc") : t("beginTokenworks")
|
|
381
|
+
})
|
|
382
|
+
}),
|
|
383
|
+
state.errorAction === "saveApiKey" || state.errorAction === "unsetApiKey" || state.errorAction === "selectKeySource" || state.errorAction === "beginTokenworks" || state.errorAction === "cancelTokenworks" || state.errorAction === "logoutTokenworks" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
384
|
+
className: "ulu-alert error",
|
|
385
|
+
children: state.error
|
|
386
|
+
}) : null,
|
|
387
|
+
snapshot.keySource === "tokenworks" && snapshot.tokenworks.error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
388
|
+
className: "ulu-alert error",
|
|
389
|
+
children: snapshot.tokenworks.error
|
|
390
|
+
}) : null
|
|
330
391
|
]
|
|
331
392
|
}),
|
|
393
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
394
|
+
className: "ulu-status-row",
|
|
395
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("route") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
396
|
+
className: "ulu-route-value",
|
|
397
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: snapshot.usingIwan ? t("iwanRoute") : t("directRoute") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
398
|
+
label: t("refreshRoute"),
|
|
399
|
+
side: "top",
|
|
400
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
401
|
+
className: "ulu-route-refresh",
|
|
402
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
403
|
+
type: "button",
|
|
404
|
+
variant: "ghost",
|
|
405
|
+
size: "sm",
|
|
406
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutlineMedium, { className: state.action === "refreshRoute" ? "ulu-spin" : void 0 }),
|
|
407
|
+
"aria-label": t("refreshRoute"),
|
|
408
|
+
disabled: busy,
|
|
409
|
+
onClick: () => {
|
|
410
|
+
controller.mutateSnapshot("refreshRoute");
|
|
411
|
+
}
|
|
412
|
+
})
|
|
413
|
+
})
|
|
414
|
+
})]
|
|
415
|
+
})]
|
|
416
|
+
}),
|
|
332
417
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
333
418
|
className: "ulu-section",
|
|
334
419
|
children: [
|
|
@@ -368,7 +453,8 @@ function LoadedSettings({ controller, t, state }) {
|
|
|
368
453
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
369
454
|
htmlFor: "ulu-callback-url",
|
|
370
455
|
children: t("callbackLabel")
|
|
371
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
456
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
457
|
+
className: "ulu-input",
|
|
372
458
|
id: "ulu-callback-url",
|
|
373
459
|
value: callbackUrl,
|
|
374
460
|
placeholder: t("callbackPlaceholder"),
|
|
@@ -417,46 +503,91 @@ function LoadedSettings({ controller, t, state }) {
|
|
|
417
503
|
},
|
|
418
504
|
children: state.action === "selectServer" ? t("applyingLine") : t("selectLine")
|
|
419
505
|
})]
|
|
506
|
+
}) : null,
|
|
507
|
+
state.errorAction === "beginOidc" || state.errorAction === "completeOidc" || state.errorAction === "logoutIwan" || state.errorAction === "selectServer" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
508
|
+
className: "ulu-alert error",
|
|
509
|
+
children: state.error
|
|
420
510
|
}) : null
|
|
421
511
|
]
|
|
422
512
|
}),
|
|
423
513
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
424
514
|
className: "ulu-section",
|
|
425
|
-
children: [
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
t("
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
className: "ulu-model-
|
|
444
|
-
children: [
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
515
|
+
children: [
|
|
516
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
517
|
+
className: "ulu-section-title",
|
|
518
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("models") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", { children: [
|
|
519
|
+
t("refreshedAt"),
|
|
520
|
+
": ",
|
|
521
|
+
snapshot.modelsUpdatedAt === void 0 ? t("never") : new Date(snapshot.modelsUpdatedAt).toLocaleString()
|
|
522
|
+
] })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
523
|
+
size: "sm",
|
|
524
|
+
variant: "outline",
|
|
525
|
+
disabled: busy || !(snapshot.keySource === "manual" ? snapshot.apiKey.configured : snapshot.tokenworks.configured),
|
|
526
|
+
onClick: () => {
|
|
527
|
+
controller.mutateSnapshot("syncModels");
|
|
528
|
+
},
|
|
529
|
+
children: state.action === "syncModels" ? t("syncingModels") : t("syncModels")
|
|
530
|
+
})]
|
|
531
|
+
}),
|
|
532
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
533
|
+
className: "ulu-model-list",
|
|
534
|
+
children: [snapshot.models.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
535
|
+
className: "ulu-model-entry",
|
|
536
|
+
children: [
|
|
537
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: model.id }),
|
|
538
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: model.name === model.id ? "" : model.name }),
|
|
539
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
540
|
+
className: "ulu-model-remove",
|
|
541
|
+
type: "button",
|
|
542
|
+
title: t("removeModel"),
|
|
543
|
+
"aria-label": `${t("removeModel")}: ${model.id}`,
|
|
544
|
+
disabled: busy,
|
|
545
|
+
onClick: () => {
|
|
546
|
+
controller.mutateSnapshot("removeModel", { modelId: model.id });
|
|
547
|
+
},
|
|
548
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutlineRegular, {})
|
|
549
|
+
})
|
|
550
|
+
]
|
|
551
|
+
}, model.id)), snapshot.models.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
552
|
+
className: "ulu-model-empty",
|
|
553
|
+
children: t("modelsEmpty")
|
|
554
|
+
}) : null]
|
|
555
|
+
}),
|
|
556
|
+
state.errorAction === "syncModels" || state.errorAction === "removeModel" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
557
|
+
className: "ulu-alert error",
|
|
558
|
+
children: state.error
|
|
559
|
+
}) : null
|
|
560
|
+
]
|
|
561
|
+
}),
|
|
562
|
+
state.errorAction === "refreshRoute" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
563
|
+
className: "ulu-alert error",
|
|
564
|
+
children: state.error
|
|
565
|
+
}) : null
|
|
448
566
|
]
|
|
449
567
|
});
|
|
450
568
|
}
|
|
451
569
|
const CSS = `
|
|
452
|
-
.ulu-
|
|
453
|
-
.ulu-
|
|
454
|
-
.ulu-
|
|
455
|
-
.ulu-section{display:grid;min-width:0;gap:6px;padding:12px 0;border-top:
|
|
456
|
-
.ulu-
|
|
457
|
-
.ulu-
|
|
458
|
-
.ulu-
|
|
459
|
-
.ulu-
|
|
570
|
+
.ulu-settings{display:flex;min-width:0;flex-direction:column;color:var(--dsw-alias-label-primary)}
|
|
571
|
+
.ulu-status-row{display:flex;min-height:34px;align-items:center;justify-content:space-between;gap:16px;padding:12px 0;border-top:0.5px solid var(--dsw-alias-border-l2);font-size:13px;line-height:1.5}
|
|
572
|
+
.ulu-status-row strong{font-weight:500}.ulu-route-value{display:flex;align-items:center;gap:5px}.ulu-route-refresh{display:inline-flex}.ulu-route-refresh>button,.ulu-route-refresh>button:hover:not(:disabled),.ulu-route-refresh>button:active:not(:disabled){width:28px;padding:0;background:transparent}
|
|
573
|
+
.ulu-section{display:grid;min-width:0;gap:6px;padding:12px 0;border-top:0.5px solid var(--dsw-alias-border-l2)}.ulu-section>*{min-width:0}
|
|
574
|
+
.ulu-section-title{display:flex;min-width:0;align-items:center;justify-content:space-between;gap:8px}.ulu-section-title>div{min-width:0}
|
|
575
|
+
.ulu-section-title h3,.ulu-field>label{margin:0;color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:1.5}
|
|
576
|
+
.ulu-section-title p{margin:3px 0 0;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5;overflow-wrap:anywhere}
|
|
577
|
+
.ulu-input,.ulu-line-select{box-sizing:border-box;width:100%;height:34px;padding:0 12px;border:0.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;line-height:1.5}
|
|
578
|
+
.ulu-input::placeholder{color:var(--dsw-alias-label-dimmed)}.ulu-input:focus-visible,.ulu-line-select:focus-visible{outline:none;border-color:var(--dsw-alias-state-business-primary)}
|
|
579
|
+
.ulu-row{display:grid;min-width:0;grid-template-columns:minmax(0,1fr) auto;align-items:end;gap:10px}.ulu-field{display:grid;min-width:0;gap:6px}.ulu-field>*{min-width:0}
|
|
580
|
+
.ulu-actions,.ulu-login-row{display:flex;min-width:0;align-items:center;gap:8px}.ulu-actions{padding-top:16px}.ulu-actions button:first-child,.ulu-login-row button,.ulu-row>button{min-height:31px;padding:5px 14px;border-radius:var(--dsw-radius-md);font-size:13px;line-height:1.5}
|
|
581
|
+
.ulu-link{display:inline-flex;min-height:31px;align-items:center;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.5;text-decoration:none}.ulu-link:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}
|
|
582
|
+
.ulu-login-state{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.5}
|
|
583
|
+
.ulu-spin{animation:ulu-spin .7s linear infinite}@keyframes ulu-spin{to{transform:rotate(360deg)}}
|
|
584
|
+
.ulu-alert{margin:0;padding:10px 0;border-top:0.5px solid var(--dsw-alias-border-l2);font-size:12px;line-height:1.5}.ulu-alert.warning{color:var(--dsw-alias-label-tertiary)}.ulu-alert.error{color:var(--dsw-alias-label-error)}
|
|
585
|
+
.ulu-loading{padding:12px 0;color:var(--dsw-alias-label-tertiary);font-size:12px}.ulu-load-error{display:flex;align-items:center;justify-content:space-between;gap:12px}.ulu-load-error .ulu-alert{flex:1;border-top:0}
|
|
586
|
+
.ulu-model-list{display:flex;max-height:300px;min-width:0;flex-direction:column;overflow:auto;border-top:0.5px solid var(--dsw-alias-border-l2)}
|
|
587
|
+
.ulu-model-entry{display:grid;min-width:0;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr) auto;align-items:center;gap:8px;padding:9px 2px;border-bottom:0.5px solid var(--dsw-alias-border-l2);font-size:12px;line-height:18px}
|
|
588
|
+
.ulu-model-entry code,.ulu-model-entry span{min-width:0;overflow-wrap:anywhere}.ulu-model-entry span{color:var(--dsw-alias-label-tertiary)}
|
|
589
|
+
.ulu-model-remove{display:inline-flex;width:20px;height:20px;align-items:center;justify-content:center;padding:0;border:0;background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer}.ulu-model-remove:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.ulu-model-remove:disabled{opacity:.5;cursor:default}
|
|
590
|
+
.ulu-model-empty{padding:9px 2px;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}
|
|
460
591
|
`;
|
|
461
592
|
function installStyles() {
|
|
462
593
|
const id = "dsh-llm-ustc/client";
|
|
@@ -486,14 +617,14 @@ function apply(ctx) {
|
|
|
486
617
|
dispose();
|
|
487
618
|
};
|
|
488
619
|
}, "dsh-llm-ustc: settings invalidations");
|
|
489
|
-
ctx.slots.inject("
|
|
490
|
-
name: "
|
|
491
|
-
key:
|
|
620
|
+
ctx.slots.inject("plugins.bundle.config", () => ctx.slots.register({
|
|
621
|
+
name: "plugins.bundle.config",
|
|
622
|
+
key: "dsh-llm-ustc",
|
|
492
623
|
inject: () => ({
|
|
493
624
|
controller,
|
|
494
625
|
t
|
|
495
626
|
})
|
|
496
|
-
},
|
|
627
|
+
}, UstcBundleConfig));
|
|
497
628
|
}
|
|
498
629
|
//#endregion
|
|
499
630
|
exports.UstcSettingsController = UstcSettingsController;
|
package/lib/config.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import z from '@deepseek-ai/schemastery';
|
|
2
|
+
import { API_KEY_REF } from "./constants.js";
|
|
2
3
|
export const Config = z.object({
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
apiKeyEnv: z.union([API_KEY_REF]).role('credential-ref').default(API_KEY_REF).volatile(),
|
|
5
|
+
keySource: z.union(['manual', 'tokenworks']).default('manual').volatile(),
|
|
6
|
+
selectedServerId: z.string().volatile(),
|
|
7
|
+
directRecoverySeconds: z.number().step(1).min(30).max(86_400).default(300).volatile(),
|
|
5
8
|
});
|
|
6
9
|
export function resolveConfig(config) {
|
|
7
|
-
const directRecoverySeconds = config.directRecoverySeconds
|
|
10
|
+
const directRecoverySeconds = config.directRecoverySeconds.get();
|
|
8
11
|
if (!Number.isSafeInteger(directRecoverySeconds) || directRecoverySeconds < 30 || directRecoverySeconds > 86_400) {
|
|
9
12
|
throw new TypeError('llm-ustc.directRecoverySeconds must be an integer from 30 to 86400');
|
|
10
13
|
}
|
|
11
|
-
const selected = config.selectedServerId?.trim();
|
|
14
|
+
const selected = config.selectedServerId.get()?.trim();
|
|
12
15
|
return {
|
|
13
16
|
...(selected === undefined || selected.length === 0 ? {} : { selectedServerId: selected }),
|
|
14
17
|
directRecoverySeconds,
|
package/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,CAAC,MAAM,0BAA0B,CAAA;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAS5C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE;IACxF,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE;IACzE,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACvC,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;CACtF,CAAC,CAAA;AAOF,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,qBAAqB,GAAG,MAAM,CAAC,qBAAqB,CAAC,GAAG,EAAE,CAAA;IAChE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,qBAAqB,CAAC,IAAI,qBAAqB,GAAG,EAAE,IAAI,qBAAqB,GAAG,MAAM,EAAE,CAAC;QACjH,MAAM,IAAI,SAAS,CAAC,oEAAoE,CAAC,CAAA;IAC3F,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAA;IACtD,OAAO;QACL,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,QAAQ,EAAE,CAAC;QAC1F,qBAAqB;KACtB,CAAA;AACH,CAAC"}
|
package/lib/constants.js
CHANGED
|
@@ -2,10 +2,11 @@ export const PROVIDER = 'ustc';
|
|
|
2
2
|
export const PROVIDER_NAME = 'USTC LLM';
|
|
3
3
|
export const SETTINGS_NS = 'llm-ustc';
|
|
4
4
|
export const API_KEY_REF = 'USTC_LLM_API_KEY';
|
|
5
|
+
export const TOKENWORKS_SESSION_REF = 'USTC_LLM_TOKENWORKS_SESSION';
|
|
5
6
|
export const IWAN_CONFIG_REF = 'USTC_LLM_IWAN_CONFIG';
|
|
6
|
-
export const DEFAULT_MODEL = 'deepseek-
|
|
7
|
+
export const DEFAULT_MODEL = 'deepseek-flash';
|
|
7
8
|
export const DEFAULT_CONTEXT_WINDOW = 262_144;
|
|
8
9
|
export const DEFAULT_MAX_TOKENS = 32_768;
|
|
9
10
|
export const HELPER_PROTOCOL = 'v2';
|
|
10
|
-
export const SETTINGS_ROUTE = '/
|
|
11
|
+
export const SETTINGS_ROUTE = '/api/llm-ustc/settings';
|
|
11
12
|
//# sourceMappingURL=constants.js.map
|
package/lib/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAA;AAC9B,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAA;AACvC,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAA;AACrC,MAAM,CAAC,MAAM,WAAW,GAAG,kBAAkB,CAAA;AAC7C,MAAM,CAAC,MAAM,eAAe,GAAG,sBAAsB,CAAA;AACrD,MAAM,CAAC,MAAM,aAAa,GAAG,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAA;AAC9B,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAA;AACvC,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAA;AACrC,MAAM,CAAC,MAAM,WAAW,GAAG,kBAAkB,CAAA;AAC7C,MAAM,CAAC,MAAM,sBAAsB,GAAG,6BAA6B,CAAA;AACnE,MAAM,CAAC,MAAM,eAAe,GAAG,sBAAsB,CAAA;AACrD,MAAM,CAAC,MAAM,aAAa,GAAG,gBAAgB,CAAA;AAC7C,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAA;AAC7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAA;AACxC,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAA;AACnC,MAAM,CAAC,MAAM,cAAc,GAAG,wBAAwB,CAAA"}
|