u1s1-cli-cn 1.18.0 → 1.20.0
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/dist/agents/agent-config.d.ts +1 -1
- package/dist/agents/agent-config.js +1 -1
- package/dist/agents/claude.d.ts +4 -1
- package/dist/agents/claude.js +6 -3
- package/dist/agents/codex.d.ts +4 -1
- package/dist/agents/codex.js +6 -3
- package/dist/agents/custom-models.d.ts +61 -0
- package/dist/agents/custom-models.js +175 -0
- package/dist/agents/dsh.d.ts +90 -0
- package/dist/agents/dsh.js +243 -0
- package/dist/agents/launch.d.ts +24 -2
- package/dist/agents/launch.js +115 -15
- package/dist/agents/models-list.d.ts +65 -0
- package/dist/agents/models-list.js +297 -0
- package/dist/agents/node-runtime.d.ts +91 -0
- package/dist/agents/node-runtime.js +223 -0
- package/dist/agents/runtime.d.ts +26 -3
- package/dist/agents/runtime.js +50 -14
- package/dist/agents/status.d.ts +4 -0
- package/dist/agents/status.js +32 -7
- package/dist/api.d.ts +2 -0
- package/dist/chat-protocol/anthropic.d.ts +29 -0
- package/dist/chat-protocol/anthropic.js +484 -0
- package/dist/chat-protocol/json.d.ts +20 -0
- package/dist/chat-protocol/json.js +22 -0
- package/dist/chat-protocol/responses.d.ts +97 -0
- package/dist/chat-protocol/responses.js +1076 -0
- package/dist/chat-protocol/sse.d.ts +19 -0
- package/dist/chat-protocol/sse.js +67 -0
- package/dist/chat-protocol/thinking.d.ts +22 -0
- package/dist/chat-protocol/thinking.js +58 -0
- package/dist/config-command.d.ts +1 -1
- package/dist/config-command.js +20 -10
- package/dist/config.d.ts +23 -1
- package/dist/config.js +52 -1
- package/dist/custom-endpoint-proxy.d.ts +92 -0
- package/dist/custom-endpoint-proxy.js +461 -0
- package/dist/device-auth.d.ts +14 -3
- package/dist/device-auth.js +36 -2
- package/dist/index.js +12 -3
- package/dist/launcher.d.ts +5 -1
- package/dist/launcher.js +35 -11
- package/package.json +1 -1
package/dist/agents/runtime.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ export declare const allowedByBrake: (v: string, brake: RuntimeBrake) => boolean
|
|
|
32
32
|
* latest 超过 max_tested 时自然退到 max_tested(它是测过的版本,必然已发布)。
|
|
33
33
|
*/
|
|
34
34
|
export declare function bestInstallTarget(candidates: Array<string | undefined>, brake: RuntimeBrake): string | undefined;
|
|
35
|
-
export type ManagedAgent = "claude" | "codex";
|
|
35
|
+
export type ManagedAgent = "claude" | "codex" | "dsh";
|
|
36
36
|
export declare const MANAGED_AGENTS: readonly ManagedAgent[];
|
|
37
37
|
export declare function isManagedAgent(value: unknown): value is ManagedAgent;
|
|
38
38
|
/** 平台二进制所在的 npm 包:装进 node_modules 的目录名,以及它在 npm 源上的名字和版本。 */
|
|
@@ -60,6 +60,16 @@ export interface AgentRuntimeSpec {
|
|
|
60
60
|
platformPackage: (version: string, platform: NodeJS.Platform, arch: string, musl: boolean) => PlatformPackageRef | undefined;
|
|
61
61
|
/** 可执行文件在 node_modules 下的相对路径(posix 写法);不支持的系统/架构返回 undefined */
|
|
62
62
|
binInNodeModules: (platform: NodeJS.Platform, arch: string, musl: boolean) => string | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* 入口是 JS 文件、要用不低于这个版本的 Node 运行(dsh:engines.node >=24.9.0)。探测版本、npm 的
|
|
65
|
+
* postinstall 和启动都用调用方给的那个 node(EnsureRuntimeOptions.node);没给就当跑不起来。
|
|
66
|
+
*/
|
|
67
|
+
minNode?: string;
|
|
68
|
+
/** 没有单独的平台包、npm 元数据量不出整棵依赖树时,首次下载前提示的大致大小(字节) */
|
|
69
|
+
sizeHint?: {
|
|
70
|
+
downloadBytes: number;
|
|
71
|
+
unpackedBytes: number;
|
|
72
|
+
};
|
|
63
73
|
}
|
|
64
74
|
/**
|
|
65
75
|
* 官方包的 bin 就是 `bin/claude.exe`(各平台同名):postinstall 把对应平台的原生二进制
|
|
@@ -74,6 +84,15 @@ export declare const CLAUDE_RUNTIME: AgentRuntimeSpec;
|
|
|
74
84
|
* 让它提示用 npm 升级;更新由启动器管,不需要)。原生二进制按自己所在目录找 rg 等附带文件。
|
|
75
85
|
*/
|
|
76
86
|
export declare const CODEX_RUNTIME: AgentRuntimeSpec;
|
|
87
|
+
/** dsh 实测过的版本;网关刹车没给 max_tested_version(老网关、老缓存)时也不越过它(dsh.ts)。 */
|
|
88
|
+
export declare const DSH_TESTED_VERSION = "0.2.2-rc.1";
|
|
89
|
+
/**
|
|
90
|
+
* DeepSeek Harness:`@deepseek-ai/dsh`(MIT)是纯 JS 包,bin 是 `lib/bin.js`,依赖树里的原生模块
|
|
91
|
+
* (node-pty 等)带各平台预编译文件,由 npm 的 postinstall 处理。没有单独的平台包,校验时
|
|
92
|
+
* 主包同时充当「平台包」。engines.node >=24.9.0:便携包自带的 Node 22 跑不了,由 node-runtime.ts
|
|
93
|
+
* 找/下载 Node 24。0.2.2-rc.1 实测:下载约 290 MB,装好约 920 MB。
|
|
94
|
+
*/
|
|
95
|
+
export declare const DSH_RUNTIME: AgentRuntimeSpec;
|
|
77
96
|
export declare function runtimeSpec(agent: ManagedAgent): AgentRuntimeSpec;
|
|
78
97
|
export interface RuntimePaths {
|
|
79
98
|
/** ~/.u1s1/agents/<agent> */
|
|
@@ -121,7 +140,7 @@ export declare function findOnPath(command: string, opts: {
|
|
|
121
140
|
* 跑 `<bin> --version` 取版本。环境里去掉密钥、关掉自动更新;配置目录(CLAUDE_CONFIG_DIR /
|
|
122
141
|
* CODEX_HOME)指到启动器自己的目录,免得探测用户自己装的客户端时碰到用户的 ~/.claude、~/.codex。
|
|
123
142
|
*/
|
|
124
|
-
export declare function probeVersion(bin: string, configDir?: string, spec?: AgentRuntimeSpec): string | undefined;
|
|
143
|
+
export declare function probeVersion(bin: string, configDir?: string, spec?: AgentRuntimeSpec, node?: string): string | undefined;
|
|
125
144
|
/** 版本高于 max_tested、这次没用上的那份客户端(给用户解释为什么换版本 / 另装一份)。 */
|
|
126
145
|
export interface SkippedRuntime extends FoundRuntime {
|
|
127
146
|
maxTestedVersion: string;
|
|
@@ -274,6 +293,8 @@ export interface InstallOptions {
|
|
|
274
293
|
retryDelayMs?: number;
|
|
275
294
|
/** 校验时跑 --version 用的隔离配置目录(CLAUDE_CONFIG_DIR / CODEX_HOME) */
|
|
276
295
|
probeConfigDir?: string;
|
|
296
|
+
/** spec.minNode 时运行入口、npm 及其 postinstall 用的 Node */
|
|
297
|
+
node?: string;
|
|
277
298
|
}
|
|
278
299
|
/**
|
|
279
300
|
* 装一个确切版本:npm install 到暂存目录 → 校验(锁文件里的 integrity 与 registry 元数据一致、
|
|
@@ -329,6 +350,8 @@ export interface EnsureRuntimeOptions {
|
|
|
329
350
|
install?: (opts: InstallOptions) => Promise<FoundRuntime>;
|
|
330
351
|
/** 见 PlanInput.autoUpdate;缺省开 */
|
|
331
352
|
autoUpdate?: boolean;
|
|
353
|
+
/** spec.minNode 的客户端(dsh)用来探测、安装的 Node(node-runtime.ts 找好的) */
|
|
354
|
+
node?: string;
|
|
332
355
|
}
|
|
333
356
|
export interface EnsuredRuntime extends FoundRuntime {
|
|
334
357
|
/** pin 的版本被刹车挡住、已忽略 */
|
|
@@ -347,7 +370,7 @@ export declare class RuntimePlanError extends Error {
|
|
|
347
370
|
}>);
|
|
348
371
|
}
|
|
349
372
|
/**
|
|
350
|
-
* 找到(必要时下载或更新)可用的客户端运行时。CLI(`u1s1 claude` / `u1s1 codex`)与桌面端共用。
|
|
373
|
+
* 找到(必要时下载或更新)可用的客户端运行时。CLI(`u1s1 claude` / `u1s1 codex` / `u1s1 dsh`)与桌面端共用。
|
|
351
374
|
* 失败抛 RuntimePlanError(刹车/版本问题)或 RuntimeInstallError(下载问题)。
|
|
352
375
|
*/
|
|
353
376
|
export declare function ensureAgentRuntime(agent: ManagedAgent, opts: EnsureRuntimeOptions): Promise<EnsuredRuntime>;
|
package/dist/agents/runtime.js
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* 用户确认后才下载;不打进我们的包、不改二进制、不动它自带的登录方式。
|
|
6
6
|
* 安装交给 npm(`npm install --prefix`),上游调整包结构(平台二进制、postinstall)由 npm 处理。
|
|
7
7
|
*
|
|
8
|
-
* 目录布局(以 claude 为例;codex 同理,可执行文件在平台包里,见 CODEX_RUNTIME
|
|
8
|
+
* 目录布局(以 claude 为例;codex 同理,可执行文件在平台包里,见 CODEX_RUNTIME;dsh 的入口是 JS 文件,
|
|
9
|
+
* 由 Node ≥24.9 运行,见 DSH_RUNTIME 与 node-runtime.ts):
|
|
9
10
|
* ~/.u1s1/agents/claude/runtime/<版本>/node_modules/@anthropic-ai/claude-code/bin/claude.exe
|
|
10
11
|
* ~/.u1s1/agents/claude/state.json 当前版本、pin、每日检查时间、待更新版本
|
|
11
12
|
* ~/.u1s1/agents/claude/config/ CLAUDE_CONFIG_DIR(见 claude.ts;codex 是 home/,见 codex.ts)
|
|
@@ -128,9 +129,9 @@ export function bestInstallTarget(candidates, brake) {
|
|
|
128
129
|
}
|
|
129
130
|
return best;
|
|
130
131
|
}
|
|
131
|
-
export const MANAGED_AGENTS = ["claude", "codex"];
|
|
132
|
+
export const MANAGED_AGENTS = ["claude", "codex", "dsh"];
|
|
132
133
|
export function isManagedAgent(value) {
|
|
133
|
-
return value === "claude" || value === "codex";
|
|
134
|
+
return value === "claude" || value === "codex" || value === "dsh";
|
|
134
135
|
}
|
|
135
136
|
function npmOs(platform) {
|
|
136
137
|
return platform === "win32" ? "win32" : platform === "darwin" ? "darwin" : platform === "linux" ? "linux" : undefined;
|
|
@@ -192,11 +193,37 @@ export const CODEX_RUNTIME = {
|
|
|
192
193
|
return `@openai/codex-${os}-${arch}/vendor/${triple}/bin/${os === "win32" ? "codex.exe" : "codex"}`;
|
|
193
194
|
},
|
|
194
195
|
};
|
|
196
|
+
/** dsh 实测过的版本;网关刹车没给 max_tested_version(老网关、老缓存)时也不越过它(dsh.ts)。 */
|
|
197
|
+
export const DSH_TESTED_VERSION = "0.2.2-rc.1";
|
|
198
|
+
/**
|
|
199
|
+
* DeepSeek Harness:`@deepseek-ai/dsh`(MIT)是纯 JS 包,bin 是 `lib/bin.js`,依赖树里的原生模块
|
|
200
|
+
* (node-pty 等)带各平台预编译文件,由 npm 的 postinstall 处理。没有单独的平台包,校验时
|
|
201
|
+
* 主包同时充当「平台包」。engines.node >=24.9.0:便携包自带的 Node 22 跑不了,由 node-runtime.ts
|
|
202
|
+
* 找/下载 Node 24。0.2.2-rc.1 实测:下载约 290 MB,装好约 920 MB。
|
|
203
|
+
*/
|
|
204
|
+
export const DSH_RUNTIME = {
|
|
205
|
+
agent: "dsh",
|
|
206
|
+
npmPackage: "@deepseek-ai/dsh",
|
|
207
|
+
command: "dsh",
|
|
208
|
+
binEnv: "U1S1_DSH_BIN",
|
|
209
|
+
configDirEnv: "DSH_HOME",
|
|
210
|
+
probeEnv: { DSH_TELEMETRY_DISABLED: "1" },
|
|
211
|
+
platformPackage: (version, platform, arch) => {
|
|
212
|
+
if (!npmOs(platform) || (arch !== "x64" && arch !== "arm64"))
|
|
213
|
+
return undefined;
|
|
214
|
+
return { dir: "@deepseek-ai/dsh", name: "@deepseek-ai/dsh", version };
|
|
215
|
+
},
|
|
216
|
+
binInNodeModules: (platform, arch) => npmOs(platform) && (arch === "x64" || arch === "arm64") ? "@deepseek-ai/dsh/lib/bin.js" : undefined,
|
|
217
|
+
minNode: "24.9.0",
|
|
218
|
+
sizeHint: { downloadBytes: 290 * 1024 * 1024, unpackedBytes: 920 * 1024 * 1024 },
|
|
219
|
+
};
|
|
195
220
|
export function runtimeSpec(agent) {
|
|
196
221
|
if (agent === "claude")
|
|
197
222
|
return CLAUDE_RUNTIME;
|
|
198
223
|
if (agent === "codex")
|
|
199
224
|
return CODEX_RUNTIME;
|
|
225
|
+
if (agent === "dsh")
|
|
226
|
+
return DSH_RUNTIME;
|
|
200
227
|
throw new Error(`unknown agent runtime: ${String(agent)}`);
|
|
201
228
|
}
|
|
202
229
|
export function runtimePaths(agentsRoot, agent) {
|
|
@@ -296,7 +323,7 @@ function isFile(p) {
|
|
|
296
323
|
* 跑 `<bin> --version` 取版本。环境里去掉密钥、关掉自动更新;配置目录(CLAUDE_CONFIG_DIR /
|
|
297
324
|
* CODEX_HOME)指到启动器自己的目录,免得探测用户自己装的客户端时碰到用户的 ~/.claude、~/.codex。
|
|
298
325
|
*/
|
|
299
|
-
export function probeVersion(bin, configDir, spec = CLAUDE_RUNTIME) {
|
|
326
|
+
export function probeVersion(bin, configDir, spec = CLAUDE_RUNTIME, node) {
|
|
300
327
|
const env = stripSecretEnv(process.env);
|
|
301
328
|
for (const [key, value] of Object.entries(spec.probeEnv))
|
|
302
329
|
env[key] = value;
|
|
@@ -304,8 +331,12 @@ export function probeVersion(bin, configDir, spec = CLAUDE_RUNTIME) {
|
|
|
304
331
|
env[spec.configDirEnv] = configDir;
|
|
305
332
|
else
|
|
306
333
|
delete env[spec.configDirEnv];
|
|
334
|
+
// JS 入口(dsh):用调用方给的 Node 跑;没给就不试(系统 node 可能太旧,报出来的错不是版本号)
|
|
335
|
+
if (spec.minNode && !node)
|
|
336
|
+
return undefined;
|
|
337
|
+
const [command, args] = spec.minNode ? [node, [bin, "--version"]] : [bin, ["--version"]];
|
|
307
338
|
try {
|
|
308
|
-
const r = spawnSync(
|
|
339
|
+
const r = spawnSync(command, args, { env, encoding: "utf8", timeout: 20_000, windowsHide: true });
|
|
309
340
|
if (r.status !== 0)
|
|
310
341
|
return undefined;
|
|
311
342
|
return versionFromOutput(`${r.stdout ?? ""}`);
|
|
@@ -548,7 +579,7 @@ export async function installRuntime(opts) {
|
|
|
548
579
|
fetchPackageMeta(registry, spec.npmPackage, version),
|
|
549
580
|
fetchPackageMeta(registry, plat.name, plat.version),
|
|
550
581
|
]);
|
|
551
|
-
const downloadBytes = await downloadSize(platMeta?.tarball);
|
|
582
|
+
const downloadBytes = spec.sizeHint?.downloadBytes ?? await downloadSize(platMeta?.tarball);
|
|
552
583
|
if (opts.needsConsent) {
|
|
553
584
|
const ok = hooks.consent
|
|
554
585
|
? await hooks.consent({
|
|
@@ -557,17 +588,20 @@ export async function installRuntime(opts) {
|
|
|
557
588
|
version,
|
|
558
589
|
registry,
|
|
559
590
|
downloadBytes,
|
|
560
|
-
unpackedBytes: platMeta?.unpackedSize !== undefined
|
|
591
|
+
unpackedBytes: spec.sizeHint?.unpackedBytes ?? (platMeta?.unpackedSize !== undefined
|
|
561
592
|
? platMeta.unpackedSize + (mainMeta?.unpackedSize ?? 0)
|
|
562
|
-
: undefined,
|
|
593
|
+
: undefined),
|
|
563
594
|
})
|
|
564
595
|
: false;
|
|
565
596
|
if (!ok)
|
|
566
597
|
throw new RuntimeInstallError("declined", hooks.text.declined());
|
|
567
598
|
}
|
|
568
|
-
const
|
|
569
|
-
if (!
|
|
599
|
+
const found = opts.npm ?? findNpm({ execPath: process.execPath, platform: process.platform, env: process.env });
|
|
600
|
+
if (!found)
|
|
570
601
|
throw new RuntimeInstallError("no_npm", hooks.text.noNpm());
|
|
602
|
+
// JS 入口的客户端:npm 本身和 postinstall 都用那个够新的 Node 跑(npm 按运行它的 Node 核对 engines)
|
|
603
|
+
const scriptNode = spec.minNode ? opts.node : undefined;
|
|
604
|
+
const npm = scriptNode && found.command === process.execPath ? { ...found, command: scriptNode } : found;
|
|
571
605
|
mkdirSync(paths.runtimeDir, { recursive: true, mode: 0o700 });
|
|
572
606
|
const maxAttempts = opts.maxAttempts ?? 3;
|
|
573
607
|
const retryDelayMs = opts.retryDelayMs ?? 3_000;
|
|
@@ -584,6 +618,7 @@ export async function installRuntime(opts) {
|
|
|
584
618
|
registry,
|
|
585
619
|
progress: hooks.progress,
|
|
586
620
|
totalBytes: downloadBytes,
|
|
621
|
+
node: scriptNode,
|
|
587
622
|
});
|
|
588
623
|
lastOutput = result.output;
|
|
589
624
|
if (result.code !== 0) {
|
|
@@ -604,7 +639,7 @@ export async function installRuntime(opts) {
|
|
|
604
639
|
platVersion: plat.version,
|
|
605
640
|
mainMeta,
|
|
606
641
|
platMeta,
|
|
607
|
-
probe: (bin) => probeVersion(bin, opts.probeConfigDir, spec),
|
|
642
|
+
probe: (bin) => probeVersion(bin, opts.probeConfigDir, spec, opts.node),
|
|
608
643
|
});
|
|
609
644
|
if (problem) {
|
|
610
645
|
rmSync(staging, { recursive: true, force: true });
|
|
@@ -724,7 +759,7 @@ export function npmEnv(base, execPath, platform = process.platform) {
|
|
|
724
759
|
function runNpmInstall(npm, o) {
|
|
725
760
|
return new Promise((resolve) => {
|
|
726
761
|
const child = spawn(npm.command, [...npm.prefixArgs, ...npmInstallArgs(o)], {
|
|
727
|
-
env: npmEnv(process.env, process.execPath),
|
|
762
|
+
env: npmEnv(process.env, o.node ?? process.execPath),
|
|
728
763
|
stdio: ["ignore", "pipe", "pipe"],
|
|
729
764
|
windowsHide: true,
|
|
730
765
|
});
|
|
@@ -813,7 +848,7 @@ export class RuntimePlanError extends Error {
|
|
|
813
848
|
}
|
|
814
849
|
}
|
|
815
850
|
/**
|
|
816
|
-
* 找到(必要时下载或更新)可用的客户端运行时。CLI(`u1s1 claude` / `u1s1 codex`)与桌面端共用。
|
|
851
|
+
* 找到(必要时下载或更新)可用的客户端运行时。CLI(`u1s1 claude` / `u1s1 codex` / `u1s1 dsh`)与桌面端共用。
|
|
817
852
|
* 失败抛 RuntimePlanError(刹车/版本问题)或 RuntimeInstallError(下载问题)。
|
|
818
853
|
*/
|
|
819
854
|
export async function ensureAgentRuntime(agent, opts) {
|
|
@@ -821,7 +856,7 @@ export async function ensureAgentRuntime(agent, opts) {
|
|
|
821
856
|
const paths = runtimePaths(opts.agentsRoot, agent);
|
|
822
857
|
const env = opts.env ?? process.env;
|
|
823
858
|
const registry = npmRegistryFor(opts.site, env);
|
|
824
|
-
const probe = (bin) => probeVersion(bin, opts.probeConfigDir, spec);
|
|
859
|
+
const probe = (bin) => probeVersion(bin, opts.probeConfigDir, spec, opts.node);
|
|
825
860
|
const state = readRuntimeState(paths);
|
|
826
861
|
let latestMemo;
|
|
827
862
|
const plan = await planRuntime({
|
|
@@ -867,6 +902,7 @@ export async function ensureAgentRuntime(agent, opts) {
|
|
|
867
902
|
needsConsent: plan.needsConsent,
|
|
868
903
|
hooks: opts.hooks,
|
|
869
904
|
probeConfigDir: opts.probeConfigDir,
|
|
905
|
+
node: opts.node,
|
|
870
906
|
});
|
|
871
907
|
return { ...installed, ...extra };
|
|
872
908
|
}
|
package/dist/agents/status.d.ts
CHANGED
|
@@ -10,6 +10,10 @@ export interface InstallCommandDeps {
|
|
|
10
10
|
fetchPublicRuntime?: (url: URL) => Promise<Response>;
|
|
11
11
|
ensure?: typeof ensureAgentRuntime;
|
|
12
12
|
checkLatest?: typeof dailyUpdateCheck;
|
|
13
|
+
/** dsh 的 Node;测试注入 */
|
|
14
|
+
ensureNode?: () => Promise<{
|
|
15
|
+
bin: string;
|
|
16
|
+
} | undefined>;
|
|
13
17
|
}
|
|
14
18
|
/**
|
|
15
19
|
* `u1s1 agents install claude|codex`:找到或下载原版,不启动。与 `u1s1 claude` / `u1s1 codex` 走同一套
|
package/dist/agents/status.js
CHANGED
|
@@ -12,10 +12,14 @@ import { siteOf } from "../site.js";
|
|
|
12
12
|
import { loadPublicAgentRuntime, parseAgentConfig, readConfigCache } from "./agent-config.js";
|
|
13
13
|
import { claudePaths } from "./claude.js";
|
|
14
14
|
import { codexPaths } from "./codex.js";
|
|
15
|
-
import {
|
|
15
|
+
import { dshPaths } from "./dsh.js";
|
|
16
|
+
import { AGENT_PROFILES, agentsRoot, cliInstallHooks, effectiveBrake, ensureDshNode, notOpenText, printRuntimeFailure, printRuntimeNotes, } from "./launch.js";
|
|
17
|
+
import { findNode } from "./node-runtime.js";
|
|
16
18
|
import { readAgentPrefs } from "./prefs.js";
|
|
17
|
-
import { bestInstallTarget, checkBrake, compareVersions, dailyUpdateCheck, ensureAgentRuntime, fetchLatestVersion, findOnPath, installedVersions, MANAGED_AGENTS, NO_BRAKE, normalizeVersion, npmRegistryFor, probeVersion, readRuntimeState, runtimeSpec, updateRuntimeState, } from "./runtime.js";
|
|
19
|
+
import { bestInstallTarget, checkBrake, compareVersions, DSH_TESTED_VERSION, dailyUpdateCheck, ensureAgentRuntime, fetchLatestVersion, findOnPath, installedVersions, MANAGED_AGENTS, NO_BRAKE, normalizeVersion, npmRegistryFor, probeVersion, readRuntimeState, runtimeSpec, updateRuntimeState, } from "./runtime.js";
|
|
18
20
|
export function launchPaths(agent) {
|
|
21
|
+
if (agent === "dsh")
|
|
22
|
+
return dshPaths();
|
|
19
23
|
return agent === "codex" ? codexPaths() : claudePaths();
|
|
20
24
|
}
|
|
21
25
|
function cachedConfig(agent) {
|
|
@@ -24,7 +28,18 @@ function cachedConfig(agent) {
|
|
|
24
28
|
return cached ? parseAgentConfig(cached.body, AGENT_PROFILES[agent].gatewayAgent) : undefined;
|
|
25
29
|
}
|
|
26
30
|
function cachedBrake(agent) {
|
|
27
|
-
return cachedConfig(agent)?.runtime ?? NO_BRAKE;
|
|
31
|
+
return effectiveBrake(agent, cachedConfig(agent)?.runtime ?? NO_BRAKE);
|
|
32
|
+
}
|
|
33
|
+
/** 探测 dsh 这类 JS 入口的客户端时用的 Node:只找、不下载;找不到就不探测。 */
|
|
34
|
+
function probeNode(agent) {
|
|
35
|
+
if (!runtimeSpec(agent).minNode)
|
|
36
|
+
return undefined;
|
|
37
|
+
try {
|
|
38
|
+
return findNode(agentsRoot())?.bin;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
28
43
|
}
|
|
29
44
|
function verdictText(v, brake) {
|
|
30
45
|
if (v === "blocked")
|
|
@@ -49,7 +64,8 @@ async function managedAgentLines(agent) {
|
|
|
49
64
|
const site = siteOf(cfg);
|
|
50
65
|
const spec = runtimeSpec(agent);
|
|
51
66
|
const cached = cachedConfig(agent);
|
|
52
|
-
const brake = cached?.runtime ?? NO_BRAKE;
|
|
67
|
+
const brake = effectiveBrake(agent, cached?.runtime ?? NO_BRAKE);
|
|
68
|
+
const node = probeNode(agent);
|
|
53
69
|
const paths = launchPaths(agent);
|
|
54
70
|
const state = readRuntimeState(paths);
|
|
55
71
|
const installed = installedVersions(paths, spec);
|
|
@@ -59,7 +75,7 @@ async function managedAgentLines(agent) {
|
|
|
59
75
|
// 探测用户自己的命令时把配置目录指到启动器自己的目录(CODEX_HOME 指向不存在的目录时 Codex 会报错)
|
|
60
76
|
if (envBin || pathBin)
|
|
61
77
|
mkdirSync(paths.configDir, { recursive: true, mode: 0o700 });
|
|
62
|
-
const pathVersion = pathBin ? probeVersion(pathBin, paths.configDir, spec) : undefined;
|
|
78
|
+
const pathVersion = pathBin ? probeVersion(pathBin, paths.configDir, spec, node) : undefined;
|
|
63
79
|
const latest = await fetchLatestVersion(npmRegistryFor(site.id), spec.npmPackage);
|
|
64
80
|
const autoUpdate = readAgentPrefs(agent).autoUpdate;
|
|
65
81
|
const lines = [];
|
|
@@ -67,7 +83,7 @@ async function managedAgentLines(agent) {
|
|
|
67
83
|
lines.push(tr(`暂不可用:${cached.disabledReason ?? notOpenText()}`, `Not available: ${cached.disabledReason ?? notOpenText()}`));
|
|
68
84
|
}
|
|
69
85
|
if (envBin) {
|
|
70
|
-
const v = probeVersion(envBin, paths.configDir, spec);
|
|
86
|
+
const v = probeVersion(envBin, paths.configDir, spec, node);
|
|
71
87
|
lines.push(tr(`使用 ${spec.binEnv} 指定的 ${envBin}(${v ?? "无法运行"})`, `Using ${envBin} from ${spec.binEnv} (${v ?? "doesn't run"})`));
|
|
72
88
|
if (v && checkBrake(v, brake) === "above_max_tested") {
|
|
73
89
|
lines.push(tr(`它${verdictText("above_max_tested", brake)},运行时改用 u1s1 管理的版本`, `It's ${verdictText("above_max_tested", brake)}; u1s1 ${agent} uses a u1s1-managed copy instead`));
|
|
@@ -116,7 +132,7 @@ async function managedAgentLines(agent) {
|
|
|
116
132
|
}
|
|
117
133
|
return lines;
|
|
118
134
|
}
|
|
119
|
-
const PIN_EXAMPLE = { claude: "2.1.322", codex: "0.167.2" };
|
|
135
|
+
const PIN_EXAMPLE = { claude: "2.1.322", codex: "0.167.2", dsh: DSH_TESTED_VERSION };
|
|
120
136
|
export async function pinCommand(raw, agent = "claude") {
|
|
121
137
|
const version = normalizeVersion(raw);
|
|
122
138
|
if (!version) {
|
|
@@ -196,6 +212,7 @@ export async function installCommand(deps = {}, agent = "claude") {
|
|
|
196
212
|
return got;
|
|
197
213
|
brake = got;
|
|
198
214
|
}
|
|
215
|
+
brake = effectiveBrake(agent, brake);
|
|
199
216
|
const paths = launchPaths(agent);
|
|
200
217
|
const spec = runtimeSpec(agent);
|
|
201
218
|
mkdirSync(paths.configDir, { recursive: true, mode: 0o700 });
|
|
@@ -210,6 +227,13 @@ export async function installCommand(deps = {}, agent = "claude") {
|
|
|
210
227
|
force: true,
|
|
211
228
|
}).catch(() => undefined);
|
|
212
229
|
}
|
|
230
|
+
// dsh:先准备够新的 Node(没有就征得同意后下载)
|
|
231
|
+
let node;
|
|
232
|
+
if (spec.minNode) {
|
|
233
|
+
node = (deps.ensureNode ? await deps.ensureNode() : await ensureDshNode(site.id))?.bin;
|
|
234
|
+
if (!node)
|
|
235
|
+
return 1;
|
|
236
|
+
}
|
|
213
237
|
let runtime;
|
|
214
238
|
try {
|
|
215
239
|
runtime = await (deps.ensure ?? ensureAgentRuntime)(agent, {
|
|
@@ -218,6 +242,7 @@ export async function installCommand(deps = {}, agent = "claude") {
|
|
|
218
242
|
agentsRoot: agentsRoot(),
|
|
219
243
|
hooks: cliInstallHooks(agent),
|
|
220
244
|
probeConfigDir: paths.configDir,
|
|
245
|
+
node,
|
|
221
246
|
});
|
|
222
247
|
}
|
|
223
248
|
catch (e) {
|
package/dist/api.d.ts
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type JsonRecord } from "./json.ts";
|
|
2
|
+
import { type ReasoningFields } from "./thinking.ts";
|
|
3
|
+
export declare const MESSAGES_PATH = "/v1/messages";
|
|
4
|
+
/** Chat usage (any OpenAI-compatible shape) → Anthropic usage. */
|
|
5
|
+
export type AnthropicUsage = (usage: unknown) => JsonRecord;
|
|
6
|
+
/**
|
|
7
|
+
* Plain Chat Completions usage → Anthropic usage: cache reads
|
|
8
|
+
* (`prompt_tokens_details.cached_tokens`, or DeepSeek's
|
|
9
|
+
* `prompt_cache_hit_tokens`) are reported beside `input_tokens`, not in it.
|
|
10
|
+
*/
|
|
11
|
+
export declare function chatUsageToAnthropic(value: unknown): JsonRecord;
|
|
12
|
+
/** Anthropic error body: `{type: "error", error: {type, message}}`. */
|
|
13
|
+
export declare function anthropicErrorBody(status: number, message: string): JsonRecord;
|
|
14
|
+
/**
|
|
15
|
+
* Anthropic Messages request → Chat Completions body. `thinking` and
|
|
16
|
+
* `output_config.effort` become whatever `reasoningFields` returns for the
|
|
17
|
+
* requested level (thinking.ts); `metadata` is dropped on purpose.
|
|
18
|
+
*/
|
|
19
|
+
export declare function anthropicRequestToChat(body: JsonRecord, reasoningFields: ReasoningFields): JsonRecord;
|
|
20
|
+
export declare function chatCompletionToAnthropic(value: unknown, requestedModel: string, usage?: AnthropicUsage): JsonRecord;
|
|
21
|
+
/** OpenAI chat.completion.chunk SSE → Anthropic Messages SSE event sequence. */
|
|
22
|
+
export declare function chatSseToAnthropic(requestedModel: string, usage?: AnthropicUsage): TransformStream<Uint8Array, Uint8Array>;
|
|
23
|
+
export declare function anthropicErrorType(status: number): string;
|
|
24
|
+
/**
|
|
25
|
+
* Anthropic SDKs retry 408/409/429/5xx unless the server sends
|
|
26
|
+
* `x-should-retry: false`. Quota and policy refusals are final: without the
|
|
27
|
+
* header the client would hammer the gateway with retries.
|
|
28
|
+
*/
|
|
29
|
+
export declare function anthropicShouldRetry(status: number, code: unknown): boolean;
|