dsh-multigameassistant 2.0.0 → 2.0.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/README.md CHANGED
@@ -4,10 +4,14 @@
4
4
 
5
5
  ## 安装
6
6
 
7
- 插件包在 [Releases](https://github.com/haaahhhis/MultiGameAssistant/releases) 里(`dsh-multigameassistant-<版本>.tgz`),复制它的链接:
7
+ - **dsh 桌面版**:「Plugins」→「Add plugin」,填 `dsh-multigameassistant` →「Install」→「Enable now」。
8
+ - **命令行的 dsh**:`dsh plugin add dsh-multigameassistant`,再 `dsh web`。
8
9
 
9
- - **dsh 桌面版**:「Plugins」→「Add plugin」,填插件包的链接 →「Install」→「Enable now」。
10
- - **命令行的 dsh**:`dsh plugin add <插件包的链接>`,再 `dsh web`。
10
+ npm 慢或连不上时,用 GitHub 上最新版的插件包链接代替名字:
11
+
12
+ ```text
13
+ https://github.com/haaahhhis/MultiGameAssistant/releases/latest/download/dsh-multigameassistant.tgz
14
+ ```
11
15
 
12
16
  侧边栏会多出「多游戏助手」,点开就是它的界面。它和你平时的 dsh 对话互不影响:它的对话用自己的 agent 预设「多游戏助手」,工具、提示词、技能和权限设置只在这些对话里。
13
17
 
package/cordis.patch.yml CHANGED
@@ -1,6 +1,8 @@
1
- # dsh-multigameassistant 2.0.0: the app's plugins (packages/bundle/cordis.patch.yml, each @adg/<plugin> as dsh-multigameassistant/<plugin>)
1
+ # dsh-multigameassistant 2.0.1
2
+ # dsh-multigameassistant: the app's plugins (packages/bundle/cordis.patch.yml, each @adg/<plugin> as dsh-multigameassistant/<plugin>)
2
3
  # sharing the dsh with the person's other chats, and the app's agent preset (dsh's standard one with the app's
3
4
  # tools and prompts, and compaction as 设置 → 对话压缩 says). No row of dsh is restated.
5
+ # Made by scripts/package-plugin.mjs (--sync) from packages/bundle/cordis.patch.yml: change that one.
4
6
  - insert:
5
7
  - id: adg-gateway
6
8
  name: 'dsh-multigameassistant/gateway'
package/lib/analyzer.js CHANGED
@@ -1,18 +1,18 @@
1
1
  import { createRequire as __adgCreateRequire } from 'node:module'; import { dirname as __adgDirname } from 'node:path'; import { fileURLToPath as __adgFileURLToPath } from 'node:url'; const require = __adgCreateRequire(import.meta.url); const __filename = __adgFileURLToPath(import.meta.url); const __dirname = __adgDirname(__filename);
2
2
  import {
3
3
  probeProject
4
- } from "./chunk-KIAOFNCB.js";
4
+ } from "./chunk-YG4B5G7F.js";
5
5
  import {
6
6
  MANIFEST_FILE,
7
7
  SKILL_FILE,
8
8
  parseManifest,
9
9
  require_dist
10
- } from "./chunk-7XMNAHZ2.js";
10
+ } from "./chunk-J46OASOG.js";
11
11
  import {
12
12
  PACKS_CAPABILITY,
13
13
  ScriptId,
14
14
  external_exports
15
- } from "./chunk-BL6OSR2I.js";
15
+ } from "./chunk-HPQCV6WO.js";
16
16
  import {
17
17
  __toESM
18
18
  } from "./chunk-2UFLGPDY.js";
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __adgCreateRequire } from 'node:module'; import { dirname as __adgDirname } from 'node:path'; import { fileURLToPath as __adgFileURLToPath } from 'node:url'; const require = __adgCreateRequire(import.meta.url); const __filename = __adgFileURLToPath(import.meta.url); const __dirname = __adgDirname(__filename);
2
2
  import {
3
3
  convertRecord
4
- } from "./chunk-2DZ75ANX.js";
4
+ } from "./chunk-ZQ6KFVEO.js";
5
5
  import {
6
6
  writeFileAtomic
7
7
  } from "./chunk-CCAB6XXZ.js";
@@ -17,7 +17,7 @@ import {
17
17
  reminderPrompts,
18
18
  summarizeToolArgs,
19
19
  taskMessage
20
- } from "./chunk-BL6OSR2I.js";
20
+ } from "./chunk-HPQCV6WO.js";
21
21
 
22
22
  // packages/notify/lib/index.js
23
23
  import { readFile } from "node:fs/promises";
@@ -3,12 +3,12 @@ import {
3
3
  globToRegExp,
4
4
  renderTask,
5
5
  require_dist
6
- } from "./chunk-7XMNAHZ2.js";
6
+ } from "./chunk-J46OASOG.js";
7
7
  import {
8
8
  RUNS_CAPABILITY,
9
9
  ScriptId,
10
10
  external_exports
11
- } from "./chunk-BL6OSR2I.js";
11
+ } from "./chunk-HPQCV6WO.js";
12
12
  import {
13
13
  __toESM
14
14
  } from "./chunk-2UFLGPDY.js";
@@ -14755,7 +14755,7 @@ var SetupAgent = external_exports.object({ sessionId: external_exports.string(),
14755
14755
  var PendingSetupInfo = external_exports.object({
14756
14756
  scriptId: external_exports.string(),
14757
14757
  name: external_exports.string(),
14758
- kind: external_exports.enum(["nsis", "inno"]),
14758
+ kind: external_exports.enum(["nsis", "inno", "kachina"]),
14759
14759
  version: external_exports.string(),
14760
14760
  /** Where it installs (prefilled in its window): a new version folder, or a local import's own. */
14761
14761
  dir: external_exports.string(),
@@ -14775,7 +14775,7 @@ var ScriptJob = external_exports.object({
14775
14775
  version: external_exports.string().optional(),
14776
14776
  error: external_exports.string().optional(),
14777
14777
  /** The release was a setup program (not an archive), left for the agent to run into `dir`; in that conversation when the app started one. */
14778
- setup: external_exports.object({ kind: external_exports.enum(["nsis", "inno"]), dir: external_exports.string(), sessionId: external_exports.string().optional() }).optional(),
14778
+ setup: external_exports.object({ kind: external_exports.enum(["nsis", "inno", "kachina"]), dir: external_exports.string(), sessionId: external_exports.string().optional() }).optional(),
14779
14779
  startedAt: external_exports.number(),
14780
14780
  endedAt: external_exports.number().optional()
14781
14781
  });
@@ -15843,6 +15843,12 @@ var Activity = external_exports.object({
15843
15843
  endsAt: external_exports.number().optional(),
15844
15844
  /** A screenshot was kept (`games/evidence`). */
15845
15845
  evidence: external_exports.boolean(),
15846
+ /**
15847
+ * The screenshot it was read from (`shot:…`, fetch it with `games/image`),
15848
+ * also the activity's `cover` when no source and not the user gives one.
15849
+ * Kept from an earlier reading when the last one saved none.
15850
+ */
15851
+ image: external_exports.string().optional(),
15846
15852
  sessionId: external_exports.string().optional()
15847
15853
  }).optional(),
15848
15854
  /** Still to do, as read from the game ("活动商店还剩 3 项没换"). */
@@ -15852,8 +15858,21 @@ var Activity = external_exports.object({
15852
15858
  /** The user said they are done with it (or took it back): their word beats the lists. */
15853
15859
  finished: external_exports.object({ at: external_exports.number() }).optional(),
15854
15860
  /** The game and the data site disagree on when it ends. */
15855
- mismatch: external_exports.string().optional()
15861
+ mismatch: external_exports.string().optional(),
15862
+ /**
15863
+ * What the user (or the agent for them) wrote themselves (`games/activity/save`):
15864
+ * those fields beat every source, and a refresh never changes or drops them.
15865
+ * An activity with no `sources` and no `screen` is one the user added.
15866
+ */
15867
+ own: external_exports.object({ at: external_exports.number(), fields: external_exports.array(external_exports.enum(["name", "startsAt", "endsAt", "kind", "description", "url", "cover"])) }).optional()
15868
+ });
15869
+ var MAX_ACTIVITY_IMAGE_BASE64 = 112e5;
15870
+ var ActivityImage = external_exports.object({
15871
+ mediaType: external_exports.enum(["image/png", "image/jpeg", "image/gif", "image/webp", "image/avif"]),
15872
+ data: external_exports.string().min(1).max(MAX_ACTIVITY_IMAGE_BASE64).regex(/^[A-Za-z0-9+/]+={0,2}$/, "base64 without a data: prefix")
15856
15873
  });
15874
+ var OWN_IMAGE = /^own:[0-9a-f]{32}\.(?:png|jpg|gif|webp|avif)$/;
15875
+ var SHOT_IMAGE = /^shot:[0-9a-f]{32}\.(?:png|jpg|gif|webp|avif)$/;
15857
15876
  var GameSourceInfo = external_exports.object({
15858
15877
  id: external_exports.string(),
15859
15878
  name: external_exports.string(),
@@ -15992,7 +16011,8 @@ var GamesRequests = {
15992
16011
  */
15993
16012
  "games/image": {
15994
16013
  capability: GAMES_CAPABILITY,
15995
- params: external_exports.object({ url: external_exports.string().url() }),
16014
+ /** A data site's https address, a picture the user added (`own:…`), or a kept screenshot (`shot:…`). */
16015
+ params: external_exports.object({ url: external_exports.string().refine((u) => OWN_IMAGE.test(u) || SHOT_IMAGE.test(u) || /^https?:\/\/\S+$/.test(u), "\u4E0D\u662F\u56FE\u7247\u5730\u5740") }),
15996
16016
  result: external_exports.object({ mediaType: external_exports.string(), data: external_exports.string() })
15997
16017
  },
15998
16018
  /** Ask the agent to find where a game's events can be read and add it (a game pack of the user's own). */
@@ -16046,6 +16066,38 @@ var GamesRequests = {
16046
16066
  }),
16047
16067
  result: Activity
16048
16068
  },
16069
+ /**
16070
+ * Add an event of the user's own, or write the user's word on one
16071
+ * (`activityId`): each field set beats what the sources say, `null` takes
16072
+ * the user's value back (the sources' shows again), absent leaves it. A
16073
+ * field equal to what the sources say is not kept. `image`: a new picture
16074
+ * (kept by the host, it becomes `cover`). A new one needs a `name`; one
16075
+ * with the same name already in the calendar is that one.
16076
+ */
16077
+ "games/activity/save": {
16078
+ capability: GAMES_CAPABILITY,
16079
+ params: external_exports.object({
16080
+ game: external_exports.string(),
16081
+ activityId: external_exports.string().optional(),
16082
+ name: external_exports.string().trim().min(1).max(60).nullable().optional(),
16083
+ startsAt: external_exports.number().nullable().optional(),
16084
+ endsAt: external_exports.number().nullable().optional(),
16085
+ kind: external_exports.string().trim().max(20).nullable().optional(),
16086
+ description: external_exports.string().trim().max(500).nullable().optional(),
16087
+ url: external_exports.string().trim().refine((u) => u === "" || /^https?:\/\/\S+$/.test(u), "\u53EA\u80FD\u662F http \u6216 https \u7F51\u5740").nullable().optional(),
16088
+ /** null: drop the user's picture (the sources' shows again). */
16089
+ cover: external_exports.null().optional(),
16090
+ image: ActivityImage.optional(),
16091
+ todo: external_exports.array(external_exports.string().min(1).max(80)).max(30).optional()
16092
+ }),
16093
+ result: Activity
16094
+ },
16095
+ /** Take back everything the user wrote on an event: the sources' word shows again; one only the user added goes. */
16096
+ "games/activity/reset": {
16097
+ capability: GAMES_CAPABILITY,
16098
+ params: external_exports.object({ activityId: external_exports.string() }),
16099
+ result: external_exports.object({ activity: Activity.optional() })
16100
+ },
16049
16101
  /** Forget an event (wrongly read, or no longer wanted). */
16050
16102
  "games/activity/remove": {
16051
16103
  capability: GAMES_CAPABILITY,
@@ -16069,7 +16121,7 @@ var AGENT_AREAS = [
16069
16121
  { id: "scripts-install", title: "\u5B89\u88C5\u3001\u66F4\u65B0\u3001\u5220\u9664\u811A\u672C", description: "\u4ECE GitHub \u5B89\u88C5\u3001\u66F4\u65B0\u3001\u56DE\u6EDA\u3001\u5220\u9664\u811A\u672C\uFF0C\u8FD0\u884C\u811A\u672C\u7684\u5B89\u88C5\u7A0B\u5E8F\uFF0C\u5BFC\u5165\u672C\u5730\u811A\u672C\uFF0C\u4FEE\u590D\u8FD0\u884C\u73AF\u5883\uFF0C\u8D77\u8349\u811A\u672C\u5305\u3002", tools: ["script_install", "script_update", "script_rollback", "script_remove", "script_setup_run", "script_import", "script_env_fix", "pack_propose"] },
16070
16122
  { id: "screen", title: "\u64CD\u4F5C\u5C4F\u5E55\u548C\u6A21\u62DF\u5668", description: "\u5728\u6E38\u620F\u7A97\u53E3\u6216\u6A21\u62DF\u5668\u91CC\u70B9\u51FB\u3001\u8F93\u5165\u3001\u6309\u952E\u3001\u6ED1\u52A8\u3001\u5207\u6362\u7A97\u53E3\uFF08\u622A\u56FE\u4E0D\u7B97\uFF09\u3002", tools: ["screen_tap", "screen_type", "screen_key", "screen_scroll", "screen_swipe", "window_focus"] },
16071
16123
  { id: "games", title: "\u542F\u52A8\u3001\u5173\u95ED\u6E38\u620F\u548C\u6A21\u62DF\u5668", description: "\u6253\u5F00\u3001\u5173\u6389\u6E38\u620F\uFF0C\u542F\u52A8\u3001\u5173\u95ED\u3001\u5B89\u88C5\u3001\u8BBE\u7F6E\u6A21\u62DF\u5668\u3002", tools: ["game_launch", "game_close", "emulator_start", "emulator_stop", "emulator_install", "emulator_configure"] },
16072
- { id: "game-records", title: "\u8BB0\u5F55\u6D3B\u52A8\u3001\u6DFB\u52A0\u6E38\u620F", description: "\u628A\u8BFB\u5230\u7684\u6D3B\u52A8\u5199\u8FDB\u65E5\u5386\uFF0C\u7ED9\u65B0\u6E38\u620F\u5EFA\u6E38\u620F\u5305\u3002", tools: ["game_record", "game_add"] },
16124
+ { id: "game-records", title: "\u8BB0\u5F55\u6D3B\u52A8\u3001\u6DFB\u52A0\u6E38\u620F", description: "\u628A\u8BFB\u5230\u7684\u6D3B\u52A8\u5199\u8FDB\u65E5\u5386\uFF0C\u66FF\u4F60\u6DFB\u52A0\u3001\u4FEE\u6539\u6216\u53BB\u6389\u6D3B\u52A8\uFF0C\u7ED9\u65B0\u6E38\u620F\u5EFA\u6E38\u620F\u5305\u3002", tools: ["game_record", "game_activity_save", "game_activity_remove", "game_add"] },
16073
16125
  { id: "skills", title: "\u4FDD\u5B58\u6280\u80FD", description: "\u628A\u505A\u6CD5\u5B58\u6210\u6280\u80FD\uFF0C\u4EE5\u540E\u7684\u5BF9\u8BDD\u90FD\u4F1A\u7528\u5230\u3002", tools: ["skill_save"] },
16074
16126
  { id: "web", title: "\u4E0A\u7F51\u67E5\u8D44\u6599", description: "\u8BFB\u7F51\u9875\u3001\u641C\u7D22\u3002", tools: ["web_fetch", "web_search"] },
16075
16127
  { id: "shell", title: "\u8FD0\u884C\u547D\u4EE4\u3001\u6539\u6587\u4EF6", description: "dsh \u81EA\u5E26\u7684\u547D\u4EE4\u884C\u548C\u6587\u4EF6\u7F16\u8F91\u3002\u53EA\u5728\u5B83\u8BF7\u6C42\u786E\u8BA4\u65F6\u6309\u8FD9\u91CC\u7684\u8BBE\u7F6E\u5904\u7406\uFF08\u6C99\u7BB1\u91CC\u7684\u666E\u901A\u547D\u4EE4\u4E0D\u4F1A\u8BF7\u6C42\uFF09\u3002", tools: ["pwsh", "bash", "edit", "write"], approvalOnly: true }
@@ -16859,6 +16911,7 @@ var CredentialInfo = external_exports.object({
16859
16911
  /** False when a read-only layer (the launch environment) shadows the reference. */
16860
16912
  writable: external_exports.boolean()
16861
16913
  });
16914
+ var DEEPSEEK_API_KEY = "DEEPSEEK_API_KEY";
16862
16915
  var Capability = external_exports.object({
16863
16916
  id: external_exports.string(),
16864
16917
  version: external_exports.number().int().positive()
@@ -17003,6 +17056,16 @@ var ProviderProfile = external_exports.object({
17003
17056
  /** Configuration diagnostic reported by the adapter. */
17004
17057
  error: external_exports.string().optional()
17005
17058
  });
17059
+ var ProviderBalance = external_exports.object({
17060
+ /** False when the balance is too low for API calls. */
17061
+ available: external_exports.boolean(),
17062
+ balances: external_exports.array(external_exports.object({
17063
+ currency: external_exports.string(),
17064
+ total: external_exports.string(),
17065
+ granted: external_exports.string(),
17066
+ toppedUp: external_exports.string()
17067
+ }))
17068
+ });
17006
17069
  var MAX_IMAGE_BASE64 = 35e5;
17007
17070
  var PromptImage = external_exports.object({
17008
17071
  mediaType: external_exports.enum(["image/png", "image/jpeg", "image/gif", "image/webp"]),
@@ -17258,6 +17321,12 @@ var Requests = {
17258
17321
  }),
17259
17322
  result: external_exports.object({ models: external_exports.array(ProviderModel) })
17260
17323
  },
17324
+ "providers/balance": {
17325
+ capability: "providers",
17326
+ params: external_exports.object({ provider: external_exports.string().min(1) }),
17327
+ /** Null when the route is not served by DeepSeek's own API or has no key; a failed query is an error, never a zero. */
17328
+ result: external_exports.object({ balance: ProviderBalance.nullable() })
17329
+ },
17261
17330
  "providers/save": {
17262
17331
  capability: "providers",
17263
17332
  params: external_exports.object({
@@ -17696,6 +17765,8 @@ export {
17696
17765
  AgentTaskRun,
17697
17766
  INTERVENE_CAPABILITY,
17698
17767
  GAMES_CAPABILITY,
17768
+ OWN_IMAGE,
17769
+ SHOT_IMAGE,
17699
17770
  GamesSettings,
17700
17771
  PERMISSIONS_CAPABILITY,
17701
17772
  AreaPolicy,
@@ -17713,6 +17784,7 @@ export {
17713
17784
  DEFAULT_COMPACTION_THRESHOLD,
17714
17785
  CompactionSettings,
17715
17786
  RUNS_CAPABILITY,
17787
+ DEEPSEEK_API_KEY,
17716
17788
  AGENTS_CAPABILITY,
17717
17789
  ProviderApi,
17718
17790
  Requests,
@@ -3,7 +3,7 @@ import {
3
3
  ScriptFamily,
4
4
  ScriptId,
5
5
  external_exports
6
- } from "./chunk-BL6OSR2I.js";
6
+ } from "./chunk-HPQCV6WO.js";
7
7
  import {
8
8
  __commonJS,
9
9
  __require,
@@ -1382,10 +1382,26 @@ function mirrored(mirror, url) {
1382
1382
  }
1383
1383
  var IntegrityError = class extends DownloadError {
1384
1384
  };
1385
+ var StalePartError = class extends DownloadError {
1386
+ };
1385
1387
  async function downloadFrom(url, options2) {
1388
+ try {
1389
+ return await downloadOnce(url, options2);
1390
+ } catch (error) {
1391
+ if (!(error instanceof StalePartError))
1392
+ throw error;
1393
+ await rm(`${options2.dest}.part`, { force: true });
1394
+ return downloadOnce(url, options2);
1395
+ }
1396
+ }
1397
+ async function downloadOnce(url, options2) {
1386
1398
  const part = `${options2.dest}.part`;
1387
1399
  await mkdir(dirname(options2.dest), { recursive: true });
1388
- const have = await stat(part).then((s) => s.size, () => 0);
1400
+ let have = await stat(part).then((s) => s.size, () => 0);
1401
+ if (options2.expectedSize !== void 0 && have > options2.expectedSize) {
1402
+ await rm(part, { force: true });
1403
+ have = 0;
1404
+ }
1389
1405
  const fetchImpl = options2.fetch ?? globalThis.fetch;
1390
1406
  const response = await fetchImpl(url, {
1391
1407
  headers: { "user-agent": options2.userAgent ?? "MultiGameAssistant", ...have > 0 ? { range: `bytes=${have}-` } : {} },
@@ -1397,6 +1413,12 @@ async function downloadFrom(url, options2) {
1397
1413
  const resumed = response.status === 206 && have > 0;
1398
1414
  if (response.status === 416 && have > 0 && have === options2.expectedSize) {
1399
1415
  await response.body?.cancel();
1416
+ } else if (response.status === 416 && have > 0) {
1417
+ await response.body?.cancel();
1418
+ throw new StalePartError(`${host(url)} \u4E0D\u63A5\u53D7\u4ECE\u7B2C ${have} \u5B57\u8282\u7EED\u4F20`);
1419
+ } else if (resumed && rangeStart(response.headers.get("content-range")) !== have) {
1420
+ await response.body?.cancel();
1421
+ throw new StalePartError(`${host(url)} \u7EED\u4F20\u7684\u4F4D\u7F6E\u4E0D\u5BF9`);
1400
1422
  } else if (!response.ok || response.body === null) {
1401
1423
  await response.body?.cancel();
1402
1424
  throw new DownloadError(`${host(url)} \u8FD4\u56DE ${response.status}`);
@@ -1428,18 +1450,26 @@ async function downloadFrom(url, options2) {
1428
1450
  const bytes = (await stat(part)).size;
1429
1451
  if (options2.expectedSize !== void 0 && bytes !== options2.expectedSize) {
1430
1452
  await rm(part, { force: true });
1453
+ if (have > 0)
1454
+ throw new StalePartError(`\u7EED\u4F20\u540E\u6587\u4EF6\u5927\u5C0F\u4E0D\u7B26\uFF1A\u5E94\u4E3A ${options2.expectedSize} \u5B57\u8282\uFF0C\u5B9E\u9645 ${bytes} \u5B57\u8282`);
1431
1455
  throw new DownloadError(`\u6587\u4EF6\u5927\u5C0F\u4E0D\u7B26\uFF1A\u5E94\u4E3A ${options2.expectedSize} \u5B57\u8282\uFF0C\u5B9E\u9645 ${bytes} \u5B57\u8282`);
1432
1456
  }
1433
1457
  const sha256 = await hashFile(part);
1434
1458
  const expected = parseDigest(options2.digest);
1435
1459
  if (expected !== void 0 && expected !== sha256) {
1436
1460
  await rm(part, { force: true });
1461
+ if (have > 0)
1462
+ throw new StalePartError(`\u7EED\u4F20\u540E\u6821\u9A8C\u5931\u8D25\uFF1ASHA-256 \u5E94\u4E3A ${expected}\uFF0C\u5B9E\u9645 ${sha256}`);
1437
1463
  throw new IntegrityError(`\u6821\u9A8C\u5931\u8D25\uFF1ASHA-256 \u5E94\u4E3A ${expected}\uFF0C\u5B9E\u9645 ${sha256}\uFF1B\u6587\u4EF6\u5DF2\u5220\u9664`);
1438
1464
  }
1439
1465
  await rm(options2.dest, { force: true });
1440
1466
  await rename(part, options2.dest);
1441
1467
  return { path: options2.dest, bytes, sha256, via: url, finalUrl: response.url || url, resumed };
1442
1468
  }
1469
+ function rangeStart(header) {
1470
+ const match = header === null ? null : /^bytes\s+(\d+)-/i.exec(header.trim());
1471
+ return match === null ? void 0 : Number(match[1]);
1472
+ }
1443
1473
  function parseDigest(digest) {
1444
1474
  if (digest === void 0)
1445
1475
  return void 0;
@@ -1823,7 +1853,9 @@ var MARKERS = [
1823
1853
  { kind: "nsis", text: "Nullsoft.NSIS.exehead" },
1824
1854
  { kind: "nsis", text: "NullsoftInst" },
1825
1855
  { kind: "inno", text: "JR.Inno.Setup" },
1826
- { kind: "inno", text: "Inno Setup Setup Data" }
1856
+ { kind: "inno", text: "Inno Setup Setup Data" },
1857
+ // Kachina Installer (BetterGI's BetterGI.Install.*.exe) writes it over the DOS stub's text (native/builder/pack.rs).
1858
+ { kind: "kachina", text: "!KachinaInstaller!" }
1827
1859
  ];
1828
1860
  async function setupKind(file) {
1829
1861
  const handle = await open2(file, "r").catch(() => void 0);
@@ -1841,9 +1873,9 @@ async function setupKind(file) {
1841
1873
  await handle.close();
1842
1874
  }
1843
1875
  }
1844
- var SETUP_NAMES = { nsis: "NSIS", inno: "Inno Setup" };
1876
+ var SETUP_NAMES = { nsis: "NSIS", inno: "Inno Setup", kachina: "Kachina" };
1845
1877
  function setupCommandLine(kind, dir, quiet) {
1846
- if (kind === "nsis")
1878
+ if (kind === "nsis" || kind === "kachina")
1847
1879
  return `${quiet ? "/S " : ""}/D=${dir}`;
1848
1880
  return `${quiet ? "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- " : ""}/DIR="${dir}"`;
1849
1881
  }
@@ -1852,7 +1884,8 @@ function setupExitText(kind, code) {
1852
1884
  return "\u5B89\u88C5\u5B8C\u6210";
1853
1885
  const nsis = { 1: "\u5B89\u88C5\u88AB\u53D6\u6D88\u4E86", 2: "\u5B89\u88C5\u4E2D\u9014\u51FA\u9519" };
1854
1886
  const inno = { 1: "\u5B89\u88C5\u7A0B\u5E8F\u6CA1\u80FD\u542F\u52A8", 2: "\u5B89\u88C5\u8FD8\u6CA1\u5F00\u59CB\u5C31\u88AB\u53D6\u6D88\u4E86", 3: "\u51C6\u5907\u5B89\u88C5\u65F6\u51FA\u9519", 4: "\u5B89\u88C5\u4E2D\u9014\u51FA\u9519", 5: "\u5B89\u88C5\u88AB\u53D6\u6D88\u4E86", 6: "\u5B89\u88C5\u7A0B\u5E8F\u88AB\u5F3A\u884C\u7ED3\u675F", 7: "\u5B89\u88C5\u524D\u68C0\u67E5\u6CA1\u901A\u8FC7", 8: "\u5B89\u88C5\u524D\u68C0\u67E5\u6CA1\u901A\u8FC7\uFF0C\u9700\u8981\u91CD\u542F\u7535\u8111" };
1855
- return (kind === "nsis" ? nsis : inno)[code] ?? `\u5B89\u88C5\u7A0B\u5E8F\u9000\u51FA\u7801 ${code}`;
1887
+ const kachina = { 1: "\u5B89\u88C5\u6CA1\u6709\u5B8C\u6210" };
1888
+ return { nsis, inno, kachina }[kind][code] ?? `\u5B89\u88C5\u7A0B\u5E8F\u9000\u51FA\u7801 ${code}`;
1856
1889
  }
1857
1890
  function runSetup(file, options2) {
1858
1891
  const commandLine = setupCommandLine(options2.kind, options2.dir, options2.quiet);
@@ -8,6 +8,7 @@ import {
8
8
  AreaPolicy,
9
9
  COMPACTION_CAPABILITY,
10
10
  CompactionSettings,
11
+ DEEPSEEK_API_KEY,
11
12
  DEFAULT_COMPACTION_THRESHOLD,
12
13
  ErrorCode,
13
14
  INSTANCES_CAPABILITY,
@@ -24,7 +25,7 @@ import {
24
25
  areaOf,
25
26
  classify,
26
27
  external_exports
27
- } from "./chunk-BL6OSR2I.js";
28
+ } from "./chunk-HPQCV6WO.js";
28
29
  import {
29
30
  __commonJS,
30
31
  __require,
@@ -3781,6 +3782,32 @@ async function addRetryPolicies(settings, namespace) {
3781
3782
  await settings.mutate(namespace, ops, descriptor.revision);
3782
3783
  return ops.length;
3783
3784
  }
3785
+ var OFFICIAL_PROVIDER = "deepseek-official";
3786
+ var OFFICIAL_NAMESPACE = "llm-deepseek-api-key";
3787
+ var DEEPSEEK_ORIGIN = "https://api.deepseek.com";
3788
+ var BALANCE_URL = `${DEEPSEEK_ORIGIN}/user/balance`;
3789
+ var BALANCE_TIMEOUT_MS = 15e3;
3790
+ var originOf = (url) => {
3791
+ try {
3792
+ return url === void 0 ? void 0 : new URL(url).origin;
3793
+ } catch {
3794
+ return void 0;
3795
+ }
3796
+ };
3797
+ function toProviderBalance(body) {
3798
+ const { is_available: available, balance_infos: infos } = body ?? {};
3799
+ if (typeof available !== "boolean" || !Array.isArray(infos))
3800
+ return void 0;
3801
+ const balances = [];
3802
+ for (const info of infos) {
3803
+ const currency = str(info?.currency);
3804
+ const total = str(info?.total_balance);
3805
+ if (currency === void 0 || total === void 0)
3806
+ return void 0;
3807
+ balances.push({ currency, total, granted: str(info.granted_balance) ?? "0", toppedUp: str(info.topped_up_balance) ?? "0" });
3808
+ }
3809
+ return { available, balances };
3810
+ }
3784
3811
  function storedModel(model) {
3785
3812
  return {
3786
3813
  id: model.id,
@@ -3861,6 +3888,45 @@ function providersCapability(deps) {
3861
3888
  }, call.signal);
3862
3889
  return { models: found.map(toProviderModel).filter((m) => m !== void 0) };
3863
3890
  };
3891
+ const balanceKeyRef = (provider) => {
3892
+ if (provider === OFFICIAL_PROVIDER) {
3893
+ const config = settings.describe({ redactSecrets: true }).find((d) => d.ns === OFFICIAL_NAMESPACE)?.value;
3894
+ const baseURL = str(config?.baseURL) ?? str(process.env.DEEPSEEK_BASE_URL) ?? DEEPSEEK_ORIGIN;
3895
+ return originOf(baseURL) === DEEPSEEK_ORIGIN ? str(config?.apiKeyEnv) ?? DEEPSEEK_API_KEY : void 0;
3896
+ }
3897
+ const profile = read().value[provider];
3898
+ return originOf(str(profile?.baseURL)) === DEEPSEEK_ORIGIN ? str(profile?.apiKeyEnv) : void 0;
3899
+ };
3900
+ const balance = async (params, call) => {
3901
+ const ref = balanceKeyRef(params.provider);
3902
+ const key = ref === void 0 ? void 0 : await deps.secret(ref);
3903
+ if (key === void 0 || key === "")
3904
+ return { balance: null };
3905
+ const failed = (message) => new RpcError(ErrorCode.HostError, message, { code: "BALANCE_UNAVAILABLE" });
3906
+ let body;
3907
+ let status;
3908
+ try {
3909
+ const response = await (deps.fetch ?? fetch)(BALANCE_URL, {
3910
+ headers: { Accept: "application/json", Authorization: `Bearer ${key}` },
3911
+ redirect: "error",
3912
+ signal: AbortSignal.any([call.signal, AbortSignal.timeout(BALANCE_TIMEOUT_MS)])
3913
+ });
3914
+ status = response.status;
3915
+ body = response.ok ? await response.json().catch(() => void 0) : void 0;
3916
+ } catch (error) {
3917
+ if (call.signal.aborted)
3918
+ throw error;
3919
+ throw failed("\u8FDE\u4E0D\u4E0A DeepSeek\uFF0C\u67E5\u4E0D\u5230\u4F59\u989D");
3920
+ }
3921
+ if (status === 401)
3922
+ throw failed("DeepSeek \u62D2\u7EDD\u4E86\u8FD9\u4E2A API Key\uFF0C\u67E5\u4E0D\u5230\u4F59\u989D");
3923
+ if (status < 200 || status >= 300)
3924
+ throw failed(`DeepSeek \u6CA1\u6709\u8FD4\u56DE\u4F59\u989D\uFF08HTTP ${status}\uFF09`);
3925
+ const parsed = toProviderBalance(body);
3926
+ if (parsed === void 0)
3927
+ throw failed("DeepSeek \u8FD4\u56DE\u7684\u4F59\u989D\u770B\u4E0D\u61C2");
3928
+ return { balance: parsed };
3929
+ };
3864
3930
  const save = async (params) => {
3865
3931
  const section = read();
3866
3932
  const existing = section.user[params.id];
@@ -3928,6 +3994,7 @@ function providersCapability(deps) {
3928
3994
  methods: {
3929
3995
  "providers/list": () => list(),
3930
3996
  "providers/discover": (params, call) => discover(params, call),
3997
+ "providers/balance": (params, call) => balance(params, call),
3931
3998
  "providers/save": (params) => save(params),
3932
3999
  "providers/remove": (params) => remove(params)
3933
4000
  }
@@ -6835,6 +6902,7 @@ var AdgGateway = class extends Service {
6835
6902
  settings: scoped.settings,
6836
6903
  llm: scoped.llm,
6837
6904
  credentials: () => scoped.get("credentialsController"),
6905
+ secret: async (ref) => (await scoped.get("credentials")?.resolve(ref))?.value,
6838
6906
  namespace: config.providersNamespace ?? "llm-pi-ai",
6839
6907
  changed: providersChanged,
6840
6908
  defaultModel: () => {
package/lib/emulator.js CHANGED
@@ -2,7 +2,7 @@ import { createRequire as __adgCreateRequire } from 'node:module'; import { dirn
2
2
  import {
3
3
  download,
4
4
  runElevated
5
- } from "./chunk-KIAOFNCB.js";
5
+ } from "./chunk-YG4B5G7F.js";
6
6
  import {
7
7
  writeFileAtomic
8
8
  } from "./chunk-CCAB6XXZ.js";
@@ -10,7 +10,7 @@ import {
10
10
  EMULATORS_CAPABILITY,
11
11
  EmulatorSettings,
12
12
  external_exports
13
- } from "./chunk-BL6OSR2I.js";
13
+ } from "./chunk-HPQCV6WO.js";
14
14
  import "./chunk-2UFLGPDY.js";
15
15
 
16
16
  // packages/emulator/lib/index.js
package/lib/feishu.js CHANGED
@@ -2,7 +2,7 @@ import { createRequire as __adgCreateRequire } from 'node:module'; import { dirn
2
2
  import {
3
3
  replyMarkdown,
4
4
  replyPlain
5
- } from "./chunk-FLQD3DKB.js";
5
+ } from "./chunk-BNGDT7YT.js";
6
6
  import {
7
7
  require_extension,
8
8
  require_permessage_deflate,
@@ -12,7 +12,7 @@ import {
12
12
  require_subprotocol,
13
13
  require_websocket,
14
14
  require_websocket_server
15
- } from "./chunk-2DZ75ANX.js";
15
+ } from "./chunk-ZQ6KFVEO.js";
16
16
  import {
17
17
  writeFileAtomic
18
18
  } from "./chunk-CCAB6XXZ.js";
@@ -22,7 +22,7 @@ import {
22
22
  FeishuPending,
23
23
  FeishuSettings,
24
24
  external_exports
25
- } from "./chunk-BL6OSR2I.js";
25
+ } from "./chunk-HPQCV6WO.js";
26
26
  import {
27
27
  __commonJS,
28
28
  __require,