@dsh-plus/llm-pi 0.1.36 → 0.1.37

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/index.js CHANGED
@@ -1809,9 +1809,9 @@ function authContextFrom(ctx) {
1809
1809
  * dsh-llm-pi-ai / dsh-llm / pi-ai 之上,从而 dsh 升级即自动跟随上游。
1810
1810
  *
1811
1811
  * 解析策略(全部模块同源地整体成功或整体回退,杜绝跨源混用):
1812
- * 1. dsh-tree:从 process.argv[1](systemd/CLI 启动的 dsh 即 bin.js shim,
1813
- * realpath 后落在 dsh 安装树内)向上找到同时含有
1814
- * node_modules/@deepseek-ai/dsh-llm-pi-ai 与 node_modules/@earendil-works/pi-ai
1812
+ * 1. dsh-tree:锚点链 = profileContext.installAnchor(CLI/桌面端同一事实,
1813
+ * 桌面端 Electron 下 argv[1] 探测走不通)→ realpath(argv[1]) 向上找到同时
1814
+ * 含 node_modules/@deepseek-ai/dsh-llm-pi-ai 与 node_modules/@earendil-works/pi-ai
1815
1815
  * 的目录,按文件路径动态 import——与 dsh 官方插件共享同一模块实例;
1816
1816
  * 2. vendored:回退到本插件 dependencies 里的固定版本副本(裸 import)。
1817
1817
  *
@@ -2064,12 +2064,20 @@ function loadVendoredKit() {
2064
2064
  assertKitShape(kit, "vendored");
2065
2065
  return kit;
2066
2066
  }
2067
- /** 定位 dsh 安装树根:realpath(argv[1]) 向上查找;argv 异常时返回 undefined。 */
2068
- function dshTreeAnchor() {
2069
- const entry = process.argv[1];
2070
- if (entry === void 0) return void 0;
2067
+ /**
2068
+ * 定位 dsh 安装树根:优先 `profileContext.installAnchor`(CLI 与桌面端同一
2069
+ * 事实——桌面端 Electron 启动时 argv[1] 是 Electron 自身、走不通 argv 探测,
2070
+ * 锚点是唯一可靠来源),其次 realpath(argv[1]) 向上查找;均失败返回 undefined。
2071
+ * argvEntry 参数仅测试注入(缺省 process.argv[1])。
2072
+ */
2073
+ function dshTreeAnchor(installAnchor, argvEntry = process.argv[1]) {
2074
+ if (installAnchor !== void 0 && installAnchor.length > 0) {
2075
+ const anchored = findDshTreeRoot(dirname(installAnchor));
2076
+ if (anchored !== void 0) return anchored;
2077
+ }
2078
+ if (argvEntry === void 0) return void 0;
2071
2079
  try {
2072
- return findDshTreeRoot(dirname(realpathSync(entry)));
2080
+ return findDshTreeRoot(dirname(realpathSync(argvEntry)));
2073
2081
  } catch {
2074
2082
  return;
2075
2083
  }
@@ -2078,10 +2086,11 @@ function dshTreeAnchor() {
2078
2086
  * 解析运行时套件:优先 dsh 安装树(自动跟随上游),失败回退 vendored 副本;
2079
2087
  * 两者都过不了形状自检时抛错(调用方应记日志并放弃注册 route)。
2080
2088
  * 返回的 diagnostics 记录回退原因,供配置卡片与日志展示。
2089
+ * @param installAnchor profile 的 dsh 安装锚点(`ctx.profileContext.installAnchor`)。
2081
2090
  */
2082
- async function resolveDshKit() {
2091
+ async function resolveDshKit(installAnchor) {
2083
2092
  const diagnostics = [];
2084
- const anchor = dshTreeAnchor();
2093
+ const anchor = dshTreeAnchor(installAnchor);
2085
2094
  if (anchor !== void 0) {
2086
2095
  const treePkgDir = join(anchor, "node_modules", "@deepseek-ai", "dsh-llm-pi-ai");
2087
2096
  try {
@@ -2108,7 +2117,7 @@ async function resolveDshKit() {
2108
2117
  } catch (error) {
2109
2118
  diagnostics.push(`dsh 安装树套件不可用(${anchor}):${error instanceof Error ? error.message : String(error)};回退 vendored 副本`);
2110
2119
  }
2111
- } else diagnostics.push("未能从 process.argv[1] 定位 dsh 安装树;回退 vendored 副本");
2120
+ } else diagnostics.push("未能从 profileContext.installAnchor / process.argv[1] 定位 dsh 安装树;回退 vendored 副本");
2112
2121
  const kit = loadVendoredKit();
2113
2122
  if (kit.deepseek === void 0) diagnostics.push("vendored 副本的 dsh-llm-deepseek 形状不兼容;adapter: deepseek 的 route 不可用");
2114
2123
  return {
@@ -2141,7 +2150,7 @@ function makeResolveApiKey(ctx, kit) {
2141
2150
  async function startRuntime(ctx, rawConfig) {
2142
2151
  const logger = ctx.logger("llm-pi");
2143
2152
  const fields = hasVolatileRefs(rawConfig) ? rawConfig : Config(rawConfig ?? {});
2144
- const { kit, diagnostics } = await resolveDshKit();
2153
+ const { kit, diagnostics } = await resolveDshKit(ctx.get("profileContext")?.installAnchor);
2145
2154
  for (const line of diagnostics) logger.warn(line);
2146
2155
  logger.info(`运行时套件来源:${kit.source}`);
2147
2156
  let snapshot = unwrapVolatile(fields);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-plus/llm-pi",
3
- "version": "0.1.36",
3
+ "version": "0.1.37",
4
4
  "description": "dsh-plus service+ui plugin: 基于 PiAiAdapter 的自定义 LLM 路由(全量 compat、模型继承、models.dev 目录兜底)",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "https-proxy-agent": "^9.1.0",
35
- "@dsh-plus/shared": "0.1.25"
35
+ "@dsh-plus/shared": "0.1.27"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@deepseek-ai/cordis": "^4.0.4",
@@ -52,6 +52,7 @@
52
52
  "devDependencies": {
53
53
  "@deepseek-ai/cordis": "4.0.4",
54
54
  "@deepseek-ai/dsh-anonymous-user-id": "0.2.0-rc.1",
55
+ "@deepseek-ai/dsh-app-boot": "0.2.0-rc.1",
55
56
  "@deepseek-ai/dsh-atomic-write": "0.2.0-rc.1",
56
57
  "@deepseek-ai/dsh-attachment": "0.2.0-rc.1",
57
58
  "@deepseek-ai/dsh-credentials": "0.2.0-rc.1",
@@ -3,9 +3,9 @@
3
3
  * dsh-llm-pi-ai / dsh-llm / pi-ai 之上,从而 dsh 升级即自动跟随上游。
4
4
  *
5
5
  * 解析策略(全部模块同源地整体成功或整体回退,杜绝跨源混用):
6
- * 1. dsh-tree:从 process.argv[1](systemd/CLI 启动的 dsh 即 bin.js shim,
7
- * realpath 后落在 dsh 安装树内)向上找到同时含有
8
- * node_modules/@deepseek-ai/dsh-llm-pi-ai 与 node_modules/@earendil-works/pi-ai
6
+ * 1. dsh-tree:锚点链 = profileContext.installAnchor(CLI/桌面端同一事实,
7
+ * 桌面端 Electron 下 argv[1] 探测走不通)→ realpath(argv[1]) 向上找到同时
8
+ * 含 node_modules/@deepseek-ai/dsh-llm-pi-ai 与 node_modules/@earendil-works/pi-ai
9
9
  * 的目录,按文件路径动态 import——与 dsh 官方插件共享同一模块实例;
10
10
  * 2. vendored:回退到本插件 dependencies 里的固定版本副本(裸 import)。
11
11
  *
@@ -450,12 +450,23 @@ export function loadVendoredKit(): DshKit {
450
450
  return kit
451
451
  }
452
452
 
453
- /** 定位 dsh 安装树根:realpath(argv[1]) 向上查找;argv 异常时返回 undefined。 */
454
- function dshTreeAnchor(): string | undefined {
455
- const entry = process.argv[1]
456
- if (entry === undefined) return undefined
453
+ /**
454
+ * 定位 dsh 安装树根:优先 `profileContext.installAnchor`(CLI 与桌面端同一
455
+ * 事实——桌面端 Electron 启动时 argv[1] 是 Electron 自身、走不通 argv 探测,
456
+ * 锚点是唯一可靠来源),其次 realpath(argv[1]) 向上查找;均失败返回 undefined。
457
+ * argvEntry 参数仅测试注入(缺省 process.argv[1])。
458
+ */
459
+ export function dshTreeAnchor(
460
+ installAnchor?: string | undefined,
461
+ argvEntry: string | undefined = process.argv[1],
462
+ ): string | undefined {
463
+ if (installAnchor !== undefined && installAnchor.length > 0) {
464
+ const anchored = findDshTreeRoot(dirname(installAnchor))
465
+ if (anchored !== undefined) return anchored
466
+ }
467
+ if (argvEntry === undefined) return undefined
457
468
  try {
458
- return findDshTreeRoot(dirname(realpathSync(entry)))
469
+ return findDshTreeRoot(dirname(realpathSync(argvEntry)))
459
470
  } catch {
460
471
  return undefined
461
472
  }
@@ -465,13 +476,14 @@ function dshTreeAnchor(): string | undefined {
465
476
  * 解析运行时套件:优先 dsh 安装树(自动跟随上游),失败回退 vendored 副本;
466
477
  * 两者都过不了形状自检时抛错(调用方应记日志并放弃注册 route)。
467
478
  * 返回的 diagnostics 记录回退原因,供配置卡片与日志展示。
479
+ * @param installAnchor profile 的 dsh 安装锚点(`ctx.profileContext.installAnchor`)。
468
480
  */
469
- export async function resolveDshKit(): Promise<{
481
+ export async function resolveDshKit(installAnchor?: string | undefined): Promise<{
470
482
  kit: DshKit
471
483
  diagnostics: string[]
472
484
  }> {
473
485
  const diagnostics: string[] = []
474
- const anchor = dshTreeAnchor()
486
+ const anchor = dshTreeAnchor(installAnchor)
475
487
  if (anchor !== undefined) {
476
488
  const treePkgDir = join(anchor, 'node_modules', '@deepseek-ai', 'dsh-llm-pi-ai')
477
489
  try {
@@ -508,7 +520,9 @@ export async function resolveDshKit(): Promise<{
508
520
  )
509
521
  }
510
522
  } else {
511
- diagnostics.push('未能从 process.argv[1] 定位 dsh 安装树;回退 vendored 副本')
523
+ diagnostics.push(
524
+ '未能从 profileContext.installAnchor / process.argv[1] 定位 dsh 安装树;回退 vendored 副本',
525
+ )
512
526
  }
513
527
  const kit = loadVendoredKit()
514
528
  if (kit.deepseek === undefined) {
package/src/service.ts CHANGED
@@ -11,6 +11,9 @@
11
11
  * @module llm-pi/service
12
12
  */
13
13
  import type { Context } from '@deepseek-ai/cordis'
14
+ // 平台类型面:profileContext.installAnchor(dsh 安装锚点,桌面端关键来源)。
15
+ // 纯类型导入,按开发规范仅需 devDeps。
16
+ import type {} from '@deepseek-ai/dsh-app-boot'
14
17
  import type { CredentialRef } from '@deepseek-ai/dsh-credentials'
15
18
  import { launchEnvironmentOf } from '@deepseek-ai/dsh-launch-environment'
16
19
  import type { DirectoryRegistrationHandle } from '@deepseek-ai/dsh-llm'
@@ -90,7 +93,7 @@ export async function startRuntime(
90
93
  const fields: LlmPiConfigFields = hasVolatileRefs(rawConfig)
91
94
  ? (rawConfig as LlmPiConfigFields)
92
95
  : Config((rawConfig ?? {}) as LlmPiConfigInput)
93
- const { kit, diagnostics } = await resolveDshKit()
96
+ const { kit, diagnostics } = await resolveDshKit(ctx.get('profileContext')?.installAnchor)
94
97
  for (const line of diagnostics) logger.warn(line)
95
98
  logger.info(`运行时套件来源:${kit.source}`)
96
99