dsh-codearts 1.1.0 → 1.1.1

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 CHANGED
@@ -3,6 +3,19 @@
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.1] - 2026-10-22
7
+
8
+ ### 修复
9
+
10
+ - **带思考档位的模型(GLM-5.2 / GLM-5.2-ArkTS-SPARK)每轮必失败,报
11
+ `Message role cannot empty`**:1.1.0 给这些模型声明了 `reasoning`,宿主 pi-ai 于是
12
+ 把系统提示从 `role:"system"` 换成 OpenAI 的新叫法 `role:"developer"` 发出来,
13
+ 华为网关只认 system/user/assistant/tool,认不出来就回这一句黑话。出口处统一把
14
+ `developer` 归一回 `system`,与档位无关(Default/High/Max 之前都必现)。
15
+ - 新增 `GET /api/codearts/debug`:回最近 8 次出站请求的**形状**摘要(消息条数、
16
+ 每条的 role 名、工具数),只含 role 名不含任何内容。上游的参数错误全是同一句
17
+ 黑话,没有这个就分不清是宿主发的还是插件拼的。
18
+
6
19
  ## [1.1.0] - 2026-10-21
7
20
 
8
21
  ### 新增
package/lib/bin.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { F as codeartsAccountsPath, M as isBenefitModel, N as CodeArtsAccountStore, d as fetchCallerIdentity, n as codeartsUsagePath, r as discoverModels, t as CodeArtsUsageTracker } from "./usage-Cie0IlC4.mjs";
2
+ import { F as codeartsAccountsPath, M as isBenefitModel, N as CodeArtsAccountStore, d as fetchCallerIdentity, n as codeartsUsagePath, r as discoverModels, t as CodeArtsUsageTracker } from "./usage-zgF0QuQ4.mjs";
3
3
  import { existsSync, statSync } from "node:fs";
4
4
  //#region src/version.ts
5
- const CODEARTS_VERSION = "1.1.0";
5
+ const CODEARTS_VERSION = "1.1.1";
6
6
  //#endregion
7
7
  //#region src/bin.ts
8
8
  /**
@@ -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
- "accountRowActions": "xoziZG_accountRowActions",
37
- "accountHint": "xoziZG_accountHint",
38
- "choiceRow": "xoziZG_choiceRow",
39
- "manualSummary": "xoziZG_manualSummary",
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",
36
+ "accountRow": "xoziZG_accountRow",
37
+ "modelTrack": "xoziZG_modelTrack",
38
+ "accountNameRow": "xoziZG_accountNameRow",
39
+ "choices": "xoziZG_choices",
40
+ "modelFill": "xoziZG_modelFill",
41
+ "claimAllRow": "xoziZG_claimAllRow",
49
42
  "manual": "xoziZG_manual",
50
- "error": "xoziZG_error",
43
+ "creditBlock": "xoziZG_creditBlock",
44
+ "header": "xoziZG_header",
51
45
  "meta": "xoziZG_meta",
46
+ "balanceMeta": "xoziZG_balanceMeta",
52
47
  "accountEntry": "xoziZG_accountEntry",
53
- "area": "xoziZG_area",
48
+ "barFill": "xoziZG_barFill",
49
+ "hint": "xoziZG_hint",
50
+ "modelTokens": "xoziZG_modelTokens",
51
+ "fieldLabel": "xoziZG_fieldLabel",
52
+ "desc": "xoziZG_desc",
53
+ "section": "xoziZG_section",
54
+ "check": "xoziZG_check",
55
+ "avatar": "xoziZG_avatar",
56
+ "creditRows": "xoziZG_creditRows",
57
+ "creditLink": "xoziZG_creditLink",
54
58
  "tabPanel": "xoziZG_tabPanel",
59
+ "accountCard": "xoziZG_accountCard",
60
+ "statusLine": "xoziZG_statusLine",
61
+ "modelRow": "xoziZG_modelRow",
62
+ "modelShare": "xoziZG_modelShare",
63
+ "sectionHead": "xoziZG_sectionHead",
64
+ "updated": "xoziZG_updated",
65
+ "bar": "xoziZG_bar",
55
66
  "card": "xoziZG_card",
56
67
  "field": "xoziZG_field",
57
- "check": "xoziZG_check",
58
- "usageFill": "xoziZG_usageFill",
59
- "creditHint": "xoziZG_creditHint",
60
- "modelShare": "xoziZG_modelShare",
61
- "barFill": "xoziZG_barFill",
62
- "body": "xoziZG_body",
63
- "headText": "xoziZG_headText",
64
- "creditLink": "xoziZG_creditLink",
65
- "desc": "xoziZG_desc",
68
+ "accountName": "xoziZG_accountName",
66
69
  "balanceRow": "xoziZG_balanceRow",
67
- "choices": "xoziZG_choices",
68
- "sectionHead": "xoziZG_sectionHead",
69
- "manualForm": "xoziZG_manualForm",
70
- "avatar": "xoziZG_avatar",
70
+ "expiryRow": "xoziZG_expiryRow",
71
+ "actions": "xoziZG_actions",
72
+ "balance": "xoziZG_balance",
73
+ "modelName": "xoziZG_modelName",
74
+ "modelRequests": "xoziZG_modelRequests",
75
+ "modelChart": "xoziZG_modelChart",
76
+ "headText": "xoziZG_headText",
77
+ "accountRowActions": "xoziZG_accountRowActions",
78
+ "usageBar": "xoziZG_usageBar",
79
+ "creditHint": "xoziZG_creditHint",
80
+ "count": "xoziZG_count",
81
+ "area": "xoziZG_area",
82
+ "accountHint": "xoziZG_accountHint",
71
83
  "expiryLabel": "xoziZG_expiryLabel",
72
- "updated": "xoziZG_updated",
73
- "balanceUnit": "xoziZG_balanceUnit",
74
84
  "accountInfo": "xoziZG_accountInfo",
85
+ "error": "xoziZG_error",
86
+ "accountToolbar": "xoziZG_accountToolbar",
87
+ "manualForm": "xoziZG_manualForm",
88
+ "body": "xoziZG_body",
89
+ "creditFooter": "xoziZG_creditFooter",
90
+ "balanceUnit": "xoziZG_balanceUnit",
91
+ "name": "xoziZG_name",
92
+ "tabs": "xoziZG_tabs",
93
+ "usageFill": "xoziZG_usageFill",
94
+ "choiceRow": "xoziZG_choiceRow",
95
+ "creditRow": "xoziZG_creditRow",
96
+ "link": "xoziZG_link",
75
97
  "sectionLabel": "xoziZG_sectionLabel",
76
98
  "danger": "xoziZG_danger",
77
- "expiryRow": "xoziZG_expiryRow",
78
- "statusLine": "xoziZG_statusLine",
79
- "section": "xoziZG_section",
80
- "link": "xoziZG_link",
81
- "modelFill": "xoziZG_modelFill",
82
- "accountName": "xoziZG_accountName",
83
- "modelRow": "xoziZG_modelRow",
84
- "modelTrack": "xoziZG_modelTrack",
85
- "hint": "xoziZG_hint",
86
- "balanceMeta": "xoziZG_balanceMeta",
87
- "count": "xoziZG_count",
88
- "modelChart": "xoziZG_modelChart",
89
- "accountRow": "xoziZG_accountRow",
90
- "creditRows": "xoziZG_creditRows",
91
- "header": "xoziZG_header",
92
- "claimAllRow": "xoziZG_claimAllRow",
93
- "creditBlock": "xoziZG_creditBlock",
94
- "modelTokens": "xoziZG_modelTokens",
95
- "balance": "xoziZG_balance",
96
- "accountNameRow": "xoziZG_accountNameRow",
97
- "bar": "xoziZG_bar",
98
- "creditFooter": "xoziZG_creditFooter",
99
- "fieldLabel": "xoziZG_fieldLabel"
99
+ "manualSummary": "xoziZG_manualSummary"
100
100
  };
101
101
  //#endregion
102
102
  //#region src/client/CodeArtsPluginCard.tsx
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 codeartsAccountsPath, I as codeartsAuthPath, L as startLogin, M as isBenefitModel, N as CodeArtsAccountStore, O as clearBenefitBlocked, P as CodeArtsCredentialStore, 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-Cie0IlC4.mjs";
1
+ import { A as filterEnabledModels, C as rateLimitFrame, D as FALLBACK_CODEARTS_MODELS, E as CodeArtsCatalog, F as codeartsAccountsPath, I as codeartsAuthPath, L as startLogin, M as isBenefitModel, N as CodeArtsAccountStore, O as clearBenefitBlocked, P as CodeArtsCredentialStore, 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-zgF0QuQ4.mjs";
2
2
  import z from "@deepseek-ai/schemastery";
3
3
  import { randomBytes, timingSafeEqual } from "node:crypto";
4
4
  import { createServer } from "node:http";
@@ -835,7 +835,6 @@ function readBody$1(req) {
835
835
  }
836
836
  /** 一次请求最多试几个账号(与 Go 参考的 MaxRotate 一致)。 */
837
837
  const MAX_ROTATE = 3;
838
- /** 一次请求最多把 max_tokens 降几档(65536 → 32768 → 16384 → 8192)。 */
839
838
  const MAX_CEILING_HEALS = 3;
840
839
  /**
841
840
  * 所有账号都撞上并发上限时,回落到「在同一账号上原地重发」的预算。
@@ -855,6 +854,35 @@ const SERVER_COOLDOWN_MS = 3e4;
855
854
  /** 零散错误累计到阈值后冷却该账号。 */
856
855
  const ERROR_COOLDOWN_MS = 6e4;
857
856
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
857
+ const recentShapes = [];
858
+ /** 最近的请求形状,最新在前。 */
859
+ function recentRequestShapes() {
860
+ return [...recentShapes].reverse();
861
+ }
862
+ function noteRequestShape(raw, model) {
863
+ let parsed;
864
+ try {
865
+ parsed = JSON.parse(raw);
866
+ } catch {
867
+ return;
868
+ }
869
+ if (parsed === null || typeof parsed !== "object") return;
870
+ const list = Array.isArray(parsed.messages) ? parsed.messages : [];
871
+ const roles = list.map((message) => {
872
+ if (message === null || typeof message !== "object") return "";
873
+ const role = message.role;
874
+ return typeof role === "string" ? role : "";
875
+ });
876
+ recentShapes.push({
877
+ at: Date.now(),
878
+ model,
879
+ messages: list.length,
880
+ roles,
881
+ emptyRoleAt: roles.map((role, index) => role === "" ? index : -1).filter((index) => index >= 0),
882
+ tools: Array.isArray(parsed.tools) ? parsed.tools.length : 0
883
+ });
884
+ if (recentShapes.length > 8) recentShapes.shift();
885
+ }
858
886
  function createCodeArtsShim(options) {
859
887
  const { store, catalog } = options;
860
888
  const logger = options.logger;
@@ -1050,6 +1078,7 @@ function createCodeArtsShim(options) {
1050
1078
  if (typeof inbound.model === "string") contextWindow = contextWindowFor(canonicalModel(inbound.model));
1051
1079
  } catch {}
1052
1080
  const checked = prepareChatBody(raw, contextWindow);
1081
+ noteRequestShape(raw, checked.model);
1053
1082
  if (checked.error !== void 0) {
1054
1083
  writeOpenAIError(res, 400, "context_overflow", checked.error);
1055
1084
  return;
@@ -1272,6 +1301,8 @@ const CODEARTS_CLAIM_PATH = "/api/codearts/claim";
1272
1301
  const CODEARTS_REFRESH_MODELS_PATH = "/api/codearts/refresh-models";
1273
1302
  /** GET /api/codearts/queue — 上游排队位置(只在等开流期间有值,底部积分条旁边展示)。 */
1274
1303
  const CODEARTS_QUEUE_PATH = "/api/codearts/queue";
1304
+ /** 最近出站请求的**形状**摘要(只有 role 名与计数,不含内容),排障用。 */
1305
+ const CODEARTS_DEBUG_PATH = "/api/codearts/debug";
1275
1306
  /**
1276
1307
  * 由完整目录 + 已存 enabled 计算 selection。
1277
1308
  * - enabled 为空/未存 => 全部勾选(restricted=false)
@@ -1725,6 +1756,20 @@ function queueHandler(deps) {
1725
1756
  json(res, 200, { queue: deps.queue?.() ?? [] });
1726
1757
  };
1727
1758
  }
1759
+ /** GET /api/codearts/debug — 最近出站请求的形状摘要(只有 role 名与计数)。 */
1760
+ function debugHandler(deps) {
1761
+ return async (req, res) => {
1762
+ if (req.method !== "GET") {
1763
+ json(res, 405, { error: "method not allowed" });
1764
+ return;
1765
+ }
1766
+ if (!loopbackRequest(req)) {
1767
+ json(res, 403, { error: "request-not-trusted" });
1768
+ return;
1769
+ }
1770
+ json(res, 200, { requests: deps.recentRequests?.() ?? [] });
1771
+ };
1772
+ }
1728
1773
  /** Mount the status / models / token routes. */
1729
1774
  function registerCodeArtsStatusRoute(ctx, deps) {
1730
1775
  ctx.effect(() => {
@@ -1781,6 +1826,11 @@ function registerCodeArtsStatusRoute(ctx, deps) {
1781
1826
  path: CODEARTS_QUEUE_PATH,
1782
1827
  handler: queueHandler(deps)
1783
1828
  });
1829
+ const disposeDebug = ctx.webServer.register({
1830
+ kind: "exact",
1831
+ path: CODEARTS_DEBUG_PATH,
1832
+ handler: debugHandler(deps)
1833
+ });
1784
1834
  return () => {
1785
1835
  disposeStatus();
1786
1836
  disposeModels();
@@ -1792,6 +1842,7 @@ function registerCodeArtsStatusRoute(ctx, deps) {
1792
1842
  disposeClaim();
1793
1843
  disposeRefresh();
1794
1844
  disposeQueue();
1845
+ disposeDebug();
1795
1846
  for (const s of activeLogins.values()) s.close();
1796
1847
  activeLogins.clear();
1797
1848
  };
@@ -2035,6 +2086,7 @@ function apply(ctx, rawConfig) {
2035
2086
  pool: () => pool.list(),
2036
2087
  usage: () => usage.snapshot(),
2037
2088
  queue: () => queue.snapshot(),
2089
+ recentRequests: () => recentRequestShapes(),
2038
2090
  credits: (signal) => loadCredits(signal),
2039
2091
  claim: async (accountId) => {
2040
2092
  const ids = accountId === void 0 ? await store.ids() : [accountId];
@@ -1476,6 +1476,10 @@ function prepareChatBody(rawJson, contextWindow = 0) {
1476
1476
  "stream_options",
1477
1477
  "reasoning_effort"
1478
1478
  ]) if (parsed[key] !== void 0) body[key] = parsed[key];
1479
+ if (Array.isArray(body.messages)) body.messages = body.messages.map((message) => message?.role === "developer" ? {
1480
+ ...message,
1481
+ role: "system"
1482
+ } : message);
1479
1483
  if (body.stream_options === void 0 || typeof body.stream_options !== "object") body.stream_options = { include_usage: true };
1480
1484
  else body.stream_options.include_usage = true;
1481
1485
  if (body.max_tokens === void 0 && typeof parsed.max_completion_tokens === "number") body.max_tokens = parsed.max_completion_tokens;
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.0",
5
+ "version": "1.1.1",
6
6
  "packageManager": "pnpm@11.24.0",
7
7
  "author": "elegant01",
8
8
  "keywords": [