web-access-cli 0.3.0 → 0.5.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/README.md +39 -27
- package/README_CN.md +39 -27
- package/THIRD_PARTY_NOTICES.md +11 -0
- package/dist/cli-output.js +16 -0
- package/dist/cli-output.js.map +1 -1
- package/dist/cli.js +48 -42
- package/dist/cli.js.map +1 -1
- package/dist/config/config.js +119 -53
- package/dist/config/config.js.map +1 -1
- package/dist/config/edit.js +88 -4
- package/dist/config/edit.js.map +1 -1
- package/dist/config/file.js +30 -0
- package/dist/config/file.js.map +1 -1
- package/dist/config/init.js +59 -0
- package/dist/config/init.js.map +1 -0
- package/dist/config/provider-order.js +14 -7
- package/dist/config/provider-order.js.map +1 -1
- package/dist/core/diagnostics.js +13 -7
- package/dist/core/diagnostics.js.map +1 -1
- package/dist/core/router.js +228 -94
- package/dist/core/router.js.map +1 -1
- package/dist/core/schema.js +33 -2
- package/dist/core/schema.js.map +1 -1
- package/dist/core/types.js +3 -0
- package/dist/core/types.js.map +1 -1
- package/dist/providers/extract.js +37 -0
- package/dist/providers/extract.js.map +1 -1
- package/dist/providers/registry.js +3 -0
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/xai.js +208 -0
- package/dist/providers/xai.js.map +1 -0
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/schemas/config.schema.json +87 -2
- package/schemas/output.schema.json +180 -0
package/dist/cli.js
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
import { realpathSync } from "node:fs";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import { Command, CommanderError, InvalidArgumentError, Option, } from "commander";
|
|
5
|
-
import {
|
|
5
|
+
import { formatMarkdown } from "./cli-output.js";
|
|
6
6
|
import { loadConfig } from "./config/config.js";
|
|
7
7
|
import { executeConfigEdit } from "./config/edit.js";
|
|
8
|
+
import { executeConfigInit } from "./config/init.js";
|
|
8
9
|
import { createProviderOrderWriter } from "./config/provider-order.js";
|
|
9
10
|
import { executeDoctor, executeProviders } from "./core/diagnostics.js";
|
|
10
11
|
import { asWebAccessError, WebAccessError } from "./core/errors.js";
|
|
@@ -47,44 +48,33 @@ function exitCode(envelope) {
|
|
|
47
48
|
return 2;
|
|
48
49
|
return 1;
|
|
49
50
|
}
|
|
50
|
-
function writeEnvelope(envelope
|
|
51
|
-
process.stdout.write(`${JSON.stringify(envelope
|
|
51
|
+
function writeEnvelope(envelope) {
|
|
52
|
+
process.stdout.write(`${JSON.stringify(envelope)}\n`);
|
|
52
53
|
}
|
|
53
|
-
function writeOutput(envelope, mode
|
|
54
|
-
if (mode === "
|
|
55
|
-
|
|
54
|
+
function writeOutput(envelope, mode) {
|
|
55
|
+
if (mode === "path" &&
|
|
56
|
+
envelope.ok &&
|
|
57
|
+
"command" in envelope &&
|
|
58
|
+
envelope.command === "config.init") {
|
|
59
|
+
process.stdout.write(`${envelope.data.path}\n`);
|
|
56
60
|
return;
|
|
57
61
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
typeof envelope.provider === "string" &&
|
|
64
|
-
"data" in envelope &&
|
|
65
|
-
typeof envelope.data === "object" &&
|
|
66
|
-
envelope.data !== null &&
|
|
67
|
-
"document" in envelope.data &&
|
|
68
|
-
typeof envelope.data.document === "object" &&
|
|
69
|
-
envelope.data.document !== null &&
|
|
70
|
-
"sourceUrl" in envelope.data.document &&
|
|
71
|
-
typeof envelope.data.document.sourceUrl === "string" &&
|
|
72
|
-
"title" in envelope.data.document &&
|
|
73
|
-
typeof envelope.data.document.title === "string" &&
|
|
74
|
-
"content" in envelope.data.document &&
|
|
75
|
-
typeof envelope.data.document.content === "string" &&
|
|
76
|
-
"contentType" in envelope.data.document &&
|
|
77
|
-
envelope.data.document.contentType === "text/markdown");
|
|
62
|
+
if (mode === "markdown" && envelope.ok) {
|
|
63
|
+
process.stdout.write(formatMarkdown(envelope));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
writeEnvelope(envelope);
|
|
78
67
|
}
|
|
79
68
|
export function createProgram(run, dependencies = {}) {
|
|
80
69
|
const program = new Command();
|
|
81
70
|
const runConfigEdit = dependencies.executeConfigEdit ?? executeConfigEdit;
|
|
71
|
+
const runConfigInit = dependencies.executeConfigInit ?? executeConfigInit;
|
|
82
72
|
program
|
|
83
73
|
.name("web-access")
|
|
84
74
|
.description("Agent-neutral 的网页搜索与内容提取 CLI")
|
|
85
75
|
.version(VERSION)
|
|
86
76
|
.option("--config <path>", "指定 JSON 配置文件")
|
|
87
|
-
.option("--
|
|
77
|
+
.option("--json", "输出 JSON envelope", false)
|
|
88
78
|
.showSuggestionAfterError();
|
|
89
79
|
program.configureOutput({ writeErr: () => { }, outputError: () => { } });
|
|
90
80
|
program.exitOverride();
|
|
@@ -102,7 +92,7 @@ export function createProgram(run, dependencies = {}) {
|
|
|
102
92
|
.option("--include-domain <domain>", "仅包含域名,可重复", collect, [])
|
|
103
93
|
.option("--exclude-domain <domain>", "排除域名,可重复", collect, [])
|
|
104
94
|
.option("--timeout <milliseconds>", "总超时毫秒数", integer)
|
|
105
|
-
.option("--
|
|
95
|
+
.option("--json", "输出 JSON envelope", false)
|
|
106
96
|
.action((query, options) => {
|
|
107
97
|
run(async () => {
|
|
108
98
|
const globals = program.opts();
|
|
@@ -123,22 +113,22 @@ export function createProgram(run, dependencies = {}) {
|
|
|
123
113
|
return executeSearch(request, {
|
|
124
114
|
loaded,
|
|
125
115
|
signal: processSignal.signal,
|
|
126
|
-
debug: options.debug,
|
|
127
116
|
persistProviderOrder: createProviderOrderWriter(loaded),
|
|
128
117
|
});
|
|
129
|
-
})
|
|
118
|
+
}, options.json || program.opts().json
|
|
119
|
+
? "json"
|
|
120
|
+
: "markdown");
|
|
130
121
|
});
|
|
131
122
|
program
|
|
132
123
|
.command("extract")
|
|
133
|
-
.description("提取网页正文并转换为 Markdown
|
|
124
|
+
.description("提取网页正文并转换为 Markdown(使用 --json 输出 JSON)")
|
|
134
125
|
.argument("<url>", "HTTP(S) URL")
|
|
135
126
|
.option("-p, --provider <id>", "provider instance id,或 auto", "auto")
|
|
136
127
|
.option("--timeout <milliseconds>", "总超时毫秒数", integer)
|
|
137
128
|
.option("--json", "输出 JSON envelope", false)
|
|
138
|
-
.option("--debug", "输出完整路由和脱敏原始响应", false)
|
|
139
129
|
.action((url, options) => {
|
|
140
130
|
const globals = program.opts();
|
|
141
|
-
const outputMode = options.json ||
|
|
131
|
+
const outputMode = options.json || globals.json ? "json" : "markdown";
|
|
142
132
|
run(async () => {
|
|
143
133
|
const loaded = loadConfig(globals.config);
|
|
144
134
|
const request = {
|
|
@@ -149,7 +139,6 @@ export function createProgram(run, dependencies = {}) {
|
|
|
149
139
|
return executeExtract(request, {
|
|
150
140
|
loaded,
|
|
151
141
|
signal: processSignal.signal,
|
|
152
|
-
debug: options.debug,
|
|
153
142
|
persistProviderOrder: createProviderOrderWriter(loaded),
|
|
154
143
|
});
|
|
155
144
|
}, outputMode);
|
|
@@ -157,18 +146,35 @@ export function createProgram(run, dependencies = {}) {
|
|
|
157
146
|
program
|
|
158
147
|
.command("providers")
|
|
159
148
|
.description("列出 provider instance、route 与配置状态")
|
|
160
|
-
.
|
|
149
|
+
.option("--json", "输出 JSON envelope", false)
|
|
150
|
+
.action((options) => run(() => executeProviders(loadConfig(program.opts().config)), options.json || program.opts().json
|
|
151
|
+
? "json"
|
|
152
|
+
: "markdown"));
|
|
161
153
|
program
|
|
162
154
|
.command("doctor")
|
|
163
155
|
.description("检查本地配置与已启用 provider 的可用性")
|
|
164
|
-
.
|
|
156
|
+
.option("--json", "输出 JSON envelope", false)
|
|
157
|
+
.action((options) => run(() => executeDoctor(loadConfig(program.opts().config)), options.json || program.opts().json
|
|
158
|
+
? "json"
|
|
159
|
+
: "markdown"));
|
|
165
160
|
const config = program.command("config").description("管理配置文件");
|
|
161
|
+
config
|
|
162
|
+
.command("init")
|
|
163
|
+
.description("按当前标准凭据环境变量创建配置")
|
|
164
|
+
.option("--json", "输出 JSON envelope", false)
|
|
165
|
+
.action((options) => {
|
|
166
|
+
const globals = program.optsWithGlobals();
|
|
167
|
+
run(() => runConfigInit({ explicitPath: globals.config }), options.json || globals.json ? "json" : "path");
|
|
168
|
+
});
|
|
166
169
|
config
|
|
167
170
|
.command("edit")
|
|
168
|
-
.description("
|
|
169
|
-
.
|
|
171
|
+
.description("创建默认配置文件并用 VISUAL 或 EDITOR 打开")
|
|
172
|
+
.option("--json", "输出 JSON envelope", false)
|
|
173
|
+
.action((options) => run(() => runConfigEdit({
|
|
170
174
|
explicitPath: program.opts().config,
|
|
171
|
-
}))
|
|
175
|
+
}), options.json || program.opts().json
|
|
176
|
+
? "json"
|
|
177
|
+
: "markdown"));
|
|
172
178
|
return program;
|
|
173
179
|
}
|
|
174
180
|
function envelopeCommand(args) {
|
|
@@ -191,7 +197,7 @@ async function main() {
|
|
|
191
197
|
});
|
|
192
198
|
if (process.argv.length <= 2) {
|
|
193
199
|
const envelope = errorEnvelope(new WebAccessError("invalid_input", "必须指定命令"));
|
|
194
|
-
writeEnvelope(envelope
|
|
200
|
+
writeEnvelope(envelope);
|
|
195
201
|
process.exitCode = 2;
|
|
196
202
|
return;
|
|
197
203
|
}
|
|
@@ -200,7 +206,7 @@ async function main() {
|
|
|
200
206
|
if (!pending)
|
|
201
207
|
throw new WebAccessError("invalid_input", "必须指定命令");
|
|
202
208
|
const envelope = await pending;
|
|
203
|
-
writeOutput(envelope, pendingOutputMode
|
|
209
|
+
writeOutput(envelope, pendingOutputMode);
|
|
204
210
|
process.exitCode = exitCode(envelope);
|
|
205
211
|
}
|
|
206
212
|
catch (caught) {
|
|
@@ -215,7 +221,7 @@ async function main() {
|
|
|
215
221
|
: caught.message)
|
|
216
222
|
: asWebAccessError(caught);
|
|
217
223
|
const envelope = errorEnvelope(normalized, envelopeCommand(program.args));
|
|
218
|
-
writeEnvelope(envelope
|
|
224
|
+
writeEnvelope(envelope);
|
|
219
225
|
process.exitCode = exitCode(envelope);
|
|
220
226
|
}
|
|
221
227
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACN,OAAO,EACP,cAAc,EACd,oBAAoB,EACpB,MAAM,GACN,MAAM,WAAW,CAAC;AACnB,OAAO,EAAsB,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config/config.js
CHANGED
|
@@ -12,7 +12,11 @@ export const DEFAULT_SEARCH_PROVIDERS = [
|
|
|
12
12
|
"searxng",
|
|
13
13
|
"anysearch",
|
|
14
14
|
"xcrawl",
|
|
15
|
+
];
|
|
16
|
+
export const DEFAULT_SEARCH_FALLBACK_PROVIDERS = [
|
|
15
17
|
"deepseek",
|
|
18
|
+
"xai_x_search",
|
|
19
|
+
"xai_web_search",
|
|
16
20
|
];
|
|
17
21
|
export const DEFAULT_EXTRACT_PROVIDERS = [
|
|
18
22
|
"firecrawl",
|
|
@@ -20,18 +24,20 @@ export const DEFAULT_EXTRACT_PROVIDERS = [
|
|
|
20
24
|
"exa",
|
|
21
25
|
"anysearch",
|
|
22
26
|
"xcrawl",
|
|
23
|
-
"http",
|
|
24
27
|
];
|
|
28
|
+
export const DEFAULT_EXTRACT_FALLBACK_PROVIDERS = ["http"];
|
|
25
29
|
export const DEFAULT_MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
|
|
26
30
|
const DEFAULT_SEARCH_CONFIG = {
|
|
27
31
|
providers: [...DEFAULT_SEARCH_PROVIDERS],
|
|
32
|
+
providers_fallback: [...DEFAULT_SEARCH_FALLBACK_PROVIDERS],
|
|
28
33
|
limit: 5,
|
|
29
|
-
timeoutMs:
|
|
30
|
-
attemptTimeoutMs:
|
|
34
|
+
timeoutMs: 120_000,
|
|
35
|
+
attemptTimeoutMs: 60_000,
|
|
31
36
|
maxResponseBytes: DEFAULT_MAX_RESPONSE_BYTES,
|
|
32
37
|
};
|
|
33
38
|
const DEFAULT_EXTRACT_CONFIG = {
|
|
34
39
|
providers: [...DEFAULT_EXTRACT_PROVIDERS],
|
|
40
|
+
providers_fallback: [...DEFAULT_EXTRACT_FALLBACK_PROVIDERS],
|
|
35
41
|
timeoutMs: 120_000,
|
|
36
42
|
attemptTimeoutMs: 45_000,
|
|
37
43
|
maxResponseBytes: DEFAULT_MAX_RESPONSE_BYTES,
|
|
@@ -46,6 +52,8 @@ const SEARCH_TYPES = new Set([
|
|
|
46
52
|
"anysearch",
|
|
47
53
|
"xcrawl",
|
|
48
54
|
"deepseek",
|
|
55
|
+
"xai_x_search",
|
|
56
|
+
"xai_web_search",
|
|
49
57
|
]);
|
|
50
58
|
const EXTRACT_TYPES = new Set([
|
|
51
59
|
"firecrawl",
|
|
@@ -67,6 +75,8 @@ const DEFAULT_INSTANCE_CONFIGS = [
|
|
|
67
75
|
{ id: "anysearch", type: "anysearch", searchFilterMode: "strict" },
|
|
68
76
|
{ id: "xcrawl", type: "xcrawl", searchFilterMode: "strict" },
|
|
69
77
|
{ id: "deepseek", type: "deepseek" },
|
|
78
|
+
{ id: "xai_x_search", type: "xai_x_search" },
|
|
79
|
+
{ id: "xai_web_search", type: "xai_web_search" },
|
|
70
80
|
];
|
|
71
81
|
const STANDARD_KEY_ENV = {
|
|
72
82
|
tavily: "TAVILY_API_KEY",
|
|
@@ -79,6 +89,14 @@ const STANDARD_KEY_ENV = {
|
|
|
79
89
|
xcrawl: "XCRAWL_API_KEY",
|
|
80
90
|
deepseek: "DEEPSEEK_API_KEY",
|
|
81
91
|
};
|
|
92
|
+
const STANDARD_AUTH_JSON_ENV = {
|
|
93
|
+
xai_x_search: "XAI_AUTH_JSON",
|
|
94
|
+
xai_web_search: "XAI_AUTH_JSON",
|
|
95
|
+
};
|
|
96
|
+
const STANDARD_MODEL_ENV = {
|
|
97
|
+
xai_x_search: "XAI_MODEL",
|
|
98
|
+
xai_web_search: "XAI_MODEL",
|
|
99
|
+
};
|
|
82
100
|
const STANDARD_BASE_ENV = {
|
|
83
101
|
tavily: "TAVILY_BASE_URL",
|
|
84
102
|
exa: "EXA_BASE_URL",
|
|
@@ -90,6 +108,8 @@ const STANDARD_BASE_ENV = {
|
|
|
90
108
|
anysearch: "ANYSEARCH_BASE_URL",
|
|
91
109
|
xcrawl: "XCRAWL_BASE_URL",
|
|
92
110
|
};
|
|
111
|
+
const DEFAULT_BASE_URLS_XAI = "https://cli-chat-proxy.grok.com/v1";
|
|
112
|
+
const DEFAULT_XAI_MODEL = "grok-4.6";
|
|
93
113
|
const SEARCH_FILTER_TYPES = new Set(["anysearch", "xcrawl"]);
|
|
94
114
|
const ALLOWED_INSTANCE_KEYS = new Set([
|
|
95
115
|
"id",
|
|
@@ -100,10 +120,14 @@ const ALLOWED_INSTANCE_KEYS = new Set([
|
|
|
100
120
|
"baseUrlEnv",
|
|
101
121
|
"headers",
|
|
102
122
|
"searchFilterMode",
|
|
123
|
+
"authJson",
|
|
124
|
+
"authJsonEnv",
|
|
125
|
+
"model",
|
|
126
|
+
"modelEnv",
|
|
103
127
|
]);
|
|
104
128
|
const ALLOWED_SEARCH_KEYS = new Set([
|
|
105
129
|
"providers",
|
|
106
|
-
"
|
|
130
|
+
"providers_fallback",
|
|
107
131
|
"limit",
|
|
108
132
|
"timeoutMs",
|
|
109
133
|
"attemptTimeoutMs",
|
|
@@ -111,7 +135,7 @@ const ALLOWED_SEARCH_KEYS = new Set([
|
|
|
111
135
|
]);
|
|
112
136
|
const ALLOWED_EXTRACT_KEYS = new Set([
|
|
113
137
|
"providers",
|
|
114
|
-
"
|
|
138
|
+
"providers_fallback",
|
|
115
139
|
"timeoutMs",
|
|
116
140
|
"attemptTimeoutMs",
|
|
117
141
|
"maxResponseBytes",
|
|
@@ -212,6 +236,10 @@ function parseInstance(value, index) {
|
|
|
212
236
|
? normalizeBaseUrl(baseUrlRaw, `${path}.baseUrl`)
|
|
213
237
|
: undefined;
|
|
214
238
|
const baseUrlEnvRaw = parseOptionalString(value.baseUrlEnv, `${path}.baseUrlEnv`);
|
|
239
|
+
const authJson = parseOptionalString(value.authJson, `${path}.authJson`);
|
|
240
|
+
const authJsonEnvRaw = parseOptionalString(value.authJsonEnv, `${path}.authJsonEnv`);
|
|
241
|
+
const model = parseOptionalString(value.model, `${path}.model`);
|
|
242
|
+
const modelEnvRaw = parseOptionalString(value.modelEnv, `${path}.modelEnv`);
|
|
215
243
|
const headers = normalizeHeaders(value.headers, `${path}.headers`);
|
|
216
244
|
const searchFilterMode = value.searchFilterMode === undefined
|
|
217
245
|
? undefined
|
|
@@ -222,6 +250,13 @@ function parseInstance(value, index) {
|
|
|
222
250
|
if (searchFilterMode !== undefined &&
|
|
223
251
|
!SEARCH_FILTER_TYPES.has(type))
|
|
224
252
|
throw new ConfigError(`${path}.searchFilterMode 仅适用于 anysearch 或 xcrawl`);
|
|
253
|
+
if (type !== "xai_x_search" &&
|
|
254
|
+
type !== "xai_web_search" &&
|
|
255
|
+
(authJson !== undefined ||
|
|
256
|
+
authJsonEnvRaw !== undefined ||
|
|
257
|
+
model !== undefined ||
|
|
258
|
+
modelEnvRaw !== undefined))
|
|
259
|
+
throw new ConfigError(`${path}.authJson/model 仅适用于 xAI provider`);
|
|
225
260
|
return {
|
|
226
261
|
id,
|
|
227
262
|
type: type,
|
|
@@ -233,6 +268,14 @@ function parseInstance(value, index) {
|
|
|
233
268
|
...(baseUrlEnvRaw
|
|
234
269
|
? { baseUrlEnv: validateEnvName(baseUrlEnvRaw, `${path}.baseUrlEnv`) }
|
|
235
270
|
: {}),
|
|
271
|
+
...(authJson ? { authJson } : {}),
|
|
272
|
+
...(authJsonEnvRaw
|
|
273
|
+
? { authJsonEnv: validateEnvName(authJsonEnvRaw, `${path}.authJsonEnv`) }
|
|
274
|
+
: {}),
|
|
275
|
+
...(model ? { model } : {}),
|
|
276
|
+
...(modelEnvRaw
|
|
277
|
+
? { modelEnv: validateEnvName(modelEnvRaw, `${path}.modelEnv`) }
|
|
278
|
+
: {}),
|
|
236
279
|
...(headers ? { headers } : {}),
|
|
237
280
|
...(searchFilterMode
|
|
238
281
|
? { searchFilterMode: searchFilterMode }
|
|
@@ -253,22 +296,6 @@ function parseRoute(value, path) {
|
|
|
253
296
|
}
|
|
254
297
|
return result;
|
|
255
298
|
}
|
|
256
|
-
function parseInternalRoute(value) {
|
|
257
|
-
if (value === undefined)
|
|
258
|
-
return undefined;
|
|
259
|
-
if (!Array.isArray(value))
|
|
260
|
-
return undefined;
|
|
261
|
-
const result = [];
|
|
262
|
-
for (const item of value) {
|
|
263
|
-
if (typeof item !== "string")
|
|
264
|
-
return undefined;
|
|
265
|
-
const id = item.trim();
|
|
266
|
-
if (!/^[a-z][a-z0-9_-]{0,63}$/.test(id) || id === "auto")
|
|
267
|
-
return undefined;
|
|
268
|
-
result.push(id);
|
|
269
|
-
}
|
|
270
|
-
return result;
|
|
271
|
-
}
|
|
272
299
|
function parseSearch(value) {
|
|
273
300
|
if (value === undefined)
|
|
274
301
|
return {};
|
|
@@ -276,7 +303,7 @@ function parseSearch(value) {
|
|
|
276
303
|
assertKnownKeys(value, ALLOWED_SEARCH_KEYS, "search");
|
|
277
304
|
return {
|
|
278
305
|
providers: parseRoute(value.providers, "search.providers"),
|
|
279
|
-
|
|
306
|
+
providers_fallback: parseRoute(value.providers_fallback, "search.providers_fallback"),
|
|
280
307
|
limit: parseLimit(value.limit),
|
|
281
308
|
timeoutMs: parsePositiveInt(value.timeoutMs, "search.timeoutMs", DEFAULT_SEARCH_CONFIG.timeoutMs),
|
|
282
309
|
attemptTimeoutMs: parsePositiveInt(value.attemptTimeoutMs, "search.attemptTimeoutMs", DEFAULT_SEARCH_CONFIG.attemptTimeoutMs),
|
|
@@ -290,7 +317,7 @@ function parseExtract(value) {
|
|
|
290
317
|
assertKnownKeys(value, ALLOWED_EXTRACT_KEYS, "extract");
|
|
291
318
|
return {
|
|
292
319
|
providers: parseRoute(value.providers, "extract.providers"),
|
|
293
|
-
|
|
320
|
+
providers_fallback: parseRoute(value.providers_fallback, "extract.providers_fallback"),
|
|
294
321
|
timeoutMs: parsePositiveInt(value.timeoutMs, "extract.timeoutMs", DEFAULT_EXTRACT_CONFIG.timeoutMs),
|
|
295
322
|
attemptTimeoutMs: parsePositiveInt(value.attemptTimeoutMs, "extract.attemptTimeoutMs", DEFAULT_EXTRACT_CONFIG.attemptTimeoutMs),
|
|
296
323
|
maxResponseBytes: parsePositiveInt(value.maxResponseBytes, "extract.maxResponseBytes", DEFAULT_EXTRACT_CONFIG.maxResponseBytes),
|
|
@@ -316,6 +343,8 @@ function parseRawConfig(value) {
|
|
|
316
343
|
instances,
|
|
317
344
|
search: parseSearch(value.search),
|
|
318
345
|
extract: parseExtract(value.extract),
|
|
346
|
+
searchSpecified: value.search !== undefined,
|
|
347
|
+
extractSpecified: value.extract !== undefined,
|
|
319
348
|
};
|
|
320
349
|
}
|
|
321
350
|
function mergeInstances(overrides) {
|
|
@@ -336,13 +365,12 @@ function mergeInstances(overrides) {
|
|
|
336
365
|
}
|
|
337
366
|
return merged;
|
|
338
367
|
}
|
|
339
|
-
function validateRoutes(instances, route, capability) {
|
|
368
|
+
function validateRoutes(instances, route, capability, defaultRoute, requireNonEmpty = false) {
|
|
340
369
|
const allowed = capability === "search" ? SEARCH_TYPES : EXTRACT_TYPES;
|
|
341
370
|
const byId = new Map(instances.map((instance) => [instance.id, instance]));
|
|
342
|
-
const chosen = route
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
: [...DEFAULT_EXTRACT_PROVIDERS]);
|
|
371
|
+
const chosen = route ? [...route] : [...defaultRoute];
|
|
372
|
+
if (requireNonEmpty && chosen.length === 0)
|
|
373
|
+
throw new ConfigError(`${capability}.providers 不能为空`);
|
|
346
374
|
for (const id of chosen) {
|
|
347
375
|
const instance = byId.get(id);
|
|
348
376
|
if (!instance)
|
|
@@ -352,16 +380,6 @@ function validateRoutes(instances, route, capability) {
|
|
|
352
380
|
}
|
|
353
381
|
return chosen;
|
|
354
382
|
}
|
|
355
|
-
function validInternalRoute(configured, internal) {
|
|
356
|
-
if (!internal || internal.length !== configured.length)
|
|
357
|
-
return undefined;
|
|
358
|
-
if (new Set(internal).size !== internal.length)
|
|
359
|
-
return undefined;
|
|
360
|
-
const configuredIds = new Set(configured);
|
|
361
|
-
if (internal.some((id) => !configuredIds.has(id)))
|
|
362
|
-
return undefined;
|
|
363
|
-
return internal;
|
|
364
|
-
}
|
|
365
383
|
export function getDefaultConfigPath() {
|
|
366
384
|
return join(homedir(), ".config", "web-access-cli", "config.json");
|
|
367
385
|
}
|
|
@@ -382,11 +400,25 @@ function resolveProvider(instance, env) {
|
|
|
382
400
|
const standardKeyEnv = instance.id === instance.type ? STANDARD_KEY_ENV[instance.type] : undefined;
|
|
383
401
|
const keyEnv = resolveEnvValue(instance.apiKeyEnv, standardKeyEnv, env);
|
|
384
402
|
const apiKey = keyEnv.value ?? instance.apiKey ?? null;
|
|
385
|
-
const
|
|
386
|
-
?
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
403
|
+
const standardAuthEnv = instance.id === instance.type
|
|
404
|
+
? STANDARD_AUTH_JSON_ENV[instance.type]
|
|
405
|
+
: undefined;
|
|
406
|
+
const authEnv = resolveEnvValue(instance.authJsonEnv, standardAuthEnv, env);
|
|
407
|
+
const authJson = authEnv.value ?? instance.authJson ?? null;
|
|
408
|
+
const isXai = instance.type === "xai_x_search" || instance.type === "xai_web_search";
|
|
409
|
+
const credentialSource = isXai
|
|
410
|
+
? authJson
|
|
411
|
+
? authEnv.value
|
|
412
|
+
? authEnv.source === "custom_env"
|
|
413
|
+
? "custom_auth_json"
|
|
414
|
+
: "auth_json"
|
|
415
|
+
: "auth_json"
|
|
416
|
+
: "missing"
|
|
417
|
+
: apiKey
|
|
418
|
+
? keyEnv.value
|
|
419
|
+
? keyEnv.source
|
|
420
|
+
: "config"
|
|
421
|
+
: "missing";
|
|
390
422
|
const standardBaseEnv = instance.id === instance.type
|
|
391
423
|
? STANDARD_BASE_ENV[instance.type]
|
|
392
424
|
: undefined;
|
|
@@ -394,6 +426,7 @@ function resolveProvider(instance, env) {
|
|
|
394
426
|
const rawBaseUrl = baseEnv.value ??
|
|
395
427
|
instance.baseUrl ??
|
|
396
428
|
DEFAULT_BASE_URLS[instance.type] ??
|
|
429
|
+
(isXai ? DEFAULT_BASE_URLS_XAI : undefined) ??
|
|
397
430
|
null;
|
|
398
431
|
const baseUrl = rawBaseUrl
|
|
399
432
|
? normalizeBaseUrl(rawBaseUrl, baseEnv.value
|
|
@@ -409,6 +442,20 @@ function resolveProvider(instance, env) {
|
|
|
409
442
|
: DEFAULT_BASE_URLS[instance.type]
|
|
410
443
|
? "default"
|
|
411
444
|
: "missing";
|
|
445
|
+
const standardModelEnv = instance.id === instance.type
|
|
446
|
+
? STANDARD_MODEL_ENV[instance.type]
|
|
447
|
+
: undefined;
|
|
448
|
+
const modelEnv = resolveEnvValue(instance.modelEnv, standardModelEnv, env);
|
|
449
|
+
const model = isXai
|
|
450
|
+
? (modelEnv.value ?? instance.model ?? DEFAULT_XAI_MODEL)
|
|
451
|
+
: null;
|
|
452
|
+
const modelSource = isXai
|
|
453
|
+
? modelEnv.value
|
|
454
|
+
? modelEnv.source
|
|
455
|
+
: instance.model
|
|
456
|
+
? "config"
|
|
457
|
+
: "default"
|
|
458
|
+
: "missing";
|
|
412
459
|
return {
|
|
413
460
|
id: instance.id,
|
|
414
461
|
type: instance.type,
|
|
@@ -417,6 +464,14 @@ function resolveProvider(instance, env) {
|
|
|
417
464
|
baseUrl,
|
|
418
465
|
baseUrlSource,
|
|
419
466
|
headers: { ...(instance.headers ?? {}) },
|
|
467
|
+
authJson,
|
|
468
|
+
authJsonSource: authJson
|
|
469
|
+
? authEnv.value
|
|
470
|
+
? authEnv.source
|
|
471
|
+
: "config"
|
|
472
|
+
: "missing",
|
|
473
|
+
model,
|
|
474
|
+
modelSource,
|
|
420
475
|
searchFilterMode: instance.searchFilterMode ??
|
|
421
476
|
(SEARCH_FILTER_TYPES.has(instance.type) ? "strict" : null),
|
|
422
477
|
};
|
|
@@ -431,6 +486,8 @@ const DEFAULT_BASE_URLS = {
|
|
|
431
486
|
anysearch: "https://api.anysearch.com",
|
|
432
487
|
xcrawl: "https://run.xcrawl.com",
|
|
433
488
|
deepseek: "https://api.deepseek.com/anthropic/v1",
|
|
489
|
+
xai_x_search: DEFAULT_BASE_URLS_XAI,
|
|
490
|
+
xai_web_search: DEFAULT_BASE_URLS_XAI,
|
|
434
491
|
};
|
|
435
492
|
export function createDefaultAppConfig() {
|
|
436
493
|
return {
|
|
@@ -438,10 +495,12 @@ export function createDefaultAppConfig() {
|
|
|
438
495
|
search: {
|
|
439
496
|
...DEFAULT_SEARCH_CONFIG,
|
|
440
497
|
providers: [...DEFAULT_SEARCH_CONFIG.providers],
|
|
498
|
+
providers_fallback: [...DEFAULT_SEARCH_CONFIG.providers_fallback],
|
|
441
499
|
},
|
|
442
500
|
extract: {
|
|
443
501
|
...DEFAULT_EXTRACT_CONFIG,
|
|
444
502
|
providers: [...DEFAULT_EXTRACT_CONFIG.providers],
|
|
503
|
+
providers_fallback: [...DEFAULT_EXTRACT_CONFIG.providers_fallback],
|
|
445
504
|
},
|
|
446
505
|
};
|
|
447
506
|
}
|
|
@@ -457,13 +516,15 @@ function buildLoadedConfig(path, exists, parsed, env) {
|
|
|
457
516
|
const defaults = createDefaultAppConfig();
|
|
458
517
|
const raw = parseRawConfig(parsed);
|
|
459
518
|
const instanceConfigs = mergeInstances(raw.instances);
|
|
460
|
-
const searchProviders = validateRoutes(instanceConfigs, raw.search.providers, "search");
|
|
461
|
-
const
|
|
462
|
-
|
|
463
|
-
const
|
|
519
|
+
const searchProviders = validateRoutes(instanceConfigs, raw.search.providers, "search", DEFAULT_SEARCH_PROVIDERS, true);
|
|
520
|
+
const searchFallbackProviders = validateRoutes(instanceConfigs, raw.search.providers_fallback ??
|
|
521
|
+
(raw.searchSpecified ? [] : DEFAULT_SEARCH_FALLBACK_PROVIDERS), "search", DEFAULT_SEARCH_FALLBACK_PROVIDERS);
|
|
522
|
+
const extractProviders = validateRoutes(instanceConfigs, raw.extract.providers, "extract", DEFAULT_EXTRACT_PROVIDERS);
|
|
523
|
+
const extractFallbackProviders = validateRoutes(instanceConfigs, raw.extract.providers_fallback ??
|
|
524
|
+
(raw.extractSpecified ? [] : DEFAULT_EXTRACT_FALLBACK_PROVIDERS), "extract", DEFAULT_EXTRACT_FALLBACK_PROVIDERS);
|
|
464
525
|
const search = {
|
|
465
526
|
providers: searchProviders,
|
|
466
|
-
|
|
527
|
+
providers_fallback: searchFallbackProviders,
|
|
467
528
|
limit: raw.search.limit ?? defaults.search.limit,
|
|
468
529
|
timeoutMs: raw.search.timeoutMs ?? defaults.search.timeoutMs,
|
|
469
530
|
attemptTimeoutMs: raw.search.attemptTimeoutMs ?? defaults.search.attemptTimeoutMs,
|
|
@@ -471,9 +532,7 @@ function buildLoadedConfig(path, exists, parsed, env) {
|
|
|
471
532
|
};
|
|
472
533
|
const extract = {
|
|
473
534
|
providers: extractProviders,
|
|
474
|
-
|
|
475
|
-
? { _providers: extractInternalProviders }
|
|
476
|
-
: {}),
|
|
535
|
+
providers_fallback: extractFallbackProviders,
|
|
477
536
|
timeoutMs: raw.extract.timeoutMs ?? defaults.extract.timeoutMs,
|
|
478
537
|
attemptTimeoutMs: raw.extract.attemptTimeoutMs ?? defaults.extract.attemptTimeoutMs,
|
|
479
538
|
maxResponseBytes: raw.extract.maxResponseBytes ?? defaults.extract.maxResponseBytes,
|
|
@@ -511,9 +570,16 @@ export function getRoute(config, capability) {
|
|
|
511
570
|
? config.search.providers
|
|
512
571
|
: config.extract.providers;
|
|
513
572
|
}
|
|
573
|
+
export function getFallbackRoute(config, capability) {
|
|
574
|
+
const primary = getRoute(config, capability);
|
|
575
|
+
const fallback = capability === "search"
|
|
576
|
+
? config.search.providers_fallback
|
|
577
|
+
: config.extract.providers_fallback;
|
|
578
|
+
const primaryIds = new Set(primary);
|
|
579
|
+
return fallback.filter((id) => !primaryIds.has(id));
|
|
580
|
+
}
|
|
514
581
|
export function getEffectiveRoute(config, capability) {
|
|
515
|
-
|
|
516
|
-
return capabilityConfig._providers ?? capabilityConfig.providers;
|
|
582
|
+
return getRoute(config, capability);
|
|
517
583
|
}
|
|
518
584
|
export function getCapabilityConfig(config, capability) {
|
|
519
585
|
return capability === "search" ? config.search : config.extract;
|