@aipanel/provider-deepseek 1.2.17 → 1.2.19

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.
@@ -17,6 +17,9 @@ export declare class LaunchToken {
17
17
  recordOutput(stream: "stdout" | "stderr", text: string): void;
18
18
  /** 从子进程输出写入已解析的 token(幂等:只接受第一个) */
19
19
  set(token: string): void;
20
+ /** 报错时把 dsh web 启动的原始日志作为一条日志整体输出(幂等:每实例只打一次) */
21
+ private printed;
22
+ private printStartupOutput;
20
23
  /** 已解析的 token(未就绪时 undefined) */
21
24
  get(): string | undefined;
22
25
  /** 等待 token 就绪(默认 20s 超时;未打印则抛错并快速失败,调用方降级处理) */
@@ -13,6 +13,8 @@ class LaunchToken {
13
13
  /** dsh 进程原始输出尾部缓存,超时报错时回填,便于定位真实根因 */
14
14
  __publicField(this, "stdoutTail", "");
15
15
  __publicField(this, "stderrTail", "");
16
+ /** 报错时把 dsh web 启动的原始日志作为一条日志整体输出(幂等:每实例只打一次) */
17
+ __publicField(this, "printed", false);
16
18
  }
17
19
  /** 记录 dsh 进程原始输出(只保留末尾,防止内存无限增长),用于超时报错时辅助诊断 */
18
20
  recordOutput(stream, text) {
@@ -31,6 +33,16 @@ class LaunchToken {
31
33
  }
32
34
  this.waiters = [];
33
35
  }
36
+ printStartupOutput() {
37
+ if (this.printed) return;
38
+ this.printed = true;
39
+ const stdout = this.stdoutTail.trim();
40
+ const stderr = this.stderrTail.trim();
41
+ const lines = ["dsh launch token was not captured; dsh web startup output:"];
42
+ lines.push(stdout || "(no dsh stdout captured)");
43
+ if (stderr) lines.push(`dsh web stderr: ${stderr}`);
44
+ log.warn(lines.join("\n"));
45
+ }
34
46
  /** 已解析的 token(未就绪时 undefined) */
35
47
  get() {
36
48
  return this.token;
@@ -41,16 +53,10 @@ class LaunchToken {
41
53
  if (this.failure) return Promise.reject(this.failure);
42
54
  return new Promise((resolve, reject) => {
43
55
  const timer = setTimeout(() => {
44
- const detail = [
45
- `dsh launch token was not captured from within ${timeoutMs}ms (dsh >= 0.1.2 should print the "dsh web: http://127.0.0.1:<port>/?token=..." URL)`
46
- ];
47
- if (this.stdoutTail.trim()) {
48
- detail.push("-- last dsh stdout --", this.stdoutTail.trim());
49
- }
50
- if (this.stderrTail.trim()) {
51
- detail.push("-- last dsh stderr --", this.stderrTail.trim());
52
- }
53
- const err = new Error(detail.join("\n"));
56
+ this.printStartupOutput();
57
+ const err = new Error(
58
+ `dsh launch token was not captured from stdout within ${timeoutMs}ms (dsh >= 0.1.2 should print the "dsh web: http://127.0.0.1:<port>/?token=..." URL)`
59
+ );
54
60
  this.failure = err;
55
61
  for (const w of this.waiters) {
56
62
  clearTimeout(w.timer);
@@ -12,10 +12,14 @@ export declare function resolveDevDshPackageSource(metaUrl: string, subdir: stri
12
12
  export declare function dshProfileDir(home?: string): string;
13
13
  /** 某 @aipanel/dsh-* 包在 profile 的 node_modules 中是否可解析 */
14
14
  export declare function isDshPackageInstalled(profileDir: string, packageName: string): boolean;
15
+ /** 读取 profile 内已安装的某包版本(可解析不到时返回 null) */
16
+ export declare function readPackageVersion(profileDir: string, packageName: string): string | null;
17
+ /** 读取当前 provider 包版本(运行时源码 lib/es 的上一级即 package.json) */
18
+ export declare function readProviderVersion(metaUrl: string): string | null;
15
19
  /**
16
20
  * 确保某 @aipanel/dsh-* 包已安装且为最新(官方命令 dsh plugin add)。
17
21
  * 每次启动都执行(不跳过已安装):dev 本地目录每次重装保证改代码生效,
18
22
  * 生产 npm 包每次检查 registry 拉取最新版本。安装失败返回 false(不阻塞启动,
19
23
  * 仅对应 overlay 行停用,如失去 chip 高亮 / 审查工具)。
20
24
  */
21
- export declare function ensureDshPackage(profileDir: string, packageName: string, target: string, home?: string): Promise<boolean>;
25
+ export declare function ensureDshPackage(profileDir: string, packageName: string, target: string, home?: string, expectedVersion?: string | null): Promise<boolean>;
package/es/dsh-install.js CHANGED
@@ -25,7 +25,24 @@ function dshProfileDir(home) {
25
25
  function isDshPackageInstalled(profileDir, packageName) {
26
26
  return fs.existsSync(packageJsonIn(profileDir, packageName));
27
27
  }
28
- async function ensureDshPackage(profileDir, packageName, target, home) {
28
+ function readPackageVersion(profileDir, packageName) {
29
+ try {
30
+ const pkg = JSON.parse(fs.readFileSync(packageJsonIn(profileDir, packageName), "utf8"));
31
+ return typeof pkg.version === "string" ? pkg.version : null;
32
+ } catch {
33
+ return null;
34
+ }
35
+ }
36
+ function readProviderVersion(metaUrl) {
37
+ try {
38
+ const pkgPath = path.resolve(path.dirname(fileURLToPath(metaUrl)), "../package.json");
39
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
40
+ return typeof pkg.version === "string" ? pkg.version : null;
41
+ } catch {
42
+ return null;
43
+ }
44
+ }
45
+ async function ensureDshPackage(profileDir, packageName, target, home, expectedVersion) {
29
46
  try {
30
47
  log.debug(`installing ${target} into dsh profile via dsh plugin add`);
31
48
  await execa("dsh", ["plugin", "--profile", "web", "add", target], {
@@ -42,6 +59,16 @@ async function ensureDshPackage(profileDir, packageName, target, home) {
42
59
  });
43
60
  return false;
44
61
  }
62
+ const installed = readPackageVersion(profileDir, packageName);
63
+ if (expectedVersion && installed && installed !== expectedVersion) {
64
+ log.warn(
65
+ `${packageName} version ${installed} is out of sync with provider ${expectedVersion}`,
66
+ {
67
+ profileDir,
68
+ install: `dsh plugin --profile web add ${packageName}@${expectedVersion}`
69
+ }
70
+ );
71
+ }
45
72
  return true;
46
73
  } catch (e) {
47
74
  log.warn(`failed to install ${packageName} via dsh plugin add`, {
@@ -57,5 +84,7 @@ export {
57
84
  dshProfileDir,
58
85
  ensureDshPackage,
59
86
  isDshPackageInstalled,
87
+ readPackageVersion,
88
+ readProviderVersion,
60
89
  resolveDevDshPackageSource
61
90
  };
package/es/provider.js CHANGED
@@ -20,6 +20,7 @@ import {
20
20
  DSH_PLUGIN_PACKAGE,
21
21
  dshProfileDir,
22
22
  ensureDshPackage,
23
+ readProviderVersion,
23
24
  resolveDevDshPackageSource
24
25
  } from "./dsh-install.js";
25
26
  const log = createLogger("DeepSeekWebProvider");
@@ -61,6 +62,7 @@ or run without installing:
61
62
  };
62
63
  }
63
64
  const version = await getDeepSeekVersion();
65
+ log.debug("Detected dsh version", { version: version ?? "unknown" });
64
66
  const compatible = version === null ? true : isDeepSeekVersionAtLeast(version);
65
67
  if (compatible === false) {
66
68
  return {
@@ -86,11 +88,14 @@ Please upgrade:
86
88
  const launchToken = new LaunchToken();
87
89
  this.api.setLaunchTokenSource(() => launchToken.wait());
88
90
  const devClientDir = resolveDevDshPackageSource(import.meta.url, "dsh-client", "lib/client.js");
91
+ const providerVersion = readProviderVersion(import.meta.url);
92
+ const clientTarget = devClientDir ?? (providerVersion ? `${DSH_CLIENT_PACKAGE}@${providerVersion}` : `${DSH_CLIENT_PACKAGE}@latest`);
89
93
  const clientAvailable = await ensureDshPackage(
90
94
  profileDir,
91
95
  DSH_CLIENT_PACKAGE,
92
- devClientDir ?? DSH_CLIENT_PACKAGE,
93
- this.opts.home
96
+ clientTarget,
97
+ this.opts.home,
98
+ providerVersion
94
99
  );
95
100
  if (!clientAvailable) {
96
101
  log.warn("@aipanel/dsh-client unavailable; @ menu chip highlight disabled", {
@@ -98,11 +103,13 @@ Please upgrade:
98
103
  });
99
104
  }
100
105
  const devPluginDir = resolveDevDshPackageSource(import.meta.url, "dsh-plugin", "dist/index.js");
106
+ const pluginTarget = devPluginDir ?? (providerVersion ? `${DSH_PLUGIN_PACKAGE}@${providerVersion}` : `${DSH_PLUGIN_PACKAGE}@latest`);
101
107
  const pluginAvailable = await ensureDshPackage(
102
108
  profileDir,
103
109
  DSH_PLUGIN_PACKAGE,
104
- devPluginDir ?? DSH_PLUGIN_PACKAGE,
105
- this.opts.home
110
+ pluginTarget,
111
+ this.opts.home,
112
+ providerVersion
106
113
  );
107
114
  if (!pluginAvailable) {
108
115
  log.warn("@aipanel/dsh-plugin unavailable; run_diagnostics & settings application disabled", {
@@ -35,6 +35,8 @@ class LaunchToken {
35
35
  /** dsh 进程原始输出尾部缓存,超时报错时回填,便于定位真实根因 */
36
36
  __publicField(this, "stdoutTail", "");
37
37
  __publicField(this, "stderrTail", "");
38
+ /** 报错时把 dsh web 启动的原始日志作为一条日志整体输出(幂等:每实例只打一次) */
39
+ __publicField(this, "printed", false);
38
40
  }
39
41
  /** 记录 dsh 进程原始输出(只保留末尾,防止内存无限增长),用于超时报错时辅助诊断 */
40
42
  recordOutput(stream, text) {
@@ -53,6 +55,16 @@ class LaunchToken {
53
55
  }
54
56
  this.waiters = [];
55
57
  }
58
+ printStartupOutput() {
59
+ if (this.printed) return;
60
+ this.printed = true;
61
+ const stdout = this.stdoutTail.trim();
62
+ const stderr = this.stderrTail.trim();
63
+ const lines = ["dsh launch token was not captured; dsh web startup output:"];
64
+ lines.push(stdout || "(no dsh stdout captured)");
65
+ if (stderr) lines.push(`dsh web stderr: ${stderr}`);
66
+ log.warn(lines.join("\n"));
67
+ }
56
68
  /** 已解析的 token(未就绪时 undefined) */
57
69
  get() {
58
70
  return this.token;
@@ -63,16 +75,10 @@ class LaunchToken {
63
75
  if (this.failure) return Promise.reject(this.failure);
64
76
  return new Promise((resolve, reject) => {
65
77
  const timer = setTimeout(() => {
66
- const detail = [
67
- `dsh launch token was not captured from within ${timeoutMs}ms (dsh >= 0.1.2 should print the "dsh web: http://127.0.0.1:<port>/?token=..." URL)`
68
- ];
69
- if (this.stdoutTail.trim()) {
70
- detail.push("-- last dsh stdout --", this.stdoutTail.trim());
71
- }
72
- if (this.stderrTail.trim()) {
73
- detail.push("-- last dsh stderr --", this.stderrTail.trim());
74
- }
75
- const err = new Error(detail.join("\n"));
78
+ this.printStartupOutput();
79
+ const err = new Error(
80
+ `dsh launch token was not captured from stdout within ${timeoutMs}ms (dsh >= 0.1.2 should print the "dsh web: http://127.0.0.1:<port>/?token=..." URL)`
81
+ );
76
82
  this.failure = err;
77
83
  for (const w of this.waiters) {
78
84
  clearTimeout(w.timer);
@@ -17,6 +17,9 @@ export declare class LaunchToken {
17
17
  recordOutput(stream: "stdout" | "stderr", text: string): void;
18
18
  /** 从子进程输出写入已解析的 token(幂等:只接受第一个) */
19
19
  set(token: string): void;
20
+ /** 报错时把 dsh web 启动的原始日志作为一条日志整体输出(幂等:每实例只打一次) */
21
+ private printed;
22
+ private printStartupOutput;
20
23
  /** 已解析的 token(未就绪时 undefined) */
21
24
  get(): string | undefined;
22
25
  /** 等待 token 就绪(默认 20s 超时;未打印则抛错并快速失败,调用方降级处理) */
@@ -32,6 +32,8 @@ __export(dsh_install_exports, {
32
32
  dshProfileDir: () => dshProfileDir,
33
33
  ensureDshPackage: () => ensureDshPackage,
34
34
  isDshPackageInstalled: () => isDshPackageInstalled,
35
+ readPackageVersion: () => readPackageVersion,
36
+ readProviderVersion: () => readProviderVersion,
35
37
  resolveDevDshPackageSource: () => resolveDevDshPackageSource
36
38
  });
37
39
  module.exports = __toCommonJS(dsh_install_exports);
@@ -62,7 +64,24 @@ function dshProfileDir(home) {
62
64
  function isDshPackageInstalled(profileDir, packageName) {
63
65
  return import_node_fs.default.existsSync(packageJsonIn(profileDir, packageName));
64
66
  }
65
- async function ensureDshPackage(profileDir, packageName, target, home) {
67
+ function readPackageVersion(profileDir, packageName) {
68
+ try {
69
+ const pkg = JSON.parse(import_node_fs.default.readFileSync(packageJsonIn(profileDir, packageName), "utf8"));
70
+ return typeof pkg.version === "string" ? pkg.version : null;
71
+ } catch {
72
+ return null;
73
+ }
74
+ }
75
+ function readProviderVersion(metaUrl) {
76
+ try {
77
+ const pkgPath = import_node_path.default.resolve(import_node_path.default.dirname((0, import_node_url.fileURLToPath)(metaUrl)), "../package.json");
78
+ const pkg = JSON.parse(import_node_fs.default.readFileSync(pkgPath, "utf8"));
79
+ return typeof pkg.version === "string" ? pkg.version : null;
80
+ } catch {
81
+ return null;
82
+ }
83
+ }
84
+ async function ensureDshPackage(profileDir, packageName, target, home, expectedVersion) {
66
85
  try {
67
86
  log.debug(`installing ${target} into dsh profile via dsh plugin add`);
68
87
  await (0, import_execa.execa)("dsh", ["plugin", "--profile", "web", "add", target], {
@@ -79,6 +98,16 @@ async function ensureDshPackage(profileDir, packageName, target, home) {
79
98
  });
80
99
  return false;
81
100
  }
101
+ const installed = readPackageVersion(profileDir, packageName);
102
+ if (expectedVersion && installed && installed !== expectedVersion) {
103
+ log.warn(
104
+ `${packageName} version ${installed} is out of sync with provider ${expectedVersion}`,
105
+ {
106
+ profileDir,
107
+ install: `dsh plugin --profile web add ${packageName}@${expectedVersion}`
108
+ }
109
+ );
110
+ }
82
111
  return true;
83
112
  } catch (e) {
84
113
  log.warn(`failed to install ${packageName} via dsh plugin add`, {
@@ -95,5 +124,7 @@ async function ensureDshPackage(profileDir, packageName, target, home) {
95
124
  dshProfileDir,
96
125
  ensureDshPackage,
97
126
  isDshPackageInstalled,
127
+ readPackageVersion,
128
+ readProviderVersion,
98
129
  resolveDevDshPackageSource
99
130
  });
@@ -12,10 +12,14 @@ export declare function resolveDevDshPackageSource(metaUrl: string, subdir: stri
12
12
  export declare function dshProfileDir(home?: string): string;
13
13
  /** 某 @aipanel/dsh-* 包在 profile 的 node_modules 中是否可解析 */
14
14
  export declare function isDshPackageInstalled(profileDir: string, packageName: string): boolean;
15
+ /** 读取 profile 内已安装的某包版本(可解析不到时返回 null) */
16
+ export declare function readPackageVersion(profileDir: string, packageName: string): string | null;
17
+ /** 读取当前 provider 包版本(运行时源码 lib/es 的上一级即 package.json) */
18
+ export declare function readProviderVersion(metaUrl: string): string | null;
15
19
  /**
16
20
  * 确保某 @aipanel/dsh-* 包已安装且为最新(官方命令 dsh plugin add)。
17
21
  * 每次启动都执行(不跳过已安装):dev 本地目录每次重装保证改代码生效,
18
22
  * 生产 npm 包每次检查 registry 拉取最新版本。安装失败返回 false(不阻塞启动,
19
23
  * 仅对应 overlay 行停用,如失去 chip 高亮 / 审查工具)。
20
24
  */
21
- export declare function ensureDshPackage(profileDir: string, packageName: string, target: string, home?: string): Promise<boolean>;
25
+ export declare function ensureDshPackage(profileDir: string, packageName: string, target: string, home?: string, expectedVersion?: string | null): Promise<boolean>;
package/lib/provider.cjs CHANGED
@@ -71,6 +71,7 @@ or run without installing:
71
71
  };
72
72
  }
73
73
  const version = await (0, import_system.getDeepSeekVersion)();
74
+ log.debug("Detected dsh version", { version: version ?? "unknown" });
74
75
  const compatible = version === null ? true : (0, import_system.isDeepSeekVersionAtLeast)(version);
75
76
  if (compatible === false) {
76
77
  return {
@@ -96,11 +97,14 @@ Please upgrade:
96
97
  const launchToken = new import_deepseek_web.LaunchToken();
97
98
  this.api.setLaunchTokenSource(() => launchToken.wait());
98
99
  const devClientDir = (0, import_dsh_install.resolveDevDshPackageSource)(import_meta.url, "dsh-client", "lib/client.js");
100
+ const providerVersion = (0, import_dsh_install.readProviderVersion)(import_meta.url);
101
+ const clientTarget = devClientDir ?? (providerVersion ? `${import_dsh_install.DSH_CLIENT_PACKAGE}@${providerVersion}` : `${import_dsh_install.DSH_CLIENT_PACKAGE}@latest`);
99
102
  const clientAvailable = await (0, import_dsh_install.ensureDshPackage)(
100
103
  profileDir,
101
104
  import_dsh_install.DSH_CLIENT_PACKAGE,
102
- devClientDir ?? import_dsh_install.DSH_CLIENT_PACKAGE,
103
- this.opts.home
105
+ clientTarget,
106
+ this.opts.home,
107
+ providerVersion
104
108
  );
105
109
  if (!clientAvailable) {
106
110
  log.warn("@aipanel/dsh-client unavailable; @ menu chip highlight disabled", {
@@ -108,11 +112,13 @@ Please upgrade:
108
112
  });
109
113
  }
110
114
  const devPluginDir = (0, import_dsh_install.resolveDevDshPackageSource)(import_meta.url, "dsh-plugin", "dist/index.js");
115
+ const pluginTarget = devPluginDir ?? (providerVersion ? `${import_dsh_install.DSH_PLUGIN_PACKAGE}@${providerVersion}` : `${import_dsh_install.DSH_PLUGIN_PACKAGE}@latest`);
111
116
  const pluginAvailable = await (0, import_dsh_install.ensureDshPackage)(
112
117
  profileDir,
113
118
  import_dsh_install.DSH_PLUGIN_PACKAGE,
114
- devPluginDir ?? import_dsh_install.DSH_PLUGIN_PACKAGE,
115
- this.opts.home
119
+ pluginTarget,
120
+ this.opts.home,
121
+ providerVersion
116
122
  );
117
123
  if (!pluginAvailable) {
118
124
  log.warn("@aipanel/dsh-plugin unavailable; run_diagnostics & settings application disabled", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aipanel/provider-deepseek",
3
- "version": "1.2.17",
3
+ "version": "1.2.19",
4
4
  "type": "module",
5
5
  "main": "lib/index.cjs",
6
6
  "module": "es/index.js",
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "execa": "^9.6.1",
25
- "@aipanel/core": "1.2.17"
25
+ "@aipanel/core": "1.2.19"
26
26
  },
27
27
  "devDependencies": {
28
28
  "esbuild": "^0.25.0"