@dungsil/dsh-plugin-cli-proxy-api 0.2.1 → 0.2.2
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/dist/client.js +33 -20
- package/package.json +3 -1
package/dist/client.js
CHANGED
|
@@ -115,7 +115,7 @@ const copy = {
|
|
|
115
115
|
quotaLoadTitle: "Accounts are not available yet",
|
|
116
116
|
quotaLoadHint: "Accounts and quota load automatically with a saved management key. If loading fails, refresh accounts to try again.",
|
|
117
117
|
accountsObservedAt: "Accounts checked at",
|
|
118
|
-
quotaHint: "Accounts and quota load
|
|
118
|
+
quotaHint: "Accounts and quota load once and stay cached in memory when you reopen this panel. Refresh accounts to update all results. Connection changes clear the cache. Cooldown reset only clears proxy routing blocks; it does not refill quota. No paid inference or reset credits are used.",
|
|
119
119
|
refreshQuotaAccounts: "Refresh accounts",
|
|
120
120
|
searchAccounts: "Search name / provider",
|
|
121
121
|
refreshQuota: "Refresh quota",
|
|
@@ -184,7 +184,7 @@ const copy = {
|
|
|
184
184
|
quotaLoadTitle: "아직 계정 정보를 불러오지 못했습니다",
|
|
185
185
|
quotaLoadHint: "관리 키가 저장되어 있으면 계정과 할당량을 자동으로 불러옵니다. 불러오기에 실패했다면 계정을 새로고침하세요.",
|
|
186
186
|
accountsObservedAt: "계정 확인 시각",
|
|
187
|
-
quotaHint: "계정과
|
|
187
|
+
quotaHint: "계정과 할당량은 한 번 불러온 뒤 메모리에 캐시하며, 화면을 다시 열 때 그대로 표시합니다. 계정을 새로고침하면 전체 결과를 갱신합니다. 연결이 변경되면 캐시를 비웁니다. 대기 시간 초기화는 프록시의 라우팅 차단만 해제하며 할당량을 충전하지 않습니다. 유료 추론이나 초기화 크레딧을 사용하지 않습니다.",
|
|
188
188
|
refreshQuotaAccounts: "계정 새로고침",
|
|
189
189
|
searchAccounts: "이름 / 공급자 검색",
|
|
190
190
|
refreshQuota: "할당량 새로고침",
|
|
@@ -253,7 +253,7 @@ const copy = {
|
|
|
253
253
|
quotaLoadTitle: "暂未加载账户信息",
|
|
254
254
|
quotaLoadHint: "保存管理密钥后,账户和配额会自动加载。加载失败时,请刷新账户重试。",
|
|
255
255
|
accountsObservedAt: "账户检查时间",
|
|
256
|
-
quotaHint: "
|
|
256
|
+
quotaHint: "账户和配额加载一次后会缓存在内存中,重新打开此面板时直接显示。刷新账户可更新全部结果。连接变更会清除缓存。重置冷却时间仅解除代理路由限制,不会补充配额。不会使用付费推理或重置额度。",
|
|
257
257
|
refreshQuotaAccounts: "刷新账户",
|
|
258
258
|
searchAccounts: "搜索名称 / 提供商",
|
|
259
259
|
refreshQuota: "刷新配额",
|
|
@@ -684,6 +684,7 @@ function QuotaPanel({ accounts, quotas, fetchedAt, language, text, busy, canLoad
|
|
|
684
684
|
]
|
|
685
685
|
});
|
|
686
686
|
}
|
|
687
|
+
// src/quota-cache.ts
|
|
687
688
|
const quotaKey = (account) => JSON.stringify([account.name, account.authIndex]);
|
|
688
689
|
const connectionKey = (view) => JSON.stringify([
|
|
689
690
|
view.baseURL,
|
|
@@ -692,6 +693,9 @@ const connectionKey = (view) => JSON.stringify([
|
|
|
692
693
|
]);
|
|
693
694
|
var QuotaCache = class {
|
|
694
695
|
entry;
|
|
696
|
+
get connection() {
|
|
697
|
+
return this.entry?.view;
|
|
698
|
+
}
|
|
695
699
|
read(view) {
|
|
696
700
|
if (this.entry?.key !== connectionKey(view)) {
|
|
697
701
|
this.clear();
|
|
@@ -702,6 +706,7 @@ var QuotaCache = class {
|
|
|
702
706
|
write(view, snapshot) {
|
|
703
707
|
this.entry = {
|
|
704
708
|
key: connectionKey(view),
|
|
709
|
+
view,
|
|
705
710
|
snapshot
|
|
706
711
|
};
|
|
707
712
|
}
|
|
@@ -726,10 +731,6 @@ function subscribeQuotaGeneration(generation, cache, cancel, changed) {
|
|
|
726
731
|
changed(!!generation.getSnapshot());
|
|
727
732
|
});
|
|
728
733
|
}
|
|
729
|
-
function isQuotaCacheFresh(snapshot, now = Date.now()) {
|
|
730
|
-
const age = now - snapshot.fetchedAt;
|
|
731
|
-
return age >= 0 && age < 3e5;
|
|
732
|
-
}
|
|
733
734
|
async function loadQuotaSnapshot(list, fetch, signal, publish) {
|
|
734
735
|
signal.throwIfAborted();
|
|
735
736
|
const accounts = await list();
|
|
@@ -807,18 +808,20 @@ function ProxyPage({ ctx, cache, settings = false }) {
|
|
|
807
808
|
const id = (0, react.useId)();
|
|
808
809
|
const [connectionVersion, setConnectionVersion] = (0, react.useState)(0);
|
|
809
810
|
const connection = ctx.get("connection");
|
|
810
|
-
const
|
|
811
|
-
const
|
|
811
|
+
const cachedView = settings ? void 0 : cache.connection;
|
|
812
|
+
const cached = cachedView && cache.read(cachedView);
|
|
813
|
+
const [view, setView] = (0, react.useState)(cachedView);
|
|
814
|
+
const [baseURL, setBaseURL] = (0, react.useState)(cachedView?.baseURL ?? "");
|
|
812
815
|
const [apiKey, setAPIKey] = (0, react.useState)("");
|
|
813
816
|
const [managementKey, setManagementKey] = (0, react.useState)("");
|
|
814
817
|
const [removeAPIKey, setRemoveAPIKey] = (0, react.useState)(false);
|
|
815
818
|
const [removeManagementKey, setRemoveManagementKey] = (0, react.useState)(false);
|
|
816
|
-
const [synchronized, setSynchronized] = (0, react.useState)(
|
|
817
|
-
const [busy, setBusy] = (0, react.useState)(
|
|
819
|
+
const [synchronized, setSynchronized] = (0, react.useState)(!!cached);
|
|
820
|
+
const [busy, setBusy] = (0, react.useState)(!cached);
|
|
818
821
|
const [notice, setNotice] = (0, react.useState)();
|
|
819
|
-
const [quotaAccounts, setQuotaAccounts] = (0, react.useState)();
|
|
820
|
-
const [quotas, setQuotas] = (0, react.useState)({});
|
|
821
|
-
const [fetchedAt, setFetchedAt] = (0, react.useState)();
|
|
822
|
+
const [quotaAccounts, setQuotaAccounts] = (0, react.useState)(cached?.accounts);
|
|
823
|
+
const [quotas, setQuotas] = (0, react.useState)(cached?.quotas ?? {});
|
|
824
|
+
const [fetchedAt, setFetchedAt] = (0, react.useState)(cached?.fetchedAt);
|
|
822
825
|
const [uncertain, setUncertain] = (0, react.useState)(false);
|
|
823
826
|
const lock = (0, react.useRef)(true);
|
|
824
827
|
const lifetime = (0, react.useRef)();
|
|
@@ -831,6 +834,7 @@ function ProxyPage({ ctx, cache, settings = false }) {
|
|
|
831
834
|
const describe = (0, react.useCallback)(async (controller) => {
|
|
832
835
|
setSynchronized(false);
|
|
833
836
|
const next = await call("describe", {}, controller);
|
|
837
|
+
cache.read(next);
|
|
834
838
|
setView(next);
|
|
835
839
|
setBaseURL(next.baseURL);
|
|
836
840
|
setSynchronized(true);
|
|
@@ -842,7 +846,7 @@ function ProxyPage({ ctx, cache, settings = false }) {
|
|
|
842
846
|
setQuotas({});
|
|
843
847
|
setFetchedAt(void 0);
|
|
844
848
|
return next;
|
|
845
|
-
}, [call]);
|
|
849
|
+
}, [call, cache]);
|
|
846
850
|
const showSnapshot = (0, react.useCallback)((snapshot) => {
|
|
847
851
|
setQuotaAccounts(snapshot.accounts);
|
|
848
852
|
setQuotas(snapshot.quotas);
|
|
@@ -898,6 +902,20 @@ function ProxyPage({ ctx, cache, settings = false }) {
|
|
|
898
902
|
(0, react.useEffect)(() => {
|
|
899
903
|
const controller = new AbortController();
|
|
900
904
|
lifetime.current = controller;
|
|
905
|
+
const restoreView = settings ? void 0 : cache.connection;
|
|
906
|
+
const restore = restoreView && cache.read(restoreView);
|
|
907
|
+
if (restore && restoreView) {
|
|
908
|
+
setView(restoreView);
|
|
909
|
+
setBaseURL(restoreView.baseURL);
|
|
910
|
+
setSynchronized(true);
|
|
911
|
+
showSnapshot(restore);
|
|
912
|
+
lock.current = false;
|
|
913
|
+
setBusy(false);
|
|
914
|
+
return () => {
|
|
915
|
+
controller.abort();
|
|
916
|
+
if (lifetime.current === controller) lifetime.current = void 0;
|
|
917
|
+
};
|
|
918
|
+
}
|
|
901
919
|
lock.current = true;
|
|
902
920
|
setBusy(true);
|
|
903
921
|
setSynchronized(false);
|
|
@@ -911,12 +929,7 @@ function ProxyPage({ ctx, cache, settings = false }) {
|
|
|
911
929
|
setNotice(void 0);
|
|
912
930
|
describe(controller).then(async (next) => {
|
|
913
931
|
if (settings) return;
|
|
914
|
-
const cached = cache.read(next);
|
|
915
932
|
if (!next.managementKeySaved) return;
|
|
916
|
-
if (cached) {
|
|
917
|
-
showSnapshot(cached);
|
|
918
|
-
if (isQuotaCacheFresh(cached)) return;
|
|
919
|
-
}
|
|
920
933
|
await loadAccounts(next, controller);
|
|
921
934
|
}).catch(() => {
|
|
922
935
|
if (!controller.signal.aborted && lifetime.current === controller) setNotice("error");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dungsil/dsh-plugin-cli-proxy-api",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "CLIProxyAPI model provider and owner-only management settings for DeepSeek Harness.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -43,7 +43,9 @@
|
|
|
43
43
|
"@dungsil/dsh-tsdown": "0.0.0",
|
|
44
44
|
"@dungsil/dsh-ui": "0.0.0",
|
|
45
45
|
"@types/react": "18.3.31",
|
|
46
|
+
"happy-dom": "21.0.4",
|
|
46
47
|
"react": "18.3.1",
|
|
48
|
+
"react-dom": "18.3.1",
|
|
47
49
|
"tsdown": "0.23.4"
|
|
48
50
|
},
|
|
49
51
|
"peerDependencies": {
|