dsh-provider-qoder 0.1.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/lib/client.js ADDED
@@ -0,0 +1,944 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "dsh-provider-qoder",
3
+ factory: (require) => {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ let react = require("react");
8
+ let react_jsx_runtime = require("react/jsx-runtime");
9
+ //#region src/credential-contract.ts
10
+ /** Shared Host/browser contract for the one managed Qoder credential. */
11
+ const qoderCredentialRef = "QODER_MANAGED_CREDENTIAL";
12
+ /** DSH's local provider uses `env` and `*-env` for ambient credential layers. */
13
+ function isEnvironmentCredentialSource(source) {
14
+ return source === "env" || source?.endsWith("-env") === true;
15
+ }
16
+ //#endregion
17
+ //#region \0dsh-css:D:\code\dsh\dsh-llm-qoder\src\client\QoderCredentialCard.module.css.mjs
18
+ const css = ".OAuTmW_credential{color:var(--dsw-alias-label-primary);border-radius:10px;margin-top:12px}.OAuTmW_credential p{margin:8px 0 0}.OAuTmW_credentialEditor{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;flex-direction:column;gap:12px;padding:12px 14px;display:flex}.OAuTmW_credentialRowHead{align-items:center;gap:10px;display:flex}.OAuTmW_credentialIdentity{align-items:center;gap:6px;min-width:0;display:inline-flex}.OAuTmW_credentialName{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.OAuTmW_credentialDot{box-sizing:border-box;border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.OAuTmW_credentialDotConfigured{background:var(--dsw-alias-state-success-primary)}.OAuTmW_credentialDotMissing{background:var(--dsw-alias-state-error-primary)}.OAuTmW_regionBadge{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:4px;align-items:center;padding:1px 6px;font-size:11px;font-weight:500;line-height:16px;display:inline-flex}.OAuTmW_regionSelector{flex-direction:column;gap:8px;margin-bottom:14px;display:flex}.OAuTmW_regionGroup{gap:8px;display:flex}.OAuTmW_regionOption{border:1px solid var(--dsw-alias-border-l2);cursor:pointer;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);user-select:none;border-radius:8px;align-items:center;gap:6px;padding:6px 12px;font-size:12px;line-height:18px;transition:all .12s;display:inline-flex}.OAuTmW_regionOption:hover:not(.OAuTmW_regionOptionDisabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.OAuTmW_credential button.OAuTmW_regionOptionActive{border-color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-interactive-bg-selected);color:var(--dsw-alias-brand-primary);font-weight:500}.OAuTmW_regionOptionDisabled{cursor:not-allowed;opacity:.5}.OAuTmW_editButton{box-sizing:border-box;font:inherit;background:0 0;margin-left:auto;font-size:12px;line-height:18px;border:1px solid var(--dsw-alias-border-l2)!important;border-radius:14px!important;height:28px!important;padding:0 10px!important}.OAuTmW_editButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.OAuTmW_editor{background:var(--dsw-alias-bg-module-platform);border-radius:12px;padding:14px 16px}.OAuTmW_customized{border-top:1px solid var(--dsw-alias-border-l2);margin-top:14px;padding-top:10px}.OAuTmW_customizedSummary{cursor:pointer;width:fit-content;color:var(--dsw-alias-label-secondary);border-radius:6px;align-items:center;gap:6px;margin-left:-4px;padding:2px 4px;font-size:12px;font-weight:500;line-height:18px;list-style:none;display:flex}.OAuTmW_customizedSummary::-webkit-details-marker{display:none}.OAuTmW_customizedSummary:before{content:\"\";border-bottom:1.5px solid;border-right:1.5px solid;width:5px;height:5px;transition:transform .12s;transform:rotate(-45deg)translate(-1px,-1px)}.OAuTmW_customized[open]>.OAuTmW_customizedSummary:before{transform:rotate(45deg)translate(-1px,-1px)}.OAuTmW_customizedBody{padding-top:12px}.OAuTmW_modelCatalog,.OAuTmW_modelList{flex-direction:column;gap:10px;display:flex}.OAuTmW_modelCatalogHead{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.OAuTmW_modelCatalogTitle{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}.OAuTmW_modelCatalogMeta{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;margin:2px 0 0!important}.OAuTmW_linkButton{box-sizing:border-box;font:inherit;background:0 0;font-size:12px;line-height:18px;border:none!important;border-radius:14px!important;height:28px!important;padding:0 10px!important}.OAuTmW_linkButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.OAuTmW_modelChoice{cursor:pointer;border-radius:6px;grid-template-columns:auto minmax(0,1fr) auto auto auto;align-items:center;gap:8px;padding:6px 8px;font-size:13px;display:grid}.OAuTmW_modelChoice:hover{background:var(--dsw-alias-interactive-bg-hover)}.OAuTmW_modelChoiceName{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.OAuTmW_modelChoice code{color:var(--dsw-alias-label-tertiary);font-size:11px}.OAuTmW_modelRate{min-width:34px;color:var(--dsw-alias-brand-primary);text-align:right;font-size:12px;font-weight:600}.OAuTmW_modelUnavailable{cursor:not-allowed;opacity:.55}.OAuTmW_modelBadge{color:var(--dsw-alias-state-error-primary);font-size:11px}@media (prefers-reduced-motion:reduce){.OAuTmW_customizedSummary:before{transition:none}}.OAuTmW_head{justify-content:space-between;align-items:center;gap:12px;margin-bottom:20px;display:flex}.OAuTmW_heading{margin:0;font-size:18px;font-weight:600}.OAuTmW_status{color:var(--dsw-alias-label-secondary);font-size:12px}.OAuTmW_configured,.OAuTmW_success{color:var(--dsw-alias-state-success-primary)}.OAuTmW_label{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px;display:block}.OAuTmW_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;height:32px;color:var(--dsw-alias-label-primary);border-radius:8px;outline:none;margin-top:6px;padding:0 10px}.OAuTmW_input:focus{border-color:var(--dsw-alias-brand-primary)}.OAuTmW_input::placeholder{color:var(--dsw-alias-label-dimmed)}.OAuTmW_input:disabled{cursor:not-allowed;opacity:.4}.OAuTmW_hint{color:var(--dsw-alias-label-secondary);font-size:12px}.OAuTmW_actions{justify-content:flex-end;gap:8px;margin-top:14px;display:flex}.OAuTmW_credential button{cursor:pointer;height:32px;color:var(--dsw-alias-label-primary);border:1px solid #0000;border-radius:16px;padding:0 12px}.OAuTmW_credential button:disabled{cursor:not-allowed;opacity:.4}.OAuTmW_primary{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)!important}.OAuTmW_primary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}.OAuTmW_secondary{background:0 0;border-color:var(--dsw-alias-border-l2)!important}.OAuTmW_secondary:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.OAuTmW_danger{background:0 0;border-color:var(--dsw-alias-state-error-primary)!important;color:var(--dsw-alias-state-error-primary)!important}.OAuTmW_danger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.OAuTmW_error{color:var(--dsw-alias-state-error-primary);font-size:12px}.OAuTmW_success{font-size:12px}.OAuTmW_accountSection{background:var(--dsw-alias-bg-module-platform);border-radius:8px;flex-direction:column;gap:10px;margin-top:12px;padding:12px;display:flex}.OAuTmW_accountHead{justify-content:space-between;align-items:center;gap:8px;display:flex}.OAuTmW_userInfo{align-items:center;gap:10px;min-width:0;display:flex}.OAuTmW_avatar{background:var(--dsw-alias-brand-primary);width:32px;height:32px;color:var(--dsw-alias-label-primary-foreground);text-transform:uppercase;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-size:14px;font-weight:600;display:flex}.OAuTmW_userDetails{flex-direction:column;gap:2px;min-width:0;display:flex}.OAuTmW_userName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;overflow:hidden}.OAuTmW_userEmail{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.OAuTmW_refreshBtn{border:1px solid var(--dsw-alias-border-l2)!important;height:26px!important;color:var(--dsw-alias-label-secondary)!important;background:0 0!important;border-radius:13px!important;padding:0 8px!important;font-size:12px!important}.OAuTmW_refreshBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)!important}.OAuTmW_quotaBlock{border-top:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:6px;padding-top:8px;display:flex}.OAuTmW_quotaHeader{justify-content:space-between;align-items:center;gap:8px;display:flex}.OAuTmW_quotaLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}.OAuTmW_quotaTop{justify-content:space-between;align-items:baseline;gap:8px;font-size:12px;display:flex}.OAuTmW_quotaTop strong{color:var(--dsw-alias-brand-primary);font-size:13px}.OAuTmW_quotaProgress{background:var(--dsw-alias-border-l3);width:100%;height:6px;accent-color:var(--dsw-alias-brand-primary);-webkit-appearance:none;appearance:none;border:0;border-radius:999px;overflow:hidden}.OAuTmW_quotaProgress::-webkit-progress-bar{background:var(--dsw-alias-border-l3);border-radius:999px}.OAuTmW_quotaProgress::-webkit-progress-value{background:var(--dsw-alias-brand-primary);border-radius:999px}.OAuTmW_quotaProgress::-moz-progress-bar{background:var(--dsw-alias-brand-primary);border-radius:999px}.OAuTmW_quotaMeta{color:var(--dsw-alias-label-tertiary);justify-content:space-between;align-items:center;gap:8px;font-size:11px;display:flex}.OAuTmW_accountLoadingText,.OAuTmW_accountEmptyText{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px}";
19
+ const tagId = "dsh-provider-qoder/QoderCredentialCard.module.css";
20
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
21
+ const tag = document.createElement("style");
22
+ tag.dataset.plugin = "dsh-provider-qoder";
23
+ tag.dataset.pluginCss = tagId;
24
+ tag.textContent = css;
25
+ document.head.appendChild(tag);
26
+ }
27
+ var QoderCredentialCard_module_css_default = {
28
+ "accountEmptyText": "OAuTmW_accountEmptyText",
29
+ "accountHead": "OAuTmW_accountHead",
30
+ "accountLoadingText": "OAuTmW_accountLoadingText",
31
+ "accountSection": "OAuTmW_accountSection",
32
+ "actions": "OAuTmW_actions",
33
+ "avatar": "OAuTmW_avatar",
34
+ "configured": "OAuTmW_configured",
35
+ "credential": "OAuTmW_credential",
36
+ "credentialDot": "OAuTmW_credentialDot",
37
+ "credentialDotConfigured": "OAuTmW_credentialDotConfigured",
38
+ "credentialDotMissing": "OAuTmW_credentialDotMissing",
39
+ "credentialEditor": "OAuTmW_credentialEditor",
40
+ "credentialIdentity": "OAuTmW_credentialIdentity",
41
+ "credentialName": "OAuTmW_credentialName",
42
+ "credentialRowHead": "OAuTmW_credentialRowHead",
43
+ "customized": "OAuTmW_customized",
44
+ "customizedBody": "OAuTmW_customizedBody",
45
+ "customizedSummary": "OAuTmW_customizedSummary",
46
+ "danger": "OAuTmW_danger",
47
+ "editButton": "OAuTmW_editButton",
48
+ "editor": "OAuTmW_editor",
49
+ "error": "OAuTmW_error",
50
+ "head": "OAuTmW_head",
51
+ "heading": "OAuTmW_heading",
52
+ "hint": "OAuTmW_hint",
53
+ "input": "OAuTmW_input",
54
+ "label": "OAuTmW_label",
55
+ "linkButton": "OAuTmW_linkButton",
56
+ "modelBadge": "OAuTmW_modelBadge",
57
+ "modelCatalog": "OAuTmW_modelCatalog",
58
+ "modelCatalogHead": "OAuTmW_modelCatalogHead",
59
+ "modelCatalogMeta": "OAuTmW_modelCatalogMeta",
60
+ "modelCatalogTitle": "OAuTmW_modelCatalogTitle",
61
+ "modelChoice": "OAuTmW_modelChoice",
62
+ "modelChoiceName": "OAuTmW_modelChoiceName",
63
+ "modelList": "OAuTmW_modelList",
64
+ "modelRate": "OAuTmW_modelRate",
65
+ "modelUnavailable": "OAuTmW_modelUnavailable",
66
+ "primary": "OAuTmW_primary",
67
+ "quotaBlock": "OAuTmW_quotaBlock",
68
+ "quotaHeader": "OAuTmW_quotaHeader",
69
+ "quotaLabel": "OAuTmW_quotaLabel",
70
+ "quotaMeta": "OAuTmW_quotaMeta",
71
+ "quotaProgress": "OAuTmW_quotaProgress",
72
+ "quotaTop": "OAuTmW_quotaTop",
73
+ "refreshBtn": "OAuTmW_refreshBtn",
74
+ "regionBadge": "OAuTmW_regionBadge",
75
+ "regionGroup": "OAuTmW_regionGroup",
76
+ "regionOption": "OAuTmW_regionOption",
77
+ "regionOptionActive": "OAuTmW_regionOptionActive",
78
+ "regionOptionDisabled": "OAuTmW_regionOptionDisabled",
79
+ "regionSelector": "OAuTmW_regionSelector",
80
+ "secondary": "OAuTmW_secondary",
81
+ "status": "OAuTmW_status",
82
+ "success": "OAuTmW_success",
83
+ "userDetails": "OAuTmW_userDetails",
84
+ "userEmail": "OAuTmW_userEmail",
85
+ "userInfo": "OAuTmW_userInfo",
86
+ "userName": "OAuTmW_userName"
87
+ };
88
+ //#endregion
89
+ //#region src/client/QoderAccountCard.tsx
90
+ function formatResetDate(dateStr) {
91
+ if (!dateStr) return void 0;
92
+ const date = new Date(dateStr);
93
+ if (Number.isNaN(date.getTime())) return void 0;
94
+ return date.toLocaleString(void 0, {
95
+ month: "numeric",
96
+ day: "numeric",
97
+ hour: "2-digit",
98
+ minute: "2-digit"
99
+ });
100
+ }
101
+ function QoderAccountCard({ operations, t }) {
102
+ const [credentialState, setCredentialState] = (0, react.useState)({ status: "loading" });
103
+ const [accountState, setAccountState] = (0, react.useState)({ status: "idle" });
104
+ const [refreshing, setRefreshing] = (0, react.useState)(false);
105
+ const [credentialRevision, setCredentialRevision] = (0, react.useState)(0);
106
+ const latestAccountRequest = (0, react.useRef)(0);
107
+ const loadCredential = (0, react.useCallback)(async () => {
108
+ const info = await operations.describe();
109
+ setCredentialState(info === void 0 ? { status: "failed" } : {
110
+ status: "ready",
111
+ info
112
+ });
113
+ }, [operations]);
114
+ const loadAccount = (0, react.useCallback)(async (force = false) => {
115
+ const requestId = ++latestAccountRequest.current;
116
+ if (force) setRefreshing(true);
117
+ else setAccountState({ status: "loading" });
118
+ try {
119
+ const result = await operations.getAccount(force);
120
+ if (requestId !== latestAccountRequest.current) return;
121
+ if (result?.ok) setAccountState({
122
+ status: "ready",
123
+ account: result.data
124
+ });
125
+ else setAccountState({
126
+ status: "failed",
127
+ error: result?.error
128
+ });
129
+ } catch (error) {
130
+ if (requestId !== latestAccountRequest.current) return;
131
+ setAccountState({
132
+ status: "failed",
133
+ error: error instanceof Error ? error.message : String(error)
134
+ });
135
+ } finally {
136
+ if (requestId === latestAccountRequest.current) setRefreshing(false);
137
+ }
138
+ }, [operations]);
139
+ (0, react.useEffect)(() => {
140
+ loadCredential();
141
+ return operations.subscribe(() => {
142
+ loadCredential();
143
+ setCredentialRevision((revision) => revision + 1);
144
+ });
145
+ }, [loadCredential, operations]);
146
+ const configured = credentialState.status === "ready" && credentialState.info.configured && !isEnvironmentCredentialSource(credentialState.info.source);
147
+ (0, react.useEffect)(() => {
148
+ if (configured) loadAccount(false);
149
+ else {
150
+ latestAccountRequest.current++;
151
+ setRefreshing(false);
152
+ setAccountState({ status: "idle" });
153
+ }
154
+ }, [
155
+ configured,
156
+ credentialRevision,
157
+ loadAccount
158
+ ]);
159
+ if (credentialState.status === "loading") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
160
+ className: QoderCredentialCard_module_css_default.credential,
161
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("loading") })
162
+ });
163
+ if (credentialState.status === "failed") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
164
+ className: QoderCredentialCard_module_css_default.credential,
165
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
166
+ className: QoderCredentialCard_module_css_default.error,
167
+ role: "alert",
168
+ children: t("loadFailed")
169
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
170
+ type: "button",
171
+ className: QoderCredentialCard_module_css_default.secondary,
172
+ onClick: () => {
173
+ loadCredential();
174
+ },
175
+ children: t("retry")
176
+ })]
177
+ });
178
+ const renderQuota = (label, quota, resetDate) => {
179
+ if (!quota || quota.total <= 0) return null;
180
+ const remainingPercent = Math.max(0, Math.min(100, Math.round(quota.remaining / quota.total * 100)));
181
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
182
+ className: QoderCredentialCard_module_css_default.quotaBlock,
183
+ children: [
184
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
185
+ className: QoderCredentialCard_module_css_default.quotaHeader,
186
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
187
+ className: QoderCredentialCard_module_css_default.quotaLabel,
188
+ children: label
189
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("quotaRemaining", { value: remainingPercent }) })]
190
+ }),
191
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
192
+ className: QoderCredentialCard_module_css_default.quotaTop,
193
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("quotaUsed", {
194
+ used: quota.used.toFixed(1),
195
+ total: quota.total.toFixed(1),
196
+ unit: quota.unit
197
+ }) })
198
+ }),
199
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("progress", {
200
+ className: QoderCredentialCard_module_css_default.quotaProgress,
201
+ max: quota.total,
202
+ value: Math.min(quota.total, quota.used),
203
+ "aria-label": `${label} ${t("quotaRemaining", { value: remainingPercent })}`
204
+ }),
205
+ resetDate ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
206
+ className: QoderCredentialCard_module_css_default.quotaMeta,
207
+ children: t("resetsAt", { value: resetDate })
208
+ }) : null
209
+ ]
210
+ }, label);
211
+ };
212
+ const renderAccount = () => {
213
+ if (!configured) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
214
+ className: QoderCredentialCard_module_css_default.hint,
215
+ children: t("accountCredentialHint")
216
+ });
217
+ if (accountState.status === "loading") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
218
+ className: QoderCredentialCard_module_css_default.accountSection,
219
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
220
+ className: QoderCredentialCard_module_css_default.accountLoadingText,
221
+ children: t("accountLoading")
222
+ })
223
+ });
224
+ if (accountState.status === "failed") {
225
+ const detail = accountState.error ? ` (${accountState.error})` : "";
226
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
227
+ className: QoderCredentialCard_module_css_default.accountSection,
228
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
229
+ className: QoderCredentialCard_module_css_default.accountHead,
230
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
231
+ className: QoderCredentialCard_module_css_default.error,
232
+ children: [t("accountFailed"), detail]
233
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
234
+ type: "button",
235
+ className: QoderCredentialCard_module_css_default.refreshBtn,
236
+ onClick: () => {
237
+ loadAccount(true);
238
+ },
239
+ children: t("retry")
240
+ })]
241
+ })
242
+ });
243
+ }
244
+ if (accountState.status !== "ready") return null;
245
+ const { profile, usage } = accountState.account;
246
+ const userQuota = usage?.userQuota;
247
+ const orgPackage = usage?.orgResourcePackage;
248
+ const avatarInitial = (profile.name || profile.email || "Q").charAt(0).toUpperCase();
249
+ const resetDate = formatResetDate(usage?.expiresAt);
250
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
251
+ className: QoderCredentialCard_module_css_default.accountSection,
252
+ children: [
253
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
254
+ className: QoderCredentialCard_module_css_default.accountHead,
255
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
256
+ className: QoderCredentialCard_module_css_default.userInfo,
257
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
258
+ className: QoderCredentialCard_module_css_default.avatar,
259
+ "aria-hidden": "true",
260
+ children: avatarInitial
261
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
262
+ className: QoderCredentialCard_module_css_default.userDetails,
263
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
264
+ className: QoderCredentialCard_module_css_default.userName,
265
+ children: profile.name || "Qoder Subscriber"
266
+ }), profile.email ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
267
+ className: QoderCredentialCard_module_css_default.userEmail,
268
+ children: profile.email
269
+ }) : null]
270
+ })]
271
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
272
+ type: "button",
273
+ className: QoderCredentialCard_module_css_default.refreshBtn,
274
+ disabled: refreshing,
275
+ onClick: () => {
276
+ loadAccount(true);
277
+ },
278
+ children: refreshing ? t("refreshing") : t("refresh")
279
+ })]
280
+ }),
281
+ usage?.isQuotaExceeded ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
282
+ className: QoderCredentialCard_module_css_default.error,
283
+ children: t("quotaExceeded")
284
+ }) : null,
285
+ renderQuota(t("userQuotaTitle"), userQuota, resetDate),
286
+ renderQuota(t("orgResourceTitle"), orgPackage, resetDate),
287
+ (!userQuota || userQuota.total <= 0) && (!orgPackage || orgPackage.total <= 0) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
288
+ className: QoderCredentialCard_module_css_default.accountEmptyText,
289
+ children: t("noQuota")
290
+ }) : null
291
+ ]
292
+ });
293
+ };
294
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
295
+ className: QoderCredentialCard_module_css_default.credential,
296
+ "aria-label": t("accountTitle"),
297
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
298
+ className: QoderCredentialCard_module_css_default.head,
299
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
300
+ className: QoderCredentialCard_module_css_default.heading,
301
+ children: t("accountTitle")
302
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
303
+ className: configured ? `${QoderCredentialCard_module_css_default.status} ${QoderCredentialCard_module_css_default.configured}` : QoderCredentialCard_module_css_default.status,
304
+ children: configured ? t("configured") : t("missing")
305
+ })]
306
+ }), renderAccount()]
307
+ });
308
+ }
309
+ //#endregion
310
+ //#region src/client/credential-operations.ts
311
+ function reconcileQoderModels(known, discovered) {
312
+ const availableIds = new Set(discovered.map((model) => model.id));
313
+ const unavailable = known.filter((model) => !availableIds.has(model.id));
314
+ return {
315
+ catalog: [...discovered, ...unavailable],
316
+ selected: [...discovered],
317
+ unavailableIds: new Set(unavailable.map((model) => model.id))
318
+ };
319
+ }
320
+ //#endregion
321
+ //#region src/client/QoderModelCatalog.tsx
322
+ function validateModelCatalog(models) {
323
+ return models.length === 0 ? "modelsRequired" : void 0;
324
+ }
325
+ function QoderModelCatalog(props) {
326
+ const { operations, models, disabled, onChange, t } = props;
327
+ const [fetching, setFetching] = (0, react.useState)(false);
328
+ const [failure, setFailure] = (0, react.useState)();
329
+ const [catalog, setCatalog] = (0, react.useState)();
330
+ const [unavailableIds, setUnavailableIds] = (0, react.useState)(/* @__PURE__ */ new Set());
331
+ const displayedModels = catalog ?? models;
332
+ const selectedIds = (0, react.useMemo)(() => new Set(models.map((model) => model.id)), [models]);
333
+ const fetchModels = async () => {
334
+ setFetching(true);
335
+ setFailure(void 0);
336
+ const result = await operations.discoverModels();
337
+ setFetching(false);
338
+ if (!result.ok) {
339
+ setFailure(result.error || t("modelsFetchFailed"));
340
+ return;
341
+ }
342
+ const reconciled = reconcileQoderModels(catalog ?? models, result.data);
343
+ setCatalog(reconciled.catalog);
344
+ setUnavailableIds(reconciled.unavailableIds);
345
+ onChange(reconciled.selected);
346
+ };
347
+ const toggleModel = (id, enabled) => {
348
+ if (unavailableIds.has(id)) return;
349
+ const source = catalog ?? models;
350
+ if (catalog === void 0) setCatalog(source);
351
+ const nextSelected = new Set(selectedIds);
352
+ if (enabled) nextSelected.add(id);
353
+ else nextSelected.delete(id);
354
+ onChange(source.filter((model) => nextSelected.has(model.id) && !unavailableIds.has(model.id)));
355
+ };
356
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
357
+ className: QoderCredentialCard_module_css_default.modelCatalog,
358
+ "aria-label": t("modelsTitle"),
359
+ children: [
360
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
361
+ className: QoderCredentialCard_module_css_default.modelCatalogHead,
362
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
363
+ className: QoderCredentialCard_module_css_default.modelCatalogTitle,
364
+ children: t("modelsTitle")
365
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
366
+ className: QoderCredentialCard_module_css_default.modelCatalogMeta,
367
+ children: t("modelsEnabled", { count: models.length })
368
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
369
+ type: "button",
370
+ className: QoderCredentialCard_module_css_default.linkButton,
371
+ disabled: disabled || fetching,
372
+ onClick: () => {
373
+ fetchModels();
374
+ },
375
+ children: fetching ? t("modelsFetching") : t("modelsFetch")
376
+ })]
377
+ }),
378
+ failure ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
379
+ className: QoderCredentialCard_module_css_default.error,
380
+ role: "alert",
381
+ children: failure
382
+ }) : null,
383
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
384
+ className: QoderCredentialCard_module_css_default.modelList,
385
+ children: displayedModels.map((model) => {
386
+ const unavailable = unavailableIds.has(model.id);
387
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
388
+ className: `${QoderCredentialCard_module_css_default.modelChoice} ${unavailable ? QoderCredentialCard_module_css_default.modelUnavailable : ""}`,
389
+ children: [
390
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
391
+ type: "checkbox",
392
+ checked: !unavailable && selectedIds.has(model.id),
393
+ disabled: disabled || unavailable,
394
+ onChange: (event) => {
395
+ toggleModel(model.id, event.currentTarget.checked);
396
+ }
397
+ }),
398
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
399
+ className: QoderCredentialCard_module_css_default.modelChoiceName,
400
+ children: model.name
401
+ }),
402
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
403
+ className: QoderCredentialCard_module_css_default.modelRate,
404
+ children: model.priceFactor === void 0 ? t("modelRateUnknown") : t("modelRate", { value: model.priceFactor })
405
+ }),
406
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: model.id }),
407
+ unavailable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
408
+ className: QoderCredentialCard_module_css_default.modelBadge,
409
+ children: t("modelUnavailable")
410
+ }) : null
411
+ ]
412
+ }, model.id);
413
+ })
414
+ })
415
+ ]
416
+ });
417
+ }
418
+ //#endregion
419
+ //#region src/client/QoderCredentialCard.tsx
420
+ function modelsOf(value) {
421
+ if (typeof value !== "object" || value === null) return [];
422
+ const models = value.models;
423
+ return Array.isArray(models) ? models : [];
424
+ }
425
+ function regionOf(value) {
426
+ if (typeof value !== "object" || value === null) return "global";
427
+ return value.region === "china" ? "china" : "global";
428
+ }
429
+ function QoderCredentialCard({ operations, t }) {
430
+ const [state, setState] = (0, react.useState)({ status: "loading" });
431
+ const [editing, setEditing] = (0, react.useState)(false);
432
+ const [draft, setDraft] = (0, react.useState)("");
433
+ const [regionDraft, setRegionDraft] = (0, react.useState)("global");
434
+ const [regionDirty, setRegionDirty] = (0, react.useState)(false);
435
+ const [modelDraft, setModelDraft] = (0, react.useState)([]);
436
+ const [modelsDirty, setModelsDirty] = (0, react.useState)(false);
437
+ const [mutation, setMutation] = (0, react.useState)();
438
+ const [notice, setNotice] = (0, react.useState)();
439
+ const modelSnapshot = (0, react.useSyncExternalStore)(operations.subscribeModels, operations.getModelSnapshot, operations.getModelSnapshot);
440
+ (0, react.useEffect)(() => {
441
+ if (modelSnapshot.status === "ready") {
442
+ if (!modelsDirty) setModelDraft(modelsOf(modelSnapshot.value));
443
+ if (!regionDirty) setRegionDraft(regionOf(modelSnapshot.value));
444
+ }
445
+ }, [
446
+ modelSnapshot,
447
+ modelsDirty,
448
+ regionDirty
449
+ ]);
450
+ const load = (0, react.useCallback)(async () => {
451
+ const info = await operations.describe();
452
+ setState(info === void 0 ? { status: "failed" } : {
453
+ status: "ready",
454
+ info
455
+ });
456
+ }, [operations]);
457
+ (0, react.useEffect)(() => {
458
+ load();
459
+ return operations.subscribe(() => {
460
+ load();
461
+ });
462
+ }, [load, operations]);
463
+ if (state.status === "loading") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
464
+ className: QoderCredentialCard_module_css_default.credential,
465
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("loading") })
466
+ });
467
+ if (state.status === "failed") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
468
+ className: QoderCredentialCard_module_css_default.credential,
469
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
470
+ className: QoderCredentialCard_module_css_default.error,
471
+ role: "alert",
472
+ children: t("loadFailed")
473
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
474
+ type: "button",
475
+ className: QoderCredentialCard_module_css_default.secondary,
476
+ onClick: () => {
477
+ load();
478
+ },
479
+ children: t("retry")
480
+ })]
481
+ });
482
+ const configured = state.info.configured && !isEnvironmentCredentialSource(state.info.source);
483
+ const writable = state.info.writable;
484
+ const busy = mutation !== void 0;
485
+ const normalized = draft.trim();
486
+ const modelFailure = modelSnapshot.status === "ready" ? validateModelCatalog(modelDraft) : void 0;
487
+ const modelWritable = modelSnapshot.status === "ready" && modelSnapshot.writable;
488
+ const currentRegion = regionOf(modelSnapshot.value);
489
+ const closeEditor = () => {
490
+ setDraft("");
491
+ setModelDraft(modelsOf(modelSnapshot.value));
492
+ setRegionDraft(regionOf(modelSnapshot.value));
493
+ setModelsDirty(false);
494
+ setRegionDirty(false);
495
+ setNotice(void 0);
496
+ setEditing(false);
497
+ };
498
+ const save = async () => {
499
+ if (busy || !modelsDirty && !regionDirty && normalized.length === 0 || modelsDirty && (!modelWritable || modelFailure !== void 0) || regionDirty && !modelWritable) return;
500
+ setMutation("saving");
501
+ setNotice(void 0);
502
+ if (regionDirty) {
503
+ if (!await operations.storeRegion(regionDraft)) {
504
+ setNotice("saveFailed");
505
+ setMutation(void 0);
506
+ return;
507
+ }
508
+ setRegionDirty(false);
509
+ }
510
+ if (modelsDirty) {
511
+ if (!await operations.storeModels(modelDraft)) {
512
+ setNotice("saveFailed");
513
+ setMutation(void 0);
514
+ return;
515
+ }
516
+ setModelsDirty(false);
517
+ }
518
+ if (normalized.length === 0 || await operations.store(normalized)) {
519
+ setDraft("");
520
+ setNotice("saved");
521
+ if (normalized.length > 0) await load();
522
+ setEditing(false);
523
+ } else setNotice("saveFailed");
524
+ setMutation(void 0);
525
+ };
526
+ const remove = async () => {
527
+ if (!configured || !writable || busy || !window.confirm(t("confirmRemove"))) return;
528
+ setMutation("removing");
529
+ setNotice(void 0);
530
+ if (await operations.remove()) {
531
+ setDraft("");
532
+ await load();
533
+ } else setNotice("removeFailed");
534
+ setMutation(void 0);
535
+ };
536
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
537
+ className: `${QoderCredentialCard_module_css_default.credential} ${QoderCredentialCard_module_css_default.credentialEditor}`,
538
+ "aria-label": t("title"),
539
+ children: [
540
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
541
+ className: QoderCredentialCard_module_css_default.credentialRowHead,
542
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
543
+ className: QoderCredentialCard_module_css_default.credentialIdentity,
544
+ children: [
545
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
546
+ className: QoderCredentialCard_module_css_default.credentialName,
547
+ children: t("nav")
548
+ }),
549
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
550
+ className: QoderCredentialCard_module_css_default.regionBadge,
551
+ children: currentRegion === "china" ? t("regionChina") : t("regionGlobal")
552
+ }),
553
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
554
+ className: `${QoderCredentialCard_module_css_default.credentialDot} ${configured ? QoderCredentialCard_module_css_default.credentialDotConfigured : QoderCredentialCard_module_css_default.credentialDotMissing}`,
555
+ role: "img",
556
+ "aria-label": configured ? t("configured") : t("missing"),
557
+ title: configured ? t("configured") : t("missing")
558
+ })
559
+ ]
560
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
561
+ type: "button",
562
+ className: QoderCredentialCard_module_css_default.editButton,
563
+ "aria-expanded": editing,
564
+ "aria-controls": "qoder-credential-editor",
565
+ onClick: () => {
566
+ if (editing) closeEditor();
567
+ else {
568
+ setNotice(void 0);
569
+ setEditing(true);
570
+ }
571
+ },
572
+ children: t("edit")
573
+ })]
574
+ }),
575
+ notice === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
576
+ className: notice === "saved" ? QoderCredentialCard_module_css_default.success : QoderCredentialCard_module_css_default.error,
577
+ role: "status",
578
+ children: t(notice)
579
+ }),
580
+ editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
581
+ id: "qoder-credential-editor",
582
+ className: QoderCredentialCard_module_css_default.editor,
583
+ children: [
584
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
585
+ className: QoderCredentialCard_module_css_default.regionSelector,
586
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
587
+ className: QoderCredentialCard_module_css_default.label,
588
+ children: t("regionLabel")
589
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
590
+ className: QoderCredentialCard_module_css_default.regionGroup,
591
+ role: "radiogroup",
592
+ "aria-label": t("regionLabel"),
593
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
594
+ type: "button",
595
+ role: "radio",
596
+ "aria-checked": regionDraft === "global",
597
+ className: `${QoderCredentialCard_module_css_default.regionOption} ${regionDraft === "global" ? QoderCredentialCard_module_css_default.regionOptionActive : ""}`,
598
+ disabled: !modelWritable || busy,
599
+ onClick: () => {
600
+ setRegionDraft("global");
601
+ setRegionDirty(true);
602
+ },
603
+ children: t("regionGlobal")
604
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
605
+ type: "button",
606
+ role: "radio",
607
+ "aria-checked": regionDraft === "china",
608
+ className: `${QoderCredentialCard_module_css_default.regionOption} ${regionDraft === "china" ? QoderCredentialCard_module_css_default.regionOptionActive : ""}`,
609
+ disabled: !modelWritable || busy,
610
+ onClick: () => {
611
+ setRegionDraft("china");
612
+ setRegionDirty(true);
613
+ },
614
+ children: t("regionChina")
615
+ })]
616
+ })]
617
+ }),
618
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
619
+ className: QoderCredentialCard_module_css_default.label,
620
+ htmlFor: "qoder-managed-credential",
621
+ children: t("tokenLabel")
622
+ }),
623
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
624
+ id: "qoder-managed-credential",
625
+ className: QoderCredentialCard_module_css_default.input,
626
+ type: "password",
627
+ autoComplete: "new-password",
628
+ value: draft,
629
+ disabled: !writable || busy,
630
+ placeholder: configured ? t("configuredHint") : t("tokenPlaceholder"),
631
+ onChange: (event) => setDraft(event.currentTarget.value)
632
+ }),
633
+ !writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
634
+ className: QoderCredentialCard_module_css_default.error,
635
+ role: "alert",
636
+ children: t("readOnly")
637
+ }) : null,
638
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
639
+ className: QoderCredentialCard_module_css_default.customized,
640
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", {
641
+ className: QoderCredentialCard_module_css_default.customizedSummary,
642
+ children: t("customized")
643
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
644
+ className: QoderCredentialCard_module_css_default.customizedBody,
645
+ children: [modelSnapshot.status === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
646
+ className: QoderCredentialCard_module_css_default.hint,
647
+ children: t("modelsLoading")
648
+ }) : modelSnapshot.status === "unavailable" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
649
+ className: QoderCredentialCard_module_css_default.error,
650
+ children: t("modelsUnavailable")
651
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QoderModelCatalog, {
652
+ operations,
653
+ models: modelDraft,
654
+ disabled: !modelWritable || busy,
655
+ t,
656
+ onChange: (models) => {
657
+ setModelDraft(models);
658
+ setModelsDirty(true);
659
+ }
660
+ }), modelSnapshot.status === "ready" && modelFailure !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
661
+ className: QoderCredentialCard_module_css_default.error,
662
+ children: t(modelFailure)
663
+ }) : null]
664
+ })]
665
+ }),
666
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
667
+ className: QoderCredentialCard_module_css_default.actions,
668
+ children: [
669
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
670
+ type: "button",
671
+ className: QoderCredentialCard_module_css_default.secondary,
672
+ disabled: busy,
673
+ onClick: closeEditor,
674
+ children: t("cancel")
675
+ }),
676
+ configured ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
677
+ type: "button",
678
+ className: QoderCredentialCard_module_css_default.danger,
679
+ disabled: !writable || busy,
680
+ onClick: () => {
681
+ remove();
682
+ },
683
+ children: mutation === "removing" ? t("removing") : t("remove")
684
+ }) : null,
685
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
686
+ type: "button",
687
+ className: QoderCredentialCard_module_css_default.primary,
688
+ disabled: busy || !modelsDirty && !regionDirty && normalized.length === 0 || modelsDirty && (modelSnapshot.status !== "ready" || modelFailure !== void 0 || !modelWritable) || regionDirty && (modelSnapshot.status !== "ready" || !modelWritable) || normalized.length > 0 && !writable,
689
+ onClick: () => {
690
+ save();
691
+ },
692
+ children: mutation === "saving" ? t("saving") : t("save")
693
+ })
694
+ ]
695
+ })
696
+ ]
697
+ }) : null
698
+ ]
699
+ });
700
+ }
701
+ //#endregion
702
+ //#region src/client/locales.ts
703
+ const zh = {
704
+ nav: "Qoder",
705
+ title: "Qoder 凭据",
706
+ configured: "已配置",
707
+ missing: "未配置",
708
+ loading: "正在读取凭据状态…",
709
+ loadFailed: "无法读取凭据状态。",
710
+ retry: "重试",
711
+ edit: "编辑",
712
+ cancel: "取消",
713
+ regionLabel: "服务区域",
714
+ regionGlobal: "国际版 (Global)",
715
+ regionChina: "中国区 (CN)",
716
+ regionHint: "请确保 PAT 与所选服务区域匹配。",
717
+ tokenLabel: "API 密钥",
718
+ tokenPlaceholder: "输入新的 Personal Access Token",
719
+ configuredHint: "已配置——输入新值可替换",
720
+ readOnly: "当前凭据存储不可写。",
721
+ save: "保存",
722
+ saving: "正在保存…",
723
+ saved: "Qoder 设置已保存。",
724
+ saveFailed: "Qoder 设置保存失败,请重试。",
725
+ remove: "删除",
726
+ removing: "正在删除…",
727
+ removeFailed: "凭据删除失败,请重试。",
728
+ confirmRemove: "删除已保存的 Qoder 凭据?删除后,新的模型请求将无法运行。",
729
+ customized: "自定义设置",
730
+ modelsTitle: "模型目录",
731
+ modelsLoading: "正在读取模型设置…",
732
+ modelsUnavailable: "当前无法读取或保存模型设置。",
733
+ modelsEnabled: "已启用 {count} 个模型",
734
+ modelsFetch: "获取可用模型",
735
+ modelsFetching: "正在获取…",
736
+ modelsFetchFailed: "无法获取可用模型。",
737
+ modelsRequired: "至少需要保留一个模型。",
738
+ modelUnavailable: "不可用",
739
+ modelRate: "{value}x",
740
+ modelRateUnknown: "倍率未知",
741
+ accountTitle: "Qoder",
742
+ accountLoading: "正在读取账号与额度…",
743
+ accountFailed: "无法读取账号信息与额度。",
744
+ accountCredentialHint: "请先在“模型”设置中配置 Qoder Personal Access Token。",
745
+ refresh: "刷新",
746
+ refreshing: "正在刷新…",
747
+ userQuotaTitle: "个人额度",
748
+ orgResourceTitle: "组织资源包",
749
+ quotaRemaining: "剩余 {value}%",
750
+ quotaUsed: "已用 {used} / {total} {unit}",
751
+ resetsAt: "重置时间:{value}",
752
+ noQuota: "暂无可用额度信息",
753
+ quotaExceeded: "当前订阅额度已用尽。"
754
+ };
755
+ const en = {
756
+ nav: "Qoder",
757
+ title: "Qoder credential",
758
+ configured: "Configured",
759
+ missing: "Not configured",
760
+ loading: "Reading credential status…",
761
+ loadFailed: "Could not read credential status.",
762
+ retry: "Retry",
763
+ edit: "Edit",
764
+ cancel: "Cancel",
765
+ regionLabel: "Service Region",
766
+ regionGlobal: "Global",
767
+ regionChina: "China (CN)",
768
+ regionHint: "Ensure your PAT matches the selected service region.",
769
+ tokenLabel: "API Key",
770
+ tokenPlaceholder: "Enter a new Personal Access Token",
771
+ configuredHint: "Configured — enter a new value to replace",
772
+ readOnly: "The current credential store is read-only.",
773
+ save: "Save",
774
+ saving: "Saving…",
775
+ saved: "Qoder settings saved.",
776
+ saveFailed: "Could not save the Qoder settings. Try again.",
777
+ remove: "Remove",
778
+ removing: "Removing…",
779
+ removeFailed: "Could not remove the credential. Try again.",
780
+ confirmRemove: "Remove the stored Qoder credential? New model requests will stop working.",
781
+ customized: "Custom settings",
782
+ modelsTitle: "Model catalog",
783
+ modelsLoading: "Reading model settings…",
784
+ modelsUnavailable: "Model settings cannot currently be read or saved.",
785
+ modelsEnabled: "{count} models enabled",
786
+ modelsFetch: "Fetch available models",
787
+ modelsFetching: "Fetching…",
788
+ modelsFetchFailed: "Could not fetch available models.",
789
+ modelsRequired: "Keep at least one model.",
790
+ modelUnavailable: "Unavailable",
791
+ modelRate: "{value}x",
792
+ modelRateUnknown: "Rate unknown",
793
+ accountTitle: "Qoder",
794
+ accountLoading: "Reading account and quota…",
795
+ accountFailed: "Could not read account details or quota.",
796
+ accountCredentialHint: "Configure the Qoder Personal Access Token in Models settings first.",
797
+ refresh: "Refresh",
798
+ refreshing: "Refreshing…",
799
+ userQuotaTitle: "Personal Quota",
800
+ orgResourceTitle: "Org Resource Package",
801
+ quotaRemaining: "{value}% remaining",
802
+ quotaUsed: "Used {used} / {total} {unit}",
803
+ resetsAt: "Resets: {value}",
804
+ noQuota: "No quota metrics available",
805
+ quotaExceeded: "The current subscription quota is exhausted."
806
+ };
807
+ //#endregion
808
+ //#region src/client/index.ts
809
+ const localeNamespace = "settings.qoderCredential";
810
+ const qoderChannel = "/qoder-subscription";
811
+ const settingsNamespace = "provider-qoder";
812
+ const inject = [
813
+ "slots",
814
+ "locale",
815
+ "remote",
816
+ "remote.credentials",
817
+ "connection",
818
+ "settingsScope"
819
+ ];
820
+ const fill = (text, values) => {
821
+ if (!values) return text;
822
+ return Object.entries(values).reduce((next, [key, value]) => next.replace(new RegExp(`\\{${key}\\}`, "g"), String(value)), text);
823
+ };
824
+ function apply(ctx) {
825
+ ctx.effect(() => ctx.locale.register(localeNamespace, {
826
+ zh,
827
+ en
828
+ }), "provider-qoder: credential copy");
829
+ const credentials = ctx.remote.credentials;
830
+ const connection = ctx.connection;
831
+ const modelScope = ctx.settingsScope.bind({ namespace: settingsNamespace });
832
+ const operations = {
833
+ describe: async () => {
834
+ try {
835
+ const response = await credentials.describe([qoderCredentialRef]);
836
+ return response.ok ? response.value[qoderCredentialRef] : void 0;
837
+ } catch {
838
+ return;
839
+ }
840
+ },
841
+ store: async (value) => {
842
+ try {
843
+ return (await credentials.set(qoderCredentialRef, value.trim())).ok;
844
+ } catch {
845
+ return false;
846
+ }
847
+ },
848
+ remove: async () => {
849
+ try {
850
+ return (await credentials.unset(qoderCredentialRef)).ok;
851
+ } catch {
852
+ return false;
853
+ }
854
+ },
855
+ getAccount: async (force) => {
856
+ try {
857
+ const response = await connection.rpc.call(qoderChannel, "account", { force });
858
+ if (response.ok) return {
859
+ ok: true,
860
+ data: response.value
861
+ };
862
+ return {
863
+ ok: false,
864
+ error: response.error?.message || "RPC returned error"
865
+ };
866
+ } catch (error) {
867
+ return {
868
+ ok: false,
869
+ error: error instanceof Error ? error.message : String(error)
870
+ };
871
+ }
872
+ },
873
+ getModelSnapshot: () => modelScope.getSnapshot(),
874
+ subscribeModels: (listener) => modelScope.subscribe(listener),
875
+ storeModels: async (models) => {
876
+ try {
877
+ await modelScope.set("models", models);
878
+ return true;
879
+ } catch {
880
+ return false;
881
+ }
882
+ },
883
+ storeRegion: async (region) => {
884
+ try {
885
+ await modelScope.set("region", region);
886
+ return true;
887
+ } catch {
888
+ return false;
889
+ }
890
+ },
891
+ discoverModels: async () => {
892
+ try {
893
+ const response = await connection.rpc.call(qoderChannel, "models", {});
894
+ if (response.ok) return {
895
+ ok: true,
896
+ data: response.value
897
+ };
898
+ return {
899
+ ok: false,
900
+ error: response.error?.message || "RPC returned error"
901
+ };
902
+ } catch (error) {
903
+ return {
904
+ ok: false,
905
+ error: error instanceof Error ? error.message : String(error)
906
+ };
907
+ }
908
+ },
909
+ subscribe: (listener) => ctx.remote.$on("credentials/reference-updated", (ref) => {
910
+ if (ref === "QODER_MANAGED_CREDENTIAL") listener();
911
+ })
912
+ };
913
+ const rawT = ctx.locale.bind(localeNamespace);
914
+ const t = (key, values) => {
915
+ const raw = rawT(key);
916
+ return fill(raw, values);
917
+ };
918
+ ctx.slots.inject("settings.section", () => ctx.slots.register({
919
+ name: "settings.section",
920
+ id: "qoder",
921
+ order: 15,
922
+ label: () => t("nav"),
923
+ locale: localeNamespace,
924
+ inject: () => ({
925
+ operations,
926
+ t
927
+ })
928
+ }, QoderAccountCard));
929
+ ctx.slots.inject("settings.models.footer", () => ctx.slots.register({
930
+ name: "settings.models.footer",
931
+ id: "qoder-credential",
932
+ order: 15,
933
+ inject: () => ({
934
+ operations,
935
+ t
936
+ })
937
+ }, QoderCredentialCard));
938
+ }
939
+ //#endregion
940
+ exports.apply = apply;
941
+ exports.inject = inject;
942
+ return module.exports;
943
+ }
944
+ });