@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/config/schema.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { HOOK_EVENTS } from "../hooks/types.js";
|
|
9
9
|
import { PERMISSION_MODES_STRICT_FIRST } from "../permissions/types.js";
|
|
10
10
|
import { WARMING_MODES } from "../ai/cache/types.js";
|
|
11
|
-
import { CACHE_RETENTIONS, CODEMODE_MODES,
|
|
11
|
+
import { CACHE_RETENTIONS, CHANNEL_NAME_PATTERN, CODEMODE_MODES, TOOLS_PRESET_INPUTS, } from "./types.js";
|
|
12
12
|
export { CONFIG_FILE_VERSION } from "./types.js";
|
|
13
13
|
export const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh"];
|
|
14
14
|
export const HOOK_TIMEOUT_MAX_MS = 600_000;
|
|
@@ -116,6 +116,7 @@ const CONFIG_KEYS = [
|
|
|
116
116
|
"ui",
|
|
117
117
|
"skills",
|
|
118
118
|
"cache",
|
|
119
|
+
"request",
|
|
119
120
|
"$schema",
|
|
120
121
|
];
|
|
121
122
|
const PROVIDER_KEYS = [
|
|
@@ -128,9 +129,12 @@ const PROVIDER_KEYS = [
|
|
|
128
129
|
"headers",
|
|
129
130
|
"compat",
|
|
130
131
|
"requiresApiKey",
|
|
132
|
+
"channels",
|
|
133
|
+
"defaultChannel",
|
|
131
134
|
"models",
|
|
132
135
|
"modelOverrides",
|
|
133
136
|
];
|
|
137
|
+
const CHANNEL_KEYS = ["api", "baseUrl", "apiKey", "authHeader", "headers", "compat"];
|
|
134
138
|
/** 第三波 §1.3 的缓存兼容开关(其余 compat 字段按协议各异,只查是对象)。 */
|
|
135
139
|
const CACHE_COMPAT_FLAGS = [
|
|
136
140
|
"sendPromptCacheKey",
|
|
@@ -138,7 +142,7 @@ const CACHE_COMPAT_FLAGS = [
|
|
|
138
142
|
"supportsLongCacheRetention",
|
|
139
143
|
"supportsExplicitPromptCacheMode",
|
|
140
144
|
];
|
|
141
|
-
function checkModels(c, value, path) {
|
|
145
|
+
function checkModels(c, value, path, channels) {
|
|
142
146
|
if (value === undefined)
|
|
143
147
|
return;
|
|
144
148
|
if (!Array.isArray(value)) {
|
|
@@ -157,6 +161,24 @@ function checkModels(c, value, path) {
|
|
|
157
161
|
c.string(item, "api", p);
|
|
158
162
|
c.string(item, "baseUrl", p);
|
|
159
163
|
c.stringRecord(item, "headers", p);
|
|
164
|
+
const modelsDev = item["modelsDev"];
|
|
165
|
+
if (modelsDev !== undefined &&
|
|
166
|
+
modelsDev !== false &&
|
|
167
|
+
(typeof modelsDev !== "string" || !/^[^/]+\/.+$/.test(modelsDev))) {
|
|
168
|
+
c.error(join(p, "modelsDev"), `应为 "provider/model" 或 false`);
|
|
169
|
+
}
|
|
170
|
+
c.stringArray(item, "channels", p);
|
|
171
|
+
const used = item["channels"];
|
|
172
|
+
if (Array.isArray(used)) {
|
|
173
|
+
used.forEach((name, i) => {
|
|
174
|
+
if (typeof name !== "string")
|
|
175
|
+
return;
|
|
176
|
+
if (channels === undefined)
|
|
177
|
+
c.error(join(join(p, "channels"), i), "供应商没有 channels");
|
|
178
|
+
else if (!channels.has(name))
|
|
179
|
+
c.error(join(join(p, "channels"), i), `渠道 "${name}" 不存在(可用:${[...channels].join(", ")})`);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
160
182
|
const promptCache = item["promptCache"];
|
|
161
183
|
if (promptCache !== undefined && c.object(promptCache, join(p, "promptCache"))) {
|
|
162
184
|
const pp = join(p, "promptCache");
|
|
@@ -171,6 +193,51 @@ function checkModels(c, value, path) {
|
|
|
171
193
|
}
|
|
172
194
|
});
|
|
173
195
|
}
|
|
196
|
+
function checkCompat(c, compat, path) {
|
|
197
|
+
if (compat === undefined || !c.object(compat, path))
|
|
198
|
+
return;
|
|
199
|
+
for (const key of CACHE_COMPAT_FLAGS)
|
|
200
|
+
c.boolean(compat, key, path);
|
|
201
|
+
c.oneOf(compat, "cacheReporting", path, ["auto", "silent", "reported"]);
|
|
202
|
+
}
|
|
203
|
+
/** 返回合法的渠道名集合;没有 `channels` 时 undefined。 */
|
|
204
|
+
function checkChannels(c, value, path) {
|
|
205
|
+
const channels = value["channels"];
|
|
206
|
+
if (channels === undefined)
|
|
207
|
+
return undefined;
|
|
208
|
+
const cp = join(path, "channels");
|
|
209
|
+
if (!c.object(channels, cp))
|
|
210
|
+
return new Set();
|
|
211
|
+
const names = new Set();
|
|
212
|
+
for (const [name, channel] of Object.entries(channels)) {
|
|
213
|
+
const p = join(cp, name);
|
|
214
|
+
if (!CHANNEL_NAME_PATTERN.test(name)) {
|
|
215
|
+
c.error(p, "渠道名只能含字母、数字、_ 与 -(不含 / 与 @),最长 32");
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
names.add(name);
|
|
219
|
+
if (!c.object(channel, p))
|
|
220
|
+
continue;
|
|
221
|
+
c.keys(channel, p, CHANNEL_KEYS);
|
|
222
|
+
c.string(channel, "api", p, true);
|
|
223
|
+
c.string(channel, "baseUrl", p, true);
|
|
224
|
+
c.string(channel, "apiKey", p);
|
|
225
|
+
c.stringRecord(channel, "headers", p);
|
|
226
|
+
if (channel["authHeader"] !== undefined)
|
|
227
|
+
c.object(channel["authHeader"], join(p, "authHeader"));
|
|
228
|
+
checkCompat(c, channel["compat"], join(p, "compat"));
|
|
229
|
+
}
|
|
230
|
+
if (names.size === 0 && Object.keys(channels).length === 0)
|
|
231
|
+
c.error(cp, "至少要有一个渠道");
|
|
232
|
+
const preferred = value["defaultChannel"];
|
|
233
|
+
if (preferred !== undefined) {
|
|
234
|
+
if (typeof preferred !== "string")
|
|
235
|
+
c.error(join(path, "defaultChannel"), "应为字符串");
|
|
236
|
+
else if (!names.has(preferred))
|
|
237
|
+
c.error(join(path, "defaultChannel"), `渠道 "${preferred}" 不存在`);
|
|
238
|
+
}
|
|
239
|
+
return names;
|
|
240
|
+
}
|
|
174
241
|
function checkProvider(c, value, path) {
|
|
175
242
|
if (!c.object(value, path))
|
|
176
243
|
return;
|
|
@@ -180,17 +247,14 @@ function checkProvider(c, value, path) {
|
|
|
180
247
|
c.stringArray(value, "envKeys", path);
|
|
181
248
|
c.stringRecord(value, "headers", path);
|
|
182
249
|
c.boolean(value, "requiresApiKey", path);
|
|
183
|
-
|
|
184
|
-
if (compat !== undefined && c.object(compat, join(path, "compat"))) {
|
|
185
|
-
const cp = join(path, "compat");
|
|
186
|
-
for (const key of CACHE_COMPAT_FLAGS)
|
|
187
|
-
c.boolean(compat, key, cp);
|
|
188
|
-
c.oneOf(compat, "cacheReporting", cp, ["auto", "silent", "reported"]);
|
|
189
|
-
}
|
|
250
|
+
checkCompat(c, value["compat"], join(path, "compat"));
|
|
190
251
|
if (value["authHeader"] !== undefined)
|
|
191
252
|
c.object(value["authHeader"], join(path, "authHeader"));
|
|
192
|
-
|
|
193
|
-
|
|
253
|
+
const channels = checkChannels(c, value, path);
|
|
254
|
+
if (channels === undefined && value["defaultChannel"] !== undefined)
|
|
255
|
+
c.error(join(path, "defaultChannel"), "没有 channels 时不能设 defaultChannel");
|
|
256
|
+
checkModels(c, value["models"], join(path, "models"), channels);
|
|
257
|
+
checkModels(c, value["modelOverrides"], join(path, "modelOverrides"), channels);
|
|
194
258
|
}
|
|
195
259
|
function checkSection(c, config, key, allowed, body) {
|
|
196
260
|
const section = config[key];
|
|
@@ -215,10 +279,13 @@ export function validateConfig(value) {
|
|
|
215
279
|
checkProvider(c, provider, join("providers", id));
|
|
216
280
|
}
|
|
217
281
|
}
|
|
218
|
-
|
|
282
|
+
const permissionKeys = ["mode", "allow", "deny", "builtinDeny", "autoModel", "autoSafeCommands"];
|
|
283
|
+
checkSection(c, value, "permission", permissionKeys, (s, p) => {
|
|
219
284
|
c.oneOf(s, "mode", p, PERMISSION_MODES_STRICT_FIRST);
|
|
220
285
|
c.stringArray(s, "allow", p);
|
|
221
286
|
c.stringArray(s, "deny", p);
|
|
287
|
+
c.string(s, "autoModel", p);
|
|
288
|
+
c.stringArray(s, "autoSafeCommands", p);
|
|
222
289
|
const builtinDeny = s["builtinDeny"];
|
|
223
290
|
if (builtinDeny !== undefined &&
|
|
224
291
|
typeof builtinDeny !== "boolean" &&
|
|
@@ -238,7 +305,7 @@ export function validateConfig(value) {
|
|
|
238
305
|
c.number(s, "maxDelayMs", p);
|
|
239
306
|
});
|
|
240
307
|
checkSection(c, value, "tools", ["preset", "default", "maxToolResultChars", "bashTimeoutMs", "disabled"], (s, p) => {
|
|
241
|
-
c.oneOf(s, "preset", p,
|
|
308
|
+
c.oneOf(s, "preset", p, TOOLS_PRESET_INPUTS);
|
|
242
309
|
c.stringArray(s, "default", p);
|
|
243
310
|
c.number(s, "maxToolResultChars", p, 1);
|
|
244
311
|
c.number(s, "bashTimeoutMs", p, 1);
|
|
@@ -252,14 +319,29 @@ export function validateConfig(value) {
|
|
|
252
319
|
checkSection(c, value, "hooks", ["timeoutMs"], (s, p) => {
|
|
253
320
|
c.number(s, "timeoutMs", p, 1, HOOK_TIMEOUT_MAX_MS);
|
|
254
321
|
});
|
|
255
|
-
checkSection(c, value, "ui", [
|
|
256
|
-
|
|
322
|
+
checkSection(c, value, "ui", [
|
|
323
|
+
"theme",
|
|
324
|
+
"markdown",
|
|
325
|
+
"showThinking",
|
|
326
|
+
"tuiMode",
|
|
327
|
+
"quietStartup",
|
|
328
|
+
"ascii",
|
|
329
|
+
"compact",
|
|
330
|
+
"animation",
|
|
331
|
+
], (s, p) => {
|
|
332
|
+
c.oneOf(s, "theme", p, ["dark", "light", "auto"]);
|
|
257
333
|
c.boolean(s, "markdown", p);
|
|
258
334
|
c.oneOf(s, "showThinking", p, ["full", "collapsed", "hidden"]);
|
|
259
335
|
c.oneOf(s, "tuiMode", p, ["regular"]);
|
|
260
336
|
c.oneOf(s, "quietStartup", p, ["normal", "header", "silent"]);
|
|
337
|
+
c.boolean(s, "ascii", p);
|
|
338
|
+
c.boolean(s, "compact", p);
|
|
339
|
+
c.boolean(s, "animation", p);
|
|
261
340
|
});
|
|
262
341
|
checkSection(c, value, "skills", ["dirs"], (s, p) => c.stringArray(s, "dirs", p));
|
|
342
|
+
checkSection(c, value, "request", ["idleTimeoutMs"], (s, p) => {
|
|
343
|
+
c.number(s, "idleTimeoutMs", p, 0);
|
|
344
|
+
});
|
|
263
345
|
checkSection(c, value, "cache", ["warming", "retention", "minSavingsUsd", "missNotices", "warmSubagents"], (s, p) => {
|
|
264
346
|
c.oneOf(s, "warming", p, WARMING_MODES);
|
|
265
347
|
c.oneOf(s, "retention", p, CACHE_RETENTIONS);
|
package/dist/config/types.d.ts
CHANGED
|
@@ -16,13 +16,27 @@ export declare const CONFIG_FILE_VERSION: 1;
|
|
|
16
16
|
* 自定义模型条目;缺省 maxTokens 8192、reasoning false、input ["text"],不猜 contextWindow。
|
|
17
17
|
* `api` 缺省沿用供应商的协议。
|
|
18
18
|
*/
|
|
19
|
-
export type ModelConfig = Partial<Omit<Model, "id" | "provider">> & {
|
|
20
|
-
id: string;
|
|
21
|
-
};
|
|
22
|
-
/** 只改元数据的覆盖项(含模型级 `api`)。 */
|
|
23
|
-
export type ModelOverride = Partial<Omit<Model, "id" | "provider">> & {
|
|
19
|
+
export type ModelConfig = Partial<Omit<Model, "id" | "provider" | "channel" | "channels">> & {
|
|
24
20
|
id: string;
|
|
21
|
+
/** 挂载的渠道名,第一个是首选;缺省 `defaultChannel`(docs/providers.md「渠道」)。 */
|
|
22
|
+
channels?: string[];
|
|
23
|
+
/** models.dev 条目 `provider/model`(显式匹配);false 关闭 models.dev 补全。 */
|
|
24
|
+
modelsDev?: string | false;
|
|
25
25
|
};
|
|
26
|
+
/** 只改元数据的覆盖项(含模型级 `api` 与 `channels`)。 */
|
|
27
|
+
export type ModelOverride = ModelConfig;
|
|
28
|
+
/** 渠道:协议 + 地址(+ 可选 key / headers / compat),缺省继承供应商级。 */
|
|
29
|
+
export interface ChannelConfig {
|
|
30
|
+
api: Api;
|
|
31
|
+
baseUrl: string;
|
|
32
|
+
/** 同供应商级 `apiKey` 的写法;缺省用供应商的 key。 */
|
|
33
|
+
apiKey?: string;
|
|
34
|
+
authHeader?: AuthHeader;
|
|
35
|
+
headers?: Record<string, string>;
|
|
36
|
+
compat?: ProviderCompat;
|
|
37
|
+
}
|
|
38
|
+
/** 渠道名:不含 `/` 与 `@`(`provider/model@channel`)。 */
|
|
39
|
+
export declare const CHANNEL_NAME_PATTERN: RegExp;
|
|
26
40
|
export interface ProviderConfig {
|
|
27
41
|
name?: string;
|
|
28
42
|
/** 自定义供应商缺省 openai-completions。 */
|
|
@@ -35,6 +49,10 @@ export interface ProviderConfig {
|
|
|
35
49
|
headers?: Record<string, string>;
|
|
36
50
|
compat?: ProviderCompat;
|
|
37
51
|
requiresApiKey?: boolean;
|
|
52
|
+
/** 多渠道(docs/providers.md「渠道」);不写时 `api` + `baseUrl` 是隐式的 `default` 渠道。 */
|
|
53
|
+
channels?: Record<string, ChannelConfig>;
|
|
54
|
+
/** 缺省 `channels` 的第一个键。 */
|
|
55
|
+
defaultChannel?: string;
|
|
38
56
|
models?: ModelConfig[];
|
|
39
57
|
modelOverrides?: ModelOverride[];
|
|
40
58
|
}
|
|
@@ -47,6 +65,10 @@ export interface PermissionConfig {
|
|
|
47
65
|
* 数组 = 要移除的规则原文。放宽项,只认用户级 / profile,项目级忽略并 warning。
|
|
48
66
|
*/
|
|
49
67
|
builtinDeny?: boolean | string[];
|
|
68
|
+
/** auto 模式分类器的模型(`provider/model`);缺省 = 当前会话模型。放宽项,项目级忽略。 */
|
|
69
|
+
autoModel?: string;
|
|
70
|
+
/** auto 模式安全名单追加(词前缀或含 `*` 的通配)。放宽项,项目级忽略;各层累加。 */
|
|
71
|
+
autoSafeCommands?: string[];
|
|
50
72
|
}
|
|
51
73
|
export interface CompactionConfig {
|
|
52
74
|
enabled?: boolean;
|
|
@@ -59,13 +81,22 @@ export interface RetryConfig {
|
|
|
59
81
|
baseDelayMs?: number;
|
|
60
82
|
maxDelayMs?: number;
|
|
61
83
|
}
|
|
62
|
-
/** 工具预设(设计 §5.6
|
|
63
|
-
export type ToolsPreset = "default" | "minimal" | "codemode" | "coordinator";
|
|
64
|
-
/**
|
|
84
|
+
/** 工具预设(设计 §5.6):模型直接看到的工具集合(规范名)。 */
|
|
85
|
+
export type ToolsPreset = "default" | "minimal" | "codemode-only" | "coordinator";
|
|
86
|
+
/** 预设别名 → 规范名:`codemode` 是 0.3.0 的旧名(行为同 `codemode-only`)。 */
|
|
87
|
+
export declare const TOOLS_PRESET_ALIASES: Readonly<Record<string, ToolsPreset>>;
|
|
88
|
+
/** 配置文件、命令行、RPC、SDK 接受的写法:规范名或别名。 */
|
|
89
|
+
export type ToolsPresetInput = ToolsPreset | "codemode";
|
|
90
|
+
/** 从严到宽:项目级只能把预设改成不比当前更宽的那个(coordinator 最严,codemode-only 最宽)。 */
|
|
65
91
|
export declare const TOOLS_PRESETS_STRICT_FIRST: readonly ToolsPreset[];
|
|
92
|
+
/** 全部可接受的写法(规范名在前,别名在后;schema 与命令行校验用)。 */
|
|
93
|
+
export declare const TOOLS_PRESET_INPUTS: readonly ToolsPresetInput[];
|
|
94
|
+
/** 规范名;未知名字原样返回(校验由 schema 负责)。 */
|
|
95
|
+
export declare function canonicalPreset(name: ToolsPresetInput): ToolsPreset;
|
|
96
|
+
export declare function canonicalPreset(name: string | undefined): ToolsPreset | undefined;
|
|
66
97
|
export interface ToolsConfig {
|
|
67
|
-
/** 缺省 `default`;命令行 `--tools-preset
|
|
68
|
-
preset?:
|
|
98
|
+
/** 缺省 `default`;命令行 `--tools-preset`;`codemode` 是 `codemode-only` 的别名。 */
|
|
99
|
+
preset?: ToolsPresetInput;
|
|
69
100
|
/**
|
|
70
101
|
* 在预设上微调(设计 §5.6):`+name` 加、`-name` 去;不带前缀的名字整组替换预设的内置工具。
|
|
71
102
|
* 只认用户级 / profile(项目级忽略并 warning)。
|
|
@@ -90,12 +121,19 @@ export interface HooksSettings {
|
|
|
90
121
|
timeoutMs?: number;
|
|
91
122
|
}
|
|
92
123
|
export interface UiConfig {
|
|
93
|
-
|
|
124
|
+
/** auto 按 `COLORFGBG` / `TERM_PROGRAM` 猜(不发查询序列),猜不出用 dark。 */
|
|
125
|
+
theme?: "dark" | "light" | "auto";
|
|
94
126
|
markdown?: boolean;
|
|
95
127
|
showThinking?: "full" | "collapsed" | "hidden";
|
|
96
128
|
/** 第一期只有 regular(§12.10)。 */
|
|
97
129
|
tuiMode?: "regular";
|
|
98
130
|
quietStartup?: "normal" | "header" | "silent";
|
|
131
|
+
/** ASCII 字形(`AMA_ASCII=1` 等价);缺省按区域设置 / TERM 自动检测。 */
|
|
132
|
+
ascii?: boolean;
|
|
133
|
+
/** 消息区块间不空行、启动头无框,缺省 false。 */
|
|
134
|
+
compact?: boolean;
|
|
135
|
+
/** false:运行中 spinner 固定为 `·`,缺省 true。 */
|
|
136
|
+
animation?: boolean;
|
|
99
137
|
}
|
|
100
138
|
export interface SkillsConfig {
|
|
101
139
|
dirs?: string[];
|
|
@@ -118,6 +156,13 @@ export interface CacheConfig {
|
|
|
118
156
|
warmSubagents?: boolean;
|
|
119
157
|
}
|
|
120
158
|
export declare const DEFAULT_CACHE_CONFIG: Readonly<Required<CacheConfig>>;
|
|
159
|
+
/**
|
|
160
|
+
* 模型请求(W4-C)。只认用户级 / profile;环境变量 `AMA_IDLE_TIMEOUT_MS` 覆盖 `idleTimeoutMs`。
|
|
161
|
+
*/
|
|
162
|
+
export interface RequestConfig {
|
|
163
|
+
/** 等响应头与流中两块数据之间的最长间隔(毫秒),收到任何字节即重新计时;缺省 300 000,0 关闭。 */
|
|
164
|
+
idleTimeoutMs?: number;
|
|
165
|
+
}
|
|
121
166
|
/** config.json(用户级 / 项目级 / profile.config 同形状;项目级只接受受限字段,§10.2)。 */
|
|
122
167
|
export interface AmaConfig {
|
|
123
168
|
version: typeof CONFIG_FILE_VERSION;
|
|
@@ -134,6 +179,7 @@ export interface AmaConfig {
|
|
|
134
179
|
ui?: UiConfig;
|
|
135
180
|
skills?: SkillsConfig;
|
|
136
181
|
cache?: CacheConfig;
|
|
182
|
+
request?: RequestConfig;
|
|
137
183
|
}
|
|
138
184
|
/** auth.json(0600)。 */
|
|
139
185
|
export interface AuthFile {
|
package/dist/config/types.js
CHANGED
|
@@ -9,13 +9,31 @@
|
|
|
9
9
|
* 允许模型级 `api`(§2.3,同一中转的模型走不同协议),由 W3-B12 在注册表里生效。
|
|
10
10
|
*/
|
|
11
11
|
export const CONFIG_FILE_VERSION = 1;
|
|
12
|
-
/**
|
|
12
|
+
/** 渠道名:不含 `/` 与 `@`(`provider/model@channel`)。 */
|
|
13
|
+
export const CHANNEL_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,31}$/;
|
|
14
|
+
/** 预设别名 → 规范名:`codemode` 是 0.3.0 的旧名(行为同 `codemode-only`)。 */
|
|
15
|
+
export const TOOLS_PRESET_ALIASES = Object.freeze({
|
|
16
|
+
codemode: "codemode-only",
|
|
17
|
+
});
|
|
18
|
+
/** 从严到宽:项目级只能把预设改成不比当前更宽的那个(coordinator 最严,codemode-only 最宽)。 */
|
|
13
19
|
export const TOOLS_PRESETS_STRICT_FIRST = [
|
|
14
20
|
"coordinator",
|
|
15
21
|
"minimal",
|
|
16
22
|
"default",
|
|
23
|
+
"codemode-only",
|
|
24
|
+
];
|
|
25
|
+
/** 全部可接受的写法(规范名在前,别名在后;schema 与命令行校验用)。 */
|
|
26
|
+
export const TOOLS_PRESET_INPUTS = [
|
|
27
|
+
...TOOLS_PRESETS_STRICT_FIRST,
|
|
17
28
|
"codemode",
|
|
18
29
|
];
|
|
30
|
+
export function canonicalPreset(name) {
|
|
31
|
+
if (name === undefined)
|
|
32
|
+
return undefined;
|
|
33
|
+
return Object.hasOwn(TOOLS_PRESET_ALIASES, name)
|
|
34
|
+
? TOOLS_PRESET_ALIASES[name]
|
|
35
|
+
: name;
|
|
36
|
+
}
|
|
19
37
|
export const CODEMODE_MODES = ["off", "on", "only"];
|
|
20
38
|
export const CACHE_RETENTIONS = ["none", "short", "long"];
|
|
21
39
|
export const DEFAULT_CACHE_CONFIG = Object.freeze({
|
|
@@ -13,7 +13,7 @@ import { AgentSessionImpl } from "../agent/session.js";
|
|
|
13
13
|
import { WARMING_MODES } from "../ai/cache/types.js";
|
|
14
14
|
import { THINKING_LEVELS } from "../ai/thinking.js";
|
|
15
15
|
import { AmaError } from "../errors.js";
|
|
16
|
-
import {
|
|
16
|
+
import { PERMISSION_MODE_ORDER, parsePermissionMode, permissionModeLabel, } from "../permissions/modes.js";
|
|
17
17
|
import { describeCache, describeFingerprint, describeSession } from "./session-report.js";
|
|
18
18
|
export { describeSession } from "./session-report.js";
|
|
19
19
|
export const BUILTIN_COMMANDS = [
|
|
@@ -133,11 +133,12 @@ export async function runSlashCommand(line, ctx) {
|
|
|
133
133
|
case "permission": {
|
|
134
134
|
if (args === "")
|
|
135
135
|
return { kind: "pick", what: "permission" };
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
const mode = parsePermissionMode(args);
|
|
137
|
+
if (mode === undefined) {
|
|
138
|
+
throw new AmaError("invalid_arguments", `权限模式应为 ${PERMISSION_MODE_ORDER.join(" | ")}(也可写显示名,如 "Accept edits")`);
|
|
138
139
|
}
|
|
139
|
-
session.setPermissionMode(
|
|
140
|
-
return { kind: "handled", message: `权限模式:${
|
|
140
|
+
session.setPermissionMode(mode);
|
|
141
|
+
return { kind: "handled", message: `权限模式:${permissionModeLabel(mode)}` };
|
|
141
142
|
}
|
|
142
143
|
case "tools": {
|
|
143
144
|
if (args !== "")
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 用户侧的图片输入(docs/providers.md「图像输入」):`ama -p --image`、交互 / 行式界面里的 `@图片路径`
|
|
3
|
+
* 与粘贴 / 拖入的图片文件路径。
|
|
4
|
+
*
|
|
5
|
+
* - `--image` 与 `@路径` 是显式附件:文件不存在、不是图片、超过上限,或当前模型 `input` 不含 image
|
|
6
|
+
* → 报错,不发请求;
|
|
7
|
+
* - 不带 `@` 的词只在「以图片扩展名结尾且文件存在」时才算附件,当前模型不收图片时静默忽略(用户可能
|
|
8
|
+
* 只是在文字里提到一个文件);
|
|
9
|
+
* - 与 read 工具共用 image-file.ts 的 MIME 检测与 5 MB 上限。提示文字原样保留。
|
|
10
|
+
*/
|
|
11
|
+
import type { AgentSession } from "../agent/types.js";
|
|
12
|
+
import type { ImageBlock, Model, ProviderRegistryApi } from "../ai/types.js";
|
|
13
|
+
export interface ImageRef {
|
|
14
|
+
path: string;
|
|
15
|
+
/** `@路径` 或 `--image`:显式附件。 */
|
|
16
|
+
explicit: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** 从提示里找图片引用:`@路径`(可加引号)与以图片扩展名结尾、文件存在的词(拖入的路径常带 `\ `)。 */
|
|
19
|
+
export declare function findImageRefs(text: string, cwd: string): ImageRef[];
|
|
20
|
+
/** 当前会话的模型(查不到返回 undefined)。 */
|
|
21
|
+
export declare function sessionModel(providers: ProviderRegistryApi, session: AgentSession): Model | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* 读出附件:显式附件遇到模型不收图片 → AmaError(提示换模型);隐式附件此时忽略。
|
|
24
|
+
*/
|
|
25
|
+
export declare function loadPromptImages(refs: readonly ImageRef[], model: Model | undefined): Promise<ImageBlock[]>;
|
|
26
|
+
/** 提示 + 额外的显式图片路径(`--image`)→ 附件。 */
|
|
27
|
+
export declare function promptImages(text: string, extra: readonly string[], cwd: string, model: Model | undefined): Promise<ImageBlock[]>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 用户侧的图片输入(docs/providers.md「图像输入」):`ama -p --image`、交互 / 行式界面里的 `@图片路径`
|
|
3
|
+
* 与粘贴 / 拖入的图片文件路径。
|
|
4
|
+
*
|
|
5
|
+
* - `--image` 与 `@路径` 是显式附件:文件不存在、不是图片、超过上限,或当前模型 `input` 不含 image
|
|
6
|
+
* → 报错,不发请求;
|
|
7
|
+
* - 不带 `@` 的词只在「以图片扩展名结尾且文件存在」时才算附件,当前模型不收图片时静默忽略(用户可能
|
|
8
|
+
* 只是在文字里提到一个文件);
|
|
9
|
+
* - 与 read 工具共用 image-file.ts 的 MIME 检测与 5 MB 上限。提示文字原样保留。
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync } from "node:fs";
|
|
12
|
+
import { homedir } from "node:os";
|
|
13
|
+
import { resolve } from "node:path";
|
|
14
|
+
import { formatModelRef } from "../ai/providers/channels.js";
|
|
15
|
+
import { AmaError } from "../errors.js";
|
|
16
|
+
import { imageMimeFromPath, loadImageFile } from "../tools/image-file.js";
|
|
17
|
+
const TOKEN = /@?"([^"]+)"|@?'([^']+)'|((?:\\ |\S)+)/g;
|
|
18
|
+
function expand(path, cwd) {
|
|
19
|
+
const home = path === "~" || path.startsWith("~/") ? homedir() + path.slice(1) : path;
|
|
20
|
+
return resolve(cwd, home);
|
|
21
|
+
}
|
|
22
|
+
/** 从提示里找图片引用:`@路径`(可加引号)与以图片扩展名结尾、文件存在的词(拖入的路径常带 `\ `)。 */
|
|
23
|
+
export function findImageRefs(text, cwd) {
|
|
24
|
+
const out = [];
|
|
25
|
+
const seen = new Set();
|
|
26
|
+
for (const m of text.matchAll(TOKEN)) {
|
|
27
|
+
let token = m[1] ?? m[2] ?? m[3] ?? "";
|
|
28
|
+
const explicit = m[0].startsWith("@");
|
|
29
|
+
if (m[3] !== undefined && explicit)
|
|
30
|
+
token = token.slice(1);
|
|
31
|
+
token = token.replace(/\\ /g, " ").replace(/[,,。;;))]+$/, "");
|
|
32
|
+
if (token === "" || imageMimeFromPath(token) === undefined)
|
|
33
|
+
continue;
|
|
34
|
+
const path = expand(token, cwd);
|
|
35
|
+
if (!explicit && !existsSync(path))
|
|
36
|
+
continue;
|
|
37
|
+
if (seen.has(path))
|
|
38
|
+
continue;
|
|
39
|
+
seen.add(path);
|
|
40
|
+
out.push({ path, explicit });
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
/** 当前会话的模型(查不到返回 undefined)。 */
|
|
45
|
+
export function sessionModel(providers, session) {
|
|
46
|
+
const ref = session.state.model;
|
|
47
|
+
if (ref === undefined)
|
|
48
|
+
return undefined;
|
|
49
|
+
const found = providers.findModel(formatModelRef(ref));
|
|
50
|
+
return found.ok ? found.model : undefined;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 读出附件:显式附件遇到模型不收图片 → AmaError(提示换模型);隐式附件此时忽略。
|
|
54
|
+
*/
|
|
55
|
+
export async function loadPromptImages(refs, model) {
|
|
56
|
+
const accepts = model === undefined || model.input.includes("image");
|
|
57
|
+
const wanted = refs.filter((ref) => ref.explicit || accepts);
|
|
58
|
+
if (wanted.length === 0)
|
|
59
|
+
return [];
|
|
60
|
+
if (!accepts) {
|
|
61
|
+
const name = model === undefined ? "当前模型" : `${model.provider}/${model.id}`;
|
|
62
|
+
throw new AmaError("invalid_arguments", `${name} 不接受图片输入(模型 input 没有 image);换一个支持图像的模型再试` +
|
|
63
|
+
`(ama models list 里标「图片」的,或在配置里给该模型写 "input": ["text", "image"])`);
|
|
64
|
+
}
|
|
65
|
+
const blocks = [];
|
|
66
|
+
for (const ref of wanted)
|
|
67
|
+
blocks.push((await loadImageFile(ref.path)).block);
|
|
68
|
+
return blocks;
|
|
69
|
+
}
|
|
70
|
+
/** 提示 + 额外的显式图片路径(`--image`)→ 附件。 */
|
|
71
|
+
export async function promptImages(text, extra, cwd, model) {
|
|
72
|
+
const refs = [
|
|
73
|
+
...extra.map((path) => ({ path: expand(path, cwd), explicit: true })),
|
|
74
|
+
...findImageRefs(text, cwd),
|
|
75
|
+
];
|
|
76
|
+
const unique = refs.filter((ref, i) => refs.findIndex((r) => r.path === ref.path) === i);
|
|
77
|
+
return loadPromptImages(unique, model);
|
|
78
|
+
}
|
|
@@ -7,7 +7,11 @@
|
|
|
7
7
|
* - 执行前预览(W3-B9a-2,`request.preview`):输入摘要之后列出会碰到的路径与规模,danger 红、
|
|
8
8
|
* warn 黄、info 暗色;`other` 类预览与输入摘要重复,不显示;
|
|
9
9
|
* - 原因:mode(当前权限模式需要确认)/ dangerous / hook + Hook 给的文本;
|
|
10
|
-
* -
|
|
10
|
+
* - 选项(终端界面视觉设计 v1 §3.11):编号列表 `1. 允许 y` / `2. 本会话允许同类 a` / `3. 拒绝 n Esc`,
|
|
11
|
+
* 选中行 `›` + selection 底色;缺省选中:危险命令 → 拒绝,其余 → 允许。按键 `y / a / n / Esc / Ctrl+C /
|
|
12
|
+
* 1 2 3 / ↑↓ Enter / v` 都有效;
|
|
13
|
+
* - 标题按原因:需要确认 / 危险命令 / Hook 要求确认(子 Agent 发起前缀 `[task] `);边框颜色随预览严重度
|
|
14
|
+
* (danger error、warn warning);宽 < 56 时紧凑:工具名单独一行、去掉空行、按键提示缩短;
|
|
11
15
|
* - 超时与中断:broker 链在超时(缺省 10 分钟)或运行被中断时 abort `signal`,对话框关闭并返回
|
|
12
16
|
* undefined(链按 deny 处理),消息区留一行说明。
|
|
13
17
|
*
|
|
@@ -29,13 +33,24 @@ export interface ApprovalHost {
|
|
|
29
33
|
/** 结果说明(消息区一行)。 */
|
|
30
34
|
report?(request: ApprovalRequest, outcome: ApprovalDecision | "cancelled"): void;
|
|
31
35
|
}
|
|
32
|
-
|
|
33
|
-
export declare function describeRequest(request: ApprovalRequest, theme: Theme, options?: {
|
|
36
|
+
export interface DescribeOptions {
|
|
34
37
|
cwd?: string;
|
|
35
38
|
permissionMode?: string;
|
|
36
39
|
expanded?: boolean;
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
/** 紧凑(窄屏):首行只放工具名(原因已在标题上)。 */
|
|
41
|
+
compact?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** 原因 → 标题文字(子 Agent 发起加 `[task] `)。 */
|
|
44
|
+
export declare function approvalTitle(request: ApprovalRequest): string;
|
|
45
|
+
/** 对话框正文(不含选项与按键行)。 */
|
|
46
|
+
export declare function describeRequest(request: ApprovalRequest, theme: Theme, options?: DescribeOptions): string[];
|
|
47
|
+
interface ApprovalOption {
|
|
48
|
+
decision: ApprovalDecision;
|
|
49
|
+
label: string;
|
|
50
|
+
/** 右侧按键提示。 */
|
|
51
|
+
keys: string;
|
|
52
|
+
}
|
|
53
|
+
export declare const APPROVAL_OPTIONS: readonly ApprovalOption[];
|
|
39
54
|
/** UI broker:每个请求开一个底部覆盖层,等用户按键或 signal abort。 */
|
|
40
55
|
export declare class ApprovalDialogBroker implements ApprovalBroker {
|
|
41
56
|
private readonly host;
|
|
@@ -46,3 +61,4 @@ export declare class ApprovalDialogBroker implements ApprovalBroker {
|
|
|
46
61
|
}
|
|
47
62
|
/** 结果的一行说明(消息区)。 */
|
|
48
63
|
export declare function approvalOutcomeText(request: ApprovalRequest, outcome: ApprovalDecision | "cancelled"): string;
|
|
64
|
+
export {};
|