helixlife-expert-cli 0.3.0 → 0.3.1
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/cli/dist/core/api/client.d.ts.map +1 -1
- package/cli/dist/core/api/client.js +34 -9
- package/cli/dist/core/api/client.js.map +1 -1
- package/cli/dist/core/api/http.d.ts +3 -0
- package/cli/dist/core/api/http.d.ts.map +1 -1
- package/cli/dist/core/api/http.js +38 -6
- package/cli/dist/core/api/http.js.map +1 -1
- package/cli/dist/core/errors.d.ts +27 -0
- package/cli/dist/core/errors.d.ts.map +1 -1
- package/cli/dist/core/errors.js +49 -0
- package/cli/dist/core/errors.js.map +1 -1
- package/cli/dist/core/index.d.ts +3 -3
- package/cli/dist/core/index.d.ts.map +1 -1
- package/cli/dist/core/index.js +3 -3
- package/cli/dist/core/index.js.map +1 -1
- package/cli/dist/core/paths.d.ts +16 -0
- package/cli/dist/core/paths.d.ts.map +1 -1
- package/cli/dist/core/paths.js +70 -1
- package/cli/dist/core/paths.js.map +1 -1
- package/cli/dist/core/sse-utils.d.ts +6 -1
- package/cli/dist/core/sse-utils.d.ts.map +1 -1
- package/cli/dist/core/sse-utils.js +39 -5
- package/cli/dist/core/sse-utils.js.map +1 -1
- package/cli/dist/index.d.ts.map +1 -1
- package/cli/dist/index.js +27 -1
- package/cli/dist/index.js.map +1 -1
- package/cli/dist/modules/fund/clinical/commands/article-download.js +2 -2
- package/cli/dist/modules/fund/clinical/commands/article-download.js.map +1 -1
- package/cli/dist/modules/fund/clinical/session-cache.d.ts +1 -0
- package/cli/dist/modules/fund/clinical/session-cache.d.ts.map +1 -1
- package/cli/dist/modules/fund/clinical/session-cache.js +9 -5
- package/cli/dist/modules/fund/clinical/session-cache.js.map +1 -1
- package/cli/dist/modules/fund/nsfc/article-cache.d.ts +1 -1
- package/cli/dist/modules/fund/nsfc/article-cache.d.ts.map +1 -1
- package/cli/dist/modules/fund/nsfc/article-cache.js +9 -7
- package/cli/dist/modules/fund/nsfc/article-cache.js.map +1 -1
- package/cli/dist/modules/fund/nsfc/commands/article-download.js +2 -2
- package/cli/dist/modules/fund/nsfc/commands/article-download.js.map +1 -1
- package/cli/dist/modules/fund/nsfc/commands/hypothesis-figure.d.ts.map +1 -1
- package/cli/dist/modules/fund/nsfc/commands/hypothesis-figure.js +12 -3
- package/cli/dist/modules/fund/nsfc/commands/hypothesis-figure.js.map +1 -1
- package/cli/dist/modules/fund/nsfc/commands/tech-roadmap.js +2 -2
- package/cli/dist/modules/fund/nsfc/commands/tech-roadmap.js.map +1 -1
- package/cli/dist/modules/fund/nsfc/session-cache.d.ts +1 -1
- package/cli/dist/modules/fund/nsfc/session-cache.d.ts.map +1 -1
- package/cli/dist/modules/fund/nsfc/session-cache.js +9 -7
- package/cli/dist/modules/fund/nsfc/session-cache.js.map +1 -1
- package/cli/dist/modules/literature/commands/workflow-run.d.ts +1 -0
- package/cli/dist/modules/literature/commands/workflow-run.d.ts.map +1 -1
- package/cli/dist/modules/literature/commands/workflow-run.js +1 -0
- package/cli/dist/modules/literature/commands/workflow-run.js.map +1 -1
- package/cli/dist/modules/literature/index.d.ts.map +1 -1
- package/cli/dist/modules/literature/index.js +3 -0
- package/cli/dist/modules/literature/index.js.map +1 -1
- package/cli/dist/modules/meta/analysis.d.ts.map +1 -1
- package/cli/dist/modules/meta/analysis.js +12 -10
- package/cli/dist/modules/meta/analysis.js.map +1 -1
- package/cli/dist/modules/meta/extraction.d.ts.map +1 -1
- package/cli/dist/modules/meta/extraction.js +8 -8
- package/cli/dist/modules/meta/extraction.js.map +1 -1
- package/cli/dist/modules/meta/retrieve.d.ts.map +1 -1
- package/cli/dist/modules/meta/retrieve.js +2 -1
- package/cli/dist/modules/meta/retrieve.js.map +1 -1
- package/cli/dist/modules/meta/screening.d.ts.map +1 -1
- package/cli/dist/modules/meta/screening.js +6 -5
- package/cli/dist/modules/meta/screening.js.map +1 -1
- package/cli/dist/modules/meta/topic.d.ts.map +1 -1
- package/cli/dist/modules/meta/topic.js +2 -1
- package/cli/dist/modules/meta/topic.js.map +1 -1
- package/cli/dist/modules/meta/writing.d.ts.map +1 -1
- package/cli/dist/modules/meta/writing.js +14 -7
- package/cli/dist/modules/meta/writing.js.map +1 -1
- package/cli/dist/modules/proposal/commands/bioinfo-run.d.ts +1 -0
- package/cli/dist/modules/proposal/commands/bioinfo-run.d.ts.map +1 -1
- package/cli/dist/modules/proposal/commands/bioinfo-run.js +1 -0
- package/cli/dist/modules/proposal/commands/bioinfo-run.js.map +1 -1
- package/cli/dist/modules/proposal/commands/clinical-run.d.ts +1 -0
- package/cli/dist/modules/proposal/commands/clinical-run.d.ts.map +1 -1
- package/cli/dist/modules/proposal/commands/clinical-run.js +1 -0
- package/cli/dist/modules/proposal/commands/clinical-run.js.map +1 -1
- package/cli/dist/modules/proposal/index.d.ts.map +1 -1
- package/cli/dist/modules/proposal/index.js +5 -0
- package/cli/dist/modules/proposal/index.js.map +1 -1
- package/cli/dist/modules/sci/article-cache.d.ts +1 -1
- package/cli/dist/modules/sci/article-cache.d.ts.map +1 -1
- package/cli/dist/modules/sci/article-cache.js +12 -12
- package/cli/dist/modules/sci/article-cache.js.map +1 -1
- package/cli/dist/modules/sci/commands/article-download.d.ts.map +1 -1
- package/cli/dist/modules/sci/commands/article-download.js +5 -4
- package/cli/dist/modules/sci/commands/article-download.js.map +1 -1
- package/cli/dist/modules/sci/precheck-cache.js +1 -1
- package/cli/dist/modules/shared/result-wrapper.d.ts +4 -2
- package/cli/dist/modules/shared/result-wrapper.d.ts.map +1 -1
- package/cli/dist/modules/shared/result-wrapper.js +3 -1
- package/cli/dist/modules/shared/result-wrapper.js.map +1 -1
- package/cli/dist/modules/shared/workflow-app/command.d.ts +4 -1
- package/cli/dist/modules/shared/workflow-app/command.d.ts.map +1 -1
- package/cli/dist/modules/shared/workflow-app/command.js +88 -21
- package/cli/dist/modules/shared/workflow-app/command.js.map +1 -1
- package/cli/dist/modules/shared/workflow-app/form.d.ts +5 -1
- package/cli/dist/modules/shared/workflow-app/form.d.ts.map +1 -1
- package/cli/dist/modules/shared/workflow-app/form.js +6 -2
- package/cli/dist/modules/shared/workflow-app/form.js.map +1 -1
- package/cli/dist/modules/shared/workflow-app/index.d.ts +1 -1
- package/cli/dist/modules/shared/workflow-app/index.d.ts.map +1 -1
- package/cli/dist/modules/shared/workflow-app/index.js +1 -1
- package/cli/dist/modules/shared/workflow-app/index.js.map +1 -1
- package/cli/dist/modules/shared/workflow-app/run.d.ts.map +1 -1
- package/cli/dist/modules/shared/workflow-app/run.js +3 -7
- package/cli/dist/modules/shared/workflow-app/run.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/core/api/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/core/api/client.ts"],"names":[],"mappings":"AAWA,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAuB/D,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IAC/D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IAGrB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC;CAChD;AAGD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAgBD,qBAAa,SAAS;IAEpB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,QAAQ;IAkBhB,OAAO,CAAC,YAAY;YAkBN,gBAAgB;IAwC9B,OAAO,CAAC,uBAAuB;YAsBjB,IAAI;IAmCZ,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;IA0BlE,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,cAAc,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO,GAClD,OAAO,CAAC,cAAc,CAAC;IAQpB,UAAU,CACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GACzC,OAAO,CAAC,IAAI,CAAC;YA0CF,kBAAkB;IAehC,OAAO,CAAC,qCAAqC;CAa9C"}
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
// 后台 API 请求客户端:统一附加 Token、平台头、超时与 401 处理
|
|
2
|
-
import { helixlifeError, helixlifeErrorCode, NOT_AUTHENTICATED_MESSAGE, TOKEN_EXPIRED_MESSAGE, } from "../errors.js";
|
|
2
|
+
import { createNetworkBlockedError, helixlifeError, helixlifeErrorCode, isNetworkBlockedText, isNonRetryableServerMessage, NOT_AUTHENTICATED_MESSAGE, TOKEN_EXPIRED_MESSAGE, } from "../errors.js";
|
|
3
3
|
import { getDefaultBaseUrl } from "../types/config.js";
|
|
4
4
|
import { parseSseStream } from "./sse.js";
|
|
5
5
|
import { loadTokenFromFile } from "../token/index.js";
|
|
6
6
|
import { getPackageVersion } from "../version.js";
|
|
7
|
-
import { DEFAULT_REQUEST_TIMEOUT_MS, fetchWithTimeout } from "./http.js";
|
|
7
|
+
import { DEFAULT_REQUEST_TIMEOUT_MS, fetchWithTimeout, toNetworkError, } from "./http.js";
|
|
8
|
+
// 后端常见的追踪 ID 响应头
|
|
9
|
+
const TRACE_ID_HEADERS = ["x-trace-id", "trace-id", "x-request-id", "traceid"];
|
|
10
|
+
function readTraceId(response) {
|
|
11
|
+
for (const name of TRACE_ID_HEADERS) {
|
|
12
|
+
const value = response.headers.get(name);
|
|
13
|
+
if (value) {
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
8
19
|
// 当前安装的 CLI 版本(来自本包 package.json,不是 npm 最新版)
|
|
9
20
|
const CLI_VERSION = getPackageVersion();
|
|
10
21
|
// 前台通用请求头,与 vip.helixlife.cn 浏览器调用保持一致
|
|
@@ -12,6 +23,7 @@ const PLATFORM_HEADERS = {
|
|
|
12
23
|
platform: "pc",
|
|
13
24
|
source: "PC",
|
|
14
25
|
website: "helixlife-ai",
|
|
26
|
+
"x-user-identity": "open-sience-pro",
|
|
15
27
|
"User-Agent": `helix-cli/${CLI_VERSION}`,
|
|
16
28
|
"X-Client-Version": CLI_VERSION,
|
|
17
29
|
};
|
|
@@ -51,17 +63,30 @@ export class ApiClient {
|
|
|
51
63
|
return headers;
|
|
52
64
|
}
|
|
53
65
|
// 校验 HTTP 响应状态:401 视为凭证无效;403 解开后端文案(含购买链接)为 E1005
|
|
54
|
-
|
|
66
|
+
// 沙箱代理拦截的 403 正文带 OPEN_SCIENCE_NETWORK_DOMAIN_BLOCKED,需与业务 403 区分
|
|
67
|
+
async assertOkResponse(response, url) {
|
|
68
|
+
const traceId = readTraceId(response);
|
|
55
69
|
if (response.status === 401) {
|
|
56
|
-
throw new helixlifeError(helixlifeErrorCode.TOKEN_EXPIRED, TOKEN_EXPIRED_MESSAGE);
|
|
70
|
+
throw new helixlifeError(helixlifeErrorCode.TOKEN_EXPIRED, TOKEN_EXPIRED_MESSAGE, { traceId });
|
|
57
71
|
}
|
|
58
72
|
if (response.status === 403) {
|
|
59
73
|
const text = await response.text().catch(() => "");
|
|
60
|
-
|
|
74
|
+
if (isNetworkBlockedText(text)) {
|
|
75
|
+
throw createNetworkBlockedError(url.hostname);
|
|
76
|
+
}
|
|
77
|
+
throw new helixlifeError(helixlifeErrorCode.PERMISSION_DENIED, this.resolveForbiddenMessage(text, response.statusText), { traceId });
|
|
61
78
|
}
|
|
62
79
|
if (!response.ok) {
|
|
63
80
|
const text = await response.text().catch(() => "");
|
|
64
|
-
|
|
81
|
+
// 5xx / 429 多为瞬时故障;其余 4xx 与「参数非法」类为确定性失败
|
|
82
|
+
const transient = (response.status >= 500 || response.status === 429) &&
|
|
83
|
+
!isNonRetryableServerMessage(text);
|
|
84
|
+
throw new helixlifeError(helixlifeErrorCode.REQUEST_FAILED, `请求失败 (${response.status}): ${text || response.statusText}`, {
|
|
85
|
+
traceId,
|
|
86
|
+
retryable: transient,
|
|
87
|
+
nextAction: transient ? "retry_once" : "stop_and_report",
|
|
88
|
+
detail: { status: response.status, path: url.pathname },
|
|
89
|
+
});
|
|
65
90
|
}
|
|
66
91
|
}
|
|
67
92
|
// 403 优先使用后端 message(已含购买链接),解析失败再回退原始正文
|
|
@@ -99,7 +124,7 @@ export class ApiClient {
|
|
|
99
124
|
? options.body
|
|
100
125
|
: JSON.stringify(options.body),
|
|
101
126
|
}, DEFAULT_REQUEST_TIMEOUT_MS);
|
|
102
|
-
await this.assertOkResponse(response);
|
|
127
|
+
await this.assertOkResponse(response, url);
|
|
103
128
|
return response;
|
|
104
129
|
}
|
|
105
130
|
// 发起 REST 请求并解析 JSON 响应
|
|
@@ -149,9 +174,9 @@ export class ApiClient {
|
|
|
149
174
|
if (error instanceof Error && error.name === "AbortError") {
|
|
150
175
|
throw error;
|
|
151
176
|
}
|
|
152
|
-
throw
|
|
177
|
+
throw toNetworkError(url.toString(), error);
|
|
153
178
|
}
|
|
154
|
-
await this.assertOkResponse(response);
|
|
179
|
+
await this.assertOkResponse(response, url);
|
|
155
180
|
if (!response.body) {
|
|
156
181
|
throw new helixlifeError(helixlifeErrorCode.INVALID_RESPONSE, "SSE 响应体为空");
|
|
157
182
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/core/api/client.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAuB,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/core/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { helixlifeError } from "../errors.js";
|
|
1
2
|
export declare const DEFAULT_REQUEST_TIMEOUT_MS = 60000;
|
|
3
|
+
/** fetch 抛错(非 HTTP 状态)统一映射为 NETWORK_ERROR,并附带目标 hostname */
|
|
4
|
+
export declare function toNetworkError(url: string, error: unknown, timedOut?: boolean): helixlifeError;
|
|
2
5
|
export declare function fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number): Promise<Response>;
|
|
3
6
|
//# sourceMappingURL=http.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/core/api/http.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/core/api/http.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,cAAc,EAGf,MAAM,cAAc,CAAC;AAGtB,eAAO,MAAM,0BAA0B,QAAS,CAAC;AA0BjD,4DAA4D;AAC5D,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,QAAQ,UAAQ,GACf,cAAc,CAahB;AAGD,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,CAAC,CAUnB"}
|
|
@@ -1,7 +1,42 @@
|
|
|
1
1
|
// 带超时的 fetch 封装,供 REST 请求与授权接口统一复用
|
|
2
|
-
import { helixlifeError, helixlifeErrorCode } from "../errors.js";
|
|
2
|
+
import { createNetworkBlockedError, helixlifeError, helixlifeErrorCode, isNetworkBlockedText, } from "../errors.js";
|
|
3
3
|
// 普通 REST / 授权类请求的默认整体超时(毫秒)
|
|
4
4
|
export const DEFAULT_REQUEST_TIMEOUT_MS = 60_000;
|
|
5
|
+
function hostnameOf(url) {
|
|
6
|
+
try {
|
|
7
|
+
return new URL(url).hostname;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
// 拼接错误链上的文本,用于识别沙箱代理拦截(undici 把代理 403 放在 cause 里)
|
|
14
|
+
function collectErrorText(error) {
|
|
15
|
+
const parts = [];
|
|
16
|
+
let current = error;
|
|
17
|
+
for (let depth = 0; current && depth < 5; depth += 1) {
|
|
18
|
+
if (current instanceof Error) {
|
|
19
|
+
parts.push(current.message);
|
|
20
|
+
current = current.cause;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
parts.push(String(current));
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return parts.join(" | ");
|
|
28
|
+
}
|
|
29
|
+
/** fetch 抛错(非 HTTP 状态)统一映射为 NETWORK_ERROR,并附带目标 hostname */
|
|
30
|
+
export function toNetworkError(url, error, timedOut = false) {
|
|
31
|
+
const hostname = hostnameOf(url);
|
|
32
|
+
if (hostname && isNetworkBlockedText(collectErrorText(error))) {
|
|
33
|
+
return createNetworkBlockedError(hostname, error);
|
|
34
|
+
}
|
|
35
|
+
const target = hostname ? `(${hostname})` : "";
|
|
36
|
+
return new helixlifeError(helixlifeErrorCode.NETWORK_ERROR, timedOut
|
|
37
|
+
? `请求超时${target},请检查网络或稍后重试`
|
|
38
|
+
: `网络请求失败${target},请检查后台服务是否可用`, { cause: error, hostname });
|
|
39
|
+
}
|
|
5
40
|
// 带超时的 fetch:超时或网络失败统一映射为 helixlifeError(NETWORK_ERROR),避免网络挂起时长时间无响应
|
|
6
41
|
export async function fetchWithTimeout(url, init, timeoutMs) {
|
|
7
42
|
const controller = new AbortController();
|
|
@@ -9,11 +44,8 @@ export async function fetchWithTimeout(url, init, timeoutMs) {
|
|
|
9
44
|
try {
|
|
10
45
|
return await fetch(url, { ...init, signal: controller.signal });
|
|
11
46
|
}
|
|
12
|
-
catch {
|
|
13
|
-
|
|
14
|
-
throw new helixlifeError(helixlifeErrorCode.NETWORK_ERROR, "请求超时,请检查网络或稍后重试");
|
|
15
|
-
}
|
|
16
|
-
throw new helixlifeError(helixlifeErrorCode.NETWORK_ERROR, "网络请求失败,请检查后台服务是否可用");
|
|
47
|
+
catch (error) {
|
|
48
|
+
throw toNetworkError(url, error, controller.signal.aborted);
|
|
17
49
|
}
|
|
18
50
|
finally {
|
|
19
51
|
clearTimeout(timer);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/core/api/http.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,OAAO,
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/core/api/http.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,OAAO,EACL,yBAAyB,EACzB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,cAAc,CAAC;AAEtB,6BAA6B;AAC7B,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAEjD,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,kDAAkD;AAClD,SAAS,gBAAgB,CAAC,KAAc;IACtC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO,GAAY,KAAK,CAAC;IAC7B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,OAAO,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACrD,IAAI,OAAO,YAAY,KAAK,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC5B,OAAO,GAAI,OAA+B,CAAC,KAAK,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YAC5B,MAAM;QACR,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,cAAc,CAC5B,GAAW,EACX,KAAc,EACd,QAAQ,GAAG,KAAK;IAEhB,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,QAAQ,IAAI,oBAAoB,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QAC9D,OAAO,yBAAyB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/C,OAAO,IAAI,cAAc,CACvB,kBAAkB,CAAC,aAAa,EAChC,QAAQ;QACN,CAAC,CAAC,OAAO,MAAM,aAAa;QAC5B,CAAC,CAAC,SAAS,MAAM,cAAc,EACjC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAC3B,CAAC;AACJ,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAW,EACX,IAAiB,EACjB,SAAiB;IAEjB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;IAC9D,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;IAClE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9D,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const NOT_AUTHENTICATED_MESSAGE = "\u672C\u5730\u65E0\u6709\u6548\u51ED\u8BC1\uFF0C\u65E0\u6CD5\u8BBF\u95EE\u540E\u53F0\u63A5\u53E3";
|
|
2
2
|
export declare const TOKEN_EXPIRED_MESSAGE = "\u5F53\u524D\u51ED\u8BC1\u65E0\u6CD5\u8BBF\u95EE\u540E\u53F0\u63A5\u53E3";
|
|
3
|
+
export declare const OPEN_SCIENCE_NETWORK_BLOCKED_MARKER = "OPEN_SCIENCE_NETWORK_DOMAIN_BLOCKED";
|
|
3
4
|
export declare enum helixlifeErrorCode {
|
|
4
5
|
NOT_AUTHENTICATED = "E1001",
|
|
5
6
|
TOKEN_EXPIRED = "E1004",
|
|
@@ -9,12 +10,38 @@ export declare enum helixlifeErrorCode {
|
|
|
9
10
|
NETWORK_ERROR = "E5001",
|
|
10
11
|
INVALID_RESPONSE = "E5002"
|
|
11
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* 宿主 Agent 收到错误后的处置建议:
|
|
15
|
+
* - ask_user:需用户介入(登录、授权、购买、补充参数)
|
|
16
|
+
* - fix_inputs:Agent 自行修正命令参数 / inputs 后重试一次
|
|
17
|
+
* - request_network_access:向平台申请该 hostname 的网络访问后重试一次
|
|
18
|
+
* - retry_once:瞬时故障,原样重试一次,仍失败则停止并报告
|
|
19
|
+
* - stop_and_report:服务端确定性失败,重试无意义,直接向用户报告
|
|
20
|
+
*/
|
|
21
|
+
export type helixlifeNextAction = "ask_user" | "fix_inputs" | "request_network_access" | "retry_once" | "stop_and_report";
|
|
12
22
|
export interface helixlifeErrorOptions extends ErrorOptions {
|
|
13
23
|
cause?: unknown;
|
|
24
|
+
retryable?: boolean;
|
|
25
|
+
nextAction?: helixlifeNextAction;
|
|
26
|
+
/** 网络类错误的目标主机名(不含协议与端口),供申请网络访问 */
|
|
27
|
+
hostname?: string;
|
|
28
|
+
/** 服务端返回的追踪 ID,供后端排查 */
|
|
29
|
+
traceId?: string;
|
|
30
|
+
/** 服务端原始错误事件 / 响应片段(已去除凭证) */
|
|
31
|
+
detail?: unknown;
|
|
14
32
|
}
|
|
15
33
|
export declare class helixlifeError extends Error {
|
|
16
34
|
readonly code: helixlifeErrorCode;
|
|
17
35
|
readonly cause?: unknown;
|
|
36
|
+
readonly retryable: boolean;
|
|
37
|
+
readonly nextAction: helixlifeNextAction;
|
|
38
|
+
readonly hostname?: string;
|
|
39
|
+
readonly traceId?: string;
|
|
40
|
+
readonly detail?: unknown;
|
|
18
41
|
constructor(code: helixlifeErrorCode, message: string, options?: helixlifeErrorOptions);
|
|
42
|
+
toJSON(): Record<string, unknown>;
|
|
19
43
|
}
|
|
44
|
+
export declare function isNonRetryableServerMessage(message: string): boolean;
|
|
45
|
+
export declare function isNetworkBlockedText(text: string): boolean;
|
|
46
|
+
export declare function createNetworkBlockedError(hostname: string, cause?: unknown): helixlifeError;
|
|
20
47
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,yBAAyB,qGAClB,CAAC;AAGrB,eAAO,MAAM,qBAAqB,6EAAiB,CAAC;AAGpD,oBAAY,kBAAkB;IAC5B,iBAAiB,UAAU;IAC3B,aAAa,UAAU;IACvB,iBAAiB,UAAU;IAC3B,gBAAgB,UAAU;IAC1B,cAAc,UAAU;IACxB,aAAa,UAAU;IACvB,gBAAgB,UAAU;CAC3B;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,yBAAyB,qGAClB,CAAC;AAGrB,eAAO,MAAM,qBAAqB,6EAAiB,CAAC;AAGpD,eAAO,MAAM,mCAAmC,wCACT,CAAC;AAGxC,oBAAY,kBAAkB;IAC5B,iBAAiB,UAAU;IAC3B,aAAa,UAAU;IACvB,iBAAiB,UAAU;IAC3B,gBAAgB,UAAU;IAC1B,cAAc,UAAU;IACxB,aAAa,UAAU;IACvB,gBAAgB,UAAU;CAC3B;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAC3B,UAAU,GACV,YAAY,GACZ,wBAAwB,GACxB,YAAY,GACZ,iBAAiB,CAAC;AAGtB,MAAM,WAAW,qBAAsB,SAAQ,YAAY;IACzD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAiBD,qBAAa,cAAe,SAAQ,KAAK;IACvC,SAAgB,IAAI,EAAE,kBAAkB,CAAC;IACzC,SAAyB,KAAK,CAAC,EAAE,OAAO,CAAC;IACzC,SAAgB,SAAS,EAAE,OAAO,CAAC;IACnC,SAAgB,UAAU,EAAE,mBAAmB,CAAC;IAChD,SAAgB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClC,SAAgB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjC,SAAgB,MAAM,CAAC,EAAE,OAAO,CAAC;gBAG/B,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,qBAAqB;IAejC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAWlC;AAQD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEpE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAGD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,OAAO,GACd,cAAc,CAMhB"}
|
package/cli/dist/core/errors.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
export const NOT_AUTHENTICATED_MESSAGE = "本地无有效凭证,无法访问后台接口";
|
|
3
3
|
// 后台返回 401 时的全局统一提示文案,供 API 调用与命令层复用
|
|
4
4
|
export const TOKEN_EXPIRED_MESSAGE = "当前凭证无法访问后台接口";
|
|
5
|
+
// Open-Science 沙箱代理拦截未授权域名时,在 403 正文 / 代理错误里携带的标记
|
|
6
|
+
export const OPEN_SCIENCE_NETWORK_BLOCKED_MARKER = "OPEN_SCIENCE_NETWORK_DOMAIN_BLOCKED";
|
|
5
7
|
// helixlife CLI 统一错误码定义
|
|
6
8
|
export var helixlifeErrorCode;
|
|
7
9
|
(function (helixlifeErrorCode) {
|
|
@@ -13,16 +15,63 @@ export var helixlifeErrorCode;
|
|
|
13
15
|
helixlifeErrorCode["NETWORK_ERROR"] = "E5001";
|
|
14
16
|
helixlifeErrorCode["INVALID_RESPONSE"] = "E5002";
|
|
15
17
|
})(helixlifeErrorCode || (helixlifeErrorCode = {}));
|
|
18
|
+
const DEFAULT_DISPOSITION = {
|
|
19
|
+
[helixlifeErrorCode.NOT_AUTHENTICATED]: { retryable: false, nextAction: "ask_user" },
|
|
20
|
+
[helixlifeErrorCode.TOKEN_EXPIRED]: { retryable: false, nextAction: "ask_user" },
|
|
21
|
+
[helixlifeErrorCode.PERMISSION_DENIED]: { retryable: false, nextAction: "ask_user" },
|
|
22
|
+
[helixlifeErrorCode.INVALID_ARGUMENT]: { retryable: false, nextAction: "fix_inputs" },
|
|
23
|
+
[helixlifeErrorCode.REQUEST_FAILED]: { retryable: false, nextAction: "stop_and_report" },
|
|
24
|
+
[helixlifeErrorCode.NETWORK_ERROR]: { retryable: true, nextAction: "retry_once" },
|
|
25
|
+
[helixlifeErrorCode.INVALID_RESPONSE]: { retryable: true, nextAction: "retry_once" },
|
|
26
|
+
};
|
|
16
27
|
// 结构化 CLI 错误,供命令层与 Agent 解析
|
|
17
28
|
// 支持错误链(cause)以便调试时追溯原始错误
|
|
18
29
|
export class helixlifeError extends Error {
|
|
19
30
|
code;
|
|
20
31
|
cause;
|
|
32
|
+
retryable;
|
|
33
|
+
nextAction;
|
|
34
|
+
hostname;
|
|
35
|
+
traceId;
|
|
36
|
+
detail;
|
|
21
37
|
constructor(code, message, options) {
|
|
22
38
|
super(message, options);
|
|
23
39
|
this.name = "helixlifeError";
|
|
24
40
|
this.code = code;
|
|
25
41
|
this.cause = options?.cause;
|
|
42
|
+
const disposition = DEFAULT_DISPOSITION[code];
|
|
43
|
+
this.retryable = options?.retryable ?? disposition.retryable;
|
|
44
|
+
this.nextAction = options?.nextAction ?? disposition.nextAction;
|
|
45
|
+
this.hostname = options?.hostname;
|
|
46
|
+
this.traceId = options?.traceId;
|
|
47
|
+
this.detail = options?.detail;
|
|
26
48
|
}
|
|
49
|
+
// 机器可读的错误描述,供入口统一输出
|
|
50
|
+
toJSON() {
|
|
51
|
+
return {
|
|
52
|
+
code: this.code,
|
|
53
|
+
message: this.message,
|
|
54
|
+
retryable: this.retryable,
|
|
55
|
+
nextAction: this.nextAction,
|
|
56
|
+
...(this.hostname ? { hostname: this.hostname } : {}),
|
|
57
|
+
...(this.traceId ? { traceId: this.traceId } : {}),
|
|
58
|
+
...(this.detail !== undefined ? { detail: this.detail } : {}),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// 后端「参数非法 / 服务已停止」属于确定性失败,换参数或重试都不会成功
|
|
63
|
+
const NON_RETRYABLE_SERVER_PATTERNS = [
|
|
64
|
+
/parameter invalid/i,
|
|
65
|
+
/service has been stopped/i,
|
|
66
|
+
];
|
|
67
|
+
export function isNonRetryableServerMessage(message) {
|
|
68
|
+
return NON_RETRYABLE_SERVER_PATTERNS.some((pattern) => pattern.test(message));
|
|
69
|
+
}
|
|
70
|
+
export function isNetworkBlockedText(text) {
|
|
71
|
+
return text.includes(OPEN_SCIENCE_NETWORK_BLOCKED_MARKER);
|
|
72
|
+
}
|
|
73
|
+
// 沙箱拦截:统一构造「申请网络访问」错误,hostname 供 Agent 直接填入审批请求
|
|
74
|
+
export function createNetworkBlockedError(hostname, cause) {
|
|
75
|
+
return new helixlifeError(helixlifeErrorCode.NETWORK_ERROR, `平台沙箱未放行域名 ${hostname},需申请网络访问后重试`, { cause, retryable: true, nextAction: "request_network_access", hostname });
|
|
27
76
|
}
|
|
28
77
|
//# sourceMappingURL=errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,MAAM,CAAC,MAAM,yBAAyB,GACpC,kBAAkB,CAAC;AAErB,qCAAqC;AACrC,MAAM,CAAC,MAAM,qBAAqB,GAAG,cAAc,CAAC;AAEpD,wBAAwB;AACxB,MAAM,CAAN,IAAY,kBAQX;AARD,WAAY,kBAAkB;IAC5B,iDAA2B,CAAA;IAC3B,6CAAuB,CAAA;IACvB,iDAA2B,CAAA;IAC3B,gDAA0B,CAAA;IAC1B,8CAAwB,CAAA;IACxB,6CAAuB,CAAA;IACvB,gDAA0B,CAAA;AAC5B,CAAC,EARW,kBAAkB,KAAlB,kBAAkB,QAQ7B;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"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"}
|
package/cli/dist/core/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { helixlifeError, helixlifeErrorCode, NOT_AUTHENTICATED_MESSAGE, TOKEN_EXPIRED_MESSAGE, } from "./errors.js";
|
|
1
|
+
export { helixlifeError, helixlifeErrorCode, NOT_AUTHENTICATED_MESSAGE, TOKEN_EXPIRED_MESSAGE, OPEN_SCIENCE_NETWORK_BLOCKED_MARKER, createNetworkBlockedError, isNetworkBlockedText, isNonRetryableServerMessage, type helixlifeNextAction, } from "./errors.js";
|
|
2
2
|
export { fetchWithTimeout, DEFAULT_REQUEST_TIMEOUT_MS } from "./api/http.js";
|
|
3
3
|
export { ApiClient, type BinaryResponse, type RequestOptions, } from "./api/client.js";
|
|
4
4
|
export { parseSseStream, type SseDataPayload } from "./api/sse.js";
|
|
@@ -6,10 +6,10 @@ export { unwrapResponse, unwrapApiData, unwrapNestedApiData, extractNestedData,
|
|
|
6
6
|
export { getTokenFilePath, loadTokenFromFile, TOKEN_DIR_NAME, TOKEN_FILE_NAME, } from "./token/index.js";
|
|
7
7
|
export { getDefaultBaseUrl, getDefaultAuthBaseUrl, getDefaultNewideaBaseUrl, type helixlifeConfig, } from "./types/config.js";
|
|
8
8
|
export { loadLocalConfig, saveLocalConfig, updateLocalConfigField, clearLocalConfig, getLocalConfigPath, isValidConfigSetKey, CONFIG_SET_KEYS, CONFIG_DIR_NAME, LOCAL_CONFIG_FILE_NAME, type LocalConfig, type ConfigSetKey, } from "./env-config.js";
|
|
9
|
-
export { getUserDownloadsDir, resolveUserPath, sanitizeFilename, type SanitizeFilenameOptions, } from "./paths.js";
|
|
9
|
+
export { getUserDownloadsDir, getHelixlifeOutputDir, getHelixlifeStateDir, getOpenScienceHandoffDir, isOpenScienceRuntime, pruneStaleStateFiles, OPEN_SCIENCE_HANDOFF_ENV, HELIXLIFE_CACHE_DIR_ENV, resolveUserPath, sanitizeFilename, type SanitizeFilenameOptions, } from "./paths.js";
|
|
10
10
|
export { printOutput, emitJson, stringifyJsonAscii, renderListAsMarkdown, renderListAsHtmlTable, createStderrProgress, createFormatLogger, parseOutputFormat, type OutputFormat, type ProgressReporter, } from "./output/index.js";
|
|
11
11
|
export { getPackageVersion } from "./version.js";
|
|
12
|
-
export { extractSseText, assertWorkflowSucceeded, pickWorkflowOutputText, extractReferences, collectOutputs, extractRecordId, joinOutputsAsMarkdown, type ExtractSseTextOptions, } from "./sse-utils.js";
|
|
12
|
+
export { extractSseText, assertWorkflowSucceeded, createSseErrorEventError, pickWorkflowOutputText, extractReferences, collectOutputs, extractRecordId, joinOutputsAsMarkdown, type ExtractSseTextOptions, } from "./sse-utils.js";
|
|
13
13
|
export { parseIntegerOption, parseEnumOption } from "./parse.js";
|
|
14
14
|
export { isInteractiveTerminal } from "./terminal.js";
|
|
15
15
|
export { createInteractiveInterface, askOption, askOptionWithRl, } from "./interactive.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,EACrB,mCAAmC,EACnC,yBAAyB,EACzB,oBAAoB,EACpB,2BAA2B,EAC3B,KAAK,mBAAmB,GACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EACL,SAAS,EACT,KAAK,cAAc,EACnB,KAAK,cAAc,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EACL,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,gBAAgB,GACtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,KAAK,eAAe,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,KAAK,WAAW,EAChB,KAAK,YAAY,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,EACvB,eAAe,EACf,gBAAgB,EAChB,KAAK,uBAAuB,GAC7B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,WAAW,EACX,QAAQ,EACR,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,gBAAgB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,wBAAwB,EACxB,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,KAAK,qBAAqB,GAC3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EACL,0BAA0B,EAC1B,SAAS,EACT,eAAe,GAChB,MAAM,kBAAkB,CAAC"}
|
package/cli/dist/core/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { helixlifeError, helixlifeErrorCode, NOT_AUTHENTICATED_MESSAGE, TOKEN_EXPIRED_MESSAGE, } from "./errors.js";
|
|
1
|
+
export { helixlifeError, helixlifeErrorCode, NOT_AUTHENTICATED_MESSAGE, TOKEN_EXPIRED_MESSAGE, OPEN_SCIENCE_NETWORK_BLOCKED_MARKER, createNetworkBlockedError, isNetworkBlockedText, isNonRetryableServerMessage, } from "./errors.js";
|
|
2
2
|
export { fetchWithTimeout, DEFAULT_REQUEST_TIMEOUT_MS } from "./api/http.js";
|
|
3
3
|
export { ApiClient, } from "./api/client.js";
|
|
4
4
|
export { parseSseStream } from "./api/sse.js";
|
|
@@ -6,10 +6,10 @@ export { unwrapResponse, unwrapApiData, unwrapNestedApiData, extractNestedData,
|
|
|
6
6
|
export { getTokenFilePath, loadTokenFromFile, TOKEN_DIR_NAME, TOKEN_FILE_NAME, } from "./token/index.js";
|
|
7
7
|
export { getDefaultBaseUrl, getDefaultAuthBaseUrl, getDefaultNewideaBaseUrl, } from "./types/config.js";
|
|
8
8
|
export { loadLocalConfig, saveLocalConfig, updateLocalConfigField, clearLocalConfig, getLocalConfigPath, isValidConfigSetKey, CONFIG_SET_KEYS, CONFIG_DIR_NAME, LOCAL_CONFIG_FILE_NAME, } from "./env-config.js";
|
|
9
|
-
export { getUserDownloadsDir, resolveUserPath, sanitizeFilename, } from "./paths.js";
|
|
9
|
+
export { getUserDownloadsDir, getHelixlifeOutputDir, getHelixlifeStateDir, getOpenScienceHandoffDir, isOpenScienceRuntime, pruneStaleStateFiles, OPEN_SCIENCE_HANDOFF_ENV, HELIXLIFE_CACHE_DIR_ENV, resolveUserPath, sanitizeFilename, } from "./paths.js";
|
|
10
10
|
export { printOutput, emitJson, stringifyJsonAscii, renderListAsMarkdown, renderListAsHtmlTable, createStderrProgress, createFormatLogger, parseOutputFormat, } from "./output/index.js";
|
|
11
11
|
export { getPackageVersion } from "./version.js";
|
|
12
|
-
export { extractSseText, assertWorkflowSucceeded, pickWorkflowOutputText, extractReferences, collectOutputs, extractRecordId, joinOutputsAsMarkdown, } from "./sse-utils.js";
|
|
12
|
+
export { extractSseText, assertWorkflowSucceeded, createSseErrorEventError, pickWorkflowOutputText, extractReferences, collectOutputs, extractRecordId, joinOutputsAsMarkdown, } from "./sse-utils.js";
|
|
13
13
|
export { parseIntegerOption, parseEnumOption } from "./parse.js";
|
|
14
14
|
export { isInteractiveTerminal } from "./terminal.js";
|
|
15
15
|
export { createInteractiveInterface, askOption, askOptionWithRl, } from "./interactive.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,EACrB,mCAAmC,EACnC,yBAAyB,EACzB,oBAAoB,EACpB,2BAA2B,GAE5B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EACL,SAAS,GAGV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAuB,MAAM,cAAc,CAAC;AACnE,OAAO,EACL,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,GAGf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,GAEzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,sBAAsB,GAGvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,EACvB,eAAe,EACf,gBAAgB,GAEjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,WAAW,EACX,QAAQ,EACR,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,GAGlB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,wBAAwB,EACxB,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,qBAAqB,GAEtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EACL,0BAA0B,EAC1B,SAAS,EACT,eAAe,GAChB,MAAM,kBAAkB,CAAC"}
|
package/cli/dist/core/paths.d.ts
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
export declare const OPEN_SCIENCE_HANDOFF_ENV = "OPEN_SCIENCE_HANDOFF_DIR";
|
|
2
|
+
export declare const HELIXLIFE_CACHE_DIR_ENV = "HELIXLIFE_CACHE_DIR";
|
|
3
|
+
export declare function getOpenScienceHandoffDir(): string | undefined;
|
|
4
|
+
export declare function isOpenScienceRuntime(): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* 跨 CLI 进程的流程状态目录。
|
|
7
|
+
* 优先级:HELIXLIFE_CACHE_DIR → Open-Science 会话 handoff → ~/.config/helixlife/cache。
|
|
8
|
+
*/
|
|
9
|
+
export declare function getHelixlifeStateDir(kind: string): string;
|
|
10
|
+
/** 结果文件目录:Open-Science 下写入会话 handoff,供 Agent 以 Artifact 发布 */
|
|
11
|
+
export declare function getHelixlifeOutputDir(): string;
|
|
12
|
+
/**
|
|
13
|
+
* 清理用户目录兜底下的过期状态文件。
|
|
14
|
+
* handoff 目录随会话由平台管理,不做清理;失败静默,不影响主流程。
|
|
15
|
+
*/
|
|
16
|
+
export declare function pruneStaleStateFiles(directory: string, maxAgeMs?: number): Promise<void>;
|
|
1
17
|
export declare function getUserDownloadsDir(): string;
|
|
2
18
|
export interface SanitizeFilenameOptions {
|
|
3
19
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AAGnE,eAAO,MAAM,uBAAuB,wBAAwB,CAAC;AAK7D,wBAAgB,wBAAwB,IAAI,MAAM,GAAG,SAAS,CAG7D;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAUzD;AAED,8DAA8D;AAC9D,wBAAgB,qBAAqB,IAAI,MAAM,CAG9C;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,QAAQ,SAAyB,GAChC,OAAO,CAAC,IAAI,CAAC,CAqBf;AAGD,wBAAgB,mBAAmB,IAAI,MAAM,CAI5C;AAED,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,uBAA4B,GACpC,MAAM,CAsBR;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAsCvD"}
|
package/cli/dist/core/paths.js
CHANGED
|
@@ -1,5 +1,66 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readdir, rm, stat } from "node:fs/promises";
|
|
1
3
|
import { homedir, tmpdir } from "node:os";
|
|
2
|
-
import { join, resolve } from "node:path";
|
|
4
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
5
|
+
// Open-Science 为每个会话注入的跨调用共享目录;存在即视为运行在 Open-Science 中。
|
|
6
|
+
// 平台每条命令的 TEMP/TMP 都是一次性目录,命令结束即整目录删除,跨进程状态不能放在 tmpdir。
|
|
7
|
+
export const OPEN_SCIENCE_HANDOFF_ENV = "OPEN_SCIENCE_HANDOFF_DIR";
|
|
8
|
+
// 显式覆盖状态根目录(测试或 home 不可写的环境)
|
|
9
|
+
export const HELIXLIFE_CACHE_DIR_ENV = "HELIXLIFE_CACHE_DIR";
|
|
10
|
+
// 用户目录兜底时,超过该时长未更新的状态文件在写入时顺带清理
|
|
11
|
+
const STALE_STATE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
12
|
+
export function getOpenScienceHandoffDir() {
|
|
13
|
+
const value = process.env[OPEN_SCIENCE_HANDOFF_ENV]?.trim();
|
|
14
|
+
return value ? value : undefined;
|
|
15
|
+
}
|
|
16
|
+
export function isOpenScienceRuntime() {
|
|
17
|
+
return getOpenScienceHandoffDir() !== undefined;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 跨 CLI 进程的流程状态目录。
|
|
21
|
+
* 优先级:HELIXLIFE_CACHE_DIR → Open-Science 会话 handoff → ~/.config/helixlife/cache。
|
|
22
|
+
*/
|
|
23
|
+
export function getHelixlifeStateDir(kind) {
|
|
24
|
+
const override = process.env[HELIXLIFE_CACHE_DIR_ENV]?.trim();
|
|
25
|
+
if (override) {
|
|
26
|
+
return join(override, kind);
|
|
27
|
+
}
|
|
28
|
+
const handoff = getOpenScienceHandoffDir();
|
|
29
|
+
if (handoff) {
|
|
30
|
+
return join(handoff, "helixlife", kind);
|
|
31
|
+
}
|
|
32
|
+
return join(homedir(), ".config", "helixlife", "cache", kind);
|
|
33
|
+
}
|
|
34
|
+
/** 结果文件目录:Open-Science 下写入会话 handoff,供 Agent 以 Artifact 发布 */
|
|
35
|
+
export function getHelixlifeOutputDir() {
|
|
36
|
+
const handoff = getOpenScienceHandoffDir();
|
|
37
|
+
return handoff ? join(handoff, "helixlife", "outputs") : getUserDownloadsDir();
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 清理用户目录兜底下的过期状态文件。
|
|
41
|
+
* handoff 目录随会话由平台管理,不做清理;失败静默,不影响主流程。
|
|
42
|
+
*/
|
|
43
|
+
export async function pruneStaleStateFiles(directory, maxAgeMs = STALE_STATE_MAX_AGE_MS) {
|
|
44
|
+
if (isOpenScienceRuntime() && !process.env[HELIXLIFE_CACHE_DIR_ENV]?.trim()) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
try {
|
|
49
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
50
|
+
await Promise.all(entries
|
|
51
|
+
.filter((entry) => entry.isFile())
|
|
52
|
+
.map(async (entry) => {
|
|
53
|
+
const path = join(directory, entry.name);
|
|
54
|
+
const info = await stat(path);
|
|
55
|
+
if (now - info.mtimeMs > maxAgeMs) {
|
|
56
|
+
await rm(path, { force: true });
|
|
57
|
+
}
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
/* 目录不存在或无权限时忽略 */
|
|
62
|
+
}
|
|
63
|
+
}
|
|
3
64
|
// 获取用户系统下载目录,供 docx 等文件默认保存
|
|
4
65
|
export function getUserDownloadsDir() {
|
|
5
66
|
const home = homedir();
|
|
@@ -41,6 +102,14 @@ export function resolveUserPath(rawPath) {
|
|
|
41
102
|
if (!rawPath?.trim()) {
|
|
42
103
|
return resolve(rawPath);
|
|
43
104
|
}
|
|
105
|
+
// Open-Science:相对路径统一落到会话 handoff 目录;仅当 handoff 下没有而 cwd 下已有该文件时
|
|
106
|
+
// (如用户上传到 data 目录的文件)才沿用 cwd
|
|
107
|
+
const handoff = getOpenScienceHandoffDir();
|
|
108
|
+
if (handoff && !isAbsolute(rawPath) && !/^[\\/]/.test(rawPath)) {
|
|
109
|
+
const inHandoff = resolve(handoff, rawPath);
|
|
110
|
+
const inCwd = resolve(rawPath);
|
|
111
|
+
return !existsSync(inHandoff) && existsSync(inCwd) ? inCwd : inHandoff;
|
|
112
|
+
}
|
|
44
113
|
if (process.platform !== "win32") {
|
|
45
114
|
return resolve(rawPath);
|
|
46
115
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import { type SseDataPayload } from "./index.js";
|
|
1
|
+
import { helixlifeError, type SseDataPayload } from "./index.js";
|
|
2
|
+
/**
|
|
3
|
+
* 后端 SSE error 事件 → helixlifeError:保留原始事件与 trace_id 供后端排查;
|
|
4
|
+
* 「参数非法 / 服务已停止」标为不可重试,避免 Agent 反复提交同一请求。
|
|
5
|
+
*/
|
|
6
|
+
export declare function createSseErrorEventError(payload: SseDataPayload, fallbackMessage?: string): helixlifeError;
|
|
2
7
|
export interface ExtractSseTextOptions {
|
|
3
8
|
/** 是否检查嵌套的 data.text/data.answer 字段 */
|
|
4
9
|
nested?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse-utils.d.ts","sourceRoot":"","sources":["../../src/core/sse-utils.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"sse-utils.d.ts","sourceRoot":"","sources":["../../src/core/sse-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EAGd,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAkBpB;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,cAAc,EACvB,eAAe,SAAgB,GAC9B,cAAc,CA0BhB;AAGD,MAAM,WAAW,qBAAqB;IACpC,uCAAuC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,cAAc,EACvB,OAAO,GAAE,qBAA0B,GAClC,MAAM,CAgCR;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,cAAc,EACvB,cAAc,EAAE,MAAM,EACtB,cAAc,CAAC,EAAE,MAAM,EAAE,GACxB,IAAI,CAqBN;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC5C,QAAQ,SAAI,GACX,MAAM,CAKR;AA0CD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC3C,MAAM,EAAE,CAmBV;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,cAAc,EAAE,EACxB,OAAO,GAAE,qBAA0B,GAClC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAsBxB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,GAAG,SAAS,CAO5E;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,CAQR"}
|
|
@@ -1,4 +1,41 @@
|
|
|
1
|
-
import { helixlifeError, helixlifeErrorCode, } from "./index.js";
|
|
1
|
+
import { helixlifeError, helixlifeErrorCode, isNonRetryableServerMessage, } from "./index.js";
|
|
2
|
+
const SSE_TRACE_ID_KEYS = ["trace_id", "traceId", "request_id", "task_id"];
|
|
3
|
+
const SSE_ERROR_DETAIL_MAX_CHARS = 2000;
|
|
4
|
+
function pickString(record, keys) {
|
|
5
|
+
for (const key of keys) {
|
|
6
|
+
const value = record[key];
|
|
7
|
+
if (typeof value === "string" && value) {
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 后端 SSE error 事件 → helixlifeError:保留原始事件与 trace_id 供后端排查;
|
|
15
|
+
* 「参数非法 / 服务已停止」标为不可重试,避免 Agent 反复提交同一请求。
|
|
16
|
+
*/
|
|
17
|
+
export function createSseErrorEventError(payload, fallbackMessage = "SSE 流返回错误事件") {
|
|
18
|
+
const data = typeof payload.data === "object" && payload.data !== null
|
|
19
|
+
? payload.data
|
|
20
|
+
: {};
|
|
21
|
+
const message = pickString(payload, ["message", "err_msg", "error"]) ??
|
|
22
|
+
pickString(data, ["message", "err_msg", "error"]) ??
|
|
23
|
+
fallbackMessage;
|
|
24
|
+
const traceId = pickString(payload, SSE_TRACE_ID_KEYS) ?? pickString(data, SSE_TRACE_ID_KEYS);
|
|
25
|
+
const raw = JSON.stringify(payload);
|
|
26
|
+
const transient = !isNonRetryableServerMessage(message) &&
|
|
27
|
+
/timeout|busy|rate limit|稍后/i.test(message);
|
|
28
|
+
return new helixlifeError(helixlifeErrorCode.REQUEST_FAILED, message, {
|
|
29
|
+
traceId,
|
|
30
|
+
retryable: transient,
|
|
31
|
+
nextAction: transient ? "retry_once" : "stop_and_report",
|
|
32
|
+
detail: {
|
|
33
|
+
sseEvent: raw.length > SSE_ERROR_DETAIL_MAX_CHARS
|
|
34
|
+
? `${raw.slice(0, SSE_ERROR_DETAIL_MAX_CHARS)}…`
|
|
35
|
+
: raw,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
2
39
|
/**
|
|
3
40
|
* 从 SSE 事件载荷中提取可追加的流式文本片段
|
|
4
41
|
* @param payload SSE 事件载荷
|
|
@@ -43,10 +80,7 @@ export function extractSseText(payload, options = {}) {
|
|
|
43
80
|
*/
|
|
44
81
|
export function assertWorkflowSucceeded(payload, failureMessage, terminalEvents) {
|
|
45
82
|
if (payload.event === "error") {
|
|
46
|
-
|
|
47
|
-
? payload.message
|
|
48
|
-
: "SSE 流返回错误事件";
|
|
49
|
-
throw new helixlifeError(helixlifeErrorCode.REQUEST_FAILED, message);
|
|
83
|
+
throw createSseErrorEventError(payload);
|
|
50
84
|
}
|
|
51
85
|
if (terminalEvents && payload.event) {
|
|
52
86
|
// 检查是否为终端事件
|