@aipanel/provider-deepseek 1.3.9 → 1.3.11
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/es/constants.d.ts +2 -0
- package/es/constants.js +5 -1
- package/es/deepseek-web.d.ts +9 -0
- package/es/deepseek-web.js +17 -2
- package/es/dsh-install.d.ts +3 -3
- package/es/dsh-install.js +6 -6
- package/es/index.d.ts +1 -1
- package/es/index.js +3 -1
- package/es/profile-check.d.ts +19 -0
- package/es/profile-check.js +41 -0
- package/es/provider.js +16 -3
- package/es/types.d.ts +10 -1
- package/lib/constants.cjs +6 -1
- package/lib/constants.d.ts +2 -0
- package/lib/deepseek-web.cjs +17 -2
- package/lib/deepseek-web.d.ts +9 -0
- package/lib/dsh-install.cjs +6 -6
- package/lib/dsh-install.d.ts +3 -3
- package/lib/index.cjs +2 -0
- package/lib/index.d.ts +1 -1
- package/lib/profile-check.cjs +77 -0
- package/lib/profile-check.d.ts +19 -0
- package/lib/provider.cjs +19 -6
- package/lib/types.d.ts +10 -1
- package/package.json +8 -8
package/es/constants.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export declare const DSH_REMOTE_MUX_PATH = "/api/remote.mux";
|
|
|
17
17
|
export declare const DSH_LOOPBACK_HOST = "127.0.0.1";
|
|
18
18
|
/** dsh web 默认端口(未显式指定时) */
|
|
19
19
|
export declare const DSH_DEFAULT_PORT = 3080;
|
|
20
|
+
/** dsh 默认 profile($DSH_HOME/profiles/<name>);用户可经 providerOptions.profile 覆盖 */
|
|
21
|
+
export declare const DSH_DEFAULT_PROFILE = "web";
|
|
20
22
|
/** ==================== Provider 专属配置默认值 ==================== */
|
|
21
23
|
/**
|
|
22
24
|
* Provider 选项兜底值。
|
package/es/constants.js
CHANGED
|
@@ -2,11 +2,15 @@ const DSH_API_BASE = "/api";
|
|
|
2
2
|
const DSH_REMOTE_MUX_PATH = "/api/remote.mux";
|
|
3
3
|
const DSH_LOOPBACK_HOST = "127.0.0.1";
|
|
4
4
|
const DSH_DEFAULT_PORT = 3080;
|
|
5
|
-
const
|
|
5
|
+
const DSH_DEFAULT_PROFILE = "web";
|
|
6
|
+
const DEFAULT_DEEPSEEK_PROVIDER_OPTIONS = {
|
|
7
|
+
profile: DSH_DEFAULT_PROFILE
|
|
8
|
+
};
|
|
6
9
|
export {
|
|
7
10
|
DEFAULT_DEEPSEEK_PROVIDER_OPTIONS,
|
|
8
11
|
DSH_API_BASE,
|
|
9
12
|
DSH_DEFAULT_PORT,
|
|
13
|
+
DSH_DEFAULT_PROFILE,
|
|
10
14
|
DSH_LOOPBACK_HOST,
|
|
11
15
|
DSH_REMOTE_MUX_PATH
|
|
12
16
|
};
|
package/es/deepseek-web.d.ts
CHANGED
|
@@ -33,6 +33,13 @@ export declare class LaunchToken {
|
|
|
33
33
|
fail(err: Error): void;
|
|
34
34
|
/** 窗口到点:输出 dsh web 启动原始日志辅助诊断,再按未捕获 token 判定本次启动失败 */
|
|
35
35
|
private expire;
|
|
36
|
+
/**
|
|
37
|
+
* 附上"这次起的是哪个 profile"的上下文(provider 起进程前调用)。
|
|
38
|
+
* 只加在这里、不进 printStartupOutput:超时的那条错误要能自己说清 profile 与它的 bundle 列表,
|
|
39
|
+
* 否则症状永远只是"启动超时"(见 profile-check 的注释)。
|
|
40
|
+
*/
|
|
41
|
+
attachContext(provider: () => string): void;
|
|
42
|
+
private context?;
|
|
36
43
|
/** 报错时把 dsh web 启动的原始日志作为一条日志整体输出(幂等:每实例只打一次) */
|
|
37
44
|
private printed;
|
|
38
45
|
private printStartupOutput;
|
|
@@ -48,6 +55,8 @@ export interface DeepSeekWebOptions {
|
|
|
48
55
|
hostname: string;
|
|
49
56
|
/** 工作目录 */
|
|
50
57
|
cwd: string;
|
|
58
|
+
/** dsh profile 名($DSH_HOME/profiles/<name>),默认 "web" */
|
|
59
|
+
profile?: string;
|
|
51
60
|
/** cordis overlay 文件路径(--patch 注入 MCP client / aipanel 插件) */
|
|
52
61
|
patchPath?: string;
|
|
53
62
|
/** dsh 数据目录(透传 DSH_HOME;缺省跟随 $DSH_HOME / ~/.dsh) */
|
package/es/deepseek-web.js
CHANGED
|
@@ -3,6 +3,7 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
|
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
import { execa } from "execa";
|
|
5
5
|
import { createLogger, getProcessLogBuffer } from "@aipanel/core/node";
|
|
6
|
+
import { DSH_DEFAULT_PROFILE } from "./constants.js";
|
|
6
7
|
const log = createLogger("DeepSeekWeb");
|
|
7
8
|
class LaunchToken {
|
|
8
9
|
/** @param timeoutMs token 等待窗口(自 arm 起算,默认 20s) */
|
|
@@ -18,6 +19,7 @@ class LaunchToken {
|
|
|
18
19
|
/** dsh 进程是否已 spawn:token 只可能在 spawn 后打印,超时窗口自 arm 起算 */
|
|
19
20
|
__publicField(this, "spawned", false);
|
|
20
21
|
__publicField(this, "windowTimer");
|
|
22
|
+
__publicField(this, "context");
|
|
21
23
|
/** 报错时把 dsh web 启动的原始日志作为一条日志整体输出(幂等:每实例只打一次) */
|
|
22
24
|
__publicField(this, "printed", false);
|
|
23
25
|
}
|
|
@@ -62,12 +64,24 @@ class LaunchToken {
|
|
|
62
64
|
/** 窗口到点:输出 dsh web 启动原始日志辅助诊断,再按未捕获 token 判定本次启动失败 */
|
|
63
65
|
expire() {
|
|
64
66
|
this.printStartupOutput();
|
|
67
|
+
const context = this.context?.();
|
|
68
|
+
const base = `dsh launch token was not captured from stdout within ${this.timeoutMs}ms (dsh >= 0.1.2 should print the "dsh web: http://127.0.0.1:<port>/?token=..." URL)`;
|
|
65
69
|
this.fail(
|
|
66
70
|
new Error(
|
|
67
|
-
|
|
71
|
+
context === void 0 || context.trim() === "" ? base : `${base}
|
|
72
|
+
${context}
|
|
73
|
+
\uFF08\u8FD9\u4E2A profile \u8D77\u4E0D\u4E86 Web UI \u65F6\u5C31\u662F\u8FD9\u4E2A\u75C7\u72B6\uFF1A\u5148\u786E\u8BA4\u5B83\u5EFA\u597D\u4E86\uFF09`
|
|
68
74
|
)
|
|
69
75
|
);
|
|
70
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* 附上"这次起的是哪个 profile"的上下文(provider 起进程前调用)。
|
|
79
|
+
* 只加在这里、不进 printStartupOutput:超时的那条错误要能自己说清 profile 与它的 bundle 列表,
|
|
80
|
+
* 否则症状永远只是"启动超时"(见 profile-check 的注释)。
|
|
81
|
+
*/
|
|
82
|
+
attachContext(provider) {
|
|
83
|
+
this.context = provider;
|
|
84
|
+
}
|
|
71
85
|
printStartupOutput() {
|
|
72
86
|
if (this.printed) return;
|
|
73
87
|
this.printed = true;
|
|
@@ -93,7 +107,8 @@ class LaunchToken {
|
|
|
93
107
|
}
|
|
94
108
|
function startDeepSeekWeb(options) {
|
|
95
109
|
const { port, hostname, cwd, patchPath, home, verbose, launchToken } = options;
|
|
96
|
-
const
|
|
110
|
+
const profile = options.profile ?? DSH_DEFAULT_PROFILE;
|
|
111
|
+
const args = ["--profile", profile];
|
|
97
112
|
if (patchPath) {
|
|
98
113
|
args.push("--patch", patchPath);
|
|
99
114
|
}
|
package/es/dsh-install.d.ts
CHANGED
|
@@ -8,8 +8,8 @@ export declare const DSH_PLUGIN_PACKAGE = "@aipanel/dsh-plugin";
|
|
|
8
8
|
* @param distRel 产物相对路径(client 为 "lib/client.js",plugin 为 "dist/index.js")
|
|
9
9
|
*/
|
|
10
10
|
export declare function resolveDevDshPackageSource(metaUrl: string, subdir: string, distRel: string): string | null;
|
|
11
|
-
/** dsh
|
|
12
|
-
export declare function dshProfileDir(home?: string): string;
|
|
11
|
+
/** dsh profile 目录($DSH_HOME/profiles/<profile>);home 未指定时回退 $DSH_HOME / ~/.dsh */
|
|
12
|
+
export declare function dshProfileDir(profile: string, home?: string): string;
|
|
13
13
|
/** 某 @aipanel/dsh-* 包在 profile 的 node_modules 中是否可解析 */
|
|
14
14
|
export declare function isDshPackageInstalled(profileDir: string, packageName: string): boolean;
|
|
15
15
|
/** 读取 profile 内已安装的某包版本(可解析不到时返回 null) */
|
|
@@ -22,4 +22,4 @@ export declare function readProviderVersion(metaUrl: string): string | null;
|
|
|
22
22
|
* 生产 npm 包每次检查 registry 拉取最新版本。安装失败返回 false(不阻塞启动,
|
|
23
23
|
* 仅对应 overlay 行停用,如失去 chip 高亮 / 审查工具)。
|
|
24
24
|
*/
|
|
25
|
-
export declare function ensureDshPackage(profileDir: string, packageName: string, target: string, home?: string, expectedVersion?: string | null): Promise<boolean>;
|
|
25
|
+
export declare function ensureDshPackage(profileDir: string, packageName: string, target: string, profile: string, home?: string, expectedVersion?: string | null): Promise<boolean>;
|
package/es/dsh-install.js
CHANGED
|
@@ -18,9 +18,9 @@ function resolveDevDshPackageSource(metaUrl, subdir, distRel) {
|
|
|
18
18
|
}
|
|
19
19
|
return null;
|
|
20
20
|
}
|
|
21
|
-
function dshProfileDir(home) {
|
|
21
|
+
function dshProfileDir(profile, home) {
|
|
22
22
|
const resolved = home || process.env.DSH_HOME || path.join(os.homedir(), ".dsh");
|
|
23
|
-
return path.join(resolved, "profiles",
|
|
23
|
+
return path.join(resolved, "profiles", profile);
|
|
24
24
|
}
|
|
25
25
|
function isDshPackageInstalled(profileDir, packageName) {
|
|
26
26
|
return fs.existsSync(packageJsonIn(profileDir, packageName));
|
|
@@ -42,10 +42,10 @@ function readProviderVersion(metaUrl) {
|
|
|
42
42
|
return null;
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
async function ensureDshPackage(profileDir, packageName, target, home, expectedVersion) {
|
|
45
|
+
async function ensureDshPackage(profileDir, packageName, target, profile, home, expectedVersion) {
|
|
46
46
|
try {
|
|
47
|
-
log.debug(`installing ${target} into dsh profile via dsh plugin add
|
|
48
|
-
await execa("dsh", ["plugin", "--profile",
|
|
47
|
+
log.debug(`installing ${target} into dsh profile via dsh plugin add`, { profile });
|
|
48
|
+
await execa("dsh", ["plugin", "--profile", profile, "add", target], {
|
|
49
49
|
reject: true,
|
|
50
50
|
env: {
|
|
51
51
|
...process.env,
|
|
@@ -64,7 +64,7 @@ async function ensureDshPackage(profileDir, packageName, target, home, expectedV
|
|
|
64
64
|
`${packageName} version ${installed} is out of sync with provider ${expectedVersion}`,
|
|
65
65
|
{
|
|
66
66
|
profileDir,
|
|
67
|
-
install: `dsh plugin --profile
|
|
67
|
+
install: `dsh plugin --profile ${profile} add ${packageName}@${expectedVersion}`
|
|
68
68
|
}
|
|
69
69
|
);
|
|
70
70
|
}
|
package/es/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export type { DeepSeekWebProviderConfig, DeepSeekWebProviderDeps } from "./provi
|
|
|
11
11
|
export { startDeepSeekWeb, type DeepSeekWebOptions } from "./deepseek-web";
|
|
12
12
|
export { buildDshOverlay, writeDshOverlay } from "./profile";
|
|
13
13
|
export { checkDeepSeekInstalled, getDeepSeekVersion, killOrphanDeepSeekProcesses } from "./system";
|
|
14
|
-
export { DEFAULT_DEEPSEEK_PROVIDER_OPTIONS, DSH_LOOPBACK_HOST, DSH_DEFAULT_PORT, } from "./constants";
|
|
14
|
+
export { DEFAULT_DEEPSEEK_PROVIDER_OPTIONS, DSH_LOOPBACK_HOST, DSH_DEFAULT_PORT, DSH_DEFAULT_PROFILE, } from "./constants";
|
|
15
15
|
export type { DeepSeekProviderOptions, DeepSeekPermissionPreset, DeepSeekBusyEnter } from "./types";
|
|
16
16
|
export type { ClientRequest, RpcMessage, ServerResponse } from "@deepseek-ai/dsh-client-connection";
|
|
17
17
|
export type { SessionCreateValue, SessionListValue, SessionSummary, } from "@deepseek-ai/dsh-api-session-controller/types";
|
package/es/index.js
CHANGED
|
@@ -14,11 +14,13 @@ import { checkDeepSeekInstalled, getDeepSeekVersion, killOrphanDeepSeekProcesses
|
|
|
14
14
|
import {
|
|
15
15
|
DEFAULT_DEEPSEEK_PROVIDER_OPTIONS,
|
|
16
16
|
DSH_LOOPBACK_HOST as DSH_LOOPBACK_HOST2,
|
|
17
|
-
DSH_DEFAULT_PORT
|
|
17
|
+
DSH_DEFAULT_PORT,
|
|
18
|
+
DSH_DEFAULT_PROFILE
|
|
18
19
|
} from "./constants.js";
|
|
19
20
|
export {
|
|
20
21
|
DEFAULT_DEEPSEEK_PROVIDER_OPTIONS,
|
|
21
22
|
DSH_DEFAULT_PORT,
|
|
23
|
+
DSH_DEFAULT_PROFILE,
|
|
22
24
|
DSH_LOOPBACK_HOST2 as DSH_LOOPBACK_HOST,
|
|
23
25
|
DeepSeekAPI,
|
|
24
26
|
buildDshOverlay,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** dsh 的 Web 应用 bundle(`dsh web` 的 profile 必有;纯终端类 profile 没有) */
|
|
2
|
+
export declare const DSH_WEB_APP_BUNDLE = "@deepseek-ai/dsh-web-app";
|
|
3
|
+
export type DshProfileProblem = "missing" | "no-web-app";
|
|
4
|
+
export interface DshProfileInspection {
|
|
5
|
+
/** 这个 profile 现在能不能起 Web UI */
|
|
6
|
+
readonly ok: boolean;
|
|
7
|
+
/** 不能时是哪一类问题;能时为 null */
|
|
8
|
+
readonly problem: DshProfileProblem | null;
|
|
9
|
+
/** profile 声明的 bundle 列表(读不到时为空数组) */
|
|
10
|
+
readonly bundles: readonly string[];
|
|
11
|
+
/** profile 清单文件路径(报错信息里给绝对路径,方便直接去看) */
|
|
12
|
+
readonly manifest: string;
|
|
13
|
+
}
|
|
14
|
+
/** 读 profile 清单并判断它是否具备启动 Web UI 的条件 */
|
|
15
|
+
export declare function inspectDshProfile(profileDir: string): DshProfileInspection;
|
|
16
|
+
/** 预检没过时给用户的说明(通用措辞:说清是什么、去哪看、怎么修) */
|
|
17
|
+
export declare function profileProblemText(inspection: DshProfileInspection, profileDir: string, profile: string): string;
|
|
18
|
+
/** 启动超时诊断用的一行上下文:profile 在哪、声明了哪些 bundle */
|
|
19
|
+
export declare function describeDshProfile(profileDir: string, profile: string): string;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const DSH_WEB_APP_BUNDLE = "@deepseek-ai/dsh-web-app";
|
|
4
|
+
function inspectDshProfile(profileDir) {
|
|
5
|
+
const manifest = path.join(profileDir, "package.json");
|
|
6
|
+
let parsed;
|
|
7
|
+
try {
|
|
8
|
+
parsed = JSON.parse(fs.readFileSync(manifest, "utf8"));
|
|
9
|
+
} catch {
|
|
10
|
+
return { ok: false, problem: "missing", bundles: [], manifest };
|
|
11
|
+
}
|
|
12
|
+
const declared = parsed?.dsh?.profile?.bundles;
|
|
13
|
+
const bundles = Array.isArray(declared) ? declared.filter((one) => typeof one === "string") : [];
|
|
14
|
+
if (!bundles.includes(DSH_WEB_APP_BUNDLE)) {
|
|
15
|
+
return { ok: false, problem: "no-web-app", bundles, manifest };
|
|
16
|
+
}
|
|
17
|
+
return { ok: true, problem: null, bundles, manifest };
|
|
18
|
+
}
|
|
19
|
+
function profileProblemText(inspection, profileDir, profile) {
|
|
20
|
+
const head = inspection.problem === "missing" ? `dsh profile "${profile}" \u8FD8\u4E0D\u5B58\u5728\uFF08\u627E\u4E0D\u5230 ${inspection.manifest}\uFF09` : `dsh profile "${profile}" \u91CC\u6CA1\u6709 Web \u5E94\u7528 bundle\uFF08${DSH_WEB_APP_BUNDLE}\uFF09`;
|
|
21
|
+
const bundles = inspection.bundles.length === 0 ? "\uFF08\u8BFB\u4E0D\u5230 bundle \u5217\u8868\uFF09" : `\u73B0\u6709 bundles\uFF1A${inspection.bundles.join("\u3001")}`;
|
|
22
|
+
return [
|
|
23
|
+
`${head}\uFF1A${profileDir}`,
|
|
24
|
+
` ${bundles}`,
|
|
25
|
+
" dsh \u5728 profile \u7F3A\u5931\u65F6\u4F1A\u81EA\u5DF1\u5EFA\u4E00\u4E2A\u53EA\u6709 @deepseek-ai/dsh-base \u7684\u7A7A\u58F3\uFF0C\u8D77\u6765\u4E0D\u4F1A\u6709\u754C\u9762\uFF1B",
|
|
26
|
+
" \u800C provider \u7684\u7F16\u6392\u662F\u300C\u5148\u88C5\u63D2\u4EF6\u3001\u518D\u8D77\u8FDB\u7A0B\u300D\uFF0C\u90A3\u4E00\u6B65\u4F1A\u628A\u7A7A\u58F3\u5EFA\u51FA\u6765\uFF0C\u75C7\u72B6\u53EA\u662F\u542F\u52A8\u8D85\u65F6\u3002",
|
|
27
|
+
" \u5148\u628A\u8FD9\u4E2A profile \u5EFA\u597D\uFF08\u5B83\u81EA\u5DF1\u7684\u5B89\u88C5\u6D41\u7A0B\uFF0C\u6216 `dsh <\u540D> --from-default-profile web`\uFF09\u518D\u91CD\u5F00\u3002"
|
|
28
|
+
].join("\n");
|
|
29
|
+
}
|
|
30
|
+
function describeDshProfile(profileDir, profile) {
|
|
31
|
+
const inspection = inspectDshProfile(profileDir);
|
|
32
|
+
const bundles = inspection.bundles.length === 0 ? "\uFF08\u8BFB\u4E0D\u5230\uFF09" : inspection.bundles.join("\u3001");
|
|
33
|
+
return `profile: ${profile} (${profileDir})
|
|
34
|
+
bundles: ${bundles}`;
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
DSH_WEB_APP_BUNDLE,
|
|
38
|
+
describeDshProfile,
|
|
39
|
+
inspectDshProfile,
|
|
40
|
+
profileProblemText
|
|
41
|
+
};
|
package/es/provider.js
CHANGED
|
@@ -4,11 +4,11 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4
4
|
import { sleep } from "@aipanel/core";
|
|
5
5
|
import { DEFAULT_DIAGNOSTICS_POLICY, resolveDiagnosticsPolicy } from "@aipanel/core";
|
|
6
6
|
import { createLogger } from "@aipanel/core/node";
|
|
7
|
-
import { DEFAULT_DEEPSEEK_PROVIDER_OPTIONS } from "./constants.js";
|
|
8
|
-
import { DSH_LOOPBACK_HOST } from "./constants.js";
|
|
7
|
+
import { DEFAULT_DEEPSEEK_PROVIDER_OPTIONS, DSH_DEFAULT_PROFILE, DSH_LOOPBACK_HOST } from "./constants.js";
|
|
9
8
|
import { DeepSeekAPI } from "./api.js";
|
|
10
9
|
import { LaunchToken, startDeepSeekWeb } from "./deepseek-web.js";
|
|
11
10
|
import { buildDshOverlay, writeDshOverlay } from "./profile.js";
|
|
11
|
+
import { describeDshProfile, inspectDshProfile, profileProblemText } from "./profile-check.js";
|
|
12
12
|
import {
|
|
13
13
|
checkDeepSeekInstalled,
|
|
14
14
|
getDeepSeekVersion,
|
|
@@ -85,12 +85,21 @@ Please upgrade:
|
|
|
85
85
|
port: options.port,
|
|
86
86
|
hostname: DSH_LOOPBACK_HOST,
|
|
87
87
|
cwd: options.cwd,
|
|
88
|
+
profile: this.opts.profile,
|
|
88
89
|
vitePort: options.vitePort
|
|
89
90
|
});
|
|
90
|
-
const profileDir = dshProfileDir(this.opts.home);
|
|
91
|
+
const profileDir = dshProfileDir(this.opts.profile, this.opts.home);
|
|
91
92
|
const launchToken = new LaunchToken();
|
|
92
93
|
this.launchToken = launchToken;
|
|
93
94
|
this.api.setLaunchTokenSource(() => launchToken.wait());
|
|
95
|
+
launchToken.attachContext(() => describeDshProfile(profileDir, this.opts.profile));
|
|
96
|
+
const profileCheck = inspectDshProfile(profileDir);
|
|
97
|
+
if (!profileCheck.ok) {
|
|
98
|
+
const reason = profileProblemText(profileCheck, profileDir, this.opts.profile);
|
|
99
|
+
log.error(reason);
|
|
100
|
+
launchToken.fail(new Error(reason));
|
|
101
|
+
throw new Error(reason);
|
|
102
|
+
}
|
|
94
103
|
const devClientDir = resolveDevDshPackageSource(import.meta.url, "dsh-client", "lib/client.js");
|
|
95
104
|
const providerVersion = readProviderVersion(import.meta.url);
|
|
96
105
|
const clientTarget = devClientDir ?? (providerVersion ? `${DSH_CLIENT_PACKAGE}@${providerVersion}` : `${DSH_CLIENT_PACKAGE}@latest`);
|
|
@@ -98,6 +107,7 @@ Please upgrade:
|
|
|
98
107
|
profileDir,
|
|
99
108
|
DSH_CLIENT_PACKAGE,
|
|
100
109
|
clientTarget,
|
|
110
|
+
this.opts.profile,
|
|
101
111
|
this.opts.home,
|
|
102
112
|
providerVersion
|
|
103
113
|
);
|
|
@@ -112,6 +122,7 @@ Please upgrade:
|
|
|
112
122
|
profileDir,
|
|
113
123
|
DSH_PLUGIN_PACKAGE,
|
|
114
124
|
pluginTarget,
|
|
125
|
+
this.opts.profile,
|
|
115
126
|
this.opts.home,
|
|
116
127
|
providerVersion
|
|
117
128
|
);
|
|
@@ -139,6 +150,7 @@ Please upgrade:
|
|
|
139
150
|
port: options.port,
|
|
140
151
|
hostname: DSH_LOOPBACK_HOST,
|
|
141
152
|
cwd: options.cwd,
|
|
153
|
+
profile: this.opts.profile,
|
|
142
154
|
patchPath,
|
|
143
155
|
home: this.opts.home,
|
|
144
156
|
verbose: options.verbose,
|
|
@@ -233,6 +245,7 @@ function resolveDeepSeekOptions(options) {
|
|
|
233
245
|
return {
|
|
234
246
|
...DEFAULT_DEEPSEEK_PROVIDER_OPTIONS,
|
|
235
247
|
home: po.home ?? options?.home,
|
|
248
|
+
profile: po.profile ?? options?.profile ?? DSH_DEFAULT_PROFILE,
|
|
236
249
|
agentPreset: po.agentPreset ?? options?.agentPreset,
|
|
237
250
|
permissionPreset: po.permissionPreset ?? options?.permissionPreset,
|
|
238
251
|
busyEnter: po.busyEnter ?? options?.busyEnter,
|
package/es/types.d.ts
CHANGED
|
@@ -17,6 +17,14 @@ export type DeepSeekBusyEnter = BusyEnterBehavior;
|
|
|
17
17
|
export type DeepSeekProviderOptions = {
|
|
18
18
|
/** dsh 数据目录($DSH_HOME),默认跟随系统(~/.dsh) */
|
|
19
19
|
home?: string;
|
|
20
|
+
/**
|
|
21
|
+
* dsh profile 名($DSH_HOME/profiles/<name>),默认 "web";AIPanel 侧插件与 web 进程都指向该 profile。
|
|
22
|
+
*
|
|
23
|
+
* ⚠️ 该 profile 必须**先建好**:其 `dsh.profile.bundles` 里要有 `@deepseek-ai/dsh-web-app`。
|
|
24
|
+
* 缺失时 dsh 的 `plugin` 子命令会自己建出一个只有 `@deepseek-ai/dsh-base` 的空壳,
|
|
25
|
+
* 于是启动只会表现为"等 launch token 超时"(见 profile-check.ts 的预检与说明)。
|
|
26
|
+
*/
|
|
27
|
+
profile?: string;
|
|
20
28
|
/** 默认 Agent 预设(dsh settings agent-presets.default,如 code/standard;新建会话的默认模式) */
|
|
21
29
|
agentPreset?: string;
|
|
22
30
|
/** 默认权限预设(dsh settings permission.defaultPreset) */
|
|
@@ -34,7 +42,8 @@ export type DeepSeekProviderOptions = {
|
|
|
34
42
|
*/
|
|
35
43
|
[key: string]: unknown;
|
|
36
44
|
};
|
|
37
|
-
/** 归一化后的 Provider 选项:诊断策略一定是完整的(Partial 已在 provider
|
|
45
|
+
/** 归一化后的 Provider 选项:诊断策略一定是完整的(Partial 已在 provider 内解析),profile 一定落到默认值 */
|
|
38
46
|
export type DeepSeekResolvedOptions = DeepSeekProviderOptions & {
|
|
47
|
+
profile: string;
|
|
39
48
|
diagnostics: DiagnosticsPolicy;
|
|
40
49
|
};
|
package/lib/constants.cjs
CHANGED
|
@@ -20,6 +20,7 @@ __export(constants_exports, {
|
|
|
20
20
|
DEFAULT_DEEPSEEK_PROVIDER_OPTIONS: () => DEFAULT_DEEPSEEK_PROVIDER_OPTIONS,
|
|
21
21
|
DSH_API_BASE: () => DSH_API_BASE,
|
|
22
22
|
DSH_DEFAULT_PORT: () => DSH_DEFAULT_PORT,
|
|
23
|
+
DSH_DEFAULT_PROFILE: () => DSH_DEFAULT_PROFILE,
|
|
23
24
|
DSH_LOOPBACK_HOST: () => DSH_LOOPBACK_HOST,
|
|
24
25
|
DSH_REMOTE_MUX_PATH: () => DSH_REMOTE_MUX_PATH
|
|
25
26
|
});
|
|
@@ -28,12 +29,16 @@ const DSH_API_BASE = "/api";
|
|
|
28
29
|
const DSH_REMOTE_MUX_PATH = "/api/remote.mux";
|
|
29
30
|
const DSH_LOOPBACK_HOST = "127.0.0.1";
|
|
30
31
|
const DSH_DEFAULT_PORT = 3080;
|
|
31
|
-
const
|
|
32
|
+
const DSH_DEFAULT_PROFILE = "web";
|
|
33
|
+
const DEFAULT_DEEPSEEK_PROVIDER_OPTIONS = {
|
|
34
|
+
profile: DSH_DEFAULT_PROFILE
|
|
35
|
+
};
|
|
32
36
|
// Annotate the CommonJS export names for ESM import in node:
|
|
33
37
|
0 && (module.exports = {
|
|
34
38
|
DEFAULT_DEEPSEEK_PROVIDER_OPTIONS,
|
|
35
39
|
DSH_API_BASE,
|
|
36
40
|
DSH_DEFAULT_PORT,
|
|
41
|
+
DSH_DEFAULT_PROFILE,
|
|
37
42
|
DSH_LOOPBACK_HOST,
|
|
38
43
|
DSH_REMOTE_MUX_PATH
|
|
39
44
|
});
|
package/lib/constants.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export declare const DSH_REMOTE_MUX_PATH = "/api/remote.mux";
|
|
|
17
17
|
export declare const DSH_LOOPBACK_HOST = "127.0.0.1";
|
|
18
18
|
/** dsh web 默认端口(未显式指定时) */
|
|
19
19
|
export declare const DSH_DEFAULT_PORT = 3080;
|
|
20
|
+
/** dsh 默认 profile($DSH_HOME/profiles/<name>);用户可经 providerOptions.profile 覆盖 */
|
|
21
|
+
export declare const DSH_DEFAULT_PROFILE = "web";
|
|
20
22
|
/** ==================== Provider 专属配置默认值 ==================== */
|
|
21
23
|
/**
|
|
22
24
|
* Provider 选项兜底值。
|
package/lib/deepseek-web.cjs
CHANGED
|
@@ -25,6 +25,7 @@ __export(deepseek_web_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(deepseek_web_exports);
|
|
26
26
|
var import_execa = require("execa");
|
|
27
27
|
var import_node = require("@aipanel/core/node");
|
|
28
|
+
var import_constants = require("./constants.cjs");
|
|
28
29
|
const log = (0, import_node.createLogger)("DeepSeekWeb");
|
|
29
30
|
class LaunchToken {
|
|
30
31
|
/** @param timeoutMs token 等待窗口(自 arm 起算,默认 20s) */
|
|
@@ -40,6 +41,7 @@ class LaunchToken {
|
|
|
40
41
|
/** dsh 进程是否已 spawn:token 只可能在 spawn 后打印,超时窗口自 arm 起算 */
|
|
41
42
|
__publicField(this, "spawned", false);
|
|
42
43
|
__publicField(this, "windowTimer");
|
|
44
|
+
__publicField(this, "context");
|
|
43
45
|
/** 报错时把 dsh web 启动的原始日志作为一条日志整体输出(幂等:每实例只打一次) */
|
|
44
46
|
__publicField(this, "printed", false);
|
|
45
47
|
}
|
|
@@ -84,12 +86,24 @@ class LaunchToken {
|
|
|
84
86
|
/** 窗口到点:输出 dsh web 启动原始日志辅助诊断,再按未捕获 token 判定本次启动失败 */
|
|
85
87
|
expire() {
|
|
86
88
|
this.printStartupOutput();
|
|
89
|
+
const context = this.context?.();
|
|
90
|
+
const base = `dsh launch token was not captured from stdout within ${this.timeoutMs}ms (dsh >= 0.1.2 should print the "dsh web: http://127.0.0.1:<port>/?token=..." URL)`;
|
|
87
91
|
this.fail(
|
|
88
92
|
new Error(
|
|
89
|
-
|
|
93
|
+
context === void 0 || context.trim() === "" ? base : `${base}
|
|
94
|
+
${context}
|
|
95
|
+
\uFF08\u8FD9\u4E2A profile \u8D77\u4E0D\u4E86 Web UI \u65F6\u5C31\u662F\u8FD9\u4E2A\u75C7\u72B6\uFF1A\u5148\u786E\u8BA4\u5B83\u5EFA\u597D\u4E86\uFF09`
|
|
90
96
|
)
|
|
91
97
|
);
|
|
92
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* 附上"这次起的是哪个 profile"的上下文(provider 起进程前调用)。
|
|
101
|
+
* 只加在这里、不进 printStartupOutput:超时的那条错误要能自己说清 profile 与它的 bundle 列表,
|
|
102
|
+
* 否则症状永远只是"启动超时"(见 profile-check 的注释)。
|
|
103
|
+
*/
|
|
104
|
+
attachContext(provider) {
|
|
105
|
+
this.context = provider;
|
|
106
|
+
}
|
|
93
107
|
printStartupOutput() {
|
|
94
108
|
if (this.printed) return;
|
|
95
109
|
this.printed = true;
|
|
@@ -115,7 +129,8 @@ class LaunchToken {
|
|
|
115
129
|
}
|
|
116
130
|
function startDeepSeekWeb(options) {
|
|
117
131
|
const { port, hostname, cwd, patchPath, home, verbose, launchToken } = options;
|
|
118
|
-
const
|
|
132
|
+
const profile = options.profile ?? import_constants.DSH_DEFAULT_PROFILE;
|
|
133
|
+
const args = ["--profile", profile];
|
|
119
134
|
if (patchPath) {
|
|
120
135
|
args.push("--patch", patchPath);
|
|
121
136
|
}
|
package/lib/deepseek-web.d.ts
CHANGED
|
@@ -33,6 +33,13 @@ export declare class LaunchToken {
|
|
|
33
33
|
fail(err: Error): void;
|
|
34
34
|
/** 窗口到点:输出 dsh web 启动原始日志辅助诊断,再按未捕获 token 判定本次启动失败 */
|
|
35
35
|
private expire;
|
|
36
|
+
/**
|
|
37
|
+
* 附上"这次起的是哪个 profile"的上下文(provider 起进程前调用)。
|
|
38
|
+
* 只加在这里、不进 printStartupOutput:超时的那条错误要能自己说清 profile 与它的 bundle 列表,
|
|
39
|
+
* 否则症状永远只是"启动超时"(见 profile-check 的注释)。
|
|
40
|
+
*/
|
|
41
|
+
attachContext(provider: () => string): void;
|
|
42
|
+
private context?;
|
|
36
43
|
/** 报错时把 dsh web 启动的原始日志作为一条日志整体输出(幂等:每实例只打一次) */
|
|
37
44
|
private printed;
|
|
38
45
|
private printStartupOutput;
|
|
@@ -48,6 +55,8 @@ export interface DeepSeekWebOptions {
|
|
|
48
55
|
hostname: string;
|
|
49
56
|
/** 工作目录 */
|
|
50
57
|
cwd: string;
|
|
58
|
+
/** dsh profile 名($DSH_HOME/profiles/<name>),默认 "web" */
|
|
59
|
+
profile?: string;
|
|
51
60
|
/** cordis overlay 文件路径(--patch 注入 MCP client / aipanel 插件) */
|
|
52
61
|
patchPath?: string;
|
|
53
62
|
/** dsh 数据目录(透传 DSH_HOME;缺省跟随 $DSH_HOME / ~/.dsh) */
|
package/lib/dsh-install.cjs
CHANGED
|
@@ -57,9 +57,9 @@ function resolveDevDshPackageSource(metaUrl, subdir, distRel) {
|
|
|
57
57
|
}
|
|
58
58
|
return null;
|
|
59
59
|
}
|
|
60
|
-
function dshProfileDir(home) {
|
|
60
|
+
function dshProfileDir(profile, home) {
|
|
61
61
|
const resolved = home || process.env.DSH_HOME || import_node_path.default.join(import_node_os.default.homedir(), ".dsh");
|
|
62
|
-
return import_node_path.default.join(resolved, "profiles",
|
|
62
|
+
return import_node_path.default.join(resolved, "profiles", profile);
|
|
63
63
|
}
|
|
64
64
|
function isDshPackageInstalled(profileDir, packageName) {
|
|
65
65
|
return import_node_fs.default.existsSync(packageJsonIn(profileDir, packageName));
|
|
@@ -81,10 +81,10 @@ function readProviderVersion(metaUrl) {
|
|
|
81
81
|
return null;
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
async function ensureDshPackage(profileDir, packageName, target, home, expectedVersion) {
|
|
84
|
+
async function ensureDshPackage(profileDir, packageName, target, profile, home, expectedVersion) {
|
|
85
85
|
try {
|
|
86
|
-
log.debug(`installing ${target} into dsh profile via dsh plugin add
|
|
87
|
-
await (0, import_execa.execa)("dsh", ["plugin", "--profile",
|
|
86
|
+
log.debug(`installing ${target} into dsh profile via dsh plugin add`, { profile });
|
|
87
|
+
await (0, import_execa.execa)("dsh", ["plugin", "--profile", profile, "add", target], {
|
|
88
88
|
reject: true,
|
|
89
89
|
env: {
|
|
90
90
|
...process.env,
|
|
@@ -103,7 +103,7 @@ async function ensureDshPackage(profileDir, packageName, target, home, expectedV
|
|
|
103
103
|
`${packageName} version ${installed} is out of sync with provider ${expectedVersion}`,
|
|
104
104
|
{
|
|
105
105
|
profileDir,
|
|
106
|
-
install: `dsh plugin --profile
|
|
106
|
+
install: `dsh plugin --profile ${profile} add ${packageName}@${expectedVersion}`
|
|
107
107
|
}
|
|
108
108
|
);
|
|
109
109
|
}
|
package/lib/dsh-install.d.ts
CHANGED
|
@@ -8,8 +8,8 @@ export declare const DSH_PLUGIN_PACKAGE = "@aipanel/dsh-plugin";
|
|
|
8
8
|
* @param distRel 产物相对路径(client 为 "lib/client.js",plugin 为 "dist/index.js")
|
|
9
9
|
*/
|
|
10
10
|
export declare function resolveDevDshPackageSource(metaUrl: string, subdir: string, distRel: string): string | null;
|
|
11
|
-
/** dsh
|
|
12
|
-
export declare function dshProfileDir(home?: string): string;
|
|
11
|
+
/** dsh profile 目录($DSH_HOME/profiles/<profile>);home 未指定时回退 $DSH_HOME / ~/.dsh */
|
|
12
|
+
export declare function dshProfileDir(profile: string, home?: string): string;
|
|
13
13
|
/** 某 @aipanel/dsh-* 包在 profile 的 node_modules 中是否可解析 */
|
|
14
14
|
export declare function isDshPackageInstalled(profileDir: string, packageName: string): boolean;
|
|
15
15
|
/** 读取 profile 内已安装的某包版本(可解析不到时返回 null) */
|
|
@@ -22,4 +22,4 @@ export declare function readProviderVersion(metaUrl: string): string | null;
|
|
|
22
22
|
* 生产 npm 包每次检查 registry 拉取最新版本。安装失败返回 false(不阻塞启动,
|
|
23
23
|
* 仅对应 overlay 行停用,如失去 chip 高亮 / 审查工具)。
|
|
24
24
|
*/
|
|
25
|
-
export declare function ensureDshPackage(profileDir: string, packageName: string, target: string, home?: string, expectedVersion?: string | null): Promise<boolean>;
|
|
25
|
+
export declare function ensureDshPackage(profileDir: string, packageName: string, target: string, profile: string, home?: string, expectedVersion?: string | null): Promise<boolean>;
|
package/lib/index.cjs
CHANGED
|
@@ -19,6 +19,7 @@ var lib_exports = {};
|
|
|
19
19
|
__export(lib_exports, {
|
|
20
20
|
DEFAULT_DEEPSEEK_PROVIDER_OPTIONS: () => import_constants2.DEFAULT_DEEPSEEK_PROVIDER_OPTIONS,
|
|
21
21
|
DSH_DEFAULT_PORT: () => import_constants2.DSH_DEFAULT_PORT,
|
|
22
|
+
DSH_DEFAULT_PROFILE: () => import_constants2.DSH_DEFAULT_PROFILE,
|
|
22
23
|
DSH_LOOPBACK_HOST: () => import_constants2.DSH_LOOPBACK_HOST,
|
|
23
24
|
DeepSeekAPI: () => import_api.DeepSeekAPI,
|
|
24
25
|
buildDshOverlay: () => import_profile.buildDshOverlay,
|
|
@@ -48,6 +49,7 @@ function createProvider(ctx) {
|
|
|
48
49
|
0 && (module.exports = {
|
|
49
50
|
DEFAULT_DEEPSEEK_PROVIDER_OPTIONS,
|
|
50
51
|
DSH_DEFAULT_PORT,
|
|
52
|
+
DSH_DEFAULT_PROFILE,
|
|
51
53
|
DSH_LOOPBACK_HOST,
|
|
52
54
|
DeepSeekAPI,
|
|
53
55
|
buildDshOverlay,
|
package/lib/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export type { DeepSeekWebProviderConfig, DeepSeekWebProviderDeps } from "./provi
|
|
|
11
11
|
export { startDeepSeekWeb, type DeepSeekWebOptions } from "./deepseek-web";
|
|
12
12
|
export { buildDshOverlay, writeDshOverlay } from "./profile";
|
|
13
13
|
export { checkDeepSeekInstalled, getDeepSeekVersion, killOrphanDeepSeekProcesses } from "./system";
|
|
14
|
-
export { DEFAULT_DEEPSEEK_PROVIDER_OPTIONS, DSH_LOOPBACK_HOST, DSH_DEFAULT_PORT, } from "./constants";
|
|
14
|
+
export { DEFAULT_DEEPSEEK_PROVIDER_OPTIONS, DSH_LOOPBACK_HOST, DSH_DEFAULT_PORT, DSH_DEFAULT_PROFILE, } from "./constants";
|
|
15
15
|
export type { DeepSeekProviderOptions, DeepSeekPermissionPreset, DeepSeekBusyEnter } from "./types";
|
|
16
16
|
export type { ClientRequest, RpcMessage, ServerResponse } from "@deepseek-ai/dsh-client-connection";
|
|
17
17
|
export type { SessionCreateValue, SessionListValue, SessionSummary, } from "@deepseek-ai/dsh-api-session-controller/types";
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var profile_check_exports = {};
|
|
29
|
+
__export(profile_check_exports, {
|
|
30
|
+
DSH_WEB_APP_BUNDLE: () => DSH_WEB_APP_BUNDLE,
|
|
31
|
+
describeDshProfile: () => describeDshProfile,
|
|
32
|
+
inspectDshProfile: () => inspectDshProfile,
|
|
33
|
+
profileProblemText: () => profileProblemText
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(profile_check_exports);
|
|
36
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
37
|
+
var import_node_path = __toESM(require("node:path"));
|
|
38
|
+
const DSH_WEB_APP_BUNDLE = "@deepseek-ai/dsh-web-app";
|
|
39
|
+
function inspectDshProfile(profileDir) {
|
|
40
|
+
const manifest = import_node_path.default.join(profileDir, "package.json");
|
|
41
|
+
let parsed;
|
|
42
|
+
try {
|
|
43
|
+
parsed = JSON.parse(import_node_fs.default.readFileSync(manifest, "utf8"));
|
|
44
|
+
} catch {
|
|
45
|
+
return { ok: false, problem: "missing", bundles: [], manifest };
|
|
46
|
+
}
|
|
47
|
+
const declared = parsed?.dsh?.profile?.bundles;
|
|
48
|
+
const bundles = Array.isArray(declared) ? declared.filter((one) => typeof one === "string") : [];
|
|
49
|
+
if (!bundles.includes(DSH_WEB_APP_BUNDLE)) {
|
|
50
|
+
return { ok: false, problem: "no-web-app", bundles, manifest };
|
|
51
|
+
}
|
|
52
|
+
return { ok: true, problem: null, bundles, manifest };
|
|
53
|
+
}
|
|
54
|
+
function profileProblemText(inspection, profileDir, profile) {
|
|
55
|
+
const head = inspection.problem === "missing" ? `dsh profile "${profile}" \u8FD8\u4E0D\u5B58\u5728\uFF08\u627E\u4E0D\u5230 ${inspection.manifest}\uFF09` : `dsh profile "${profile}" \u91CC\u6CA1\u6709 Web \u5E94\u7528 bundle\uFF08${DSH_WEB_APP_BUNDLE}\uFF09`;
|
|
56
|
+
const bundles = inspection.bundles.length === 0 ? "\uFF08\u8BFB\u4E0D\u5230 bundle \u5217\u8868\uFF09" : `\u73B0\u6709 bundles\uFF1A${inspection.bundles.join("\u3001")}`;
|
|
57
|
+
return [
|
|
58
|
+
`${head}\uFF1A${profileDir}`,
|
|
59
|
+
` ${bundles}`,
|
|
60
|
+
" dsh \u5728 profile \u7F3A\u5931\u65F6\u4F1A\u81EA\u5DF1\u5EFA\u4E00\u4E2A\u53EA\u6709 @deepseek-ai/dsh-base \u7684\u7A7A\u58F3\uFF0C\u8D77\u6765\u4E0D\u4F1A\u6709\u754C\u9762\uFF1B",
|
|
61
|
+
" \u800C provider \u7684\u7F16\u6392\u662F\u300C\u5148\u88C5\u63D2\u4EF6\u3001\u518D\u8D77\u8FDB\u7A0B\u300D\uFF0C\u90A3\u4E00\u6B65\u4F1A\u628A\u7A7A\u58F3\u5EFA\u51FA\u6765\uFF0C\u75C7\u72B6\u53EA\u662F\u542F\u52A8\u8D85\u65F6\u3002",
|
|
62
|
+
" \u5148\u628A\u8FD9\u4E2A profile \u5EFA\u597D\uFF08\u5B83\u81EA\u5DF1\u7684\u5B89\u88C5\u6D41\u7A0B\uFF0C\u6216 `dsh <\u540D> --from-default-profile web`\uFF09\u518D\u91CD\u5F00\u3002"
|
|
63
|
+
].join("\n");
|
|
64
|
+
}
|
|
65
|
+
function describeDshProfile(profileDir, profile) {
|
|
66
|
+
const inspection = inspectDshProfile(profileDir);
|
|
67
|
+
const bundles = inspection.bundles.length === 0 ? "\uFF08\u8BFB\u4E0D\u5230\uFF09" : inspection.bundles.join("\u3001");
|
|
68
|
+
return `profile: ${profile} (${profileDir})
|
|
69
|
+
bundles: ${bundles}`;
|
|
70
|
+
}
|
|
71
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
72
|
+
0 && (module.exports = {
|
|
73
|
+
DSH_WEB_APP_BUNDLE,
|
|
74
|
+
describeDshProfile,
|
|
75
|
+
inspectDshProfile,
|
|
76
|
+
profileProblemText
|
|
77
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** dsh 的 Web 应用 bundle(`dsh web` 的 profile 必有;纯终端类 profile 没有) */
|
|
2
|
+
export declare const DSH_WEB_APP_BUNDLE = "@deepseek-ai/dsh-web-app";
|
|
3
|
+
export type DshProfileProblem = "missing" | "no-web-app";
|
|
4
|
+
export interface DshProfileInspection {
|
|
5
|
+
/** 这个 profile 现在能不能起 Web UI */
|
|
6
|
+
readonly ok: boolean;
|
|
7
|
+
/** 不能时是哪一类问题;能时为 null */
|
|
8
|
+
readonly problem: DshProfileProblem | null;
|
|
9
|
+
/** profile 声明的 bundle 列表(读不到时为空数组) */
|
|
10
|
+
readonly bundles: readonly string[];
|
|
11
|
+
/** profile 清单文件路径(报错信息里给绝对路径,方便直接去看) */
|
|
12
|
+
readonly manifest: string;
|
|
13
|
+
}
|
|
14
|
+
/** 读 profile 清单并判断它是否具备启动 Web UI 的条件 */
|
|
15
|
+
export declare function inspectDshProfile(profileDir: string): DshProfileInspection;
|
|
16
|
+
/** 预检没过时给用户的说明(通用措辞:说清是什么、去哪看、怎么修) */
|
|
17
|
+
export declare function profileProblemText(inspection: DshProfileInspection, profileDir: string, profile: string): string;
|
|
18
|
+
/** 启动超时诊断用的一行上下文:profile 在哪、声明了哪些 bundle */
|
|
19
|
+
export declare function describeDshProfile(profileDir: string, profile: string): string;
|
package/lib/provider.cjs
CHANGED
|
@@ -27,10 +27,10 @@ var import_core = require("@aipanel/core");
|
|
|
27
27
|
var import_core2 = require("@aipanel/core");
|
|
28
28
|
var import_node = require("@aipanel/core/node");
|
|
29
29
|
var import_constants = require("./constants.cjs");
|
|
30
|
-
var import_constants2 = require("./constants.cjs");
|
|
31
30
|
var import_api = require("./api.cjs");
|
|
32
31
|
var import_deepseek_web = require("./deepseek-web.cjs");
|
|
33
32
|
var import_profile = require("./profile.cjs");
|
|
33
|
+
var import_profile_check = require("./profile-check.cjs");
|
|
34
34
|
var import_system = require("./system.cjs");
|
|
35
35
|
var import_dsh_install = require("./dsh-install.cjs");
|
|
36
36
|
const log = (0, import_node.createLogger)("DeepSeekWebProvider");
|
|
@@ -50,7 +50,7 @@ class DeepSeekWebProvider {
|
|
|
50
50
|
__publicField(this, "opts");
|
|
51
51
|
this.deps = deps;
|
|
52
52
|
this.opts = resolveDeepSeekOptions(options);
|
|
53
|
-
this.api = new import_api.DeepSeekAPI(
|
|
53
|
+
this.api = new import_api.DeepSeekAPI(import_constants.DSH_LOOPBACK_HOST, deps.getWebPort);
|
|
54
54
|
}
|
|
55
55
|
/** 记录 AIPanel 侧主题偏好(applyConfig 在 start 前调用;start 时随 client 插件 config 下发) */
|
|
56
56
|
applyConfig(config) {
|
|
@@ -92,14 +92,23 @@ Please upgrade:
|
|
|
92
92
|
async start(options) {
|
|
93
93
|
log.debug("Starting dsh web process", {
|
|
94
94
|
port: options.port,
|
|
95
|
-
hostname:
|
|
95
|
+
hostname: import_constants.DSH_LOOPBACK_HOST,
|
|
96
96
|
cwd: options.cwd,
|
|
97
|
+
profile: this.opts.profile,
|
|
97
98
|
vitePort: options.vitePort
|
|
98
99
|
});
|
|
99
|
-
const profileDir = (0, import_dsh_install.dshProfileDir)(this.opts.home);
|
|
100
|
+
const profileDir = (0, import_dsh_install.dshProfileDir)(this.opts.profile, this.opts.home);
|
|
100
101
|
const launchToken = new import_deepseek_web.LaunchToken();
|
|
101
102
|
this.launchToken = launchToken;
|
|
102
103
|
this.api.setLaunchTokenSource(() => launchToken.wait());
|
|
104
|
+
launchToken.attachContext(() => (0, import_profile_check.describeDshProfile)(profileDir, this.opts.profile));
|
|
105
|
+
const profileCheck = (0, import_profile_check.inspectDshProfile)(profileDir);
|
|
106
|
+
if (!profileCheck.ok) {
|
|
107
|
+
const reason = (0, import_profile_check.profileProblemText)(profileCheck, profileDir, this.opts.profile);
|
|
108
|
+
log.error(reason);
|
|
109
|
+
launchToken.fail(new Error(reason));
|
|
110
|
+
throw new Error(reason);
|
|
111
|
+
}
|
|
103
112
|
const devClientDir = (0, import_dsh_install.resolveDevDshPackageSource)(import_meta.url, "dsh-client", "lib/client.js");
|
|
104
113
|
const providerVersion = (0, import_dsh_install.readProviderVersion)(import_meta.url);
|
|
105
114
|
const clientTarget = devClientDir ?? (providerVersion ? `${import_dsh_install.DSH_CLIENT_PACKAGE}@${providerVersion}` : `${import_dsh_install.DSH_CLIENT_PACKAGE}@latest`);
|
|
@@ -107,6 +116,7 @@ Please upgrade:
|
|
|
107
116
|
profileDir,
|
|
108
117
|
import_dsh_install.DSH_CLIENT_PACKAGE,
|
|
109
118
|
clientTarget,
|
|
119
|
+
this.opts.profile,
|
|
110
120
|
this.opts.home,
|
|
111
121
|
providerVersion
|
|
112
122
|
);
|
|
@@ -121,6 +131,7 @@ Please upgrade:
|
|
|
121
131
|
profileDir,
|
|
122
132
|
import_dsh_install.DSH_PLUGIN_PACKAGE,
|
|
123
133
|
pluginTarget,
|
|
134
|
+
this.opts.profile,
|
|
124
135
|
this.opts.home,
|
|
125
136
|
providerVersion
|
|
126
137
|
);
|
|
@@ -146,8 +157,9 @@ Please upgrade:
|
|
|
146
157
|
const patchPath = (0, import_profile.writeDshOverlay)(options.cwd, overlay);
|
|
147
158
|
const proc = (0, import_deepseek_web.startDeepSeekWeb)({
|
|
148
159
|
port: options.port,
|
|
149
|
-
hostname:
|
|
160
|
+
hostname: import_constants.DSH_LOOPBACK_HOST,
|
|
150
161
|
cwd: options.cwd,
|
|
162
|
+
profile: this.opts.profile,
|
|
151
163
|
patchPath,
|
|
152
164
|
home: this.opts.home,
|
|
153
165
|
verbose: options.verbose,
|
|
@@ -218,7 +230,7 @@ Please upgrade:
|
|
|
218
230
|
buildSessionUrl(projectDir, sessionId) {
|
|
219
231
|
void projectDir;
|
|
220
232
|
void sessionId;
|
|
221
|
-
return `http://${
|
|
233
|
+
return `http://${import_constants.DSH_LOOPBACK_HOST}:${this.deps.getProxyPort()}/`;
|
|
222
234
|
}
|
|
223
235
|
subscribeEvents(handler) {
|
|
224
236
|
void handler;
|
|
@@ -242,6 +254,7 @@ function resolveDeepSeekOptions(options) {
|
|
|
242
254
|
return {
|
|
243
255
|
...import_constants.DEFAULT_DEEPSEEK_PROVIDER_OPTIONS,
|
|
244
256
|
home: po.home ?? options?.home,
|
|
257
|
+
profile: po.profile ?? options?.profile ?? import_constants.DSH_DEFAULT_PROFILE,
|
|
245
258
|
agentPreset: po.agentPreset ?? options?.agentPreset,
|
|
246
259
|
permissionPreset: po.permissionPreset ?? options?.permissionPreset,
|
|
247
260
|
busyEnter: po.busyEnter ?? options?.busyEnter,
|
package/lib/types.d.ts
CHANGED
|
@@ -17,6 +17,14 @@ export type DeepSeekBusyEnter = BusyEnterBehavior;
|
|
|
17
17
|
export type DeepSeekProviderOptions = {
|
|
18
18
|
/** dsh 数据目录($DSH_HOME),默认跟随系统(~/.dsh) */
|
|
19
19
|
home?: string;
|
|
20
|
+
/**
|
|
21
|
+
* dsh profile 名($DSH_HOME/profiles/<name>),默认 "web";AIPanel 侧插件与 web 进程都指向该 profile。
|
|
22
|
+
*
|
|
23
|
+
* ⚠️ 该 profile 必须**先建好**:其 `dsh.profile.bundles` 里要有 `@deepseek-ai/dsh-web-app`。
|
|
24
|
+
* 缺失时 dsh 的 `plugin` 子命令会自己建出一个只有 `@deepseek-ai/dsh-base` 的空壳,
|
|
25
|
+
* 于是启动只会表现为"等 launch token 超时"(见 profile-check.ts 的预检与说明)。
|
|
26
|
+
*/
|
|
27
|
+
profile?: string;
|
|
20
28
|
/** 默认 Agent 预设(dsh settings agent-presets.default,如 code/standard;新建会话的默认模式) */
|
|
21
29
|
agentPreset?: string;
|
|
22
30
|
/** 默认权限预设(dsh settings permission.defaultPreset) */
|
|
@@ -34,7 +42,8 @@ export type DeepSeekProviderOptions = {
|
|
|
34
42
|
*/
|
|
35
43
|
[key: string]: unknown;
|
|
36
44
|
};
|
|
37
|
-
/** 归一化后的 Provider 选项:诊断策略一定是完整的(Partial 已在 provider
|
|
45
|
+
/** 归一化后的 Provider 选项:诊断策略一定是完整的(Partial 已在 provider 内解析),profile 一定落到默认值 */
|
|
38
46
|
export type DeepSeekResolvedOptions = DeepSeekProviderOptions & {
|
|
47
|
+
profile: string;
|
|
39
48
|
diagnostics: DiagnosticsPolicy;
|
|
40
49
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aipanel/provider-deepseek",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "lib/index.cjs",
|
|
6
6
|
"module": "es/index.js",
|
|
@@ -21,16 +21,16 @@
|
|
|
21
21
|
"registry": "https://registry.npmjs.org/"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@aipanel/core": "1.3.
|
|
24
|
+
"@aipanel/core": "1.3.11",
|
|
25
25
|
"execa": "^9.6.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@deepseek-ai/dsh-api-session-controller": "^0.
|
|
29
|
-
"@deepseek-ai/dsh-api-workspace-controller": "^0.
|
|
30
|
-
"@deepseek-ai/dsh-brand": "^0.
|
|
31
|
-
"@deepseek-ai/dsh-client-connection": "^0.
|
|
32
|
-
"@deepseek-ai/dsh-client-ui-conversation": "^0.
|
|
33
|
-
"@deepseek-ai/dsh-sandbox": "^0.
|
|
28
|
+
"@deepseek-ai/dsh-api-session-controller": "^0.2.0-rc.1",
|
|
29
|
+
"@deepseek-ai/dsh-api-workspace-controller": "^0.2.0-rc.1",
|
|
30
|
+
"@deepseek-ai/dsh-brand": "^0.2.0-rc.1",
|
|
31
|
+
"@deepseek-ai/dsh-client-connection": "^0.2.0-rc.1",
|
|
32
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.2.0-rc.1",
|
|
33
|
+
"@deepseek-ai/dsh-sandbox": "^0.2.0-rc.1",
|
|
34
34
|
"esbuild": "^0.25.0"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|