dsh-plugin-litellm-bridge 2.1.2 → 2.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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # dsh-fallback-auto-pool-arch
1
+ # dsh-plugin-litellm-bridge
2
2
 
3
3
  DSH + LiteLLM 网关桥接方案。
4
4
 
@@ -76,7 +76,7 @@ DSH + LiteLLM 网关桥接方案。
76
76
  `dsh-plugin-litellm-bridge/` 里的实现),所以可以直接按 git 装:
77
77
 
78
78
  ```
79
- git+https://github.com/heixiua/dsh-fallback-auto-pool-arch.git#<commit-sha>
79
+ git+https://github.com/heixiua/dsh-plugin-litellm-bridge.git#<commit-sha>
80
80
  ```
81
81
 
82
82
  在插件市场里粘贴这个地址即可。**建议带上 commit sha**(而不是 `#main`),
@@ -87,7 +87,7 @@ git+https://github.com/heixiua/dsh-fallback-auto-pool-arch.git#<commit-sha>
87
87
  ```bash
88
88
  # 完全退出 DSH(全部 6 个 DeepSeek Harness.exe 进程)后
89
89
  cd "D:\AI agent cache\dsh\profiles\desktop"
90
- pnpm add "file:D:/AI sandbox/dsh-sandbox/dsh-fallback-auto-pool-arch"
90
+ pnpm add "file:D:/AI sandbox/dsh-sandbox/dsh-plugin-litellm-bridge"
91
91
  ```
92
92
 
93
93
  > ⚠ 装完立刻检查 `pnpm-workspace.yaml` 的 `allowBuilds` 里有没有
@@ -97,7 +97,7 @@ pnpm add "file:D:/AI sandbox/dsh-sandbox/dsh-fallback-auto-pool-arch"
97
97
  ### 方式 C:从子目录装(旧方式,仍支持)
98
98
 
99
99
  ```bash
100
- pnpm add "file:D:/AI sandbox/dsh-sandbox/dsh-fallback-auto-pool-arch/dsh-plugin-litellm-bridge"
100
+ pnpm add "file:D:/AI sandbox/dsh-sandbox/dsh-plugin-litellm-bridge/dsh-plugin-litellm-bridge"
101
101
  ```
102
102
 
103
103
  子目录里保留了完整、可独立安装的 `package.json`,与根目录指向同一份实现
package/docs/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # dsh-fallback-auto-pool-arch
1
+ # dsh-plugin-litellm-bridge
2
2
 
3
3
  DSH 插件 **litellm-bridge**:一个 LiteLLM 网关桥接面板。
4
4
 
@@ -94,7 +94,7 @@ DSH 插件 **litellm-bridge**:一个 LiteLLM 网关桥接面板。
94
94
  ## 3. 仓库结构
95
95
 
96
96
  ```
97
- dsh-fallback-auto-pool-arch/
97
+ dsh-plugin-litellm-bridge/
98
98
  ├── dsh-plugin-litellm-bridge/ # ① DSH 桥接插件本体
99
99
  │ ├── package.json # dsh.bundle.patch + dsh.client 声明
100
100
  │ ├── cordis.patch.yml # 挂进 profile 组合树的补丁
@@ -273,7 +273,7 @@ Copy-Item "$p\cordis.patch.yml" "$p\cordis.patch.yml.bak" -Force
273
273
 
274
274
  # 3) 以 file: 依赖安装(路径必须绝对)
275
275
  Set-Location $p
276
- pnpm add "file:D:/AI sandbox/dsh-sandbox/dsh-fallback-auto-pool-arch/dsh-plugin-litellm-bridge"
276
+ pnpm add "file:D:/AI sandbox/dsh-sandbox/dsh-plugin-litellm-bridge/dsh-plugin-litellm-bridge"
277
277
 
278
278
  # 4) 确认包体完整(文件数 > 0,且 package.json 存在)
279
279
  Get-ChildItem "$p\node_modules\dsh-plugin-litellm-bridge" -Recurse | Measure-Object
@@ -622,14 +622,14 @@ python litellm-gateway/test-probe.py --model root-primary
622
622
 
623
623
  ## 9. 推送到 GitHub
624
624
 
625
- 仓库地址:<https://github.com/heixiua/dsh-fallback-auto-pool-arch>
625
+ 仓库地址:<https://github.com/heixiua/dsh-plugin-litellm-bridge>
626
626
 
627
627
  ```bash
628
- cd dsh-fallback-auto-pool-arch
628
+ cd dsh-plugin-litellm-bridge
629
629
 
630
630
  git init
631
631
  git branch -M main
632
- git remote add origin https://github.com/heixiua/dsh-fallback-auto-pool-arch.git
632
+ git remote add origin https://github.com/heixiua/dsh-plugin-litellm-bridge.git
633
633
 
634
634
  # 提交前务必确认没有密钥混进来
635
635
  git status --short
@@ -25,6 +25,7 @@ import { createConnection } from 'node:net';
25
25
  import { existsSync } from 'node:fs';
26
26
  import { dirname, join, resolve } from 'node:path';
27
27
  import { fileURLToPath } from 'node:url';
28
+ import { tmpdir } from 'node:os';
28
29
 
29
30
  /** 默认网关地址。 */
30
31
  export const DEFAULT_GATEWAY_URL = 'http://127.0.0.1:4000';
@@ -157,14 +158,14 @@ export function findGatewayDir(explicitDir) {
157
158
  for (let i = 0; i < 6; i++) {
158
159
  cur = resolve(cur, '..');
159
160
  push(join(cur, 'litellm-gateway'));
160
- push(join(cur, 'dsh-fallback-auto-pool-arch', 'litellm-gateway'));
161
+ push(join(cur, 'dsh-plugin-litellm-bridge', 'litellm-gateway'));
161
162
  }
162
163
  } catch {
163
164
  /* ignore */
164
165
  }
165
166
 
166
167
  // 4) 常见绝对路径兜底
167
- push('D:/AI sandbox/dsh-sandbox/dsh-fallback-auto-pool-arch/litellm-gateway');
168
+ push('D:/AI sandbox/dsh-sandbox/dsh-plugin-litellm-bridge/litellm-gateway');
168
169
 
169
170
  for (const c of candidates) {
170
171
  try {
@@ -267,7 +268,13 @@ export class GatewaySupervisor {
267
268
  '--port', String(port),
268
269
  ],
269
270
  {
270
- cwd: dir,
271
+ // 【关键】cwd 绝不能是网关目录 / 工作区目录。
272
+ // 旧版本传 cwd: dir,配合 start-gateway.sh 里的 `cd "$SCRIPT_DIR"`,
273
+ // 会让网关进程把 CWD 钉在工作区里;Windows 随即拒绝对整个工作区目录树
274
+ // 做 rename/move(EPERM),用户改文件夹名时看到「被占用」。
275
+ // 脚本内所有路径都是 $SCRIPT_DIR 绝对形式,不需要任何特定 CWD;
276
+ // 用系统临时目录既安全又不会锁住工作区。
277
+ cwd: tmpdir(),
271
278
  env: {
272
279
  ...process.env,
273
280
  ...(this.envFile ? { LITELLM_BRIDGE_ENV: this.envFile } : {}),
@@ -37,28 +37,66 @@
37
37
  import { readFile } from 'node:fs/promises';
38
38
  import { existsSync } from 'node:fs';
39
39
  import { join } from 'node:path';
40
+ import { homedir } from 'node:os';
41
+ import { fileURLToPath } from 'node:url';
40
42
 
41
- /** 定位 profile 的 cordis.patch.yml。 */
43
+ /**
44
+ * 定位 profile 的 cordis.patch.yml。
45
+ *
46
+ * 【曾经的致命 bug · 2026-11-10 修复】
47
+ * 旧代码用 `new URL('.', import.meta.url).pathname` 反推模块目录。这在 Windows 上
48
+ * 返回的是 **URL 形态**的路径,而不是文件系统路径:
49
+ *
50
+ * new URL('.', import.meta.url).pathname
51
+ * → "/D:/AI%20agent%20cache/dsh/profiles/desktop/node_modules/.../lib/"
52
+ * ^^^^ 前导斜杠 ^^^^ 空格被百分号编码
53
+ *
54
+ * existsSync("/D:/AI%20agent...") 恒为 false(msys 风格盘符 + %20 都不合法),
55
+ * 于是本函数在 **DSH 宿主进程里永远返回 null**,patchMap 恒空,baseURL 一条都补不上,
56
+ * 用户持续看到「供应商 agnes 缺少 API 地址」。
57
+ *
58
+ * 为什么我早期的自测没发现:当时是用 shell 里带着 `DSH_PROFILE_DIR` 环境变量跑的,
59
+ * 命中了第 1 个候选分支就提前 return,兜底分支的 bug 被掩盖。
60
+ *
61
+ * 修法:一律走 `fileURLToPath()`(它负责 decodeURIComponent + 盘符规范化),
62
+ * 并把「用户主目录下的 .dsh」作为独立候选 —— 不依赖任何可选环境变量。
63
+ */
42
64
  export function profilePatchPath() {
43
- const home = process.env.DSH_HOME || process.env.DSH_PROFILE_DIR || '';
44
65
  const candidates = [];
45
66
 
46
- if (process.env.DSH_PROFILE_DIR) {
47
- candidates.push(join(process.env.DSH_PROFILE_DIR, 'cordis.patch.yml'));
48
- }
67
+ // 1) 显式 profile 目录(部分宿主版本会注入)
68
+ const profileDir = process.env.DSH_PROFILE_DIR;
69
+ if (profileDir) candidates.push(join(profileDir, 'cordis.patch.yml'));
70
+
71
+ // 2) DSH_HOME —— 可能是 .dsh 根,也可能直接是 profile 目录
72
+ const home = process.env.DSH_HOME;
49
73
  if (home) {
50
- // DSH_HOME 可能是 .dsh 根,也可能是 profile 目录
51
74
  candidates.push(join(home, 'cordis.patch.yml'));
52
75
  candidates.push(join(home, 'profiles', 'desktop', 'cordis.patch.yml'));
76
+ const profileName = process.env.DSH_PROFILE;
77
+ if (profileName) candidates.push(join(home, 'profiles', profileName, 'cordis.patch.yml'));
53
78
  }
54
- // 兜底:从 node_modules 位置反推 profile 目录
55
- // <profile>/node_modules/dsh-plugin-litellm-bridge/lib/... → <profile>
79
+
80
+ // 3) 从本模块位置反推:<profile>/node_modules/<pkg>/<pkg>/lib/patch-providers.js
81
+ // 必须用 fileURLToPath —— 见上方 bug 说明。
82
+ try {
83
+ const here = fileURLToPath(new URL('.', import.meta.url)).replace(/\\/g, '/');
84
+ let idx = here.indexOf('/node_modules/');
85
+ while (idx > 0) {
86
+ const root = here.slice(0, idx);
87
+ candidates.push(join(root, 'cordis.patch.yml'));
88
+ candidates.push(join(root, 'profiles', 'desktop', 'cordis.patch.yml'));
89
+ idx = here.indexOf('/node_modules/', idx + 1);
90
+ }
91
+ } catch { /* ignore */ }
92
+
93
+ // 4) 用户主目录兜底:只依赖 homedir(),不依赖任何可选环境变量
56
94
  try {
57
- const here = new URL('.', import.meta.url).pathname;
58
- const idx = here.replace(/\\/g, '/').indexOf('/node_modules/');
59
- if (idx > 0) {
60
- const profileRoot = here.slice(0, idx);
61
- candidates.push(join(profileRoot, 'cordis.patch.yml'));
95
+ const h = homedir();
96
+ candidates.push(join(h, '.dsh', 'profiles', 'desktop', 'cordis.patch.yml'));
97
+ const profileName = process.env.DSH_PROFILE;
98
+ if (profileName) {
99
+ candidates.push(join(h, '.dsh', 'profiles', profileName, 'cordis.patch.yml'));
62
100
  }
63
101
  } catch { /* ignore */ }
64
102
 
@@ -53,5 +53,5 @@
53
53
  }
54
54
  ],
55
55
  "license": "MIT",
56
- "repository": "https://github.com/heixiua/dsh-fallback-auto-pool-arch"
56
+ "repository": "https://github.com/heixiua/dsh-plugin-litellm-bridge"
57
57
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-litellm-bridge",
3
- "version": "2.1.2",
3
+ "version": "2.1.3",
4
4
  "description": "LiteLLM gateway bridge for DSH: assemble root / coder / research fallback chains from the DSH model pool and hand the order to a LiteLLM gateway that executes retries and fallbacks. The plugin performs no routing itself.",
5
5
  "keywords": [
6
6
  "dsh",
@@ -16,12 +16,12 @@
16
16
  "author": "heixiua",
17
17
  "repository": {
18
18
  "type": "git",
19
- "url": "git+https://github.com/heixiua/dsh-fallback-auto-pool-arch.git"
19
+ "url": "git+https://github.com/heixiua/dsh-plugin-litellm-bridge.git"
20
20
  },
21
21
  "bugs": {
22
- "url": "https://github.com/heixiua/dsh-fallback-auto-pool-arch/issues"
22
+ "url": "https://github.com/heixiua/dsh-plugin-litellm-bridge/issues"
23
23
  },
24
- "homepage": "https://github.com/heixiua/dsh-fallback-auto-pool-arch#readme",
24
+ "homepage": "https://github.com/heixiua/dsh-plugin-litellm-bridge#readme",
25
25
  "main": "./dsh-plugin-litellm-bridge/lib/index.js",
26
26
  "icon": "./dsh-plugin-litellm-bridge/icon.svg",
27
27
  "exports": {