dsh-codearts 1.1.0 → 1.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/CHANGELOG.md +47 -0
- package/lib/bin.mjs +2 -2
- package/lib/client/index.js +350 -343
- package/lib/index.d.mts +8 -0
- package/lib/index.mjs +170 -6
- package/lib/{usage-Cie0IlC4.mjs → usage-5YK7bW-e.mjs} +52 -8
- package/package.json +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,53 @@
|
|
|
3
3
|
本文件记录本插件的重要改动。格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
|
|
4
4
|
版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
|
5
5
|
|
|
6
|
+
## [1.1.3] - 2026-10-26
|
|
7
|
+
|
|
8
|
+
### 修复
|
|
9
|
+
|
|
10
|
+
- **与 billion-context 同用时账号被永久禁用,报「当前没有可用账号」(issue #1)**:
|
|
11
|
+
billion-context 拦下 SDK-HMAC-SHA256 签名请求做压缩、找不到重签凭据时在本地回 403
|
|
12
|
+
(`signed_request_requires_resign`),插件把它当凭据失效,账号被禁用且没有任何恢复
|
|
13
|
+
路径。现在按 body 里的拒签标记识别这类本地拦截:不再禁用账号,直接回 400(宿主不会
|
|
14
|
+
再拿它重试 5 次),报错里给出 `resign.passthrough` 的配置方法。带标记的 401/403 之外
|
|
15
|
+
的真凭据失效行为不变。
|
|
16
|
+
- **重新登录救不回被禁用的账号**:`disabled` 以前只能靠重启清掉,`pool.sync()` 对同一
|
|
17
|
+
userId 保留运行时状态。现在登录成功(OAuth 与手工贴 token 两条路)会调用池的
|
|
18
|
+
`revive()`,清掉该账号的禁用/冷却/错误计数。
|
|
19
|
+
- **「没有可用账号」不再一概而论**:一个账号都选不出来时,报错分清原因——全禁用(401,
|
|
20
|
+
附各号最后错误并提示重新登录)、全在冷却(429,附剩余秒数)、本地并发槽位全满
|
|
21
|
+
(429,说明每账号 2 个在飞上限)。
|
|
22
|
+
- **已登录却报「积分不可用:statistics HTTP 0 Failed to parse URL from [object
|
|
23
|
+
Request]」(模型清单同时变空,issue #2)**:出网原本是 `fetch(new Request(url, ...), {signal})`
|
|
24
|
+
——邻居插件(如 IP 池出口路由)会把 `globalThis.fetch` 换成它自己那份 undici 的
|
|
25
|
+
fetch,而 `globalThis.Request` 还是另一份实例。undici 用 `instanceof` 认自己的
|
|
26
|
+
Request,认不出就当 URL 字符串处理,于是每条请求在出网之前抛错(HTTP 0)。现在
|
|
27
|
+
`Request` 只当签名的载体,出网统一走 `dispatch()`:交「字符串 URL + 已展开的普通
|
|
28
|
+
头 + 原字节请求体」,7 处调用点一并收口。
|
|
29
|
+
- **选中 CodeArts 模型后每条消息都「本轮运行失败:Cannot read properties of undefined
|
|
30
|
+
(reading 'length')」(issue #2)**:`@earendil-works/pi-ai` 过去只写在 `peerDependencies`
|
|
31
|
+
(`>=0.84.2 <2.0.0`),区间不会被安装流程强制满足;插件自己没有 `node_modules` 时
|
|
32
|
+
import 直接落到 profile 顶层被别的插件 hoist 上来的旧版。旧版的 `estimateMessageTokens`
|
|
33
|
+
没有 `role:"system"` 分支,而宿主(`dsh-llm-pi-ai` 0.2.1-rc.2 起)会把系统提示折叠成
|
|
34
|
+
一条 content 为**字符串**的 system 消息交给 provider —— 字符串被按字符遍历,读到
|
|
35
|
+
`block.name.length` 就崩,且崩在出网之前。现在 pi-ai 移进 `dependencies`(`^1.3.0`,
|
|
36
|
+
自带一份),并在启动时探测这份能不能估折叠后的 system 消息:不满足就在日志和积分
|
|
37
|
+
卡片上明说「pi-ai 不兼容,需要 >= 1.3.0」,不再让每条消息各自崩在一个看不懂的
|
|
38
|
+
TypeError 上。
|
|
39
|
+
|
|
40
|
+
## [1.1.1] - 2026-10-22
|
|
41
|
+
|
|
42
|
+
### 修复
|
|
43
|
+
|
|
44
|
+
- **带思考档位的模型(GLM-5.2 / GLM-5.2-ArkTS-SPARK)每轮必失败,报
|
|
45
|
+
`Message role cannot empty`**:1.1.0 给这些模型声明了 `reasoning`,宿主 pi-ai 于是
|
|
46
|
+
把系统提示从 `role:"system"` 换成 OpenAI 的新叫法 `role:"developer"` 发出来,
|
|
47
|
+
华为网关只认 system/user/assistant/tool,认不出来就回这一句黑话。出口处统一把
|
|
48
|
+
`developer` 归一回 `system`,与档位无关(Default/High/Max 之前都必现)。
|
|
49
|
+
- 新增 `GET /api/codearts/debug`:回最近 8 次出站请求的**形状**摘要(消息条数、
|
|
50
|
+
每条的 role 名、工具数),只含 role 名不含任何内容。上游的参数错误全是同一句
|
|
51
|
+
黑话,没有这个就分不清是宿主发的还是插件拼的。
|
|
52
|
+
|
|
6
53
|
## [1.1.0] - 2026-10-21
|
|
7
54
|
|
|
8
55
|
### 新增
|
package/lib/bin.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { I as codeartsAccountsPath, M as isBenefitModel, N as CodeArtsAccountStore, d as fetchCallerIdentity, n as codeartsUsagePath, r as discoverModels, t as CodeArtsUsageTracker } from "./usage-5YK7bW-e.mjs";
|
|
3
3
|
import { existsSync, statSync } from "node:fs";
|
|
4
4
|
//#region src/version.ts
|
|
5
|
-
const CODEARTS_VERSION = "1.1.
|
|
5
|
+
const CODEARTS_VERSION = "1.1.3";
|
|
6
6
|
//#endregion
|
|
7
7
|
//#region src/bin.ts
|
|
8
8
|
/**
|
package/lib/client/index.js
CHANGED
|
@@ -33,70 +33,70 @@ if (typeof document !== "undefined" && document.querySelector("style[data-plugin
|
|
|
33
33
|
document.head.appendChild(tag);
|
|
34
34
|
}
|
|
35
35
|
var CodeArtsPluginCard_module_css_default = {
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"accountCard": "xoziZG_accountCard",
|
|
41
|
-
"modelName": "xoziZG_modelName",
|
|
42
|
-
"name": "xoziZG_name",
|
|
43
|
-
"tabs": "xoziZG_tabs",
|
|
44
|
-
"actions": "xoziZG_actions",
|
|
45
|
-
"accountToolbar": "xoziZG_accountToolbar",
|
|
46
|
-
"creditRow": "xoziZG_creditRow",
|
|
47
|
-
"modelRequests": "xoziZG_modelRequests",
|
|
48
|
-
"usageBar": "xoziZG_usageBar",
|
|
49
|
-
"manual": "xoziZG_manual",
|
|
50
|
-
"error": "xoziZG_error",
|
|
51
|
-
"meta": "xoziZG_meta",
|
|
52
|
-
"accountEntry": "xoziZG_accountEntry",
|
|
53
|
-
"area": "xoziZG_area",
|
|
54
|
-
"tabPanel": "xoziZG_tabPanel",
|
|
55
|
-
"card": "xoziZG_card",
|
|
56
|
-
"field": "xoziZG_field",
|
|
36
|
+
"choices": "xoziZG_choices",
|
|
37
|
+
"claimAllRow": "xoziZG_claimAllRow",
|
|
38
|
+
"fieldLabel": "xoziZG_fieldLabel",
|
|
39
|
+
"balanceUnit": "xoziZG_balanceUnit",
|
|
57
40
|
"check": "xoziZG_check",
|
|
58
41
|
"usageFill": "xoziZG_usageFill",
|
|
59
|
-
"creditHint": "xoziZG_creditHint",
|
|
60
42
|
"modelShare": "xoziZG_modelShare",
|
|
61
|
-
"
|
|
62
|
-
"
|
|
43
|
+
"bar": "xoziZG_bar",
|
|
44
|
+
"balance": "xoziZG_balance",
|
|
45
|
+
"link": "xoziZG_link",
|
|
46
|
+
"tabPanel": "xoziZG_tabPanel",
|
|
63
47
|
"headText": "xoziZG_headText",
|
|
64
|
-
"creditLink": "xoziZG_creditLink",
|
|
65
|
-
"desc": "xoziZG_desc",
|
|
66
48
|
"balanceRow": "xoziZG_balanceRow",
|
|
67
|
-
"
|
|
68
|
-
"sectionHead": "xoziZG_sectionHead",
|
|
49
|
+
"card": "xoziZG_card",
|
|
69
50
|
"manualForm": "xoziZG_manualForm",
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
51
|
+
"name": "xoziZG_name",
|
|
52
|
+
"creditRow": "xoziZG_creditRow",
|
|
53
|
+
"creditLink": "xoziZG_creditLink",
|
|
54
|
+
"tabs": "xoziZG_tabs",
|
|
55
|
+
"body": "xoziZG_body",
|
|
56
|
+
"count": "xoziZG_count",
|
|
57
|
+
"accountHint": "xoziZG_accountHint",
|
|
58
|
+
"meta": "xoziZG_meta",
|
|
75
59
|
"sectionLabel": "xoziZG_sectionLabel",
|
|
60
|
+
"manual": "xoziZG_manual",
|
|
61
|
+
"creditFooter": "xoziZG_creditFooter",
|
|
62
|
+
"creditHint": "xoziZG_creditHint",
|
|
63
|
+
"modelChart": "xoziZG_modelChart",
|
|
64
|
+
"accountCard": "xoziZG_accountCard",
|
|
76
65
|
"danger": "xoziZG_danger",
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"link": "xoziZG_link",
|
|
81
|
-
"modelFill": "xoziZG_modelFill",
|
|
82
|
-
"accountName": "xoziZG_accountName",
|
|
83
|
-
"modelRow": "xoziZG_modelRow",
|
|
84
|
-
"modelTrack": "xoziZG_modelTrack",
|
|
85
|
-
"hint": "xoziZG_hint",
|
|
66
|
+
"accountToolbar": "xoziZG_accountToolbar",
|
|
67
|
+
"modelTokens": "xoziZG_modelTokens",
|
|
68
|
+
"manualSummary": "xoziZG_manualSummary",
|
|
86
69
|
"balanceMeta": "xoziZG_balanceMeta",
|
|
87
|
-
"count": "xoziZG_count",
|
|
88
|
-
"modelChart": "xoziZG_modelChart",
|
|
89
|
-
"accountRow": "xoziZG_accountRow",
|
|
90
|
-
"creditRows": "xoziZG_creditRows",
|
|
91
70
|
"header": "xoziZG_header",
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
71
|
+
"sectionHead": "xoziZG_sectionHead",
|
|
72
|
+
"accountEntry": "xoziZG_accountEntry",
|
|
73
|
+
"hint": "xoziZG_hint",
|
|
74
|
+
"error": "xoziZG_error",
|
|
75
|
+
"modelName": "xoziZG_modelName",
|
|
76
|
+
"field": "xoziZG_field",
|
|
77
|
+
"avatar": "xoziZG_avatar",
|
|
78
|
+
"modelTrack": "xoziZG_modelTrack",
|
|
79
|
+
"usageBar": "xoziZG_usageBar",
|
|
80
|
+
"updated": "xoziZG_updated",
|
|
81
|
+
"modelRow": "xoziZG_modelRow",
|
|
82
|
+
"expiryRow": "xoziZG_expiryRow",
|
|
83
|
+
"actions": "xoziZG_actions",
|
|
84
|
+
"accountRowActions": "xoziZG_accountRowActions",
|
|
85
|
+
"accountRow": "xoziZG_accountRow",
|
|
86
|
+
"accountInfo": "xoziZG_accountInfo",
|
|
87
|
+
"modelRequests": "xoziZG_modelRequests",
|
|
88
|
+
"modelFill": "xoziZG_modelFill",
|
|
89
|
+
"desc": "xoziZG_desc",
|
|
96
90
|
"accountNameRow": "xoziZG_accountNameRow",
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"
|
|
91
|
+
"area": "xoziZG_area",
|
|
92
|
+
"creditBlock": "xoziZG_creditBlock",
|
|
93
|
+
"expiryLabel": "xoziZG_expiryLabel",
|
|
94
|
+
"accountName": "xoziZG_accountName",
|
|
95
|
+
"section": "xoziZG_section",
|
|
96
|
+
"choiceRow": "xoziZG_choiceRow",
|
|
97
|
+
"barFill": "xoziZG_barFill",
|
|
98
|
+
"statusLine": "xoziZG_statusLine",
|
|
99
|
+
"creditRows": "xoziZG_creditRows"
|
|
100
100
|
};
|
|
101
101
|
//#endregion
|
|
102
102
|
//#region src/client/CodeArtsPluginCard.tsx
|
|
@@ -879,311 +879,318 @@ function CodeArtsPluginCard({ t }) {
|
|
|
879
879
|
})]
|
|
880
880
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
881
881
|
className: CodeArtsPluginCard_module_css_default.body,
|
|
882
|
-
children: [
|
|
883
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
884
|
-
className: CodeArtsPluginCard_module_css_default.
|
|
885
|
-
|
|
886
|
-
value: activeTab,
|
|
887
|
-
onChange: setTab,
|
|
888
|
-
label: t("tabsLabel")
|
|
882
|
+
children: [
|
|
883
|
+
status?.piAiError !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
884
|
+
className: CodeArtsPluginCard_module_css_default.error,
|
|
885
|
+
children: status.piAiError
|
|
889
886
|
}),
|
|
890
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
className: CodeArtsPluginCard_module_css_default.accountToolbar,
|
|
909
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
910
|
-
variant: "outline",
|
|
911
|
-
size: "sm",
|
|
912
|
-
"aria-expanded": manualOpen,
|
|
913
|
-
disabled: busy,
|
|
914
|
-
onClick: () => setManualOpen((open) => !open),
|
|
915
|
-
children: t("pasteTokenAdd")
|
|
916
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
917
|
-
variant: "primary",
|
|
918
|
-
size: "sm",
|
|
919
|
-
disabled: busy || loginPending,
|
|
920
|
-
onClick: () => void startOAuthLogin(),
|
|
921
|
-
children: loginPending ? t("signingIn") : t("addAccount")
|
|
922
|
-
})]
|
|
923
|
-
}),
|
|
924
|
-
loginUrl !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
925
|
-
className: CodeArtsPluginCard_module_css_default.hint,
|
|
926
|
-
children: [
|
|
927
|
-
t("openManually"),
|
|
928
|
-
" ",
|
|
929
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
930
|
-
className: CodeArtsPluginCard_module_css_default.link,
|
|
931
|
-
href: loginUrl,
|
|
932
|
-
target: "_blank",
|
|
933
|
-
rel: "noreferrer",
|
|
934
|
-
children: loginUrl
|
|
935
|
-
})
|
|
936
|
-
]
|
|
937
|
-
}),
|
|
938
|
-
manualOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
939
|
-
className: CodeArtsPluginCard_module_css_default.manualForm,
|
|
940
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ManualTokenForm, {
|
|
941
|
-
t,
|
|
942
|
-
token,
|
|
943
|
-
label,
|
|
944
|
-
busy,
|
|
945
|
-
onToken: setToken,
|
|
946
|
-
onLabel: setLabel,
|
|
947
|
-
onSubmit: (e) => void saveToken(e)
|
|
948
|
-
})
|
|
949
|
-
}),
|
|
950
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
951
|
-
className: CodeArtsPluginCard_module_css_default.accountCard,
|
|
952
|
-
children: [
|
|
953
|
-
accounts.map((account) => {
|
|
954
|
-
const accountLine = accountMeta(account);
|
|
955
|
-
const credit = creditFor(account.id);
|
|
956
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
957
|
-
className: CodeArtsPluginCard_module_css_default.accountEntry,
|
|
958
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
959
|
-
className: CodeArtsPluginCard_module_css_default.accountRow,
|
|
960
|
-
children: [
|
|
961
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
962
|
-
className: CodeArtsPluginCard_module_css_default.avatar,
|
|
963
|
-
"aria-hidden": "true",
|
|
964
|
-
children: Array.from(accountName(account))[0] ?? "*"
|
|
965
|
-
}),
|
|
966
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
967
|
-
className: CodeArtsPluginCard_module_css_default.accountInfo,
|
|
968
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
969
|
-
className: CodeArtsPluginCard_module_css_default.accountNameRow,
|
|
970
|
-
children: [
|
|
971
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
972
|
-
className: CodeArtsPluginCard_module_css_default.accountName,
|
|
973
|
-
children: accountName(account)
|
|
974
|
-
}),
|
|
975
|
-
account.stale && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, { children: t("accountNeedsSignIn") }),
|
|
976
|
-
!account.signable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, { children: t("accountNoKey") })
|
|
977
|
-
]
|
|
978
|
-
}), accountLine !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
979
|
-
className: CodeArtsPluginCard_module_css_default.meta,
|
|
980
|
-
children: accountLine
|
|
981
|
-
})]
|
|
982
|
-
}),
|
|
983
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
984
|
-
className: CodeArtsPluginCard_module_css_default.accountRowActions,
|
|
985
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
986
|
-
variant: "outline",
|
|
987
|
-
size: "sm",
|
|
988
|
-
className: CodeArtsPluginCard_module_css_default.danger,
|
|
989
|
-
disabled: busy,
|
|
990
|
-
onClick: () => void removeAccount(account.id),
|
|
991
|
-
children: t("accountRemove")
|
|
992
|
-
})
|
|
993
|
-
})
|
|
994
|
-
]
|
|
995
|
-
}), credit !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CreditBlock, {
|
|
996
|
-
credits: credit.credits,
|
|
997
|
-
error: credit.creditsError,
|
|
998
|
-
t,
|
|
999
|
-
onClaim: () => void claim(account.id),
|
|
1000
|
-
claiming: claimingId === account.id || claimingId === CLAIM_ALL,
|
|
1001
|
-
claimResult: claimResults[account.id] ?? null,
|
|
1002
|
-
justClaimed: claimedIds[account.id] === true
|
|
1003
|
-
})]
|
|
1004
|
-
}, account.id);
|
|
1005
|
-
}),
|
|
1006
|
-
accounts.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1007
|
-
className: CodeArtsPluginCard_module_css_default.claimAllRow,
|
|
1008
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1009
|
-
variant: "outline",
|
|
1010
|
-
size: "sm",
|
|
1011
|
-
disabled: claimingId !== null,
|
|
1012
|
-
onClick: () => void claim(),
|
|
1013
|
-
children: claimingId === CLAIM_ALL ? t("claimPending") : t("claimAll")
|
|
1014
|
-
})
|
|
1015
|
-
}),
|
|
1016
|
-
accounts.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1017
|
-
className: CodeArtsPluginCard_module_css_default.accountHint,
|
|
1018
|
-
children: t("accountsRotateHint")
|
|
1019
|
-
})
|
|
1020
|
-
]
|
|
1021
|
-
}),
|
|
1022
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1023
|
-
className: CodeArtsPluginCard_module_css_default.actions,
|
|
1024
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1025
|
-
variant: "outline",
|
|
1026
|
-
size: "sm",
|
|
1027
|
-
className: CodeArtsPluginCard_module_css_default.danger,
|
|
1028
|
-
disabled: busy,
|
|
1029
|
-
onClick: () => void clearToken(),
|
|
1030
|
-
children: t("clearToken")
|
|
1031
|
-
})
|
|
1032
|
-
})
|
|
1033
|
-
]
|
|
1034
|
-
})
|
|
1035
|
-
}),
|
|
1036
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TabPanel, {
|
|
1037
|
-
id: panelId("models"),
|
|
1038
|
-
labelledBy: tabId("models"),
|
|
1039
|
-
active: activeTab === "models",
|
|
1040
|
-
children: selection ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1041
|
-
className: CodeArtsPluginCard_module_css_default.section,
|
|
1042
|
-
children: [
|
|
1043
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1044
|
-
className: CodeArtsPluginCard_module_css_default.sectionHead,
|
|
1045
|
-
children: [
|
|
1046
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
887
|
+
signedIn ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
888
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.SegmentedTabs, {
|
|
889
|
+
className: CodeArtsPluginCard_module_css_default.tabs,
|
|
890
|
+
items: tabs,
|
|
891
|
+
value: activeTab,
|
|
892
|
+
onChange: setTab,
|
|
893
|
+
label: t("tabsLabel")
|
|
894
|
+
}),
|
|
895
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TabPanel, {
|
|
896
|
+
id: panelId("accounts"),
|
|
897
|
+
labelledBy: tabId("accounts"),
|
|
898
|
+
active: activeTab === "accounts",
|
|
899
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
900
|
+
className: CodeArtsPluginCard_module_css_default.section,
|
|
901
|
+
children: [
|
|
902
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
903
|
+
className: CodeArtsPluginCard_module_css_default.sectionHead,
|
|
904
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1047
905
|
className: CodeArtsPluginCard_module_css_default.sectionLabel,
|
|
1048
|
-
children: t("
|
|
1049
|
-
}),
|
|
1050
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
906
|
+
children: t("accountsTitle")
|
|
907
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1051
908
|
className: CodeArtsPluginCard_module_css_default.count,
|
|
1052
|
-
children:
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
909
|
+
children: accounts.length
|
|
910
|
+
})]
|
|
911
|
+
}),
|
|
912
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
913
|
+
className: CodeArtsPluginCard_module_css_default.accountToolbar,
|
|
914
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1058
915
|
variant: "outline",
|
|
1059
916
|
size: "sm",
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
917
|
+
"aria-expanded": manualOpen,
|
|
918
|
+
disabled: busy,
|
|
919
|
+
onClick: () => setManualOpen((open) => !open),
|
|
920
|
+
children: t("pasteTokenAdd")
|
|
921
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
922
|
+
variant: "primary",
|
|
923
|
+
size: "sm",
|
|
924
|
+
disabled: busy || loginPending,
|
|
925
|
+
onClick: () => void startOAuthLogin(),
|
|
926
|
+
children: loginPending ? t("signingIn") : t("addAccount")
|
|
927
|
+
})]
|
|
928
|
+
}),
|
|
929
|
+
loginUrl !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
930
|
+
className: CodeArtsPluginCard_module_css_default.hint,
|
|
931
|
+
children: [
|
|
932
|
+
t("openManually"),
|
|
933
|
+
" ",
|
|
934
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
935
|
+
className: CodeArtsPluginCard_module_css_default.link,
|
|
936
|
+
href: loginUrl,
|
|
937
|
+
target: "_blank",
|
|
938
|
+
rel: "noreferrer",
|
|
939
|
+
children: loginUrl
|
|
940
|
+
})
|
|
941
|
+
]
|
|
942
|
+
}),
|
|
943
|
+
manualOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
944
|
+
className: CodeArtsPluginCard_module_css_default.manualForm,
|
|
945
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ManualTokenForm, {
|
|
946
|
+
t,
|
|
947
|
+
token,
|
|
948
|
+
label,
|
|
949
|
+
busy,
|
|
950
|
+
onToken: setToken,
|
|
951
|
+
onLabel: setLabel,
|
|
952
|
+
onSubmit: (e) => void saveToken(e)
|
|
1063
953
|
})
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
className: CodeArtsPluginCard_module_css_default.hint,
|
|
1068
|
-
children: selection.restricted ? t("optionalModelsHint") : t("optionalModelsAllHint")
|
|
1069
|
-
}),
|
|
1070
|
-
blockedCount > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1071
|
-
className: CodeArtsPluginCard_module_css_default.hint,
|
|
1072
|
-
children: t("benefitBlockedHint", { n: blockedCount })
|
|
1073
|
-
}),
|
|
1074
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1075
|
-
className: CodeArtsPluginCard_module_css_default.choices,
|
|
1076
|
-
children: selection.choices.map((choice) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1077
|
-
className: CodeArtsPluginCard_module_css_default.choiceRow,
|
|
954
|
+
}),
|
|
955
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
956
|
+
className: CodeArtsPluginCard_module_css_default.accountCard,
|
|
1078
957
|
children: [
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
958
|
+
accounts.map((account) => {
|
|
959
|
+
const accountLine = accountMeta(account);
|
|
960
|
+
const credit = creditFor(account.id);
|
|
961
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
962
|
+
className: CodeArtsPluginCard_module_css_default.accountEntry,
|
|
963
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
964
|
+
className: CodeArtsPluginCard_module_css_default.accountRow,
|
|
965
|
+
children: [
|
|
966
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
967
|
+
className: CodeArtsPluginCard_module_css_default.avatar,
|
|
968
|
+
"aria-hidden": "true",
|
|
969
|
+
children: Array.from(accountName(account))[0] ?? "*"
|
|
970
|
+
}),
|
|
971
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
972
|
+
className: CodeArtsPluginCard_module_css_default.accountInfo,
|
|
973
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
974
|
+
className: CodeArtsPluginCard_module_css_default.accountNameRow,
|
|
975
|
+
children: [
|
|
976
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
977
|
+
className: CodeArtsPluginCard_module_css_default.accountName,
|
|
978
|
+
children: accountName(account)
|
|
979
|
+
}),
|
|
980
|
+
account.stale && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, { children: t("accountNeedsSignIn") }),
|
|
981
|
+
!account.signable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, { children: t("accountNoKey") })
|
|
982
|
+
]
|
|
983
|
+
}), accountLine !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
984
|
+
className: CodeArtsPluginCard_module_css_default.meta,
|
|
985
|
+
children: accountLine
|
|
986
|
+
})]
|
|
987
|
+
}),
|
|
988
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
989
|
+
className: CodeArtsPluginCard_module_css_default.accountRowActions,
|
|
990
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
991
|
+
variant: "outline",
|
|
992
|
+
size: "sm",
|
|
993
|
+
className: CodeArtsPluginCard_module_css_default.danger,
|
|
994
|
+
disabled: busy,
|
|
995
|
+
onClick: () => void removeAccount(account.id),
|
|
996
|
+
children: t("accountRemove")
|
|
997
|
+
})
|
|
998
|
+
})
|
|
999
|
+
]
|
|
1000
|
+
}), credit !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CreditBlock, {
|
|
1001
|
+
credits: credit.credits,
|
|
1002
|
+
error: credit.creditsError,
|
|
1003
|
+
t,
|
|
1004
|
+
onClaim: () => void claim(account.id),
|
|
1005
|
+
claiming: claimingId === account.id || claimingId === CLAIM_ALL,
|
|
1006
|
+
claimResult: claimResults[account.id] ?? null,
|
|
1007
|
+
justClaimed: claimedIds[account.id] === true
|
|
1008
|
+
})]
|
|
1009
|
+
}, account.id);
|
|
1085
1010
|
}),
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
children:
|
|
1011
|
+
accounts.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1012
|
+
className: CodeArtsPluginCard_module_css_default.claimAllRow,
|
|
1013
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1014
|
+
variant: "outline",
|
|
1015
|
+
size: "sm",
|
|
1016
|
+
disabled: claimingId !== null,
|
|
1017
|
+
onClick: () => void claim(),
|
|
1018
|
+
children: claimingId === CLAIM_ALL ? t("claimPending") : t("claimAll")
|
|
1019
|
+
})
|
|
1089
1020
|
}),
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
children:
|
|
1021
|
+
accounts.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1022
|
+
className: CodeArtsPluginCard_module_css_default.accountHint,
|
|
1023
|
+
children: t("accountsRotateHint")
|
|
1093
1024
|
})
|
|
1094
1025
|
]
|
|
1095
|
-
},
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
children: t("selectAll")
|
|
1109
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1110
|
-
variant: "primary",
|
|
1111
|
-
size: "sm",
|
|
1112
|
-
disabled: !dirty || savingModels,
|
|
1113
|
-
onClick: () => void saveModels(),
|
|
1114
|
-
children: savingModels ? t("saving") : savedModels && !dirty ? t("saved") : t("saveModels")
|
|
1115
|
-
})]
|
|
1116
|
-
}),
|
|
1117
|
-
modelError !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1118
|
-
className: CodeArtsPluginCard_module_css_default.error,
|
|
1119
|
-
children: modelError
|
|
1120
|
-
})
|
|
1121
|
-
]
|
|
1122
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1123
|
-
className: CodeArtsPluginCard_module_css_default.hint,
|
|
1124
|
-
children: t("modelsLoading")
|
|
1125
|
-
})
|
|
1126
|
-
}),
|
|
1127
|
-
status?.usage !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TabPanel, {
|
|
1128
|
-
id: panelId("usage"),
|
|
1129
|
-
labelledBy: tabId("usage"),
|
|
1130
|
-
active: activeTab === "usage",
|
|
1131
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageSection, {
|
|
1132
|
-
usage: status.usage,
|
|
1133
|
-
accounts,
|
|
1134
|
-
t
|
|
1135
|
-
})
|
|
1136
|
-
})
|
|
1137
|
-
] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1138
|
-
className: CodeArtsPluginCard_module_css_default.section,
|
|
1139
|
-
children: [
|
|
1140
|
-
expired && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1141
|
-
className: CodeArtsPluginCard_module_css_default.hint,
|
|
1142
|
-
children: t("expiredHint")
|
|
1143
|
-
}),
|
|
1144
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1145
|
-
className: CodeArtsPluginCard_module_css_default.actions,
|
|
1146
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1147
|
-
variant: "primary",
|
|
1148
|
-
disabled: busy || loginPending,
|
|
1149
|
-
onClick: () => void startOAuthLogin(),
|
|
1150
|
-
children: loginPending ? t("signingIn") : t("signIn")
|
|
1026
|
+
}),
|
|
1027
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1028
|
+
className: CodeArtsPluginCard_module_css_default.actions,
|
|
1029
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1030
|
+
variant: "outline",
|
|
1031
|
+
size: "sm",
|
|
1032
|
+
className: CodeArtsPluginCard_module_css_default.danger,
|
|
1033
|
+
disabled: busy,
|
|
1034
|
+
onClick: () => void clearToken(),
|
|
1035
|
+
children: t("clearToken")
|
|
1036
|
+
})
|
|
1037
|
+
})
|
|
1038
|
+
]
|
|
1151
1039
|
})
|
|
1152
1040
|
}),
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1041
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TabPanel, {
|
|
1042
|
+
id: panelId("models"),
|
|
1043
|
+
labelledBy: tabId("models"),
|
|
1044
|
+
active: activeTab === "models",
|
|
1045
|
+
children: selection ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1046
|
+
className: CodeArtsPluginCard_module_css_default.section,
|
|
1047
|
+
children: [
|
|
1048
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1049
|
+
className: CodeArtsPluginCard_module_css_default.sectionHead,
|
|
1050
|
+
children: [
|
|
1051
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1052
|
+
className: CodeArtsPluginCard_module_css_default.sectionLabel,
|
|
1053
|
+
children: t("modelsTitle")
|
|
1054
|
+
}),
|
|
1055
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1056
|
+
className: CodeArtsPluginCard_module_css_default.count,
|
|
1057
|
+
children: t("selectedCount", {
|
|
1058
|
+
n: draft.length,
|
|
1059
|
+
total: all
|
|
1060
|
+
})
|
|
1061
|
+
}),
|
|
1062
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1063
|
+
variant: "outline",
|
|
1064
|
+
size: "sm",
|
|
1065
|
+
disabled: refreshing,
|
|
1066
|
+
onClick: () => void refreshCatalog(),
|
|
1067
|
+
children: refreshing ? t("refreshing") : t("refreshModels")
|
|
1068
|
+
})
|
|
1069
|
+
]
|
|
1070
|
+
}),
|
|
1071
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1072
|
+
className: CodeArtsPluginCard_module_css_default.hint,
|
|
1073
|
+
children: selection.restricted ? t("optionalModelsHint") : t("optionalModelsAllHint")
|
|
1074
|
+
}),
|
|
1075
|
+
blockedCount > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1076
|
+
className: CodeArtsPluginCard_module_css_default.hint,
|
|
1077
|
+
children: t("benefitBlockedHint", { n: blockedCount })
|
|
1078
|
+
}),
|
|
1079
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1080
|
+
className: CodeArtsPluginCard_module_css_default.choices,
|
|
1081
|
+
children: selection.choices.map((choice) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1082
|
+
className: CodeArtsPluginCard_module_css_default.choiceRow,
|
|
1083
|
+
children: [
|
|
1084
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Checkbox, {
|
|
1085
|
+
className: CodeArtsPluginCard_module_css_default.check,
|
|
1086
|
+
checked: draft.includes(choice.id),
|
|
1087
|
+
disabled: !selection.writable || savingModels,
|
|
1088
|
+
onChange: (on) => setModel(choice.id, on),
|
|
1089
|
+
label: modelName(choice)
|
|
1090
|
+
}),
|
|
1091
|
+
choice.benefit === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, {
|
|
1092
|
+
tone: choice.blocked === true ? "warning" : "success",
|
|
1093
|
+
children: choice.blocked === true ? t("benefitBlocked") : t("benefit")
|
|
1094
|
+
}),
|
|
1095
|
+
choice.ratio !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, {
|
|
1096
|
+
tone: "quiet",
|
|
1097
|
+
children: choice.ratio
|
|
1098
|
+
})
|
|
1099
|
+
]
|
|
1100
|
+
}, choice.id))
|
|
1101
|
+
}),
|
|
1102
|
+
selection.writable && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1103
|
+
className: CodeArtsPluginCard_module_css_default.actions,
|
|
1104
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1105
|
+
variant: "outline",
|
|
1106
|
+
size: "sm",
|
|
1107
|
+
disabled: draft.length === all,
|
|
1108
|
+
onClick: () => {
|
|
1109
|
+
setSavedModels(false);
|
|
1110
|
+
setModelError(null);
|
|
1111
|
+
setDraft(selection.choices.map((c) => c.id));
|
|
1112
|
+
},
|
|
1113
|
+
children: t("selectAll")
|
|
1114
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1115
|
+
variant: "primary",
|
|
1116
|
+
size: "sm",
|
|
1117
|
+
disabled: !dirty || savingModels,
|
|
1118
|
+
onClick: () => void saveModels(),
|
|
1119
|
+
children: savingModels ? t("saving") : savedModels && !dirty ? t("saved") : t("saveModels")
|
|
1120
|
+
})]
|
|
1121
|
+
}),
|
|
1122
|
+
modelError !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1123
|
+
className: CodeArtsPluginCard_module_css_default.error,
|
|
1124
|
+
children: modelError
|
|
1125
|
+
})
|
|
1126
|
+
]
|
|
1127
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1128
|
+
className: CodeArtsPluginCard_module_css_default.hint,
|
|
1129
|
+
children: t("modelsLoading")
|
|
1130
|
+
})
|
|
1166
1131
|
}),
|
|
1167
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
busy,
|
|
1177
|
-
onToken: setToken,
|
|
1178
|
-
onLabel: setLabel,
|
|
1179
|
-
onSubmit: (e) => void saveToken(e)
|
|
1180
|
-
})]
|
|
1132
|
+
status?.usage !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TabPanel, {
|
|
1133
|
+
id: panelId("usage"),
|
|
1134
|
+
labelledBy: tabId("usage"),
|
|
1135
|
+
active: activeTab === "usage",
|
|
1136
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageSection, {
|
|
1137
|
+
usage: status.usage,
|
|
1138
|
+
accounts,
|
|
1139
|
+
t
|
|
1140
|
+
})
|
|
1181
1141
|
})
|
|
1182
|
-
]
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1142
|
+
] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1143
|
+
className: CodeArtsPluginCard_module_css_default.section,
|
|
1144
|
+
children: [
|
|
1145
|
+
expired && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1146
|
+
className: CodeArtsPluginCard_module_css_default.hint,
|
|
1147
|
+
children: t("expiredHint")
|
|
1148
|
+
}),
|
|
1149
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1150
|
+
className: CodeArtsPluginCard_module_css_default.actions,
|
|
1151
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1152
|
+
variant: "primary",
|
|
1153
|
+
disabled: busy || loginPending,
|
|
1154
|
+
onClick: () => void startOAuthLogin(),
|
|
1155
|
+
children: loginPending ? t("signingIn") : t("signIn")
|
|
1156
|
+
})
|
|
1157
|
+
}),
|
|
1158
|
+
loginUrl !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
1159
|
+
className: CodeArtsPluginCard_module_css_default.hint,
|
|
1160
|
+
children: [
|
|
1161
|
+
t("openManually"),
|
|
1162
|
+
" ",
|
|
1163
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
1164
|
+
className: CodeArtsPluginCard_module_css_default.link,
|
|
1165
|
+
href: loginUrl,
|
|
1166
|
+
target: "_blank",
|
|
1167
|
+
rel: "noreferrer",
|
|
1168
|
+
children: loginUrl
|
|
1169
|
+
})
|
|
1170
|
+
]
|
|
1171
|
+
}),
|
|
1172
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
1173
|
+
className: CodeArtsPluginCard_module_css_default.manual,
|
|
1174
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", {
|
|
1175
|
+
className: CodeArtsPluginCard_module_css_default.manualSummary,
|
|
1176
|
+
children: t("manualToken")
|
|
1177
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ManualTokenForm, {
|
|
1178
|
+
t,
|
|
1179
|
+
token,
|
|
1180
|
+
label,
|
|
1181
|
+
busy,
|
|
1182
|
+
onToken: setToken,
|
|
1183
|
+
onLabel: setLabel,
|
|
1184
|
+
onSubmit: (e) => void saveToken(e)
|
|
1185
|
+
})]
|
|
1186
|
+
})
|
|
1187
|
+
]
|
|
1188
|
+
}),
|
|
1189
|
+
msg !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1190
|
+
className: CodeArtsPluginCard_module_css_default.error,
|
|
1191
|
+
children: msg
|
|
1192
|
+
})
|
|
1193
|
+
]
|
|
1187
1194
|
})]
|
|
1188
1195
|
});
|
|
1189
1196
|
}
|
package/lib/index.d.mts
CHANGED
|
@@ -421,6 +421,14 @@ declare class CodeArtsAccountPool {
|
|
|
421
421
|
noteConcurrencyCap(id: string): void;
|
|
422
422
|
/** 凭据失效等硬错误:直接停用,等用户重新登录。 */
|
|
423
423
|
disable(id: string, reason: string): void;
|
|
424
|
+
/**
|
|
425
|
+
* 用户重新登录(凭据已换新)后调用:把账号从禁用/冷却里捞出来。
|
|
426
|
+
*
|
|
427
|
+
* `sync()` 只对齐成员、特意保留运行时状态(account-pool 不读凭据文档),所以
|
|
428
|
+
* 「同一账号重新登录」不会自动清掉 disabled —— 以前只能靠重启(见 issue #1)。
|
|
429
|
+
* 登录成功的语义就是「这个号现在该能用了」,由登录路径显式调这里复位。
|
|
430
|
+
*/
|
|
431
|
+
revive(id: string): void;
|
|
424
432
|
/** 上游 5xx / 软限流:短时冷却。 */
|
|
425
433
|
cooldown(id: string, ms: number, reason: string): void;
|
|
426
434
|
/** 累计错误;达到阈值就冷却。 */
|
package/lib/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as filterEnabledModels, C as rateLimitFrame, D as FALLBACK_CODEARTS_MODELS, E as CodeArtsCatalog, F as
|
|
1
|
+
import { A as filterEnabledModels, C as rateLimitFrame, D as FALLBACK_CODEARTS_MODELS, E as CodeArtsCatalog, F as MANUAL_ACCOUNT_ID, I as codeartsAccountsPath, L as codeartsAuthPath, M as isBenefitModel, N as CodeArtsAccountStore, O as clearBenefitBlocked, P as CodeArtsCredentialStore, R as startLogin, S as prepareChatBody, T as upstreamErrorMessage, _ as isQueueableRate, a as SNAP_HOST, b as maxTokensCeilingFor, c as claimDailyWelfare, d as fetchCallerIdentity, f as fetchModels, g as isParamInvalidFrame, h as isConcurrencyCap, i as refreshCatalog, j as isBenefitBlocked, k as creditRatioLabel, l as clearQueueStatus, m as fetchWelfareCampaigns, n as codeartsUsagePath, o as canonicalModel, p as fetchQueueStatus, r as discoverModels, s as chatStream, t as CodeArtsUsageTracker, u as degradeTokenCeiling, v as isTpmLimit, w as signedGet, x as pickDailyWelfareCampaign, y as isWelfareClaimedStatus } from "./usage-5YK7bW-e.mjs";
|
|
2
2
|
import z from "@deepseek-ai/schemastery";
|
|
3
3
|
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
4
4
|
import { createServer } from "node:http";
|
|
@@ -106,6 +106,22 @@ var CodeArtsAccountPool = class {
|
|
|
106
106
|
account.disabled = true;
|
|
107
107
|
account.lastError = reason;
|
|
108
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* 用户重新登录(凭据已换新)后调用:把账号从禁用/冷却里捞出来。
|
|
111
|
+
*
|
|
112
|
+
* `sync()` 只对齐成员、特意保留运行时状态(account-pool 不读凭据文档),所以
|
|
113
|
+
* 「同一账号重新登录」不会自动清掉 disabled —— 以前只能靠重启(见 issue #1)。
|
|
114
|
+
* 登录成功的语义就是「这个号现在该能用了」,由登录路径显式调这里复位。
|
|
115
|
+
*/
|
|
116
|
+
revive(id) {
|
|
117
|
+
const account = this.accounts.get(id);
|
|
118
|
+
if (account === void 0) return;
|
|
119
|
+
account.disabled = false;
|
|
120
|
+
account.coolUntil = 0;
|
|
121
|
+
account.cappedUntil = 0;
|
|
122
|
+
account.errorCount = 0;
|
|
123
|
+
account.lastError = void 0;
|
|
124
|
+
}
|
|
109
125
|
/** 上游 5xx / 软限流:短时冷却。 */
|
|
110
126
|
cooldown(id, ms, reason) {
|
|
111
127
|
const account = this.accounts.get(id);
|
|
@@ -706,6 +722,56 @@ var CodeArtsPiAiAdapter = class extends PiAiAdapter {
|
|
|
706
722
|
}
|
|
707
723
|
};
|
|
708
724
|
//#endregion
|
|
725
|
+
//#region src/pi-ai-compat.ts
|
|
726
|
+
/**
|
|
727
|
+
* `@earendil-works/pi-ai` 运行时自检。
|
|
728
|
+
*
|
|
729
|
+
* 本插件编译时对齐的是 1.3.0,而宿主(`dsh-llm-pi-ai` 0.2.1-rc.2 起)会先把系统提示
|
|
730
|
+
* 折叠成一条 `role:"system"`、`content` 为**字符串**的消息,再交给 provider。1.3.0 之前
|
|
731
|
+
* 的 `estimateMessageTokens` 没有 system 分支:字符串内容被按字符遍历,每个"块"是单个
|
|
732
|
+
* 字符,`block.name` 为 undefined,于是每条消息都死在
|
|
733
|
+
* `Cannot read properties of undefined (reading 'length')` 上 —— 而且是在出网之前,
|
|
734
|
+
* 用户只看得到一句「本轮运行失败」。
|
|
735
|
+
*
|
|
736
|
+
* 什么时候会拿到旧的那份:profile 顶层被别的插件 hoist 了一个低版本,而本插件的依赖
|
|
737
|
+
* 没落地到自己的 `node_modules`。1.1.3 起 `@earendil-works/pi-ai` 已从 peerDependencies
|
|
738
|
+
* 移进 dependencies,区间真正生效;这里再探测一次,把「版本不兼容」明说,而不是让
|
|
739
|
+
* 每条消息各自崩在一个看不懂的 TypeError 上。
|
|
740
|
+
*
|
|
741
|
+
* 探测用能力而不是版本号:不依赖 package.json 能不能读到,也对未来的版本漂移免疫。
|
|
742
|
+
*
|
|
743
|
+
* @module dsh-codearts/pi-ai-compat
|
|
744
|
+
*/
|
|
745
|
+
/** 折叠后的系统消息要能被估token;从这一版起才支持。 */
|
|
746
|
+
const MIN_PI_AI_VERSION = "1.3.0";
|
|
747
|
+
let probe;
|
|
748
|
+
/** 不兼容时的说明;兼容时 undefined。结果只算一次(模块加载后版本不会再变)。 */
|
|
749
|
+
function probePiAiCompat() {
|
|
750
|
+
probe ??= runProbe();
|
|
751
|
+
return probe;
|
|
752
|
+
}
|
|
753
|
+
async function runProbe() {
|
|
754
|
+
const hint = `需要 @earendil-works/pi-ai >= ${MIN_PI_AI_VERSION},请重装 dsh-codearts(1.1.3 起它自带这份依赖),或把 profile 顶层那份升级到同一区间`;
|
|
755
|
+
let estimate;
|
|
756
|
+
try {
|
|
757
|
+
({estimateMessageTokens: estimate} = await import("@earendil-works/pi-ai/utils/estimate"));
|
|
758
|
+
} catch (error) {
|
|
759
|
+
return `pi-ai 不兼容:读不到 @earendil-works/pi-ai/utils/estimate(${messageOf(error)})。${hint}`;
|
|
760
|
+
}
|
|
761
|
+
if (typeof estimate !== "function") return `pi-ai 不兼容:这份 @earendil-works/pi-ai 没有 estimateMessageTokens。${hint}`;
|
|
762
|
+
try {
|
|
763
|
+
estimate({
|
|
764
|
+
role: "system",
|
|
765
|
+
content: "probe"
|
|
766
|
+
});
|
|
767
|
+
} catch (error) {
|
|
768
|
+
return `pi-ai 不兼容:这份 @earendil-works/pi-ai 处理不了宿主折叠出的 system 消息(${messageOf(error)}),每条请求都会在出网前失败。${hint}`;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
function messageOf(error) {
|
|
772
|
+
return error instanceof Error ? error.message : String(error);
|
|
773
|
+
}
|
|
774
|
+
//#endregion
|
|
709
775
|
//#region src/loopback.ts
|
|
710
776
|
/**
|
|
711
777
|
* Shared loopback gates for the plugin's local HTTP surfaces: the loopback
|
|
@@ -816,6 +882,40 @@ function queuedMessage(model, gate) {
|
|
|
816
882
|
const upstream = gate.message.trim();
|
|
817
883
|
return `${upstream === "" ? `上游排队中:${model} 第 ${gate.position} 位(共 ${gate.length} 条)` : upstream} 插件没有一直等下去,请稍后重试。`;
|
|
818
884
|
}
|
|
885
|
+
/**
|
|
886
|
+
* 「一个账号都选不出来」时的报错:把真实原因说清 —— 是禁用(附最后错误)、冷却
|
|
887
|
+
* (附剩余秒数),还是本地槽位全满。以前三种都回同一句「没有可用账号」,禁用那
|
|
888
|
+
* 种还把真因(比如 billion-context 本地拒签的 403)整个吞掉(issue #1)。
|
|
889
|
+
*
|
|
890
|
+
* 全部被禁用时回 401(宿主只自动重试 429,401 一次就把「去重新登录」说清);
|
|
891
|
+
* 只要还有会自己恢复的(冷却/槽位满)就回 429,宿主重试有概率直接救回来。
|
|
892
|
+
*/
|
|
893
|
+
function noAccountError(accounts) {
|
|
894
|
+
const now = Date.now();
|
|
895
|
+
const disabled = accounts.filter((a) => a.disabled);
|
|
896
|
+
const cooling = accounts.filter((a) => !a.disabled && now < a.coolUntil);
|
|
897
|
+
const busy = accounts.filter((a) => !a.disabled && now >= a.coolUntil);
|
|
898
|
+
const parts = [];
|
|
899
|
+
if (disabled.length > 0) {
|
|
900
|
+
const reasons = disabled.map((a) => a.lastError === void 0 ? a.id : `${a.id}(${a.lastError.slice(0, 120)})`).join("、");
|
|
901
|
+
parts.push(`${disabled.length} 个被禁用:${reasons}——请到设置卡片重新登录(若在用 billion-context,先检查它的 resign 配置)`);
|
|
902
|
+
}
|
|
903
|
+
if (cooling.length > 0) {
|
|
904
|
+
const secs = Math.max(1, Math.ceil((Math.min(...cooling.map((a) => a.coolUntil)) - now) / 1e3));
|
|
905
|
+
parts.push(`${cooling.length} 个在短时冷却中(约 ${secs} 秒后恢复)`);
|
|
906
|
+
}
|
|
907
|
+
if (busy.length > 0) parts.push(`${busy.length} 个的本地并发槽位已满(每账号最多 ${busy[0]?.maxConcurrent ?? 2} 个在飞请求),等几秒再发`);
|
|
908
|
+
const message = `codearts 当前没有可用账号:${parts.join(";")}`;
|
|
909
|
+
return disabled.length === accounts.length ? {
|
|
910
|
+
status: 401,
|
|
911
|
+
kind: "session_dead",
|
|
912
|
+
message
|
|
913
|
+
} : {
|
|
914
|
+
status: 429,
|
|
915
|
+
kind: "soft_rate",
|
|
916
|
+
message
|
|
917
|
+
};
|
|
918
|
+
}
|
|
819
919
|
function readBody$1(req) {
|
|
820
920
|
return new Promise((resolve, reject) => {
|
|
821
921
|
const chunks = [];
|
|
@@ -835,7 +935,6 @@ function readBody$1(req) {
|
|
|
835
935
|
}
|
|
836
936
|
/** 一次请求最多试几个账号(与 Go 参考的 MaxRotate 一致)。 */
|
|
837
937
|
const MAX_ROTATE = 3;
|
|
838
|
-
/** 一次请求最多把 max_tokens 降几档(65536 → 32768 → 16384 → 8192)。 */
|
|
839
938
|
const MAX_CEILING_HEALS = 3;
|
|
840
939
|
/**
|
|
841
940
|
* 所有账号都撞上并发上限时,回落到「在同一账号上原地重发」的预算。
|
|
@@ -855,6 +954,35 @@ const SERVER_COOLDOWN_MS = 3e4;
|
|
|
855
954
|
/** 零散错误累计到阈值后冷却该账号。 */
|
|
856
955
|
const ERROR_COOLDOWN_MS = 6e4;
|
|
857
956
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
957
|
+
const recentShapes = [];
|
|
958
|
+
/** 最近的请求形状,最新在前。 */
|
|
959
|
+
function recentRequestShapes() {
|
|
960
|
+
return [...recentShapes].reverse();
|
|
961
|
+
}
|
|
962
|
+
function noteRequestShape(raw, model) {
|
|
963
|
+
let parsed;
|
|
964
|
+
try {
|
|
965
|
+
parsed = JSON.parse(raw);
|
|
966
|
+
} catch {
|
|
967
|
+
return;
|
|
968
|
+
}
|
|
969
|
+
if (parsed === null || typeof parsed !== "object") return;
|
|
970
|
+
const list = Array.isArray(parsed.messages) ? parsed.messages : [];
|
|
971
|
+
const roles = list.map((message) => {
|
|
972
|
+
if (message === null || typeof message !== "object") return "";
|
|
973
|
+
const role = message.role;
|
|
974
|
+
return typeof role === "string" ? role : "";
|
|
975
|
+
});
|
|
976
|
+
recentShapes.push({
|
|
977
|
+
at: Date.now(),
|
|
978
|
+
model,
|
|
979
|
+
messages: list.length,
|
|
980
|
+
roles,
|
|
981
|
+
emptyRoleAt: roles.map((role, index) => role === "" ? index : -1).filter((index) => index >= 0),
|
|
982
|
+
tools: Array.isArray(parsed.tools) ? parsed.tools.length : 0
|
|
983
|
+
});
|
|
984
|
+
if (recentShapes.length > 8) recentShapes.shift();
|
|
985
|
+
}
|
|
858
986
|
function createCodeArtsShim(options) {
|
|
859
987
|
const { store, catalog } = options;
|
|
860
988
|
const logger = options.logger;
|
|
@@ -1050,6 +1178,7 @@ function createCodeArtsShim(options) {
|
|
|
1050
1178
|
if (typeof inbound.model === "string") contextWindow = contextWindowFor(canonicalModel(inbound.model));
|
|
1051
1179
|
} catch {}
|
|
1052
1180
|
const checked = prepareChatBody(raw, contextWindow);
|
|
1181
|
+
noteRequestShape(raw, checked.model);
|
|
1053
1182
|
if (checked.error !== void 0) {
|
|
1054
1183
|
writeOpenAIError(res, 400, "context_overflow", checked.error);
|
|
1055
1184
|
return;
|
|
@@ -1170,7 +1299,8 @@ function createCodeArtsShim(options) {
|
|
|
1170
1299
|
}
|
|
1171
1300
|
}
|
|
1172
1301
|
if (lastKind === void 0) {
|
|
1173
|
-
|
|
1302
|
+
const none = noAccountError(pool.list());
|
|
1303
|
+
writeOpenAIError(res, none.status, none.kind, none.message);
|
|
1174
1304
|
return;
|
|
1175
1305
|
}
|
|
1176
1306
|
const explanation = upstreamErrorMessage(lastMessage, lastStatus);
|
|
@@ -1272,6 +1402,8 @@ const CODEARTS_CLAIM_PATH = "/api/codearts/claim";
|
|
|
1272
1402
|
const CODEARTS_REFRESH_MODELS_PATH = "/api/codearts/refresh-models";
|
|
1273
1403
|
/** GET /api/codearts/queue — 上游排队位置(只在等开流期间有值,底部积分条旁边展示)。 */
|
|
1274
1404
|
const CODEARTS_QUEUE_PATH = "/api/codearts/queue";
|
|
1405
|
+
/** 最近出站请求的**形状**摘要(只有 role 名与计数,不含内容),排障用。 */
|
|
1406
|
+
const CODEARTS_DEBUG_PATH = "/api/codearts/debug";
|
|
1275
1407
|
/**
|
|
1276
1408
|
* 由完整目录 + 已存 enabled 计算 selection。
|
|
1277
1409
|
* - enabled 为空/未存 => 全部勾选(restricted=false)
|
|
@@ -1452,11 +1584,14 @@ async function buildStatus(deps) {
|
|
|
1452
1584
|
const accounts = await deps.store.list();
|
|
1453
1585
|
const cred = await deps.store.current();
|
|
1454
1586
|
const usage = usageOf(deps);
|
|
1587
|
+
const piAi = await probePiAiCompat();
|
|
1588
|
+
const compat = piAi === void 0 ? {} : { piAiError: piAi };
|
|
1455
1589
|
if (accounts.length === 0 || cred === void 0) return {
|
|
1456
1590
|
status: "signed-out",
|
|
1457
1591
|
models,
|
|
1458
1592
|
accounts,
|
|
1459
|
-
usage
|
|
1593
|
+
usage,
|
|
1594
|
+
...compat
|
|
1460
1595
|
};
|
|
1461
1596
|
const usable = accounts.some(accountUsable);
|
|
1462
1597
|
const identity = {
|
|
@@ -1468,11 +1603,13 @@ async function buildStatus(deps) {
|
|
|
1468
1603
|
};
|
|
1469
1604
|
if (!usable) return {
|
|
1470
1605
|
status: "expired",
|
|
1471
|
-
...identity
|
|
1606
|
+
...identity,
|
|
1607
|
+
...compat
|
|
1472
1608
|
};
|
|
1473
1609
|
return {
|
|
1474
1610
|
status: "signed-in",
|
|
1475
1611
|
...identity,
|
|
1612
|
+
...compat,
|
|
1476
1613
|
...await creditsOf(deps)
|
|
1477
1614
|
};
|
|
1478
1615
|
}
|
|
@@ -1582,6 +1719,7 @@ function tokenPostHandler(deps) {
|
|
|
1582
1719
|
}
|
|
1583
1720
|
const label = typeof body?.label === "string" && body.label.trim() !== "" ? body.label.trim() : void 0;
|
|
1584
1721
|
await deps.store.set(token, label);
|
|
1722
|
+
deps.reviveAccount?.(MANUAL_ACCOUNT_ID);
|
|
1585
1723
|
json(res, 200, await buildStatus(deps));
|
|
1586
1724
|
} catch (error) {
|
|
1587
1725
|
json(res, 500, { error: safeMessage(error) });
|
|
@@ -1725,6 +1863,20 @@ function queueHandler(deps) {
|
|
|
1725
1863
|
json(res, 200, { queue: deps.queue?.() ?? [] });
|
|
1726
1864
|
};
|
|
1727
1865
|
}
|
|
1866
|
+
/** GET /api/codearts/debug — 最近出站请求的形状摘要(只有 role 名与计数)。 */
|
|
1867
|
+
function debugHandler(deps) {
|
|
1868
|
+
return async (req, res) => {
|
|
1869
|
+
if (req.method !== "GET") {
|
|
1870
|
+
json(res, 405, { error: "method not allowed" });
|
|
1871
|
+
return;
|
|
1872
|
+
}
|
|
1873
|
+
if (!loopbackRequest(req)) {
|
|
1874
|
+
json(res, 403, { error: "request-not-trusted" });
|
|
1875
|
+
return;
|
|
1876
|
+
}
|
|
1877
|
+
json(res, 200, { requests: deps.recentRequests?.() ?? [] });
|
|
1878
|
+
};
|
|
1879
|
+
}
|
|
1728
1880
|
/** Mount the status / models / token routes. */
|
|
1729
1881
|
function registerCodeArtsStatusRoute(ctx, deps) {
|
|
1730
1882
|
ctx.effect(() => {
|
|
@@ -1781,6 +1933,11 @@ function registerCodeArtsStatusRoute(ctx, deps) {
|
|
|
1781
1933
|
path: CODEARTS_QUEUE_PATH,
|
|
1782
1934
|
handler: queueHandler(deps)
|
|
1783
1935
|
});
|
|
1936
|
+
const disposeDebug = ctx.webServer.register({
|
|
1937
|
+
kind: "exact",
|
|
1938
|
+
path: CODEARTS_DEBUG_PATH,
|
|
1939
|
+
handler: debugHandler(deps)
|
|
1940
|
+
});
|
|
1784
1941
|
return () => {
|
|
1785
1942
|
disposeStatus();
|
|
1786
1943
|
disposeModels();
|
|
@@ -1792,6 +1949,7 @@ function registerCodeArtsStatusRoute(ctx, deps) {
|
|
|
1792
1949
|
disposeClaim();
|
|
1793
1950
|
disposeRefresh();
|
|
1794
1951
|
disposeQueue();
|
|
1952
|
+
disposeDebug();
|
|
1795
1953
|
for (const s of activeLogins.values()) s.close();
|
|
1796
1954
|
activeLogins.clear();
|
|
1797
1955
|
};
|
|
@@ -1831,6 +1989,8 @@ function loginStartHandler(deps, active, recent) {
|
|
|
1831
1989
|
const identity = await probeIdentity(token);
|
|
1832
1990
|
const id = await deps.store.upsertFromOAuth(token, void 0, identity ?? void 0);
|
|
1833
1991
|
if (identity !== null && id !== identity.userId) await deps.store.adoptIdentity(id, identity);
|
|
1992
|
+
deps.reviveAccount?.(id);
|
|
1993
|
+
if (identity !== null && identity.userId !== id) deps.reviveAccount?.(identity.userId);
|
|
1834
1994
|
recordLoginOutcome(recent, session.url, "done");
|
|
1835
1995
|
} catch {
|
|
1836
1996
|
recordLoginOutcome(recent, session.url, "error");
|
|
@@ -2033,8 +2193,10 @@ function apply(ctx, rawConfig) {
|
|
|
2033
2193
|
enabledModels,
|
|
2034
2194
|
setEnabledModels,
|
|
2035
2195
|
pool: () => pool.list(),
|
|
2196
|
+
reviveAccount: (id) => pool.revive(id),
|
|
2036
2197
|
usage: () => usage.snapshot(),
|
|
2037
2198
|
queue: () => queue.snapshot(),
|
|
2199
|
+
recentRequests: () => recentRequestShapes(),
|
|
2038
2200
|
credits: (signal) => loadCredits(signal),
|
|
2039
2201
|
claim: async (accountId) => {
|
|
2040
2202
|
const ids = accountId === void 0 ? await store.ids() : [accountId];
|
|
@@ -2148,9 +2310,11 @@ function apply(ctx, rawConfig) {
|
|
|
2148
2310
|
logger: ctx.logger
|
|
2149
2311
|
});
|
|
2150
2312
|
usage.load().catch(() => {});
|
|
2151
|
-
shim.ready.then(() => {
|
|
2313
|
+
shim.ready.then(async () => {
|
|
2152
2314
|
if (stopped) return;
|
|
2153
2315
|
discover();
|
|
2316
|
+
const incompatible = await probePiAiCompat();
|
|
2317
|
+
if (incompatible !== void 0) ctx.logger.error(`dsh-codearts: ${incompatible}`);
|
|
2154
2318
|
const codearts = createCodeArtsAdapter({
|
|
2155
2319
|
shim,
|
|
2156
2320
|
catalog,
|
|
@@ -1246,6 +1246,7 @@ var upstream_exports = /* @__PURE__ */ __exportAll({
|
|
|
1246
1246
|
isConcurrencyCap: () => isConcurrencyCap,
|
|
1247
1247
|
isParamInvalidFrame: () => isParamInvalidFrame,
|
|
1248
1248
|
isQueueableRate: () => isQueueableRate,
|
|
1249
|
+
isResignRefusal: () => isResignRefusal,
|
|
1249
1250
|
isTpmLimit: () => isTpmLimit,
|
|
1250
1251
|
isWelfareClaimedStatus: () => isWelfareClaimedStatus,
|
|
1251
1252
|
maxTokensCeilingFor: () => maxTokensCeilingFor,
|
|
@@ -1476,6 +1477,10 @@ function prepareChatBody(rawJson, contextWindow = 0) {
|
|
|
1476
1477
|
"stream_options",
|
|
1477
1478
|
"reasoning_effort"
|
|
1478
1479
|
]) if (parsed[key] !== void 0) body[key] = parsed[key];
|
|
1480
|
+
if (Array.isArray(body.messages)) body.messages = body.messages.map((message) => message?.role === "developer" ? {
|
|
1481
|
+
...message,
|
|
1482
|
+
role: "system"
|
|
1483
|
+
} : message);
|
|
1479
1484
|
if (body.stream_options === void 0 || typeof body.stream_options !== "object") body.stream_options = { include_usage: true };
|
|
1480
1485
|
else body.stream_options.include_usage = true;
|
|
1481
1486
|
if (body.max_tokens === void 0 && typeof parsed.max_completion_tokens === "number") body.max_tokens = parsed.max_completion_tokens;
|
|
@@ -1592,6 +1597,7 @@ function rateLimitFrame(text) {
|
|
|
1592
1597
|
* 让人以为是自己配错了。默认分支仍保留原始信息,便于排查。
|
|
1593
1598
|
*/
|
|
1594
1599
|
function upstreamErrorMessage(message, status = 0) {
|
|
1600
|
+
if (isResignRefusal(message)) return "本地代理 billion-context 拦下了这条签名请求(它拿不到 CodeArts 凭据做重签,在本地直接拒了),不是你的账号问题:请在 ~/.config/billion-context/billion-context.json 加上 \"resign\": { \"sdk-hmac-sha256\": { \"passthrough\": true } } 后重启 DSH,或为它配置重签凭据。";
|
|
1595
1601
|
if (MODEL_RATE_CODE.test(message) || MODEL_RATE_TEXT.test(message)) return "华为侧该模型当前请求过多(共享 TPM 超限),不是你的账号或插件问题。稍后重试,或临时改用 GLM-5.2 / GLM-5.3。";
|
|
1596
1602
|
if (message.includes("TM.00001041")) return "CodeArts 免费档同时只允许 3 个会话,当前槽位一直占满(被打断的会话约 1 分钟才释放)。请稍后重试。";
|
|
1597
1603
|
if (isBenefitMissing("", message)) return "这个模型属于限时福利,当前福利通道不可用(不是账号问题)。可以刷新模型列表,改用非福利模型。";
|
|
@@ -1610,8 +1616,18 @@ const BENEFIT_MISSING_CODE = "InferHub.4004.200";
|
|
|
1610
1616
|
function isBenefitMissing(code, message) {
|
|
1611
1617
|
return code === "InferHub.4004.200" || message.toLowerCase().includes("benefit not found");
|
|
1612
1618
|
}
|
|
1619
|
+
/**
|
|
1620
|
+
* 本地代理「拒签」标记:billion-context 这类宿主层代理拦截出站请求做上下文压缩,
|
|
1621
|
+
* 碰到 SDK-HMAC-SHA256 签名请求要用 CodeArts 凭据重签;找不到凭据时在**本地**回
|
|
1622
|
+
* 403(根本没出网),body 里带这两个标记。这不是凭据失效 —— 归 session_dead 会把
|
|
1623
|
+
* 账号永久禁用(见 issue #1)。
|
|
1624
|
+
*/
|
|
1625
|
+
function isResignRefusal(message) {
|
|
1626
|
+
return message.includes("signed_request_requires_resign") || message.includes("bili_resign_unavailable");
|
|
1627
|
+
}
|
|
1613
1628
|
function classify(status, message) {
|
|
1614
1629
|
const m = message.toLowerCase();
|
|
1630
|
+
if (isResignRefusal(message)) return "client";
|
|
1615
1631
|
if (status === 401 || status === 403) return "session_dead";
|
|
1616
1632
|
if (status === 402) return "hard_credit";
|
|
1617
1633
|
if (status === 429) return "soft_rate";
|
|
@@ -1621,6 +1637,34 @@ function classify(status, message) {
|
|
|
1621
1637
|
if (m.includes("tpm") || m.includes("并发")) return "soft_rate";
|
|
1622
1638
|
return "client";
|
|
1623
1639
|
}
|
|
1640
|
+
/**
|
|
1641
|
+
* 出网唯一入口:**只把 URL 字符串和普通 init 交给 fetch,绝不把 Request 对象交出去**。
|
|
1642
|
+
*
|
|
1643
|
+
* 邻居插件会换掉 `globalThis.fetch`(例如 IP 池出口路由直接把 undici 模块自带的
|
|
1644
|
+
* fetch 装成全局)。这时 `globalThis.Request` 还是另一份实例,而 undici 的 fetch
|
|
1645
|
+
* 用 `instanceof` 认自己的 Request:不是自己那份就当 URL 字符串处理,报
|
|
1646
|
+
* `Failed to parse URL from [object Request]`,而且是 HTTP 0(根本没出网)。
|
|
1647
|
+
* 所以 Request 只当签名的载体(signer 要读写它的头部),发出去时拆回纯数据。
|
|
1648
|
+
*
|
|
1649
|
+
* 头部按 forEach 展开会全部变成小写名 —— 签名侧本来也按小写规范化,HTTP 头大小写
|
|
1650
|
+
* 不敏感,上游不受影响。
|
|
1651
|
+
*
|
|
1652
|
+
* @param req 已签好名的请求
|
|
1653
|
+
* @param body 原始请求体;GET/DELETE 传 undefined(带空 body 的 GET 会被 fetch 直接拒)
|
|
1654
|
+
* @param signal 中止信号
|
|
1655
|
+
*/
|
|
1656
|
+
async function dispatch(req, body, signal) {
|
|
1657
|
+
const headers = {};
|
|
1658
|
+
req.headers.forEach((value, key) => {
|
|
1659
|
+
headers[key] = value;
|
|
1660
|
+
});
|
|
1661
|
+
return fetch(req.url, {
|
|
1662
|
+
method: req.method,
|
|
1663
|
+
headers,
|
|
1664
|
+
...body === void 0 ? {} : { body },
|
|
1665
|
+
...signal === void 0 ? {} : { signal }
|
|
1666
|
+
});
|
|
1667
|
+
}
|
|
1624
1668
|
const enc = new TextEncoder();
|
|
1625
1669
|
function openAIData(obj) {
|
|
1626
1670
|
return enc.encode(`data: ${JSON.stringify(obj)}\n\n`);
|
|
@@ -1668,7 +1712,7 @@ async function chatStream(credential, prepared, signal) {
|
|
|
1668
1712
|
}
|
|
1669
1713
|
let resp;
|
|
1670
1714
|
try {
|
|
1671
|
-
resp = await
|
|
1715
|
+
resp = await dispatch(req, bodyBuf, signal);
|
|
1672
1716
|
} catch (err) {
|
|
1673
1717
|
const message = err instanceof Error ? err.message : String(err);
|
|
1674
1718
|
if (signal?.aborted === true) return {
|
|
@@ -1851,7 +1895,7 @@ async function signedGet(url, credential, agentType, signal) {
|
|
|
1851
1895
|
});
|
|
1852
1896
|
let resp;
|
|
1853
1897
|
try {
|
|
1854
|
-
resp = await
|
|
1898
|
+
resp = await dispatch(req, void 0, signal);
|
|
1855
1899
|
} catch (error) {
|
|
1856
1900
|
return {
|
|
1857
1901
|
ok: false,
|
|
@@ -2040,7 +2084,7 @@ async function fetchThinkingVariants(credential, modelIds, signal) {
|
|
|
2040
2084
|
secretAccessKey: credential.secretAccessKey,
|
|
2041
2085
|
securityToken: credential.securityToken
|
|
2042
2086
|
});
|
|
2043
|
-
const resp = await
|
|
2087
|
+
const resp = await dispatch(req, bodyBuf, signal);
|
|
2044
2088
|
if (!resp.ok) {
|
|
2045
2089
|
const text = await resp.text().catch(() => "");
|
|
2046
2090
|
throw new Error(`thinking-variants HTTP ${resp.status} ${text.slice(0, 200)}`);
|
|
@@ -2086,7 +2130,7 @@ async function fetchQueueStatus(credential, chatId, model, signal) {
|
|
|
2086
2130
|
secretAccessKey: credential.secretAccessKey,
|
|
2087
2131
|
securityToken: credential.securityToken
|
|
2088
2132
|
});
|
|
2089
|
-
const resp = await
|
|
2133
|
+
const resp = await dispatch(req, void 0, signal);
|
|
2090
2134
|
if (!resp.ok) {
|
|
2091
2135
|
const text = await resp.text().catch(() => "");
|
|
2092
2136
|
throw new Error(`queue status HTTP ${resp.status} ${text.slice(0, 200)}`);
|
|
@@ -2124,7 +2168,7 @@ async function clearQueueStatus(credential, chatId, model, signal) {
|
|
|
2124
2168
|
secretAccessKey: credential.secretAccessKey,
|
|
2125
2169
|
securityToken: credential.securityToken
|
|
2126
2170
|
});
|
|
2127
|
-
const resp = await
|
|
2171
|
+
const resp = await dispatch(req, void 0, signal);
|
|
2128
2172
|
if (!resp.ok) {
|
|
2129
2173
|
const text = await resp.text().catch(() => "");
|
|
2130
2174
|
throw new Error(`queue clear HTTP ${resp.status} ${text.slice(0, 200)}`);
|
|
@@ -2234,7 +2278,7 @@ async function claimBenefit(credential, abort) {
|
|
|
2234
2278
|
secretAccessKey: credential.secretAccessKey,
|
|
2235
2279
|
securityToken: credential.securityToken
|
|
2236
2280
|
});
|
|
2237
|
-
const resp = await
|
|
2281
|
+
const resp = await dispatch(req, bodyBuf, abort);
|
|
2238
2282
|
const raw = await resp.text().catch(() => "");
|
|
2239
2283
|
if (!resp.ok) throw new Error(`claim benefit failed: ${resp.status} ${raw.slice(0, 200)}`);
|
|
2240
2284
|
let json;
|
|
@@ -2306,7 +2350,7 @@ async function welfareRequest(url, method, credential, body, signal) {
|
|
|
2306
2350
|
});
|
|
2307
2351
|
let resp;
|
|
2308
2352
|
try {
|
|
2309
|
-
resp = await
|
|
2353
|
+
resp = await dispatch(req, body === void 0 ? void 0 : bodyBuf, signal);
|
|
2310
2354
|
} catch (error) {
|
|
2311
2355
|
return {
|
|
2312
2356
|
ok: false,
|
|
@@ -2736,4 +2780,4 @@ function sumOf(store) {
|
|
|
2736
2780
|
return out;
|
|
2737
2781
|
}
|
|
2738
2782
|
//#endregion
|
|
2739
|
-
export { filterEnabledModels as A, rateLimitFrame as C, FALLBACK_CODEARTS_MODELS as D, CodeArtsCatalog as E,
|
|
2783
|
+
export { filterEnabledModels as A, rateLimitFrame as C, FALLBACK_CODEARTS_MODELS as D, CodeArtsCatalog as E, MANUAL_ACCOUNT_ID as F, codeartsAccountsPath as I, codeartsAuthPath as L, isBenefitModel as M, CodeArtsAccountStore as N, clearBenefitBlocked as O, CodeArtsCredentialStore as P, startLogin as R, prepareChatBody as S, upstreamErrorMessage as T, isQueueableRate as _, SNAP_HOST as a, maxTokensCeilingFor as b, claimDailyWelfare as c, fetchCallerIdentity as d, fetchModels as f, isParamInvalidFrame as g, isConcurrencyCap as h, refreshCatalog as i, isBenefitBlocked as j, creditRatioLabel as k, clearQueueStatus as l, fetchWelfareCampaigns as m, codeartsUsagePath as n, canonicalModel as o, fetchQueueStatus as p, discoverModels as r, chatStream as s, CodeArtsUsageTracker as t, degradeTokenCeiling as u, isTpmLimit as v, signedGet as w, pickDailyWelfareCampaign as x, isWelfareClaimedStatus as y };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "dsh-codearts",
|
|
3
3
|
"displayName": "DSH CodeArts Connect",
|
|
4
4
|
"description": "把华为云 CodeArts 接入 DeepSeek Harness —— 内置 OAuth2 登录(PKCE + DPoP),登录后即可在 DSH 对话窗口使用 CodeArts 的模型。",
|
|
5
|
-
"version": "1.1.
|
|
5
|
+
"version": "1.1.3",
|
|
6
6
|
"packageManager": "pnpm@11.24.0",
|
|
7
7
|
"author": "elegant01",
|
|
8
8
|
"keywords": [
|
|
@@ -82,6 +82,9 @@
|
|
|
82
82
|
"platform": "web"
|
|
83
83
|
}
|
|
84
84
|
},
|
|
85
|
+
"dependencies": {
|
|
86
|
+
"@earendil-works/pi-ai": "^1.3.0"
|
|
87
|
+
},
|
|
85
88
|
"peerDependencies": {
|
|
86
89
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
87
90
|
"@deepseek-ai/dsh-atomic-write": ">=0.1.2-rc.1 <0.3.0-0",
|
|
@@ -92,7 +95,6 @@
|
|
|
92
95
|
"@deepseek-ai/dsh-llm-pi-ai": ">=0.1.2-rc.1 <0.3.0-0",
|
|
93
96
|
"@deepseek-ai/dsh-settings": ">=0.1.2-rc.1 <0.3.0-0",
|
|
94
97
|
"@deepseek-ai/schemastery": "^3.18.2",
|
|
95
|
-
"@earendil-works/pi-ai": ">=0.84.2 <2.0.0",
|
|
96
98
|
"react": "^18.2.0"
|
|
97
99
|
},
|
|
98
100
|
"devDependencies": {
|