@lijian-ui/dsh-im-gateway 0.2.1 → 0.2.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/lib/client.js CHANGED
@@ -1147,8 +1147,8 @@ window.__ModuleLoader__.load({
1147
1147
  message: result.error?.message ?? `${SERVICE}.${method} failed`
1148
1148
  };
1149
1149
  return {
1150
- ok: true,
1151
- ...result.value
1150
+ ...result.value,
1151
+ ok: true
1152
1152
  };
1153
1153
  } catch (err) {
1154
1154
  return {
@@ -1304,6 +1304,41 @@ window.__ModuleLoader__.load({
1304
1304
  t
1305
1305
  })
1306
1306
  }, ImChannelsSection));
1307
+ const navLabels = /* @__PURE__ */ new Set([zh["section.label"], en["section.label"]]);
1308
+ const imNavSvg = "<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-imgw-nav=\"1\"><path d=\"M8.3125 0.981587C8.66767 1.0545 8.97902 1.20558 9.2627 1.43374C9.48724 1.61438 9.73029 1.85933 9.97949 2.10854L14.707 6.83608L13.293 8.25014L9 3.95717V15.0431H7V3.95717L2.70703 8.25014L1.29297 6.83608L6.02051 2.10854C6.26971 1.85933 6.51277 1.61438 6.7373 1.43374C6.97662 1.24126 7.28445 1.04542 7.6875 0.981587C7.8973 0.94841 8.1031 0.956564 8.3125 0.981587Z\" fill=\"currentColor\"/></svg>";
1309
+ const patchNavIcon = () => {
1310
+ if (typeof document === "undefined") return;
1311
+ for (const span of Array.from(document.querySelectorAll("button > span"))) {
1312
+ if (!navLabels.has(span.textContent ?? "")) continue;
1313
+ const button = span.parentElement;
1314
+ if (button === null) continue;
1315
+ const stale = button.querySelector("svg:not([data-imgw-nav])");
1316
+ if (stale === null) continue;
1317
+ const template = document.createElement("template");
1318
+ template.innerHTML = imNavSvg;
1319
+ const next = template.content.firstElementChild;
1320
+ if (next === null) continue;
1321
+ const cls = stale.getAttribute("class");
1322
+ if (cls !== null) next.setAttribute("class", cls);
1323
+ stale.replaceWith(next);
1324
+ }
1325
+ };
1326
+ if (typeof document !== "undefined" && typeof MutationObserver !== "undefined" && document.body !== null) {
1327
+ let scheduled = false;
1328
+ const schedule = () => {
1329
+ if (scheduled) return;
1330
+ scheduled = true;
1331
+ queueMicrotask(() => {
1332
+ scheduled = false;
1333
+ patchNavIcon();
1334
+ });
1335
+ };
1336
+ patchNavIcon();
1337
+ new MutationObserver(schedule).observe(document.body, {
1338
+ childList: true,
1339
+ subtree: true
1340
+ });
1341
+ }
1307
1342
  }
1308
1343
  //#endregion
1309
1344
  exports.apply = apply;
@@ -1,5 +1,7 @@
1
1
  import { Context, Context as Context$1, Service } from "@deepseek-ai/cordis";
2
2
  import Schema from "@deepseek-ai/schemastery";
3
+ import { SessionId } from "@deepseek-ai/dsh-session";
4
+ import "@deepseek-ai/dsh-agent";
3
5
  import * as _deepseek_ai_cosmokit0 from "@deepseek-ai/cosmokit";
4
6
  import { AskUserQuestionAnswer, AskUserQuestionItem } from "@deepseek-ai/dsh-user-questions";
5
7
 
package/lib/index.js CHANGED
@@ -4,7 +4,7 @@ import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-sett
4
4
  import { Service } from "@deepseek-ai/cordis";
5
5
  import Schema from "@deepseek-ai/schemastery";
6
6
  import { SessionId } from "@deepseek-ai/dsh-session";
7
- import { createUserMessage } from "@deepseek-ai/dsh-llm";
7
+ import { ReasoningEffortId, createUserMessage } from "@deepseek-ai/dsh-llm";
8
8
  import { installModelSelection } from "@deepseek-ai/dsh-agent";
9
9
  import { closeSync, existsSync, fsyncSync, linkSync, mkdirSync, openSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
10
10
  import crypto, { randomUUID } from "node:crypto";
@@ -722,8 +722,11 @@ var CommandHandler = class {
722
722
  this.gw.modelOverrides.delete(currentSessionId);
723
723
  this.gw.sessionToConv.delete(currentSessionId);
724
724
  }
725
- const handle = await this.gw.ctx.agents.resume({ resumeSessionId: targetSessionId });
726
- this.gw.installModelSelection(handle.agent, targetSessionId);
725
+ const handle = await this.gw.ctx.agents.resume({
726
+ resumeSessionId: targetSessionId,
727
+ agentOptions: this.gw.currentModelFor(targetSessionId),
728
+ setup: this.gw.presetSetup(targetSessionId)
729
+ });
727
730
  this.gw.agentHandles.set(targetSessionId, handle);
728
731
  this.gw.convToSession.set(convKey, targetSessionId);
729
732
  this.gw.sessionToConv.set(targetSessionId, convKey);
@@ -1276,7 +1279,7 @@ const Config = Schema.object({
1276
1279
  */
1277
1280
  var ImGatewayService = class extends Service {
1278
1281
  config;
1279
- static inject = ["agents"];
1282
+ static inject = ["agents", "agentPresets"];
1280
1283
  channels = /* @__PURE__ */ new Map();
1281
1284
  convToSession = /* @__PURE__ */ new Map();
1282
1285
  sessionToConv = /* @__PURE__ */ new Map();
@@ -1581,8 +1584,11 @@ var ImGatewayService = class extends Service {
1581
1584
  if (persistence) {
1582
1585
  if ((await persistence.list()).find((header) => header.id === sessionId)) {
1583
1586
  console.log(`[im-gateway] ensureSession: branch 2 (resume from persistence)`);
1584
- const handle = await this.ctx.agents.resume({ resumeSessionId: sessionId });
1585
- this.installModelSelection(handle.agent, sessionId);
1587
+ const handle = await this.ctx.agents.resume({
1588
+ resumeSessionId: sessionId,
1589
+ agentOptions: this.currentModelFor(sessionId),
1590
+ setup: this.presetSetup(sessionId)
1591
+ });
1586
1592
  this.agentHandles.set(sessionId, handle);
1587
1593
  this.convToSession.set(convKey, sessionId);
1588
1594
  this.sessionToConv.set(sessionId, convKey);
@@ -1598,15 +1604,20 @@ var ImGatewayService = class extends Service {
1598
1604
  try {
1599
1605
  handle = await this.ctx.agents.create({
1600
1606
  sessionId,
1601
- meta: { cwd: effectiveCwd }
1607
+ meta: { cwd: effectiveCwd },
1608
+ agentOptions: this.currentModelFor(sessionId),
1609
+ setup: this.presetSetup(sessionId)
1602
1610
  });
1603
1611
  } catch (err) {
1604
1612
  if (isIdCollision(err)) {
1605
1613
  console.log(`[im-gateway] ensureSession: id collision, falling back to resume`);
1606
- handle = await this.ctx.agents.resume({ resumeSessionId: sessionId });
1614
+ handle = await this.ctx.agents.resume({
1615
+ resumeSessionId: sessionId,
1616
+ agentOptions: this.currentModelFor(sessionId),
1617
+ setup: this.presetSetup(sessionId)
1618
+ });
1607
1619
  } else throw err;
1608
1620
  }
1609
- this.installModelSelection(handle.agent, sessionId);
1610
1621
  this.agentHandles.set(sessionId, handle);
1611
1622
  this.convToSession.set(convKey, sessionId);
1612
1623
  this.sessionToConv.set(sessionId, convKey);
@@ -1712,6 +1723,27 @@ var ImGatewayService = class extends Service {
1712
1723
  }
1713
1724
  } catch {}
1714
1725
  }
1726
+ /** Compute the initial model selection for a session (override → global → deployment default). */
1727
+ currentModelFor(sessionId) {
1728
+ const override = this.modelOverrides.get(sessionId) ?? this.globalModelOverride;
1729
+ if (override) return override;
1730
+ return this.ctx.get("agentDefaultModel")?.currentSelection();
1731
+ }
1732
+ /**
1733
+ * Agent setup callback: mount the 'standard' preset (tools, prompt sections,
1734
+ * skills) and install model selection into the agent's prompt assembly.
1735
+ * Called by agents.create/agents.resume BEFORE the agent is published, so
1736
+ * the first prompt assembly has all tools and {{provider}}/{{model}} variables.
1737
+ */
1738
+ presetSetup(sessionId) {
1739
+ const gateway = this;
1740
+ return async (agentCtx) => {
1741
+ const presets = gateway.ctx.get("agentPresets");
1742
+ if (presets) await presets.mount(agentCtx, "standard");
1743
+ else console.warn("[im-gateway] agentPresets not available, agent will have no tools");
1744
+ gateway.installModelSelection(agentCtx, sessionId);
1745
+ };
1746
+ }
1715
1747
  /**
1716
1748
  * Wire the agent-default-model selection into one agent's prompt assembly
1717
1749
  * (mirrors dsh-host-apiproxy selectionFor). Listeners live on the agent's
@@ -1724,14 +1756,19 @@ var ImGatewayService = class extends Service {
1724
1756
  * `modelRefs` so `/model` can mutate `current` on the same object the prompt
1725
1757
  * assembly reads.
1726
1758
  */
1727
- installModelSelection(agent, sessionId) {
1759
+ installModelSelection(agentCtx, sessionId) {
1728
1760
  const gateway = this;
1729
1761
  const defaults = this.ctx.get("agentDefaultModel");
1730
1762
  const ref = {
1731
1763
  get current() {
1732
1764
  const override = gateway.modelOverrides.get(sessionId) ?? gateway.globalModelOverride;
1733
1765
  const base = defaults?.currentSelection();
1734
- return override ?? base ?? void 0;
1766
+ if (!override) return base ?? void 0;
1767
+ return {
1768
+ provider: override.provider,
1769
+ model: override.model,
1770
+ ...override.reasoningEffort === void 0 ? {} : { reasoningEffort: ReasoningEffortId(override.reasoningEffort) }
1771
+ };
1735
1772
  },
1736
1773
  set current(next) {
1737
1774
  if (next) gateway.modelOverrides.set(sessionId, {
@@ -1743,7 +1780,7 @@ var ImGatewayService = class extends Service {
1743
1780
  },
1744
1781
  assembled: void 0
1745
1782
  };
1746
- installModelSelection(agent.ctx, ref);
1783
+ installModelSelection(agentCtx, ref);
1747
1784
  this.modelRefs.set(sessionId, ref);
1748
1785
  }
1749
1786
  async runTurn(sessionId, convKey, channel, parts) {
@@ -4895,10 +4932,11 @@ function mergeStoredSecrets(current, incoming) {
4895
4932
  if (!stored) return inst;
4896
4933
  const config = { ...inst.config };
4897
4934
  for (const key of SECRET_KEYS) {
4898
- const value = config[key];
4935
+ const bag = config;
4936
+ const value = bag[key];
4899
4937
  if (value === "" || value === void 0) {
4900
4938
  const old = stored.config?.[key];
4901
- if (old !== void 0 && old !== "") config[key] = old;
4939
+ if (old !== void 0 && old !== "") bag[key] = old;
4902
4940
  }
4903
4941
  }
4904
4942
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lijian-ui/dsh-im-gateway",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Multi-channel IM gateway plugin for DeepSeek Harness (dsh): DingTalk / QQ / WeChat(iLink) with QR-scan binding, streaming replies, and a unified ctx.imGateway service. 为 DeepSeek Harness 提供钉钉/QQ/个人微信多 IM 通道接入。",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -64,13 +64,13 @@
64
64
  "peerDependencies": {
65
65
  "@deepseek-ai/cordis": "*",
66
66
  "@deepseek-ai/schemastery": "*",
67
- "@deepseek-ai/dsh-agent": "0.1.0-rc.6",
68
- "@deepseek-ai/dsh-llm": "0.1.0-rc.6",
69
- "@deepseek-ai/dsh-session": "0.1.0-rc.6",
67
+ "@deepseek-ai/dsh-agent": "0.1.1-rc.2 || 0.1.0-rc.8 || 0.1.0-rc.7 || 0.1.0-rc.6",
68
+ "@deepseek-ai/dsh-llm": "0.1.1-rc.2 || 0.1.0-rc.8 || 0.1.0-rc.7 || 0.1.0-rc.6",
69
+ "@deepseek-ai/dsh-session": "0.1.1-rc.2 || 0.1.0-rc.8 || 0.1.0-rc.7 || 0.1.0-rc.6",
70
70
  "@deepseek-ai/dsh-settings": "*",
71
71
  "@deepseek-ai/dsh-typert-protocol": "*",
72
- "@deepseek-ai/dsh-user-approval": "0.1.0-rc.6",
73
- "@deepseek-ai/dsh-user-questions": "0.1.0-rc.6"
72
+ "@deepseek-ai/dsh-user-approval": "0.1.1-rc.2 || 0.1.0-rc.8 || 0.1.0-rc.7 || 0.1.0-rc.6",
73
+ "@deepseek-ai/dsh-user-questions": "0.1.1-rc.2 || 0.1.0-rc.8 || 0.1.0-rc.7 || 0.1.0-rc.6"
74
74
  },
75
75
  "dependencies": {
76
76
  "@tencent-connect/qqbot-connector": "^1.2.0",
@@ -81,22 +81,22 @@
81
81
  },
82
82
  "devDependencies": {
83
83
  "@deepseek-ai/cordis": "4.0.1",
84
+ "@deepseek-ai/dsh-agent": "0.1.1-rc.2",
85
+ "@deepseek-ai/dsh-api-gateway": "0.1.1-rc.2",
86
+ "@deepseek-ai/dsh-client-connection": "0.1.1-rc.2",
87
+ "@deepseek-ai/dsh-client-locale": "0.1.1-rc.2",
88
+ "@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
89
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.1-rc.2",
90
+ "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.1-rc.2",
91
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2",
92
+ "@deepseek-ai/dsh-llm": "0.1.1-rc.2",
93
+ "@deepseek-ai/dsh-session": "0.1.1-rc.2",
94
+ "@deepseek-ai/dsh-settings": "0.1.1-rc.2",
95
+ "@deepseek-ai/dsh-typert-protocol": "0.1.1-rc.2",
96
+ "@deepseek-ai/dsh-typert-registry": "0.1.1-rc.2",
97
+ "@deepseek-ai/dsh-user-approval": "0.1.1-rc.2",
98
+ "@deepseek-ai/dsh-user-questions": "0.1.1-rc.2",
84
99
  "@deepseek-ai/schemastery": "3.18.1",
85
- "@deepseek-ai/dsh-agent": "0.1.0-rc.6",
86
- "@deepseek-ai/dsh-llm": "0.1.0-rc.6",
87
- "@deepseek-ai/dsh-session": "0.1.0-rc.6",
88
- "@deepseek-ai/dsh-settings": "0.1.0-rc.6",
89
- "@deepseek-ai/dsh-typert-protocol": "0.1.0-rc.6",
90
- "@deepseek-ai/dsh-user-approval": "0.1.0-rc.6",
91
- "@deepseek-ai/dsh-user-questions": "0.1.0-rc.6",
92
- "@deepseek-ai/dsh-client-connection": "0.1.0-rc.6",
93
- "@deepseek-ai/dsh-client-locale": "0.1.0-rc.6",
94
- "@deepseek-ai/dsh-client-runtime": "0.1.0-rc.6",
95
- "@deepseek-ai/dsh-client-schema-form": "0.1.0-rc.6",
96
- "@deepseek-ai/dsh-client-ui-slots": "0.1.0-rc.6",
97
- "@deepseek-ai/dsh-client-ui-settings": "0.1.0-rc.6",
98
- "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.0-rc.6",
99
- "@deepseek-ai/dsh-api-gateway": "0.1.0-rc.6",
100
100
  "@types/node": "^22.0.0",
101
101
  "@types/qrcode": "^1.5.5",
102
102
  "@types/react": "^18.3.0",