@armadra/agent 0.2.1 → 0.4.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/CHANGELOG.md +99 -0
- package/README.md +142 -49
- package/dist/agent/retry.d.ts +1 -1
- package/dist/agent/retry.js +2 -1
- package/dist/agent/session-cache.js +6 -3
- package/dist/agent/session-classifier.d.ts +18 -0
- package/dist/agent/session-classifier.js +103 -0
- package/dist/agent/session-core.d.ts +13 -0
- package/dist/agent/session-state.js +2 -1
- package/dist/agent/session-sync.js +9 -2
- package/dist/agent/session-tools.js +24 -3
- package/dist/agent/session.d.ts +3 -0
- package/dist/agent/session.js +20 -10
- package/dist/agent/tool-runner.js +15 -2
- package/dist/agent/types.d.ts +9 -1
- package/dist/ai/apis/anthropic-messages.js +3 -2
- package/dist/ai/apis/google-generative-ai.js +3 -2
- package/dist/ai/apis/openai-completions.js +3 -2
- package/dist/ai/apis/openai-responses.js +5 -3
- package/dist/ai/cache/fingerprint.d.ts +1 -1
- package/dist/ai/cache/fingerprint.js +1 -1
- package/dist/ai/cache/reporting.js +2 -1
- package/dist/ai/http.d.ts +28 -6
- package/dist/ai/http.js +41 -8
- package/dist/ai/providers/channels.d.ts +51 -0
- package/dist/ai/providers/channels.js +96 -0
- package/dist/ai/providers/enrich.d.ts +34 -0
- package/dist/ai/providers/enrich.js +86 -0
- package/dist/ai/providers/models-dev-cache.d.ts +53 -0
- package/dist/ai/providers/models-dev-cache.js +147 -0
- package/dist/ai/providers/models-dev.d.ts +99 -0
- package/dist/ai/providers/models-dev.js +315 -0
- package/dist/ai/providers/registry.d.ts +42 -4
- package/dist/ai/providers/registry.js +195 -34
- package/dist/ai/providers/suggest.d.ts +18 -0
- package/dist/ai/providers/suggest.js +72 -0
- package/dist/ai/sse.d.ts +6 -2
- package/dist/ai/sse.js +22 -2
- package/dist/ai/types.d.ts +30 -3
- package/dist/bundle/ama.cjs +17893 -10698
- package/dist/cli/args.d.ts +23 -5
- package/dist/cli/args.js +113 -13
- package/dist/cli/bootstrap.js +28 -3
- package/dist/cli/codemode-notice.d.ts +20 -0
- package/dist/cli/codemode-notice.js +55 -0
- package/dist/cli/compose-providers.js +3 -0
- package/dist/cli/compose-session.d.ts +8 -0
- package/dist/cli/compose-session.js +32 -1
- package/dist/cli/compose-store.d.ts +1 -1
- package/dist/cli/compose-store.js +3 -1
- package/dist/cli/compose.d.ts +17 -5
- package/dist/cli/compose.js +53 -19
- package/dist/cli/default-model.d.ts +38 -1
- package/dist/cli/default-model.js +96 -9
- package/dist/cli/deps.d.ts +38 -0
- package/dist/cli/exit-codes.d.ts +2 -0
- package/dist/cli/exit-codes.js +3 -0
- package/dist/cli/fake-visibility.d.ts +13 -0
- package/dist/cli/fake-visibility.js +26 -0
- package/dist/cli/from-prompt.d.ts +18 -0
- package/dist/cli/from-prompt.js +49 -0
- package/dist/cli/main.d.ts +10 -2
- package/dist/cli/main.js +88 -2
- package/dist/cli/proxy.d.ts +51 -0
- package/dist/cli/proxy.js +135 -0
- package/dist/cli/startup-screen.d.ts +29 -0
- package/dist/cli/startup-screen.js +47 -0
- package/dist/cli/startup-steps.d.ts +1 -1
- package/dist/cli/startup-steps.js +20 -13
- package/dist/cli/subcommands/config.d.ts +29 -4
- package/dist/cli/subcommands/config.js +188 -25
- package/dist/cli/subcommands/context.js +5 -1
- package/dist/cli/subcommands/doctor.js +12 -1
- package/dist/cli/subcommands/init.d.ts +6 -0
- package/dist/cli/subcommands/init.js +23 -0
- package/dist/cli/subcommands/model-meta.d.ts +16 -0
- package/dist/cli/subcommands/model-meta.js +54 -0
- package/dist/cli/subcommands/models-cache-probe.js +1 -1
- package/dist/cli/subcommands/models-discover.d.ts +18 -6
- package/dist/cli/subcommands/models-discover.js +87 -52
- package/dist/cli/subcommands/models.js +26 -18
- package/dist/cli/subcommands/probe-runner.d.ts +96 -0
- package/dist/cli/subcommands/probe-runner.js +264 -0
- package/dist/cli/subcommands/providers-list.d.ts +8 -0
- package/dist/cli/subcommands/providers-list.js +97 -0
- package/dist/cli/subcommands/providers-plan.d.ts +79 -0
- package/dist/cli/subcommands/providers-plan.js +215 -0
- package/dist/cli/subcommands/providers-probe.d.ts +34 -0
- package/dist/cli/subcommands/providers-probe.js +87 -0
- package/dist/cli/subcommands/providers.d.ts +28 -0
- package/dist/cli/subcommands/providers.js +436 -0
- package/dist/cli/subcommands/sessions-export.d.ts +10 -0
- package/dist/cli/subcommands/sessions-export.js +59 -0
- package/dist/cli/subcommands/sessions-search.d.ts +13 -0
- package/dist/cli/subcommands/sessions-search.js +103 -0
- package/dist/cli/subcommands/sessions.d.ts +3 -2
- package/dist/cli/subcommands/sessions.js +22 -1
- package/dist/cli/subcommands/stats.d.ts +17 -0
- package/dist/cli/subcommands/stats.js +198 -0
- package/dist/cli/system-prompt-arg.d.ts +11 -0
- package/dist/cli/system-prompt-arg.js +34 -0
- package/dist/codemode/modes.d.ts +4 -11
- package/dist/codemode/modes.js +5 -27
- package/dist/codemode/tool.d.ts +18 -14
- package/dist/codemode/tool.js +71 -28
- package/dist/config/init.d.ts +34 -0
- package/dist/config/init.js +99 -0
- package/dist/config/json-schema.d.ts +15 -0
- package/dist/config/json-schema.js +215 -0
- package/dist/config/key-docs.d.ts +22 -0
- package/dist/config/key-docs.js +105 -0
- package/dist/config/merge.d.ts +9 -8
- package/dist/config/merge.js +22 -7
- package/dist/config/schema.d.ts +1 -1
- package/dist/config/schema.js +97 -15
- package/dist/config/types.d.ts +57 -11
- package/dist/config/types.js +19 -1
- package/dist/modes/commands-core.js +6 -5
- package/dist/modes/image-input.d.ts +27 -0
- package/dist/modes/image-input.js +78 -0
- package/dist/modes/interactive/approval-dialog.d.ts +21 -5
- package/dist/modes/interactive/approval-dialog.js +106 -27
- package/dist/modes/interactive/commands.d.ts +11 -2
- package/dist/modes/interactive/commands.js +58 -19
- package/dist/modes/interactive/interactive-mode.d.ts +2 -1
- package/dist/modes/interactive/interactive-mode.js +70 -82
- package/dist/modes/interactive/key-dispatch.d.ts +3 -1
- package/dist/modes/interactive/key-dispatch.js +5 -6
- package/dist/modes/interactive/line/line-mode.d.ts +1 -0
- package/dist/modes/interactive/line/line-mode.js +9 -5
- package/dist/modes/interactive/line/line-render.d.ts +4 -0
- package/dist/modes/interactive/line/line-render.js +28 -6
- package/dist/modes/interactive/message-view.d.ts +48 -9
- package/dist/modes/interactive/message-view.js +238 -44
- package/dist/modes/interactive/panels.d.ts +18 -0
- package/dist/modes/interactive/panels.js +143 -0
- package/dist/modes/interactive/pickers.d.ts +23 -2
- package/dist/modes/interactive/pickers.js +48 -15
- package/dist/modes/interactive/run-indicator.d.ts +51 -0
- package/dist/modes/interactive/run-indicator.js +189 -0
- package/dist/modes/interactive/startup-header.d.ts +40 -0
- package/dist/modes/interactive/startup-header.js +169 -0
- package/dist/modes/interactive/startup-ui.d.ts +7 -2
- package/dist/modes/interactive/startup-ui.js +41 -11
- package/dist/modes/interactive/status-bar.d.ts +18 -15
- package/dist/modes/interactive/status-bar.js +98 -56
- package/dist/modes/interactive/tool-summary.d.ts +46 -0
- package/dist/modes/interactive/tool-summary.js +218 -0
- package/dist/modes/interactive/tool-view.d.ts +48 -15
- package/dist/modes/interactive/tool-view.js +203 -145
- package/dist/modes/print/print-mode.d.ts +33 -4
- package/dist/modes/print/print-mode.js +128 -8
- package/dist/modes/rpc/commands.js +12 -2
- package/dist/permissions/auto-safe.d.ts +60 -0
- package/dist/permissions/auto-safe.js +529 -0
- package/dist/permissions/classifier.d.ts +64 -0
- package/dist/permissions/classifier.js +184 -0
- package/dist/permissions/dangerous.d.ts +5 -0
- package/dist/permissions/dangerous.js +1 -1
- package/dist/permissions/modes.d.ts +30 -0
- package/dist/permissions/modes.js +78 -0
- package/dist/permissions/pipeline.d.ts +31 -4
- package/dist/permissions/pipeline.js +196 -6
- package/dist/permissions/protected.d.ts +19 -0
- package/dist/permissions/protected.js +74 -0
- package/dist/permissions/rules.js +3 -0
- package/dist/permissions/types.d.ts +50 -3
- package/dist/permissions/types.js +3 -0
- package/dist/rpc.d.ts +2 -0
- package/dist/sdk.d.ts +9 -3
- package/dist/sdk.js +10 -2
- package/dist/session/export.d.ts +32 -0
- package/dist/session/export.js +187 -0
- package/dist/session/projection.js +5 -1
- package/dist/session/redact.d.ts +15 -0
- package/dist/session/redact.js +55 -0
- package/dist/session/reuse.d.ts +33 -0
- package/dist/session/reuse.js +86 -0
- package/dist/session/scan.d.ts +34 -0
- package/dist/session/scan.js +140 -0
- package/dist/session/search.d.ts +52 -0
- package/dist/session/search.js +211 -0
- package/dist/session/stats-aggregate.d.ts +63 -0
- package/dist/session/stats-aggregate.js +163 -0
- package/dist/session/stats-index.d.ts +26 -0
- package/dist/session/stats-index.js +91 -0
- package/dist/session/stats-scan.d.ts +54 -0
- package/dist/session/stats-scan.js +236 -0
- package/dist/session/types.d.ts +2 -0
- package/dist/tools/image-file.d.ts +31 -0
- package/dist/tools/image-file.js +114 -0
- package/dist/tools/presets.d.ts +35 -8
- package/dist/tools/presets.js +56 -17
- package/dist/tools/read.d.ts +4 -8
- package/dist/tools/read.js +15 -64
- package/dist/tui/component.d.ts +8 -2
- package/dist/tui/component.js +3 -1
- package/dist/tui/components/box.d.ts +6 -1
- package/dist/tui/components/box.js +16 -6
- package/dist/tui/components/card.d.ts +23 -0
- package/dist/tui/components/card.js +37 -0
- package/dist/tui/components/editor-history.d.ts +6 -0
- package/dist/tui/components/editor-history.js +45 -0
- package/dist/tui/components/editor-paste.d.ts +1 -1
- package/dist/tui/components/editor-paste.js +4 -4
- package/dist/tui/components/editor.d.ts +11 -5
- package/dist/tui/components/editor.js +52 -58
- package/dist/tui/components/key-value.d.ts +3 -0
- package/dist/tui/components/key-value.js +16 -6
- package/dist/tui/components/loader.d.ts +37 -7
- package/dist/tui/components/loader.js +84 -21
- package/dist/tui/components/markdown.d.ts +5 -1
- package/dist/tui/components/markdown.js +45 -21
- package/dist/tui/components/meter.d.ts +3 -3
- package/dist/tui/components/meter.js +13 -11
- package/dist/tui/components/select-list.d.ts +23 -1
- package/dist/tui/components/select-list.js +76 -13
- package/dist/tui/glyphs.d.ts +68 -0
- package/dist/tui/glyphs.js +114 -0
- package/dist/tui/theme.d.ts +30 -6
- package/dist/tui/theme.js +103 -17
- package/dist/tui.d.ts +4 -2
- package/dist/tui.js +3 -1
- package/docs/codemode.md +23 -9
- package/docs/hooks.md +10 -10
- package/docs/permissions.md +148 -0
- package/docs/providers.md +241 -3
- package/docs/rpc.md +38 -38
- package/docs/session-format.md +3 -2
- package/docs/sessions.md +134 -0
- package/docs/tui.md +140 -61
- package/package.json +3 -1
package/dist/cli/main.js
CHANGED
|
@@ -4,14 +4,18 @@
|
|
|
4
4
|
*
|
|
5
5
|
* - 设 `AMA=1`、`AI_AGENT=ama`;直接执行时装 `uncaughtException` / `unhandledRejection` →
|
|
6
6
|
* stderr 一行 + 退出码 1;SIGINT / SIGTERM 交给当前模式。
|
|
7
|
-
* - `--version` / `--help` 短路;子命令 `auth / sessions / models / doctor / config
|
|
7
|
+
* - `--version` / `--help` 短路;子命令 `auth / sessions / models / providers / doctor / config /
|
|
8
|
+
* init` 分派后返回;进入对话的命令(与 `providers add`)启动前若配置目录不存在则静默初始化
|
|
9
|
+
* (`AMA_NO_INIT=1` 关闭),只读子命令(`config show`、`doctor`、`models list` 等)不写配置目录;
|
|
8
10
|
* 其余交给 `runCli()`(bootstrap → 模式)。
|
|
11
|
+
* - 设了 HTTPS_PROXY / HTTP_PROXY 时启用 Node 内置的环境变量代理(cli/proxy.ts);不支持的 Node
|
|
12
|
+
* 版本在会联网的命令里提示一次。
|
|
9
13
|
* - 运行时实现(RuntimeDeps):`MainOptions.deps` > `registerRuntimeDeps()` > 组装根
|
|
10
14
|
* `createRuntimeDeps()`(cli/compose.ts,动态 import)。
|
|
11
15
|
* - 签名 `main(argv): Promise<number>` 与「直接执行才自动运行」判定保持不变:
|
|
12
16
|
* src/bundle.ts 显式调用 `main()`。
|
|
13
17
|
*/
|
|
14
|
-
import { realpathSync } from "node:fs";
|
|
18
|
+
import { fstatSync, realpathSync } from "node:fs";
|
|
15
19
|
import { fileURLToPath } from "node:url";
|
|
16
20
|
import { AMA_VERSION } from "../version.js";
|
|
17
21
|
import { parseArgs } from "./args.js";
|
|
@@ -21,7 +25,13 @@ import { runAuth } from "./subcommands/auth.js";
|
|
|
21
25
|
import { runConfig } from "./subcommands/config.js";
|
|
22
26
|
import { runDoctor } from "./subcommands/doctor.js";
|
|
23
27
|
import { runModels } from "./subcommands/models.js";
|
|
28
|
+
import { runProviders } from "./subcommands/providers.js";
|
|
29
|
+
import { runInit } from "./subcommands/init.js";
|
|
30
|
+
import { autoInitConfigDir } from "../config/init.js";
|
|
31
|
+
import { resolveConfigDir } from "../config/paths.js";
|
|
24
32
|
import { runSessions } from "./subcommands/sessions.js";
|
|
33
|
+
import { runStats } from "./subcommands/stats.js";
|
|
34
|
+
import { enableEnvProxy, proxyHint } from "./proxy.js";
|
|
25
35
|
let registeredDeps;
|
|
26
36
|
/** 集成批次注入运行时实现(B1 / B2 / B3 / B6 / B7)。 */
|
|
27
37
|
export function registerRuntimeDeps(deps) {
|
|
@@ -67,6 +77,61 @@ export function readStdinDefault() {
|
|
|
67
77
|
stdin.on("data", onData);
|
|
68
78
|
});
|
|
69
79
|
}
|
|
80
|
+
/** fd 0 的类型;fstat 失败(已关闭)按 `null` 处理。 */
|
|
81
|
+
export function stdinKindDefault() {
|
|
82
|
+
try {
|
|
83
|
+
const stat = fstatSync(0);
|
|
84
|
+
if (stat.isFile())
|
|
85
|
+
return "file";
|
|
86
|
+
if (stat.isFIFO())
|
|
87
|
+
return "fifo";
|
|
88
|
+
if (stat.isSocket())
|
|
89
|
+
return "socket";
|
|
90
|
+
if (stat.isCharacterDevice())
|
|
91
|
+
return process.stdin.isTTY === true ? "tty" : "null";
|
|
92
|
+
return "other";
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return "null";
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/** 等 stdin 首字节至多 `timeoutMs`;超时则停止读取并返回 undefined,否则读到 EOF。 */
|
|
99
|
+
export function readStdinFirstByteDefault(timeoutMs) {
|
|
100
|
+
const stdin = process.stdin;
|
|
101
|
+
return new Promise((resolve, reject) => {
|
|
102
|
+
const chunks = [];
|
|
103
|
+
let timer;
|
|
104
|
+
const cleanup = () => {
|
|
105
|
+
clearTimeout(timer);
|
|
106
|
+
stdin.off("data", onData);
|
|
107
|
+
stdin.off("end", onEnd);
|
|
108
|
+
stdin.off("error", onError);
|
|
109
|
+
};
|
|
110
|
+
const onData = (chunk) => {
|
|
111
|
+
clearTimeout(timer);
|
|
112
|
+
timer = undefined;
|
|
113
|
+
chunks.push(chunk);
|
|
114
|
+
};
|
|
115
|
+
const onEnd = () => {
|
|
116
|
+
cleanup();
|
|
117
|
+
resolve(Buffer.concat(chunks).toString("utf8"));
|
|
118
|
+
};
|
|
119
|
+
const onError = (error) => {
|
|
120
|
+
cleanup();
|
|
121
|
+
reject(error);
|
|
122
|
+
};
|
|
123
|
+
timer = setTimeout(() => {
|
|
124
|
+
cleanup();
|
|
125
|
+
// 不再读:释放句柄,父进程留着不关的管道不会让进程挂住
|
|
126
|
+
stdin.pause();
|
|
127
|
+
stdin.destroy();
|
|
128
|
+
resolve(undefined);
|
|
129
|
+
}, timeoutMs);
|
|
130
|
+
stdin.on("data", onData);
|
|
131
|
+
stdin.once("end", onEnd);
|
|
132
|
+
stdin.once("error", onError);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
70
135
|
export function defaultIo() {
|
|
71
136
|
return {
|
|
72
137
|
stdout: (text) => void process.stdout.write(text),
|
|
@@ -76,6 +141,8 @@ export function defaultIo() {
|
|
|
76
141
|
env: process.env,
|
|
77
142
|
cwd: process.cwd(),
|
|
78
143
|
readStdin: readStdinDefault,
|
|
144
|
+
readStdinFirstByte: readStdinFirstByteDefault,
|
|
145
|
+
stdinKind: stdinKindDefault,
|
|
79
146
|
};
|
|
80
147
|
}
|
|
81
148
|
let hooksInstalled = false;
|
|
@@ -116,6 +183,19 @@ export async function main(argv, options = {}) {
|
|
|
116
183
|
const parsed = parseArgs(argv);
|
|
117
184
|
if (parsed.kind !== "subcommand")
|
|
118
185
|
noTui = parsed.args.noTui;
|
|
186
|
+
const informational = parsed.kind === "run" ? parsed.args.help || parsed.args.version : parsed.name === "init";
|
|
187
|
+
// 首次自动初始化只在会进入对话的命令(和接入供应商)里做;只读子命令不写配置目录
|
|
188
|
+
const startsWork = parsed.kind === "run" || (parsed.name === "providers" && parsed.argv[0] === "add");
|
|
189
|
+
if (!informational && startsWork)
|
|
190
|
+
autoInitConfigDir(resolveConfigDir({ env: io.env }), io.env);
|
|
191
|
+
// 进程级副作用(全局 dispatcher):只在真正的进程入口做,测试里调 main() 不碰
|
|
192
|
+
if (!informational && options.processHooks !== false) {
|
|
193
|
+
const proxy = enableEnvProxy(io.env);
|
|
194
|
+
const online = parsed.kind === "run" || parsed.name === "models" || parsed.name === "providers";
|
|
195
|
+
const hint = online ? proxyHint(proxy) : undefined;
|
|
196
|
+
if (hint !== undefined)
|
|
197
|
+
io.stderr(hint);
|
|
198
|
+
}
|
|
119
199
|
if (parsed.kind === "subcommand") {
|
|
120
200
|
switch (parsed.name) {
|
|
121
201
|
case "auth":
|
|
@@ -124,10 +204,16 @@ export async function main(argv, options = {}) {
|
|
|
124
204
|
return await runSessions(parsed.argv, io, await resolveDeps());
|
|
125
205
|
case "models":
|
|
126
206
|
return await runModels(parsed.argv, io, await resolveDeps());
|
|
207
|
+
case "providers":
|
|
208
|
+
return await runProviders(parsed.argv, io, await resolveDeps());
|
|
127
209
|
case "doctor":
|
|
128
210
|
return await runDoctor(parsed.argv, io, await resolveDeps());
|
|
129
211
|
case "config":
|
|
130
212
|
return await runConfig(parsed.argv, io, await resolveDeps());
|
|
213
|
+
case "init":
|
|
214
|
+
return runInit(parsed.argv, io);
|
|
215
|
+
case "stats":
|
|
216
|
+
return await runStats(parsed.argv, io);
|
|
131
217
|
}
|
|
132
218
|
}
|
|
133
219
|
if (parsed.args.version) {
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 环境变量代理(W4-C):Node 的全局 fetch 缺省不读 `HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY`。
|
|
3
|
+
*
|
|
4
|
+
* - 没设代理变量 → 什么都不做。
|
|
5
|
+
* - 运行时已接管(`NODE_USE_ENV_PROXY=1` 或 `--use-env-proxy`,且 Node 支持)→ 不重复设置。
|
|
6
|
+
* - Node 有 `http.setGlobalProxyFromEnv()`(24.x / 26.x 等)→ 进程启动时调用一次,等价于
|
|
7
|
+
* `NODE_USE_ENV_PROXY=1`(fetch 与 http/https 全局 agent 都走代理,`NO_PROXY` 生效)。零依赖。
|
|
8
|
+
* - 不支持的 Node 版本 → 只在会联网的命令里于 stderr 提示一次(不中断)。
|
|
9
|
+
*
|
|
10
|
+
* `ama doctor` 用 `describeProxy()` 显示同一份状态;代理 URL 里的账号密码打码。
|
|
11
|
+
*/
|
|
12
|
+
export interface ProxyEnv {
|
|
13
|
+
httpsProxy?: string;
|
|
14
|
+
httpProxy?: string;
|
|
15
|
+
noProxy?: string;
|
|
16
|
+
}
|
|
17
|
+
export type ProxyState = "none"
|
|
18
|
+
/** 运行时已按环境变量接管(NODE_USE_ENV_PROXY / --use-env-proxy)。 */
|
|
19
|
+
| "runtime"
|
|
20
|
+
/** ama 启动时调用 http.setGlobalProxyFromEnv() 启用。 */
|
|
21
|
+
| "enabled"
|
|
22
|
+
/** 设了代理变量,但当前 Node 不支持内置代理。 */
|
|
23
|
+
| "unsupported"
|
|
24
|
+
/** 代理 URL 无法解析。 */
|
|
25
|
+
| "invalid";
|
|
26
|
+
export interface ProxyStatus {
|
|
27
|
+
env: ProxyEnv;
|
|
28
|
+
state: ProxyState;
|
|
29
|
+
error?: string;
|
|
30
|
+
}
|
|
31
|
+
type SetGlobalProxy = (env?: NodeJS.ProcessEnv) => () => void;
|
|
32
|
+
export interface ProxyRuntime {
|
|
33
|
+
setGlobalProxyFromEnv?: SetGlobalProxy | undefined;
|
|
34
|
+
execArgv: readonly string[];
|
|
35
|
+
version: string;
|
|
36
|
+
}
|
|
37
|
+
export declare function readProxyEnv(env: Readonly<Record<string, string | undefined>>): ProxyEnv;
|
|
38
|
+
export declare function defaultProxyRuntime(): ProxyRuntime;
|
|
39
|
+
/** 只判断不启用:没设代理 / 运行时已接管 / 能启用 / 不支持 / URL 无法解析。 */
|
|
40
|
+
export declare function inspectProxy(env: Readonly<Record<string, string | undefined>>, runtime?: ProxyRuntime): ProxyStatus;
|
|
41
|
+
/** 按上面的规则启用代理(进程级副作用);同一进程只做一次,之后返回同一份状态。 */
|
|
42
|
+
export declare function enableEnvProxy(env: Readonly<Record<string, string | undefined>>, runtime?: ProxyRuntime): ProxyStatus;
|
|
43
|
+
/** 测试用:清掉进程内记住的状态。 */
|
|
44
|
+
export declare function resetProxyForTest(): void;
|
|
45
|
+
/** 代理 URL 里的账号密码打码。 */
|
|
46
|
+
export declare function redactProxyUrl(value: string): string;
|
|
47
|
+
/** 不能启用时给一次 stderr 提示(每个进程至多一次);能用或没设代理返回 undefined。 */
|
|
48
|
+
export declare function proxyHint(status: ProxyStatus, nodeVersion?: string): string | undefined;
|
|
49
|
+
/** `ama doctor` 的代理段落。 */
|
|
50
|
+
export declare function describeProxy(status: ProxyStatus): string[];
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 环境变量代理(W4-C):Node 的全局 fetch 缺省不读 `HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY`。
|
|
3
|
+
*
|
|
4
|
+
* - 没设代理变量 → 什么都不做。
|
|
5
|
+
* - 运行时已接管(`NODE_USE_ENV_PROXY=1` 或 `--use-env-proxy`,且 Node 支持)→ 不重复设置。
|
|
6
|
+
* - Node 有 `http.setGlobalProxyFromEnv()`(24.x / 26.x 等)→ 进程启动时调用一次,等价于
|
|
7
|
+
* `NODE_USE_ENV_PROXY=1`(fetch 与 http/https 全局 agent 都走代理,`NO_PROXY` 生效)。零依赖。
|
|
8
|
+
* - 不支持的 Node 版本 → 只在会联网的命令里于 stderr 提示一次(不中断)。
|
|
9
|
+
*
|
|
10
|
+
* `ama doctor` 用 `describeProxy()` 显示同一份状态;代理 URL 里的账号密码打码。
|
|
11
|
+
*/
|
|
12
|
+
import * as http from "node:http";
|
|
13
|
+
function pick(env, name) {
|
|
14
|
+
const value = env[name.toLowerCase()] ?? env[name.toUpperCase()];
|
|
15
|
+
return value !== undefined && value.trim() !== "" ? value.trim() : undefined;
|
|
16
|
+
}
|
|
17
|
+
export function readProxyEnv(env) {
|
|
18
|
+
const out = {};
|
|
19
|
+
const https = pick(env, "https_proxy");
|
|
20
|
+
const plain = pick(env, "http_proxy");
|
|
21
|
+
const no = pick(env, "no_proxy");
|
|
22
|
+
if (https !== undefined)
|
|
23
|
+
out.httpsProxy = https;
|
|
24
|
+
if (plain !== undefined)
|
|
25
|
+
out.httpProxy = plain;
|
|
26
|
+
if (no !== undefined)
|
|
27
|
+
out.noProxy = no;
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
export function defaultProxyRuntime() {
|
|
31
|
+
const fn = http.setGlobalProxyFromEnv;
|
|
32
|
+
return {
|
|
33
|
+
setGlobalProxyFromEnv: typeof fn === "function" ? fn.bind(http) : undefined,
|
|
34
|
+
execArgv: process.execArgv,
|
|
35
|
+
version: process.versions.node,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/** Node ≥ 24,或 22.21+:认 NODE_USE_ENV_PROXY / --use-env-proxy。 */
|
|
39
|
+
function runtimeReadsEnvProxy(version) {
|
|
40
|
+
const [major = 0, minor = 0] = version.split(".").map(Number);
|
|
41
|
+
return major >= 24 || (major === 22 && minor >= 21);
|
|
42
|
+
}
|
|
43
|
+
let current;
|
|
44
|
+
let hinted = false;
|
|
45
|
+
/** 只判断不启用:没设代理 / 运行时已接管 / 能启用 / 不支持 / URL 无法解析。 */
|
|
46
|
+
export function inspectProxy(env, runtime = defaultProxyRuntime()) {
|
|
47
|
+
if (current !== undefined)
|
|
48
|
+
return current;
|
|
49
|
+
const proxy = readProxyEnv(env);
|
|
50
|
+
if (proxy.httpsProxy === undefined && proxy.httpProxy === undefined)
|
|
51
|
+
return { env: proxy, state: "none" };
|
|
52
|
+
const flagged = env["NODE_USE_ENV_PROXY"] === "1" ||
|
|
53
|
+
runtime.execArgv.includes("--use-env-proxy") ||
|
|
54
|
+
(env["NODE_OPTIONS"] ?? "").includes("--use-env-proxy");
|
|
55
|
+
if (flagged && runtimeReadsEnvProxy(runtime.version))
|
|
56
|
+
return { env: proxy, state: "runtime" };
|
|
57
|
+
if (runtime.setGlobalProxyFromEnv === undefined)
|
|
58
|
+
return { env: proxy, state: "unsupported" };
|
|
59
|
+
for (const value of [proxy.httpsProxy, proxy.httpProxy]) {
|
|
60
|
+
if (value !== undefined && !URL.canParse(value))
|
|
61
|
+
return { env: proxy, state: "invalid", error: `无法解析 ${redactProxyUrl(value)}` };
|
|
62
|
+
}
|
|
63
|
+
return { env: proxy, state: "enabled" };
|
|
64
|
+
}
|
|
65
|
+
/** 按上面的规则启用代理(进程级副作用);同一进程只做一次,之后返回同一份状态。 */
|
|
66
|
+
export function enableEnvProxy(env, runtime = defaultProxyRuntime()) {
|
|
67
|
+
if (current !== undefined)
|
|
68
|
+
return current;
|
|
69
|
+
const status = inspectProxy(env, runtime);
|
|
70
|
+
if (status.state === "enabled") {
|
|
71
|
+
try {
|
|
72
|
+
runtime.setGlobalProxyFromEnv?.({ ...env });
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
current = { env: status.env, state: "invalid", error: error.message };
|
|
76
|
+
return current;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
current = status;
|
|
80
|
+
return current;
|
|
81
|
+
}
|
|
82
|
+
/** 测试用:清掉进程内记住的状态。 */
|
|
83
|
+
export function resetProxyForTest() {
|
|
84
|
+
current = undefined;
|
|
85
|
+
hinted = false;
|
|
86
|
+
}
|
|
87
|
+
/** 代理 URL 里的账号密码打码。 */
|
|
88
|
+
export function redactProxyUrl(value) {
|
|
89
|
+
try {
|
|
90
|
+
const url = new URL(value);
|
|
91
|
+
if (url.username === "" && url.password === "")
|
|
92
|
+
return value;
|
|
93
|
+
url.username = url.username === "" ? "" : "***";
|
|
94
|
+
url.password = url.password === "" ? "" : "***";
|
|
95
|
+
return url.toString();
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return value.replace(/\/\/[^@/]*@/, "//***@");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** 不能启用时给一次 stderr 提示(每个进程至多一次);能用或没设代理返回 undefined。 */
|
|
102
|
+
export function proxyHint(status, nodeVersion = process.versions.node) {
|
|
103
|
+
if (hinted)
|
|
104
|
+
return undefined;
|
|
105
|
+
if (status.state === "unsupported") {
|
|
106
|
+
hinted = true;
|
|
107
|
+
return (`ama: 检测到 HTTPS_PROXY / HTTP_PROXY,但 Node ${nodeVersion} 的 fetch 不读代理变量,请求将直连;` +
|
|
108
|
+
"升级到 Node 24+,或在 Node 22.21+ 上设 NODE_USE_ENV_PROXY=1\n");
|
|
109
|
+
}
|
|
110
|
+
if (status.state === "invalid") {
|
|
111
|
+
hinted = true;
|
|
112
|
+
return `ama: 代理变量无法解析,请求将直连:${status.error ?? ""}\n`;
|
|
113
|
+
}
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
/** `ama doctor` 的代理段落。 */
|
|
117
|
+
export function describeProxy(status) {
|
|
118
|
+
const { env } = status;
|
|
119
|
+
const lines = [];
|
|
120
|
+
if (env.httpsProxy !== undefined)
|
|
121
|
+
lines.push(`HTTPS_PROXY=${redactProxyUrl(env.httpsProxy)}`);
|
|
122
|
+
if (env.httpProxy !== undefined)
|
|
123
|
+
lines.push(`HTTP_PROXY=${redactProxyUrl(env.httpProxy)}`);
|
|
124
|
+
if (env.noProxy !== undefined)
|
|
125
|
+
lines.push(`NO_PROXY=${env.noProxy}`);
|
|
126
|
+
const state = {
|
|
127
|
+
none: "未设置代理变量:直连",
|
|
128
|
+
runtime: "已启用(Node 按 NODE_USE_ENV_PROXY / --use-env-proxy 接管)",
|
|
129
|
+
enabled: "已启用(ama 启动时调用 Node 内置的 setGlobalProxyFromEnv)",
|
|
130
|
+
unsupported: `✗ 当前 Node ${process.versions.node} 不支持内置代理,请求直连;升级到 Node 24+`,
|
|
131
|
+
invalid: `✗ 代理变量无法解析:${status.error ?? ""}`,
|
|
132
|
+
};
|
|
133
|
+
lines.push(state[status.state]);
|
|
134
|
+
return lines;
|
|
135
|
+
}
|
|
@@ -6,10 +6,39 @@
|
|
|
6
6
|
* - normal:标题行 + 模型 / 信任 / 已加载资源清单 / 警告数
|
|
7
7
|
* - header:只有标题行(版本与按键提示)
|
|
8
8
|
* - silent:不输出
|
|
9
|
+
*
|
|
10
|
+
* 交互模式(终端界面视觉设计 v1 §3.1)用结构化的 `startupInfo()` 自己排版(框 / 无框两态);
|
|
11
|
+
* `buildStartupScreen` 的纯文本行保留给 line 模式与测试。
|
|
9
12
|
*/
|
|
13
|
+
import type { PermissionMode } from "../permissions/types.js";
|
|
10
14
|
import type { Runtime } from "./runtime.js";
|
|
11
15
|
export type StartupScreenLevel = "normal" | "header" | "silent";
|
|
12
16
|
export declare function startupScreenLevel(runtime: Pick<Runtime, "config">): StartupScreenLevel;
|
|
13
17
|
export declare function headerLine(): string;
|
|
14
18
|
export type StartupScreenRuntime = Pick<Runtime, "config" | "trust" | "resources" | "model" | "thinkingLevel" | "hooks" | "host" | "paths" | "warnings">;
|
|
15
19
|
export declare function buildStartupScreen(runtime: StartupScreenRuntime, level?: StartupScreenLevel): string[];
|
|
20
|
+
/** 交互模式启动头的结构化字段(§3.1)。 */
|
|
21
|
+
export interface StartupInfo {
|
|
22
|
+
version: string;
|
|
23
|
+
/** `provider/id[@渠道]`。 */
|
|
24
|
+
model: string;
|
|
25
|
+
thinking: string;
|
|
26
|
+
/** 会话目录(家目录缩写为 `~`)。 */
|
|
27
|
+
cwd: string;
|
|
28
|
+
trusted: boolean;
|
|
29
|
+
/** 信任来源的短名(trust.json / 命令行 / 本次确认 / profile / 缺省)。 */
|
|
30
|
+
trustSource: string;
|
|
31
|
+
permissionMode: PermissionMode;
|
|
32
|
+
preset: string;
|
|
33
|
+
codemode: "off" | "on" | "only";
|
|
34
|
+
/** 上下文文件的文件名(外层在前)。 */
|
|
35
|
+
contextFiles: string[];
|
|
36
|
+
skills: number;
|
|
37
|
+
prompts: number;
|
|
38
|
+
hooks: number;
|
|
39
|
+
host?: string;
|
|
40
|
+
warnings: number;
|
|
41
|
+
}
|
|
42
|
+
/** 家目录前缀缩写为 `~`(`/` 与 `\` 两种分隔都认,余下部分原样保留)。 */
|
|
43
|
+
export declare function tildePath(path: string, home: string | undefined): string;
|
|
44
|
+
export declare function startupInfo(runtime: StartupScreenRuntime & Pick<Runtime, "session">, home?: string): StartupInfo;
|
|
@@ -6,7 +6,13 @@
|
|
|
6
6
|
* - normal:标题行 + 模型 / 信任 / 已加载资源清单 / 警告数
|
|
7
7
|
* - header:只有标题行(版本与按键提示)
|
|
8
8
|
* - silent:不输出
|
|
9
|
+
*
|
|
10
|
+
* 交互模式(终端界面视觉设计 v1 §3.1)用结构化的 `startupInfo()` 自己排版(框 / 无框两态);
|
|
11
|
+
* `buildStartupScreen` 的纯文本行保留给 line 模式与测试。
|
|
9
12
|
*/
|
|
13
|
+
import { basename } from "node:path";
|
|
14
|
+
import { formatModelRef } from "../ai/providers/channels.js";
|
|
15
|
+
import { effectiveCodemodeMode } from "../tools/presets.js";
|
|
10
16
|
import { AMA_VERSION } from "../version.js";
|
|
11
17
|
export function startupScreenLevel(runtime) {
|
|
12
18
|
return runtime.config.ui?.quietStartup ?? "normal";
|
|
@@ -54,3 +60,44 @@ export function buildStartupScreen(runtime, level = startupScreenLevel(runtime))
|
|
|
54
60
|
lines.push(`警告:${runtime.warnings.length} 条(ama doctor 查看)`);
|
|
55
61
|
return lines;
|
|
56
62
|
}
|
|
63
|
+
const TRUST_SOURCE = {
|
|
64
|
+
flag: "命令行",
|
|
65
|
+
"trust-file": "trust.json",
|
|
66
|
+
prompt: "本次确认",
|
|
67
|
+
profile: "profile",
|
|
68
|
+
default: "缺省",
|
|
69
|
+
};
|
|
70
|
+
/** 家目录前缀缩写为 `~`(`/` 与 `\` 两种分隔都认,余下部分原样保留)。 */
|
|
71
|
+
export function tildePath(path, home) {
|
|
72
|
+
if (home === undefined || home === "")
|
|
73
|
+
return path;
|
|
74
|
+
const trimmed = /[\\/]$/.test(home) ? home.slice(0, -1) : home;
|
|
75
|
+
if (path === trimmed)
|
|
76
|
+
return "~";
|
|
77
|
+
const next = path[trimmed.length];
|
|
78
|
+
return path.startsWith(trimmed) && (next === "/" || next === "\\")
|
|
79
|
+
? `~${path.slice(trimmed.length)}`
|
|
80
|
+
: path;
|
|
81
|
+
}
|
|
82
|
+
export function startupInfo(runtime, home) {
|
|
83
|
+
const { resources } = runtime;
|
|
84
|
+
const info = {
|
|
85
|
+
version: AMA_VERSION,
|
|
86
|
+
model: formatModelRef(runtime.model),
|
|
87
|
+
thinking: runtime.thinkingLevel,
|
|
88
|
+
cwd: tildePath(runtime.paths.cwd, home),
|
|
89
|
+
trusted: runtime.trust.trusted,
|
|
90
|
+
trustSource: TRUST_SOURCE[runtime.trust.source],
|
|
91
|
+
permissionMode: runtime.session.state.permissionMode,
|
|
92
|
+
preset: runtime.config.tools?.preset ?? "default",
|
|
93
|
+
codemode: effectiveCodemodeMode(runtime.config),
|
|
94
|
+
contextFiles: resources.contextFiles.map((f) => basename(f.path)),
|
|
95
|
+
skills: resources.skills.length,
|
|
96
|
+
prompts: resources.prompts.length,
|
|
97
|
+
hooks: runtime.hooks.list().length,
|
|
98
|
+
warnings: runtime.warnings.length,
|
|
99
|
+
};
|
|
100
|
+
if (runtime.host !== undefined)
|
|
101
|
+
info.host = runtime.host.adapter.id;
|
|
102
|
+
return info;
|
|
103
|
+
}
|
|
@@ -26,7 +26,7 @@ export interface ModelChoice {
|
|
|
26
26
|
provider: ProviderData;
|
|
27
27
|
}
|
|
28
28
|
/** 第 11 步:解析模型与 key。 */
|
|
29
|
-
export declare function resolveModel(args: ParsedArgs, registry: ProviderRegistryApi, manager: SessionManagerApi, defaultModel: string | undefined, deps: RuntimeDeps, interactive: boolean): Promise<ModelChoice>;
|
|
29
|
+
export declare function resolveModel(args: ParsedArgs, registry: ProviderRegistryApi, manager: SessionManagerApi, defaultModel: string | undefined, deps: RuntimeDeps, interactive: boolean, env?: Readonly<Record<string, string | undefined>>): Promise<ModelChoice>;
|
|
30
30
|
export declare function thinkingOf(args: ParsedArgs, manager: SessionManagerApi, fallback: ModelThinkingLevel | undefined): ModelThinkingLevel;
|
|
31
31
|
/** 第 12 步之后:`--tools` / `--exclude-tools`(宿主工具注册后再校验,宿主工具名也可用)。 */
|
|
32
32
|
export declare function applyToolFilters(args: ParsedArgs, runtimeTools: Runtime["tools"]): void;
|
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
* 启动序列的单步辅助(设计 §11.1):错误映射、模式判定、profile 合并、会话请求、
|
|
3
3
|
* 模型与思考级别解析、工具过滤、指令文件。[B5] 由 cli/bootstrap.ts 编排。
|
|
4
4
|
*/
|
|
5
|
+
import { describeLookupFailure } from "../ai/providers/suggest.js";
|
|
6
|
+
import { formatModelRef } from "../ai/providers/channels.js";
|
|
5
7
|
import { statSync } from "node:fs";
|
|
6
8
|
import { isAbsolute, resolve } from "node:path";
|
|
7
9
|
import { AmaError, StartupError, isAmaError } from "../errors.js";
|
|
8
10
|
import { UsageError } from "./args.js";
|
|
9
|
-
import { pickDefaultModel } from "./default-model.js";
|
|
11
|
+
import { noModelGuidance, pickDefaultModel } from "./default-model.js";
|
|
12
|
+
import { hideFakeProvider } from "./fake-visibility.js";
|
|
10
13
|
import { ExitCode } from "./exit-codes.js";
|
|
11
14
|
/** 把非 StartupError 包成指定退出码;StartupError / UsageError 原样透传。 */
|
|
12
15
|
export async function step(exitCode, label, fn) {
|
|
@@ -66,6 +69,8 @@ export function applyProfile(args, profile) {
|
|
|
66
69
|
return merged;
|
|
67
70
|
}
|
|
68
71
|
export function sessionRequestOf(args) {
|
|
72
|
+
if (args.noSession)
|
|
73
|
+
return { kind: "memory" };
|
|
69
74
|
if (args.continue)
|
|
70
75
|
return { kind: "continue" };
|
|
71
76
|
if (args.resume)
|
|
@@ -79,7 +84,7 @@ export function sessionRequestOf(args) {
|
|
|
79
84
|
export function sourceOf(request, manager) {
|
|
80
85
|
if (request.kind === "fork")
|
|
81
86
|
return "fork";
|
|
82
|
-
if (request.kind === "new")
|
|
87
|
+
if (request.kind === "new" || request.kind === "memory")
|
|
83
88
|
return "startup";
|
|
84
89
|
return manager.entries().length > 0 ? "resume" : "startup";
|
|
85
90
|
}
|
|
@@ -93,7 +98,7 @@ export function lastEntry(manager, predicate) {
|
|
|
93
98
|
return undefined;
|
|
94
99
|
}
|
|
95
100
|
/** 第 11 步:解析模型与 key。 */
|
|
96
|
-
export async function resolveModel(args, registry, manager, defaultModel, deps, interactive) {
|
|
101
|
+
export async function resolveModel(args, registry, manager, defaultModel, deps, interactive, env = {}) {
|
|
97
102
|
if (args.provider !== undefined && args.model === undefined) {
|
|
98
103
|
throw new UsageError(`--provider ${args.provider} 需要同时给出 --model(不回退到该供应商的缺省模型)`);
|
|
99
104
|
}
|
|
@@ -101,13 +106,8 @@ export async function resolveModel(args, registry, manager, defaultModel, deps,
|
|
|
101
106
|
const found = registry.findModel(ref);
|
|
102
107
|
if (found.ok)
|
|
103
108
|
return { model: found.model, provider: found.provider };
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
? "供应商不存在"
|
|
107
|
-
: found.reason === "ambiguous"
|
|
108
|
-
? "模型名有歧义"
|
|
109
|
-
: "模型不存在";
|
|
110
|
-
throw new StartupError("model_not_found", `${label}${what}:${ref}${hint}`, ExitCode.NoModel);
|
|
109
|
+
const code = found.reason === "provider_not_found" ? "provider_not_found" : "model_not_found";
|
|
110
|
+
throw new StartupError(code, `${label}${describeLookupFailure(ref, found)}`, ExitCode.NoModel);
|
|
111
111
|
};
|
|
112
112
|
let choice;
|
|
113
113
|
if (args.model !== undefined) {
|
|
@@ -119,7 +119,11 @@ export async function resolveModel(args, registry, manager, defaultModel, deps,
|
|
|
119
119
|
else {
|
|
120
120
|
const change = lastEntry(manager, (e) => e.type === "model_change");
|
|
121
121
|
if (change?.type === "model_change") {
|
|
122
|
-
const found = registry.findModel(
|
|
122
|
+
const found = registry.findModel(formatModelRef({
|
|
123
|
+
provider: change.provider,
|
|
124
|
+
id: change.modelId,
|
|
125
|
+
...(change.channel !== undefined ? { channel: change.channel } : {}),
|
|
126
|
+
}));
|
|
123
127
|
if (found.ok)
|
|
124
128
|
choice = { model: found.model, provider: found.provider };
|
|
125
129
|
}
|
|
@@ -132,13 +136,16 @@ export async function resolveModel(args, registry, manager, defaultModel, deps,
|
|
|
132
136
|
}
|
|
133
137
|
}
|
|
134
138
|
const pick = async (reason) => {
|
|
135
|
-
|
|
139
|
+
// 选择器不列测试供应商 fake(AMA_SHOW_FAKE=1 或 AMA_FAKE_SCRIPT 时照列)
|
|
140
|
+
const picked = interactive
|
|
141
|
+
? await deps.ui?.pickModel?.(hideFakeProvider(registry, env), reason)
|
|
142
|
+
: undefined;
|
|
136
143
|
if (picked === undefined)
|
|
137
144
|
throw new StartupError("no_api_key", reason, ExitCode.NoModel);
|
|
138
145
|
return lookup(picked, "");
|
|
139
146
|
};
|
|
140
147
|
if (choice === undefined) {
|
|
141
|
-
return pick(
|
|
148
|
+
return pick(noModelGuidance(registry));
|
|
142
149
|
}
|
|
143
150
|
if (choice.provider.requiresApiKey) {
|
|
144
151
|
const key = await registry.resolveApiKey(choice.provider.id);
|
|
@@ -3,16 +3,20 @@
|
|
|
3
3
|
* 每一项标出来自哪一层(default / user / profile / project),并给出将使用的模型与原因
|
|
4
4
|
* (`config.defaultModel` 或零配置选择)。只读;config 里的字面量 apiKey 只显示种类。[B6]
|
|
5
5
|
*
|
|
6
|
+
* 缺省值来自 config/key-docs.ts 的 DISPLAY_DEFAULTS(含 DEFAULT_CONFIG 不写的 cache / codemode 等段),
|
|
7
|
+
* `codemode.mode` 不写时显示跟随预设的结果与原因;`--tools-preset` / `--codemode` 作为 cli 层叠加;
|
|
8
|
+
* 预设写的是旧名(codemode)时显示规范名并提示。
|
|
9
|
+
*
|
|
6
10
|
* [W3-B12] 「供应商」节:config 里出现的供应商与 baseUrl 来自环境变量(`OPENAI_BASE_URL` /
|
|
7
11
|
* `ANTHROPIC_BASE_URL`)的内置供应商,列出协议、生效 baseUrl 与来源、config 里每个模型的协议
|
|
8
12
|
* (模型级 `api` 生效后的值)。
|
|
9
13
|
*/
|
|
10
|
-
import type
|
|
14
|
+
import { type AmaConfig, type CodemodeMode } from "../../config/types.js";
|
|
11
15
|
import type { Api, ProviderRegistryApi } from "../../ai/types.js";
|
|
12
16
|
import type { CliIo, RuntimeDeps } from "../deps.js";
|
|
13
|
-
export declare const CONFIG_USAGE = "\u7528\u6CD5\uFF1Aama config show [--json] [--profile <\u6587\u4EF6>] [--auth-file <\u6587\u4EF6>]\n";
|
|
17
|
+
export declare const CONFIG_USAGE = "\u7528\u6CD5\uFF1Aama config show [--json] [--profile <\u6587\u4EF6>] [--auth-file <\u6587\u4EF6>]\n [--tools-preset <\u540D>] [--codemode off|on|only]\n ama config path \u914D\u7F6E\u76EE\u5F55\u3001\u6570\u636E\u76EE\u5F55\u4E0E\u5404\u6587\u4EF6\u8DEF\u5F84\n ama config edit \u7528 $VISUAL / $EDITOR \u6253\u5F00 config.json\uFF08\u6CA1\u6709\u7F16\u8F91\u5668\u65F6\u6253\u5370\u8DEF\u5F84\uFF09\n";
|
|
14
18
|
type Layer = {
|
|
15
|
-
name: "default" | "user" | "profile" | "project";
|
|
19
|
+
name: "default" | "user" | "profile" | "project" | "cli";
|
|
16
20
|
label: string;
|
|
17
21
|
value: unknown;
|
|
18
22
|
};
|
|
@@ -30,15 +34,36 @@ export interface ProviderDescription {
|
|
|
30
34
|
baseUrl: string;
|
|
31
35
|
/** baseUrl 来自的环境变量。 */
|
|
32
36
|
baseUrlEnv?: string;
|
|
33
|
-
/**
|
|
37
|
+
/** 渠道(多渠道供应商)。 */
|
|
38
|
+
channels?: {
|
|
39
|
+
name: string;
|
|
40
|
+
api: Api;
|
|
41
|
+
baseUrl: string;
|
|
42
|
+
}[];
|
|
43
|
+
/** config 里列出的模型及其生效协议、渠道与元数据来源。 */
|
|
34
44
|
models: {
|
|
35
45
|
id: string;
|
|
36
46
|
api: Api;
|
|
47
|
+
channels?: string[];
|
|
48
|
+
flags: string;
|
|
49
|
+
sources?: string;
|
|
37
50
|
}[];
|
|
38
51
|
}
|
|
39
52
|
/** config 里出现的供应商 + baseUrl 来自环境变量的内置供应商。 */
|
|
40
53
|
export declare function describeProviders(config: AmaConfig, registry: ProviderRegistryApi | undefined): ProviderDescription[];
|
|
41
54
|
/** 每个生效叶子的来源:累加型列表列出所有贡献层,其余取最后设置它的层。 */
|
|
42
55
|
export declare function sourcesOf(effective: AmaConfig, layers: readonly Layer[]): Map<string, string>;
|
|
56
|
+
export interface CodemodeDescription {
|
|
57
|
+
mode: CodemodeMode;
|
|
58
|
+
/** config:显式 codemode.mode;preset:跟随预设。 */
|
|
59
|
+
source: "config" | "preset";
|
|
60
|
+
/** 人读原因。 */
|
|
61
|
+
reason: string;
|
|
62
|
+
strict: boolean;
|
|
63
|
+
/** 生效模式不是 off 但 codemode 工具不可用(requireStrict)时的说明。 */
|
|
64
|
+
unavailable?: string;
|
|
65
|
+
}
|
|
66
|
+
/** codemode 生效模式与原因(跟随预设时写明预设与运行时 Node 是否隔离网络)。 */
|
|
67
|
+
export declare function describeCodemode(config: AmaConfig, nodeVersion?: string): CodemodeDescription;
|
|
43
68
|
export declare function runConfig(argv: readonly string[], io: CliIo, deps: Pick<RuntimeDeps, "providers"> | undefined): Promise<number>;
|
|
44
69
|
export {};
|