@armadra/agent 0.6.1 → 0.6.3
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 +80 -0
- package/CHANGELOG.zh-CN.md +56 -0
- package/README.md +168 -575
- package/README.zh-CN.md +165 -596
- package/dist/agent/session-settings.d.ts +4 -1
- package/dist/agent/session-settings.js +7 -2
- package/dist/agent/session.d.ts +6 -0
- package/dist/agent/session.js +8 -0
- package/dist/agent/subagent-background.d.ts +75 -0
- package/dist/agent/subagent-background.js +209 -0
- package/dist/agent/subagent-registry.d.ts +24 -5
- package/dist/agent/subagent-registry.js +64 -92
- package/dist/agent/types-w5.d.ts +11 -1
- package/dist/agent/types.d.ts +5 -0
- package/dist/agents/builtin.js +0 -1
- package/dist/agents/external.js +0 -1
- package/dist/agents/parse.js +4 -3
- package/dist/agents/result.d.ts +7 -1
- package/dist/agents/result.js +20 -1
- package/dist/agents/task-control.d.ts +13 -2
- package/dist/agents/task-record.d.ts +13 -1
- package/dist/agents/task-record.js +32 -0
- package/dist/agents/types.d.ts +5 -1
- package/dist/ai/apis/chatgpt-backend.d.ts +7 -2
- package/dist/ai/apis/chatgpt-backend.js +12 -4
- package/dist/ai/providers/discovered-cache.d.ts +29 -12
- package/dist/ai/providers/discovered-cache.js +72 -12
- package/dist/ai/providers/registry.js +7 -6
- package/dist/ai/types.d.ts +5 -0
- package/dist/auth/chatgpt/backend-client.d.ts +14 -4
- package/dist/auth/chatgpt/backend-client.js +41 -8
- package/dist/auth/chatgpt/cli.d.ts +2 -1
- package/dist/auth/chatgpt/cli.js +14 -7
- package/dist/auth/chatgpt/follow.d.ts +16 -0
- package/dist/auth/chatgpt/follow.js +51 -0
- package/dist/auth/chatgpt/presets.d.ts +8 -0
- package/dist/auth/chatgpt/presets.js +12 -0
- package/dist/auth/testing/fake-oauth.d.ts +4 -1
- package/dist/auth/testing/fake-oauth.js +24 -1
- package/dist/bundle/ama.cjs +2016 -664
- package/dist/cli/compose-agents.d.ts +2 -1
- package/dist/cli/compose-agents.js +11 -2
- package/dist/cli/compose-providers.d.ts +2 -1
- package/dist/cli/compose-providers.js +6 -3
- package/dist/cli/startup-steps.js +4 -1
- package/dist/cli/subcommands/models-discover.d.ts +5 -2
- package/dist/cli/subcommands/models-discover.js +52 -10
- package/dist/config/json-schema.js +10 -2
- package/dist/config/key-docs.js +9 -3
- package/dist/config/merge.d.ts +1 -1
- package/dist/config/merge.js +20 -3
- package/dist/config/schema-w5.js +4 -2
- package/dist/config/schema-w6.d.ts +1 -1
- package/dist/config/schema-w6.js +2 -1
- package/dist/config/schema.js +2 -0
- package/dist/config/settings-registry.js +4 -0
- package/dist/config/types-w5.d.ts +10 -0
- package/dist/config/types-w5.js +2 -0
- package/dist/config/types-w6.d.ts +5 -0
- package/dist/config/types.d.ts +3 -1
- package/dist/git/info.d.ts +19 -0
- package/dist/git/info.js +64 -8
- package/dist/i18n/catalog.d.ts +52 -8
- package/dist/i18n/messages/agents.d.ts +56 -0
- package/dist/i18n/messages/agents.js +58 -2
- package/dist/i18n/messages/auth.d.ts +12 -0
- package/dist/i18n/messages/auth.js +20 -0
- package/dist/i18n/messages/config-keys.d.ts +8 -0
- package/dist/i18n/messages/config-keys.js +18 -10
- package/dist/i18n/messages/config.d.ts +8 -0
- package/dist/i18n/messages/interactive-startup.d.ts +0 -16
- package/dist/i18n/messages/interactive-startup.js +0 -16
- package/dist/i18n/messages/interactive.d.ts +23 -16
- package/dist/i18n/messages/interactive.js +25 -0
- package/dist/i18n/messages/print.d.ts +4 -0
- package/dist/i18n/messages/print.js +4 -0
- package/dist/i18n/messages/report.js +4 -4
- package/dist/i18n/messages/settings.d.ts +6 -0
- package/dist/i18n/messages/settings.js +6 -0
- package/dist/i18n/messages/subcommands-config.d.ts +4 -0
- package/dist/i18n/messages/subcommands-config.js +4 -0
- package/dist/i18n/messages/subcommands.d.ts +4 -0
- package/dist/index.d.ts +1 -0
- package/dist/modes/commands-core.js +8 -4
- package/dist/modes/interactive/agent-bar.d.ts +3 -1
- package/dist/modes/interactive/agent-bar.js +12 -5
- package/dist/modes/interactive/agent-ui.d.ts +21 -3
- package/dist/modes/interactive/agent-ui.js +81 -12
- package/dist/modes/interactive/agent-view.d.ts +4 -0
- package/dist/modes/interactive/agent-view.js +14 -1
- package/dist/modes/interactive/approval-dock.d.ts +51 -0
- package/dist/modes/interactive/approval-dock.js +112 -0
- package/dist/modes/interactive/approval-ui.d.ts +43 -0
- package/dist/modes/interactive/approval-ui.js +64 -0
- package/dist/modes/interactive/commands.js +4 -1
- package/dist/modes/interactive/event-notices.d.ts +6 -1
- package/dist/modes/interactive/event-notices.js +7 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -2
- package/dist/modes/interactive/interactive-mode.js +33 -38
- package/dist/modes/interactive/key-dispatch.d.ts +21 -4
- package/dist/modes/interactive/key-dispatch.js +60 -8
- package/dist/modes/interactive/line/line-mode.js +5 -0
- package/dist/modes/interactive/run-indicator.d.ts +15 -0
- package/dist/modes/interactive/run-indicator.js +37 -5
- package/dist/modes/interactive/session-events.js +5 -1
- package/dist/modes/interactive/startup-header.d.ts +29 -14
- package/dist/modes/interactive/startup-header.js +93 -59
- package/dist/modes/interactive/startup-logo.d.ts +83 -0
- package/dist/modes/interactive/startup-logo.js +183 -0
- package/dist/modes/interactive/status-area.d.ts +18 -0
- package/dist/modes/interactive/status-area.js +67 -1
- package/dist/modes/interactive/status-bar.d.ts +9 -1
- package/dist/modes/interactive/status-bar.js +43 -11
- package/dist/modes/interactive/status-line.d.ts +2 -0
- package/dist/modes/interactive/status-line.js +11 -6
- package/dist/modes/interactive/status-quota.d.ts +44 -0
- package/dist/modes/interactive/status-quota.js +135 -0
- package/dist/modes/interactive/subagent-view.d.ts +1 -0
- package/dist/modes/interactive/subagent-view.js +8 -0
- package/dist/modes/interactive/task-background.d.ts +31 -0
- package/dist/modes/interactive/task-background.js +68 -0
- package/dist/modes/interactive/tool-view.d.ts +7 -1
- package/dist/modes/interactive/tool-view.js +24 -1
- package/dist/modes/print/print-mode.d.ts +11 -0
- package/dist/modes/print/print-mode.js +36 -1
- package/dist/modes/rpc/commands.d.ts +2 -1
- package/dist/modes/rpc/commands.js +9 -1
- package/dist/rpc.d.ts +13 -0
- package/dist/rpc.js +3 -0
- package/dist/tools/task-ctl.d.ts +2 -0
- package/dist/tools/task-ctl.js +7 -2
- package/dist/tools/task.d.ts +11 -0
- package/dist/tools/task.js +20 -2
- package/dist/tui/components/editor.d.ts +2 -0
- package/dist/tui/components/editor.js +4 -0
- package/dist/tui/components/loader.d.ts +5 -1
- package/dist/tui/components/loader.js +18 -5
- package/dist/tui/keybindings.d.ts +8 -3
- package/dist/tui/keybindings.js +8 -3
- package/docs/agents.md +52 -28
- package/docs/en/host-api.md +5 -1
- package/docs/en/providers.md +8 -4
- package/docs/en/rpc.md +19 -7
- package/docs/en/sessions.md +3 -1
- package/docs/en/tui.md +84 -66
- package/docs/host-api.md +5 -1
- package/docs/providers.md +29 -12
- package/docs/rpc.md +19 -7
- package/docs/sessions.md +2 -1
- package/docs/tui-design.md +42 -29
- package/docs/tui.md +67 -49
- package/package.json +1 -1
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* `agentDirs` → config `agents.dirs` → 用户级 → 项目级(需信任)),建类型目录并绑到 task 工具
|
|
6
6
|
* (描述里的类型清单);工厂给每个根会话装一个扩展:建任务注册表(subagent-registry.ts,并发 /
|
|
7
7
|
* 排队上限与模型别名取自 config),`getStats().tasks` 汇总,会话 dispose 时停止后台任务。
|
|
8
|
-
* task 子会话(depth ≥ 1)与没有 task 工具的会话不装。
|
|
8
|
+
* task 子会话(depth ≥ 1)与没有 task 工具的会话不装。[W7-B1] `subagents.background`(auto:交互 / RPC /
|
|
9
|
+
* ACP 后台、`-p` 前台)解析成本进程的缺省,同时决定 task 描述的版本;`autoBackgroundAfterMs` 透传。
|
|
9
10
|
*
|
|
10
11
|
* [W5-EG] 外部 runner(claude / codex / acp:* / 宿主注入)经 agents/external.ts 接入 `runners`:每个主
|
|
11
12
|
* 会话一个 ExternalAgents(审批接 requestApproval,只交给人);PATH 上的 claude / codex 登记进类型
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* `agentDirs` → config `agents.dirs` → 用户级 → 项目级(需信任)),建类型目录并绑到 task 工具
|
|
6
6
|
* (描述里的类型清单);工厂给每个根会话装一个扩展:建任务注册表(subagent-registry.ts,并发 /
|
|
7
7
|
* 排队上限与模型别名取自 config),`getStats().tasks` 汇总,会话 dispose 时停止后台任务。
|
|
8
|
-
* task 子会话(depth ≥ 1)与没有 task 工具的会话不装。
|
|
8
|
+
* task 子会话(depth ≥ 1)与没有 task 工具的会话不装。[W7-B1] `subagents.background`(auto:交互 / RPC /
|
|
9
|
+
* ACP 后台、`-p` 前台)解析成本进程的缺省,同时决定 task 描述的版本;`autoBackgroundAfterMs` 透传。
|
|
9
10
|
*
|
|
10
11
|
* [W5-EG] 外部 runner(claude / codex / acp:* / 宿主注入)经 agents/external.ts 接入 `runners`:每个主
|
|
11
12
|
* 会话一个 ExternalAgents(审批接 requestApproval,只交给人);PATH 上的 claude / codex 登记进类型
|
|
@@ -17,7 +18,8 @@ import { AgentCatalog } from "../agents/catalog.js";
|
|
|
17
18
|
import { agentSources, discoverAgents } from "../agents/discover.js";
|
|
18
19
|
import { NO_AGENT_PROBE_ENV, SessionExternalAgents, registerExternalAgents, } from "../agents/external.js";
|
|
19
20
|
import { hostRunnersOf } from "../host/api-impl.js";
|
|
20
|
-
import { bindTaskAgents } from "../tools/task.js";
|
|
21
|
+
import { bindTaskAgents, bindTaskBackground } from "../tools/task.js";
|
|
22
|
+
import { resolveTaskBackground } from "../agent/subagent-background.js";
|
|
21
23
|
import { msg } from "../i18n/index.js";
|
|
22
24
|
/** 同一装配材料只提示一次(`/new` 等会重新装配会话)。 */
|
|
23
25
|
const warned = new WeakSet();
|
|
@@ -54,6 +56,12 @@ export function subagentEnvironment(deps, catalog) {
|
|
|
54
56
|
const pending = config.subagents?.maxPending;
|
|
55
57
|
if (pending !== undefined)
|
|
56
58
|
env.maxPending = pending;
|
|
59
|
+
// [W7-B1] 缺省后台与自动转后台(配置键 W7-B2 登记于 config/types-w5.ts)
|
|
60
|
+
const sub = config.subagents;
|
|
61
|
+
env.background = resolveTaskBackground(sub?.background, deps.assembly.unattended === true);
|
|
62
|
+
const after = sub?.autoBackgroundAfterMs;
|
|
63
|
+
if (typeof after === "number" && after > 0)
|
|
64
|
+
env.autoBackgroundAfterMs = after;
|
|
57
65
|
return env;
|
|
58
66
|
}
|
|
59
67
|
/** 外部 Agent 的装配材料(宿主、信任、探测开关取自装配材料与环境)。 */
|
|
@@ -108,5 +116,6 @@ export function createSubagentsFactory(deps) {
|
|
|
108
116
|
registerExternalAgents(catalog, wiring);
|
|
109
117
|
bindTaskAgents(task, catalog);
|
|
110
118
|
const env = subagentEnvironment(deps, catalog);
|
|
119
|
+
bindTaskBackground(task, env.background === true);
|
|
111
120
|
return ({ core }) => (core.depth > 0 ? undefined : createSubagentExtension(core, env, wiring));
|
|
112
121
|
}
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
* - [W6-O] ChatGPT 登录(docs/wave6-plan.md D14):`chatgpt` 的缺省渠道按 auth.json 条目的 flavor 定(用户写了
|
|
13
13
|
* `defaultChannel` 时不动);`AMA_CHATGPT_BASE_URL` 改该渠道地址;`auth.chatgpt.originator` 改 codex 渠道的
|
|
14
14
|
* `originator` 头;OAuth 刷新拿到 `auth.chatgpt` 配置与同一份 env。
|
|
15
|
-
* - 发现缓存(`<dataDir>/models/discovered/<provider>.json`)并入模型表为空的供应商(discovered-cache.ts
|
|
15
|
+
* - 发现缓存(`<dataDir>/models/discovered/<provider>.json`)并入模型表为空的供应商(discovered-cache.ts);
|
|
16
|
+
* chatgpt 的缓存 flavor 与当前登录不符时视为过期、不并入。
|
|
16
17
|
*/
|
|
17
18
|
import type { ApiRegistry } from "../ai/apis/api.js";
|
|
18
19
|
import { ProviderRegistry } from "../ai/providers/registry.js";
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
* - [W6-O] ChatGPT 登录(docs/wave6-plan.md D14):`chatgpt` 的缺省渠道按 auth.json 条目的 flavor 定(用户写了
|
|
13
13
|
* `defaultChannel` 时不动);`AMA_CHATGPT_BASE_URL` 改该渠道地址;`auth.chatgpt.originator` 改 codex 渠道的
|
|
14
14
|
* `originator` 头;OAuth 刷新拿到 `auth.chatgpt` 配置与同一份 env。
|
|
15
|
-
* - 发现缓存(`<dataDir>/models/discovered/<provider>.json`)并入模型表为空的供应商(discovered-cache.ts
|
|
15
|
+
* - 发现缓存(`<dataDir>/models/discovered/<provider>.json`)并入模型表为空的供应商(discovered-cache.ts);
|
|
16
|
+
* chatgpt 的缓存 flavor 与当前登录不符时视为过期、不并入。
|
|
16
17
|
*/
|
|
17
18
|
import { loadModelsDevIndex } from "../ai/providers/models-dev-cache.js";
|
|
18
19
|
import { ProviderRegistry, discoverLocalModels } from "../ai/providers/registry.js";
|
|
@@ -108,8 +109,10 @@ export async function buildProviderRegistry(input, options = {}) {
|
|
|
108
109
|
registry = make({ provider, apiKey: cli.apiKey });
|
|
109
110
|
}
|
|
110
111
|
// 发现缓存(`ama auth login chatgpt` / `ama models discover chatgpt`)并入模型表为空的供应商
|
|
111
|
-
if (dataDir !== undefined)
|
|
112
|
-
|
|
112
|
+
if (dataDir !== undefined) {
|
|
113
|
+
const flavor = readOAuthEntry(input.authFile, CHATGPT_PROVIDER_ID)?.flavor;
|
|
114
|
+
mergeDiscoveredModels(registry, dataDir, lazyIndex(() => loadModelsDevIndex(dataDir)), (id) => (id === CHATGPT_PROVIDER_ID ? flavor : undefined));
|
|
115
|
+
}
|
|
113
116
|
const probe = options.probeLocal ?? env[NO_LOCAL_PROBE_ENV] !== "1";
|
|
114
117
|
if (probe && config.defaultModel === undefined && !anyKeyConfigured(registry)) {
|
|
115
118
|
await probeLocalProviders(registry, options.probeTimeoutMs ?? LOCAL_PROBE_TIMEOUT_MS);
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { describeLookupFailure } from "../ai/providers/suggest.js";
|
|
6
6
|
import { formatModelRef } from "../ai/providers/channels.js";
|
|
7
|
+
import { CHATGPT_PROVIDER_ID } from "../auth/chatgpt/presets.js";
|
|
7
8
|
import { statSync } from "node:fs";
|
|
8
9
|
import { isAbsolute, resolve } from "node:path";
|
|
9
10
|
import { AmaError, StartupError, isAmaError } from "../errors.js";
|
|
@@ -126,10 +127,12 @@ export async function resolveModel(args, registry, manager, defaultModel, deps,
|
|
|
126
127
|
else {
|
|
127
128
|
const change = lastEntry(manager, (e) => e.type === "model_change");
|
|
128
129
|
if (change?.type === "model_change") {
|
|
130
|
+
// ChatGPT 的渠道跟随当前登录方式:会话里记的渠道不当显式渠道(可能是换登录前的)
|
|
131
|
+
const channel = change.provider === CHATGPT_PROVIDER_ID ? undefined : change.channel;
|
|
129
132
|
const found = registry.findModel(formatModelRef({
|
|
130
133
|
provider: change.provider,
|
|
131
134
|
id: change.modelId,
|
|
132
|
-
...(
|
|
135
|
+
...(channel !== undefined ? { channel } : {}),
|
|
133
136
|
}));
|
|
134
137
|
if (found.ok)
|
|
135
138
|
choice = { model: found.model, provider: found.provider };
|
|
@@ -18,8 +18,10 @@
|
|
|
18
18
|
* 匹配结果;`--write` 跳过 models.dev 标明不支持工具调用的模型。元数据不写进配置——运行时从缓存补。
|
|
19
19
|
*
|
|
20
20
|
* [W6-O] `chatgpt`:按登录的 flavor 调对应后端的模型列表(SIWC `GET /v1/models` 筛 `visibility: list`;codex
|
|
21
|
-
* `GET /models?client_version
|
|
22
|
-
*
|
|
21
|
+
* `GET /models?client_version=<codexClientVersion>`,另带上下文窗口 / 输入模态 / 推理强度),取 slug 与显示名;
|
|
22
|
+
* `--probe` 不适用(订阅后端只有一种协议)。结果另写进发现缓存 `<dataDir>/models/discovered/chatgpt.json`
|
|
23
|
+
* (discovered-cache.ts,0 个也写),`/model` 选择器由此列出;codex 返回 0 个时提示 codexClientVersion 可能过旧。
|
|
24
|
+
* 后端给了上下文窗口就显示它(标「后端」),注册表同样以它为准;没给的列出来,说明改用 models.dev。
|
|
23
25
|
*/
|
|
24
26
|
import type { Api, Model, ProviderData, ProviderRegistryApi } from "../../ai/types.js";
|
|
25
27
|
import type { ModelsAction } from "./models.js";
|
|
@@ -31,6 +33,7 @@ export declare const PROBE_APIS: readonly Api[];
|
|
|
31
33
|
export declare function modelsUrl(provider: ProviderData): string;
|
|
32
34
|
export declare function discoverModels(provider: ProviderData, apiKey: string | undefined, options?: {
|
|
33
35
|
timeoutMs?: number;
|
|
36
|
+
codexClientVersion?: string;
|
|
34
37
|
}): Promise<Model[]>;
|
|
35
38
|
export declare function probeOrder(provider: ProviderData): Api[];
|
|
36
39
|
export interface ProbeOptions {
|
|
@@ -18,15 +18,17 @@
|
|
|
18
18
|
* 匹配结果;`--write` 跳过 models.dev 标明不支持工具调用的模型。元数据不写进配置——运行时从缓存补。
|
|
19
19
|
*
|
|
20
20
|
* [W6-O] `chatgpt`:按登录的 flavor 调对应后端的模型列表(SIWC `GET /v1/models` 筛 `visibility: list`;codex
|
|
21
|
-
* `GET /models?client_version
|
|
22
|
-
*
|
|
21
|
+
* `GET /models?client_version=<codexClientVersion>`,另带上下文窗口 / 输入模态 / 推理强度),取 slug 与显示名;
|
|
22
|
+
* `--probe` 不适用(订阅后端只有一种协议)。结果另写进发现缓存 `<dataDir>/models/discovered/chatgpt.json`
|
|
23
|
+
* (discovered-cache.ts,0 个也写),`/model` 选择器由此列出;codex 返回 0 个时提示 codexClientVersion 可能过旧。
|
|
24
|
+
* 后端给了上下文窗口就显示它(标「后端」),注册表同样以它为准;没给的列出来,说明改用 models.dev。
|
|
23
25
|
*/
|
|
24
26
|
import { authHeaders, mergeHeaders } from "../../ai/http.js";
|
|
25
27
|
import { listChatGptModels } from "../../auth/chatgpt/backend-client.js";
|
|
26
|
-
import { CHATGPT_PROVIDER_ID } from "../../auth/chatgpt/presets.js";
|
|
28
|
+
import { CHATGPT_PROVIDER_ID, codexClientVersion } from "../../auth/chatgpt/presets.js";
|
|
27
29
|
import { liveToken } from "../../auth/oauth/live.js";
|
|
28
30
|
import { discoverLocalModels, materializeModel } from "../../ai/providers/registry.js";
|
|
29
|
-
import { writeDiscoveredCache } from "../../ai/providers/discovered-cache.js";
|
|
31
|
+
import { thinkingMapOf, writeDiscoveredCache, } from "../../ai/providers/discovered-cache.js";
|
|
30
32
|
import { withCustomDefaults } from "../../ai/providers/catalog.js";
|
|
31
33
|
import { describeModelsDev, loadModelsDevIndex } from "../../ai/providers/models-dev-cache.js";
|
|
32
34
|
import { matchLabel, modelsDevFields } from "../../ai/providers/models-dev.js";
|
|
@@ -65,11 +67,20 @@ export async function discoverModels(provider, apiKey, options = {}) {
|
|
|
65
67
|
accessToken: apiKey,
|
|
66
68
|
accountId: live?.accountId,
|
|
67
69
|
originator: channel?.headers?.["originator"],
|
|
70
|
+
clientVersion: options.codexClientVersion,
|
|
68
71
|
});
|
|
69
72
|
return models.map((m) => {
|
|
70
73
|
const model = withCustomDefaults({ id: m.id }, provider.id, provider.api);
|
|
71
74
|
if (m.name !== undefined)
|
|
72
75
|
model.name = m.name;
|
|
76
|
+
if (m.contextWindow !== undefined)
|
|
77
|
+
model.contextWindow = m.contextWindow;
|
|
78
|
+
if (m.input !== undefined)
|
|
79
|
+
model.input = m.input;
|
|
80
|
+
if (m.reasoningLevels?.some((x) => x !== "none") === true) {
|
|
81
|
+
model.reasoning = true;
|
|
82
|
+
model.thinkingLevelMap = thinkingMapOf(m.reasoningLevels);
|
|
83
|
+
}
|
|
73
84
|
return model;
|
|
74
85
|
});
|
|
75
86
|
}
|
|
@@ -191,7 +202,9 @@ async function run(ctx) {
|
|
|
191
202
|
}
|
|
192
203
|
let found;
|
|
193
204
|
try {
|
|
194
|
-
found = await discoverModels(provider, key.apiKey
|
|
205
|
+
found = await discoverModels(provider, key.apiKey, {
|
|
206
|
+
codexClientVersion: codexClientVersion(ctx.level.merged.config.auth?.chatgpt, io.env),
|
|
207
|
+
});
|
|
195
208
|
}
|
|
196
209
|
catch (error) {
|
|
197
210
|
io.stderr(m.listFailed(provider.id, error.message));
|
|
@@ -214,13 +227,22 @@ async function run(ctx) {
|
|
|
214
227
|
noTools.add(model.id);
|
|
215
228
|
if (match === undefined)
|
|
216
229
|
unmatched.add(model.id);
|
|
230
|
+
// 后端给的上下文窗口优先于 models.dev(订阅后端的生效窗口可能远小于 API 版)
|
|
231
|
+
const backendCtx = model.contextWindow !== undefined
|
|
232
|
+
? ` ctx ${compactTokens(model.contextWindow)}${m.fromBackend}`
|
|
233
|
+
: undefined;
|
|
217
234
|
const meta = fields === undefined
|
|
218
|
-
? m.unmatched
|
|
219
|
-
: ` ctx ${compactTokens(fields.contextWindow)} · out ${compactTokens(fields.maxTokens)}` +
|
|
235
|
+
? `${backendCtx ?? ""}${m.unmatched}`
|
|
236
|
+
: `${backendCtx ?? ` ctx ${compactTokens(fields.contextWindow)}`} · out ${compactTokens(fields.maxTokens)}` +
|
|
220
237
|
`${fields.input?.includes("image") ? m.image : ""}${fields.reasoning ? m.reasoning : ""}` +
|
|
221
238
|
`${fields.toolCall === false ? m.noTools : ""} · ${matchLabel(match)}`;
|
|
222
239
|
io.stdout(` ${model.id}${known !== undefined ? m.configured(known.api) : ""}${meta}\n`);
|
|
223
240
|
}
|
|
241
|
+
if (provider.id === CHATGPT_PROVIDER_ID) {
|
|
242
|
+
const missing = found.filter((x) => x.contextWindow === undefined).map((x) => x.id);
|
|
243
|
+
if (missing.length > 0)
|
|
244
|
+
io.stdout(m.noBackendWindow(missing.join(", ")));
|
|
245
|
+
}
|
|
224
246
|
const write = ctx.flags.has("write");
|
|
225
247
|
if (!ctx.flags.has("probe") || provider.id === CHATGPT_PROVIDER_ID) {
|
|
226
248
|
if (write)
|
|
@@ -256,17 +278,37 @@ async function run(ctx) {
|
|
|
256
278
|
}
|
|
257
279
|
return ExitCode.Ok;
|
|
258
280
|
}
|
|
259
|
-
/**
|
|
281
|
+
/** 发现得到的模型 → 缓存条目(后端给的元数据一并写入;推理强度由映射表还原)。 */
|
|
282
|
+
function cacheEntry(m) {
|
|
283
|
+
const entry = { id: m.id };
|
|
284
|
+
if (m.name !== m.id)
|
|
285
|
+
entry.name = m.name;
|
|
286
|
+
if (m.contextWindow !== undefined)
|
|
287
|
+
entry.contextWindow = m.contextWindow;
|
|
288
|
+
if (m.input.length !== 1 || m.input[0] !== "text")
|
|
289
|
+
entry.input = [...m.input];
|
|
290
|
+
if (m.reasoning && m.thinkingLevelMap !== undefined)
|
|
291
|
+
entry.reasoningLevels = Object.entries(m.thinkingLevelMap).flatMap(([level, value]) => typeof value !== "string" ? [] : level === "off" ? ["none"] : [level]);
|
|
292
|
+
return entry;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* chatgpt 的发现结果写进发现缓存(选择器与注册表读它;0 个也写,免得残留另一 flavor 的缓存);写失败不影响
|
|
296
|
+
* 列表输出。codex 返回 0 个时提示 codexClientVersion 可能过旧。
|
|
297
|
+
*/
|
|
260
298
|
function cacheChatGpt(ctx, found, apiKey) {
|
|
299
|
+
const flavor = liveToken(apiKey)?.flavor;
|
|
261
300
|
try {
|
|
262
|
-
const
|
|
263
|
-
const models = found.map((m) => ({ id: m.id, ...(m.name !== m.id ? { name: m.name } : {}) }));
|
|
301
|
+
const models = found.map(cacheEntry);
|
|
264
302
|
const path = writeDiscoveredCache(ctx.level.dataDir, CHATGPT_PROVIDER_ID, { models, flavor });
|
|
265
303
|
ctx.io.stdout(msg().subcommands.discover.cached(path));
|
|
266
304
|
}
|
|
267
305
|
catch (error) {
|
|
268
306
|
ctx.io.stderr(`ama: ${error.message}\n`);
|
|
269
307
|
}
|
|
308
|
+
if (found.length === 0 && flavor === "codex") {
|
|
309
|
+
const version = codexClientVersion(ctx.level.merged.config.auth?.chatgpt, ctx.io.env);
|
|
310
|
+
ctx.io.stderr(`${msg().auth.login.codexNoModels(version)}\n`);
|
|
311
|
+
}
|
|
270
312
|
}
|
|
271
313
|
export const DISCOVER_ACTION = {
|
|
272
314
|
usage: "ama models discover <provider> [--probe] [--write] [--limit <n>] [--concurrency <n>] [--probe-timeout <ms>]",
|
|
@@ -13,7 +13,7 @@ import { defaultFor, isDynamicDefault, keyDoc } from "./key-docs.js";
|
|
|
13
13
|
import { HOOK_TIMEOUT_MAX_MS, THINKING_LEVELS } from "./schema.js";
|
|
14
14
|
import { CACHE_RETENTIONS, CHANNEL_NAME_PATTERN, CHECKPOINT_MODES, SANDBOX_ENABLED_MODES, SANDBOX_NETWORK_MODES, CODEMODE_MODES, IMAGE_RESIZE_MODES, PLAN_BASH_MODES_STRICT_FIRST, PLAN_UNATTENDED_MODES, STATUS_LINE_MODES, TOOLS_PRESET_INPUTS, LANGUAGE_SETTINGS, AGENT_BAR_MODES, CHATGPT_FLAVORS, MEMORY_SCOPES, MEMORY_SUBAGENT_MODES, } from "./types.js";
|
|
15
15
|
import { AGENT_ID_PATTERN } from "./schema-w5.js";
|
|
16
|
-
import { AGENTS_RESERVED_KEYS } from "./types-w5.js";
|
|
16
|
+
import { AGENTS_RESERVED_KEYS, SUBAGENT_BACKGROUND_MODES } from "./types-w5.js";
|
|
17
17
|
export const CONFIG_SCHEMA_FILE = "config.schema.json";
|
|
18
18
|
export const CONFIG_SCHEMA_ID = "https://github.com/Owlbay/armadra-agent/config.schema.json";
|
|
19
19
|
const KNOWN_APIS = [
|
|
@@ -150,7 +150,13 @@ function w5Sections() {
|
|
|
150
150
|
pattern: `^(${AGENTS_RESERVED_KEYS.join("|")}|${AGENT_ID_PATTERN.source.slice(1, -1)})$`,
|
|
151
151
|
},
|
|
152
152
|
}),
|
|
153
|
-
subagents: object({
|
|
153
|
+
subagents: object({
|
|
154
|
+
maxConcurrent: num(1, 64),
|
|
155
|
+
maxPending: num(0, 1024),
|
|
156
|
+
defaultModel: str(),
|
|
157
|
+
background: oneOf(SUBAGENT_BACKGROUND_MODES),
|
|
158
|
+
autoBackgroundAfterMs: num(0),
|
|
159
|
+
}),
|
|
154
160
|
models: object({ aliases: object({ fast: str(), strong: str() }), enabled: strings }),
|
|
155
161
|
fallbackModel: str(),
|
|
156
162
|
limits: object({ maxTurns: num(1), maxCostUsd: num(0) }),
|
|
@@ -180,6 +186,7 @@ function w6Sections() {
|
|
|
180
186
|
clientId: str(),
|
|
181
187
|
issuer: str(),
|
|
182
188
|
originator: str(),
|
|
189
|
+
codexClientVersion: str(),
|
|
183
190
|
redirectPorts: {
|
|
184
191
|
type: "array",
|
|
185
192
|
items: { type: "integer", minimum: 0, maximum: 65535 },
|
|
@@ -270,6 +277,7 @@ function buildBaseSchema() {
|
|
|
270
277
|
quietStartup: oneOf(["normal", "header", "silent"]),
|
|
271
278
|
ascii: bool(),
|
|
272
279
|
compact: bool(),
|
|
280
|
+
logo: oneOf(["auto", "off"]),
|
|
273
281
|
animation: bool(),
|
|
274
282
|
restoreOnCancel: bool(),
|
|
275
283
|
statusLine: oneOf(STATUS_LINE_MODES),
|
package/dist/config/key-docs.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* DISPLAY_DEFAULTS 相同,DISPLAY_DEFAULTS 本身通过 `validateConfig`。
|
|
11
11
|
*/
|
|
12
12
|
import { DEFAULT_IDLE_TIMEOUT_MS } from "../ai/http.js";
|
|
13
|
+
import { DEFAULT_CODEX_CLIENT_VERSION } from "../auth/chatgpt/presets.js";
|
|
13
14
|
import { messagesFor, msg } from "../i18n/index.js";
|
|
14
15
|
import { DEFAULT_INLINE_BUDGET } from "../codemode/declarations.js";
|
|
15
16
|
import { DEFAULT_CONFIG, mergeConfig } from "./merge.js";
|
|
@@ -22,7 +23,7 @@ const IMPLICIT_DEFAULTS = {
|
|
|
22
23
|
codemode: { inlineBudget: DEFAULT_INLINE_BUDGET, requireStrict: false },
|
|
23
24
|
cache: { ...DEFAULT_CACHE_CONFIG },
|
|
24
25
|
request: { idleTimeoutMs: DEFAULT_IDLE_TIMEOUT_MS },
|
|
25
|
-
ui: { compact: false, animation: true, restoreOnCancel: true, language: "auto" },
|
|
26
|
+
ui: { compact: false, logo: "auto", animation: true, restoreOnCancel: true, language: "auto" },
|
|
26
27
|
// [W6-C0] 第六波键的缺省(行为由各批次实现)
|
|
27
28
|
memory: {
|
|
28
29
|
enabled: false,
|
|
@@ -33,7 +34,12 @@ const IMPLICIT_DEFAULTS = {
|
|
|
33
34
|
subagents: "read",
|
|
34
35
|
},
|
|
35
36
|
auth: {
|
|
36
|
-
chatgpt: {
|
|
37
|
+
chatgpt: {
|
|
38
|
+
flavor: "siwc",
|
|
39
|
+
issuer: "https://auth.openai.com",
|
|
40
|
+
originator: "codex_cli_rs",
|
|
41
|
+
codexClientVersion: DEFAULT_CODEX_CLIENT_VERSION,
|
|
42
|
+
},
|
|
37
43
|
},
|
|
38
44
|
checkpoints: { ...DEFAULT_CHECKPOINTS_CONFIG },
|
|
39
45
|
sandbox: { enabled: "auto", bash: "off", network: "deny", writable: [] },
|
|
@@ -42,7 +48,7 @@ const IMPLICIT_DEFAULTS = {
|
|
|
42
48
|
images: { resize: "auto" },
|
|
43
49
|
plan: { bash: "readonly", unattended: "stop" },
|
|
44
50
|
agents: { maxConcurrent: 3, dirs: [] },
|
|
45
|
-
subagents: { maxConcurrent: 4, maxPending: 16 },
|
|
51
|
+
subagents: { maxConcurrent: 4, maxPending: 16, background: "auto", autoBackgroundAfterMs: 0 },
|
|
46
52
|
reminders: { todo: true, fileChanges: true, contextPressure: true, budget: true },
|
|
47
53
|
todo: { reminder: 10 },
|
|
48
54
|
};
|
package/dist/config/merge.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* `compaction`、`tools.disabled`、`tools.preset`(只能更严)、`codemode.mode: "off"`、`ui`、
|
|
10
10
|
* `checkpoints.mode: "off"`、`checkpoints.maxFileBytes`(只能调小)、(W5-C0)`plan.bash`(只能更严)、
|
|
11
11
|
* `reminders`;`compaction.prune / pruneExclude` 与第五波其余段只认用户级;(W6-C0)`ui.language` /
|
|
12
|
-
* `ui.agentBar` 随 `ui` 段、`memory.enabled: false`;`ui.replyLanguage`、`memory` 其余键、`auth` 只认用户级;
|
|
12
|
+
* `ui.agentBar` 随 `ui` 段、`memory.enabled: false`;(W7-B2)`subagents.background / autoBackgroundAfterMs`;`ui.replyLanguage`、`memory` 其余键、`auth` 只认用户级;
|
|
13
13
|
* 其它字段与放宽项(含 `permission.builtinDeny / autoModel / autoSafeCommands`)被忽略并记 warning。
|
|
14
14
|
* - 同时产出带来源的权限规则清单(`ruleSpecs`),交给权限管线(B3 的 rules.ts 解析)。
|
|
15
15
|
*/
|
package/dist/config/merge.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* `compaction`、`tools.disabled`、`tools.preset`(只能更严)、`codemode.mode: "off"`、`ui`、
|
|
10
10
|
* `checkpoints.mode: "off"`、`checkpoints.maxFileBytes`(只能调小)、(W5-C0)`plan.bash`(只能更严)、
|
|
11
11
|
* `reminders`;`compaction.prune / pruneExclude` 与第五波其余段只认用户级;(W6-C0)`ui.language` /
|
|
12
|
-
* `ui.agentBar` 随 `ui` 段、`memory.enabled: false`;`ui.replyLanguage`、`memory` 其余键、`auth` 只认用户级;
|
|
12
|
+
* `ui.agentBar` 随 `ui` 段、`memory.enabled: false`;(W7-B2)`subagents.background / autoBackgroundAfterMs`;`ui.replyLanguage`、`memory` 其余键、`auth` 只认用户级;
|
|
13
13
|
* 其它字段与放宽项(含 `permission.builtinDeny / autoModel / autoSafeCommands`)被忽略并记 warning。
|
|
14
14
|
* - 同时产出带来源的权限规则清单(`ruleSpecs`),交给权限管线(B3 的 rules.ts 解析)。
|
|
15
15
|
*/
|
|
@@ -35,8 +35,9 @@ export const DEFAULT_CONFIG = Object.freeze({
|
|
|
35
35
|
});
|
|
36
36
|
/** 嵌入宿主(有 profile)时的缺省覆盖(§12.10)。 */
|
|
37
37
|
export const PROFILE_DEFAULTS = Object.freeze({
|
|
38
|
-
// [W5-A] 嵌入宿主以「最后一行 = 状态栏」锚定,底部信息行缺省单行;[
|
|
39
|
-
|
|
38
|
+
// [W5-A] 嵌入宿主以「最后一行 = 状态栏」锚定,底部信息行缺省单行;[W7-A] Agent 栏不再缺省关,
|
|
39
|
+
// 宿主要关就在自己的 profile 写 `ui.agentBar: "off"`
|
|
40
|
+
ui: { quietStartup: "header", statusLine: "compact" },
|
|
40
41
|
});
|
|
41
42
|
/** 层名 → 规则来源(RuleSource)。 */
|
|
42
43
|
const RULE_SOURCE = {
|
|
@@ -120,6 +121,22 @@ export function restrictProjectConfig(project, currentMode, label = ".ama/config
|
|
|
120
121
|
if (project.reminders !== undefined)
|
|
121
122
|
accepted.reminders = structuredClone(project.reminders);
|
|
122
123
|
break;
|
|
124
|
+
case "subagents": {
|
|
125
|
+
// [W7-B2] 前台 / 后台只影响呈现与等待,不放宽权限:项目级可设;并发、模型仍只认用户级
|
|
126
|
+
const subagents = project.subagents ?? {};
|
|
127
|
+
const result = {};
|
|
128
|
+
for (const sub of Object.keys(subagents)) {
|
|
129
|
+
if (sub !== "background" && sub !== "autoBackgroundAfterMs")
|
|
130
|
+
warnings.push(msg().config.merge.projectOnlyKeys(label, "subagents.background / subagents.autoBackgroundAfterMs", `subagents.${sub}`));
|
|
131
|
+
}
|
|
132
|
+
if (subagents.background !== undefined)
|
|
133
|
+
result.background = subagents.background;
|
|
134
|
+
if (subagents.autoBackgroundAfterMs !== undefined)
|
|
135
|
+
result.autoBackgroundAfterMs = subagents.autoBackgroundAfterMs;
|
|
136
|
+
if (Object.keys(result).length > 0)
|
|
137
|
+
accepted.subagents = result;
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
123
140
|
case "plan": {
|
|
124
141
|
const plan = restrictPlan(project.plan ?? {}, currentPlanBash, label, warnings);
|
|
125
142
|
if (plan !== undefined)
|
package/dist/config/schema-w5.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { PERMISSION_MODES_STRICT_FIRST } from "../permissions/types.js";
|
|
8
8
|
import { msg } from "../i18n/index.js";
|
|
9
9
|
import { Checker, THINKING_LEVELS, checkSection, join } from "./checker.js";
|
|
10
|
-
import { AGENTS_RESERVED_KEYS, IMAGE_RESIZE_MODES, MODELS_ENABLED_REF, PLAN_BASH_MODES_STRICT_FIRST, PLAN_UNATTENDED_MODES, STATUS_LINE_MODES, } from "./types-w5.js";
|
|
10
|
+
import { AGENTS_RESERVED_KEYS, IMAGE_RESIZE_MODES, MODELS_ENABLED_REF, PLAN_BASH_MODES_STRICT_FIRST, PLAN_UNATTENDED_MODES, STATUS_LINE_MODES, SUBAGENT_BACKGROUND_MODES, } from "./types-w5.js";
|
|
11
11
|
/** 第五波新增的顶层键(schema.ts 的 CONFIG_KEYS 并入)。 */
|
|
12
12
|
export const W5_CONFIG_KEYS = [
|
|
13
13
|
"images",
|
|
@@ -83,10 +83,12 @@ export function validateConfigW5(c, config) {
|
|
|
83
83
|
c.oneOf(s, "thinkingLevel", p, THINKING_LEVELS);
|
|
84
84
|
});
|
|
85
85
|
checkAgents(c, config);
|
|
86
|
-
checkSection(c, config, "subagents", ["maxConcurrent", "maxPending", "defaultModel"], (s, p) => {
|
|
86
|
+
checkSection(c, config, "subagents", ["maxConcurrent", "maxPending", "defaultModel", "background", "autoBackgroundAfterMs"], (s, p) => {
|
|
87
87
|
c.number(s, "maxConcurrent", p, 1, 64);
|
|
88
88
|
c.number(s, "maxPending", p, 0, 1024);
|
|
89
89
|
c.string(s, "defaultModel", p);
|
|
90
|
+
c.oneOf(s, "background", p, SUBAGENT_BACKGROUND_MODES);
|
|
91
|
+
c.number(s, "autoBackgroundAfterMs", p, 0);
|
|
90
92
|
});
|
|
91
93
|
checkSection(c, config, "models", ["aliases", "enabled"], (s, p) => {
|
|
92
94
|
c.stringArray(s, "enabled", p);
|
|
@@ -9,7 +9,7 @@ export declare const W6_CONFIG_KEYS: readonly ["memory", "auth"];
|
|
|
9
9
|
/** 已有 `ui` 段新增的键。 */
|
|
10
10
|
export declare const W6_UI_KEYS: readonly ["language", "replyLanguage", "agentBar"];
|
|
11
11
|
export declare const MEMORY_KEYS: readonly ["enabled", "scopes", "indexMaxBytes", "fileMaxBytes", "maxFiles", "subagents"];
|
|
12
|
-
export declare const CHATGPT_AUTH_KEYS: readonly ["flavor", "clientId", "issuer", "originator", "redirectPorts"];
|
|
12
|
+
export declare const CHATGPT_AUTH_KEYS: readonly ["flavor", "clientId", "issuer", "originator", "codexClientVersion", "redirectPorts"];
|
|
13
13
|
export declare function checkUiW6(c: Checker, ui: Obj, path: string): void;
|
|
14
14
|
/** 第六波顶层段的校验(validateConfig 末尾调用)。 */
|
|
15
15
|
export declare function validateConfigW6(c: Checker, config: Obj): void;
|
package/dist/config/schema-w6.js
CHANGED
|
@@ -24,6 +24,7 @@ export const CHATGPT_AUTH_KEYS = [
|
|
|
24
24
|
"clientId",
|
|
25
25
|
"issuer",
|
|
26
26
|
"originator",
|
|
27
|
+
"codexClientVersion",
|
|
27
28
|
"redirectPorts",
|
|
28
29
|
];
|
|
29
30
|
export function checkUiW6(c, ui, path) {
|
|
@@ -63,7 +64,7 @@ export function validateConfigW6(c, config) {
|
|
|
63
64
|
return;
|
|
64
65
|
c.keys(chatgpt, cp, CHATGPT_AUTH_KEYS);
|
|
65
66
|
c.oneOf(chatgpt, "flavor", cp, CHATGPT_FLAVORS);
|
|
66
|
-
for (const key of ["clientId", "issuer", "originator"])
|
|
67
|
+
for (const key of ["clientId", "issuer", "originator", "codexClientVersion"])
|
|
67
68
|
c.string(chatgpt, key, cp);
|
|
68
69
|
checkPorts(c, chatgpt, "redirectPorts", cp);
|
|
69
70
|
});
|
package/dist/config/schema.js
CHANGED
|
@@ -257,6 +257,7 @@ export function validateConfig(value) {
|
|
|
257
257
|
"quietStartup",
|
|
258
258
|
"ascii",
|
|
259
259
|
"compact",
|
|
260
|
+
"logo",
|
|
260
261
|
"animation",
|
|
261
262
|
"restoreOnCancel",
|
|
262
263
|
...W5_UI_KEYS,
|
|
@@ -269,6 +270,7 @@ export function validateConfig(value) {
|
|
|
269
270
|
c.oneOf(s, "quietStartup", p, ["normal", "header", "silent"]);
|
|
270
271
|
c.boolean(s, "ascii", p);
|
|
271
272
|
c.boolean(s, "compact", p);
|
|
273
|
+
c.oneOf(s, "logo", p, ["auto", "off"]);
|
|
272
274
|
c.boolean(s, "animation", p);
|
|
273
275
|
c.boolean(s, "restoreOnCancel", p);
|
|
274
276
|
checkUiW5(c, s, p);
|
|
@@ -31,6 +31,7 @@ const ROWS = [
|
|
|
31
31
|
row("ui.showThinking", "ui", "now", "any"),
|
|
32
32
|
row("ui.compact", "ui", "now", "any"),
|
|
33
33
|
row("ui.animation", "ui", "now", "any"),
|
|
34
|
+
row("ui.logo", "ui", "restart", "any"),
|
|
34
35
|
row("ui.statusLine", "ui", "now", "any"),
|
|
35
36
|
row("ui.restoreOnCancel", "ui", "nextSession", "any"),
|
|
36
37
|
row("ui.quietStartup", "ui", "restart", "any"),
|
|
@@ -92,6 +93,9 @@ const ROWS = [
|
|
|
92
93
|
row("agents.sessionBudgetUsd", "agents", "nextSession", "deny", { kind: "optionalNumber" }),
|
|
93
94
|
row("subagents.maxConcurrent", "agents", "nextSession", "deny"),
|
|
94
95
|
row("subagents.maxPending", "agents", "nextSession", "deny"),
|
|
96
|
+
// [W7-B2] 改 task 工具描述(缺省后台 / 前台两种文案),故 prefix
|
|
97
|
+
row("subagents.background", "agents", "restart", "any", { prefix: true }),
|
|
98
|
+
row("subagents.autoBackgroundAfterMs", "agents", "restart", "any"),
|
|
95
99
|
// [W6-M]
|
|
96
100
|
row("memory.enabled", "memory", "nextSession", "tighten", { envOverride: "AMA_MEMORY" }),
|
|
97
101
|
row("memory.subagents", "memory", "nextSession", "deny"),
|
|
@@ -59,6 +59,9 @@ export interface AgentsConfig {
|
|
|
59
59
|
}
|
|
60
60
|
/** 取 `agents.<id>`(保留键返回 undefined)。 */
|
|
61
61
|
export declare function agentEntry(agents: AgentsConfig | undefined, agentId: string): AgentEntryConfig | undefined;
|
|
62
|
+
/** [W7-B2] 子 Agent 缺省前台还是后台(docs/agents-concurrency-plan.md §2.6)。 */
|
|
63
|
+
export declare const SUBAGENT_BACKGROUND_MODES: readonly ["auto", "always", "never"];
|
|
64
|
+
export type SubagentBackgroundMode = (typeof SUBAGENT_BACKGROUND_MODES)[number];
|
|
62
65
|
/** [W5-G] ama 自己的子会话。 */
|
|
63
66
|
export interface SubagentsConfig {
|
|
64
67
|
/** 同时运行的子会话,缺省 4。 */
|
|
@@ -67,6 +70,13 @@ export interface SubagentsConfig {
|
|
|
67
70
|
maxPending?: number;
|
|
68
71
|
/** 子会话缺省模型;不设继承父会话。 */
|
|
69
72
|
defaultModel?: string;
|
|
73
|
+
/**
|
|
74
|
+
* [W7-B2] task 缺省后台:auto(缺省)= 交互 / RPC / ACP 下后台、`-p` 下前台;always / never 固定。
|
|
75
|
+
* 优先级:调用参数 > 类型定义 > 本键。用户 / 项目 / 宿主级都认。
|
|
76
|
+
*/
|
|
77
|
+
background?: SubagentBackgroundMode;
|
|
78
|
+
/** [W7-B2] 前台任务运行超过该毫秒数自动转后台;缺省 0 关闭。用户 / 项目级都认。 */
|
|
79
|
+
autoBackgroundAfterMs?: number;
|
|
70
80
|
}
|
|
71
81
|
/** `models.enabled` 的一项:`provider/model[@channel]` 或 `provider/*`。 */
|
|
72
82
|
export declare const MODELS_ENABLED_REF: RegExp;
|
package/dist/config/types-w5.js
CHANGED
|
@@ -18,5 +18,7 @@ export function agentEntry(agents, agentId) {
|
|
|
18
18
|
const entry = agents[agentId];
|
|
19
19
|
return typeof entry === "object" && !Array.isArray(entry) ? entry : undefined;
|
|
20
20
|
}
|
|
21
|
+
/** [W7-B2] 子 Agent 缺省前台还是后台(docs/agents-concurrency-plan.md §2.6)。 */
|
|
22
|
+
export const SUBAGENT_BACKGROUND_MODES = ["auto", "always", "never"];
|
|
21
23
|
/** `models.enabled` 的一项:`provider/model[@channel]` 或 `provider/*`。 */
|
|
22
24
|
export const MODELS_ENABLED_REF = /^[^/\s]+\/\S+$/;
|
|
@@ -53,6 +53,11 @@ export interface ChatGptAuthConfig {
|
|
|
53
53
|
issuer?: string;
|
|
54
54
|
/** codex flavor 的 `originator` 请求头,缺省 codex_cli_rs。 */
|
|
55
55
|
originator?: string;
|
|
56
|
+
/**
|
|
57
|
+
* codex flavor 模型列表的 `client_version`(Codex CLI 版本号,后端按它过滤模型),缺省见
|
|
58
|
+
* `DEFAULT_CODEX_CLIENT_VERSION`;`AMA_CHATGPT_CODEX_CLIENT_VERSION` 优先。
|
|
59
|
+
*/
|
|
60
|
+
codexClientVersion?: string;
|
|
56
61
|
/** 本地回调端口(依次尝试;0 = 任意空闲端口)。 */
|
|
57
62
|
redirectPorts?: number[];
|
|
58
63
|
}
|
package/dist/config/types.d.ts
CHANGED
|
@@ -143,8 +143,10 @@ export interface UiConfig extends UiConfigW6 {
|
|
|
143
143
|
quietStartup?: "normal" | "header" | "silent";
|
|
144
144
|
/** ASCII 字形(`AMA_ASCII=1` 等价);缺省按区域设置 / TERM 自动检测。 */
|
|
145
145
|
ascii?: boolean;
|
|
146
|
-
/**
|
|
146
|
+
/** 消息区块间不空行、启动头不画字符画,缺省 false。 */
|
|
147
147
|
compact?: boolean;
|
|
148
|
+
/** 启动头的「AMA」字符画:auto(缺省,宽度够时画)/ off(只画信息列)。 */
|
|
149
|
+
logo?: "auto" | "off";
|
|
148
150
|
/** false:运行中 spinner 固定为 `·`,缺省 true。 */
|
|
149
151
|
animation?: boolean;
|
|
150
152
|
/** 运行中 Esc 中断、本回合还没有任何输出时撤回该回合并回填原消息,缺省 true。 */
|
package/dist/git/info.d.ts
CHANGED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
* `GIT_OPTIONAL_LOCKS=0`;两次之间 ≥ `minIntervalMs`(缺省 10 s),超过 `timeoutMs`(缺省 2 s)或
|
|
8
8
|
* 非零退出 / 起不来就省略增删项,并在本实例(本会话)停用 numstat,HEAD 仍照常显示。
|
|
9
9
|
* `AMA_STATUS_GIT=0` 直接关闭 numstat(排错用)。
|
|
10
|
+
* - [W6] 领先 / 落后上游:当前分支在 git 配置里有 `branch.<名>.merge`(零依赖读 config,不起进程判断)时,
|
|
11
|
+
* numstat 之后同一节流周期再跑 `git rev-list --left-right --count @{upstream}...HEAD`(同样的超时与环境);
|
|
12
|
+
* 没有上游、detached、非零退出就省略;超时则本会话不再统计领先 / 落后。`AMA_STATUS_GIT=0` 同样关闭。
|
|
10
13
|
* - 非 git 目录 `current()` 为 undefined(状态行整段省略)。
|
|
11
14
|
* - `refresh()` 在回合边界调用(agent_settled、写类工具结束、回滚、/tree),只发起读取、不阻塞;
|
|
12
15
|
* 结果有变化时通知 `onChange` 的监听者。
|
|
@@ -19,6 +22,9 @@ export interface GitInfo {
|
|
|
19
22
|
/** 工作区(含暂存)相对 HEAD;拿不到为 undefined。 */
|
|
20
23
|
insertions?: number;
|
|
21
24
|
deletions?: number;
|
|
25
|
+
/** [W6] 领先 / 落后上游的提交数;没有上游为 undefined。 */
|
|
26
|
+
ahead?: number;
|
|
27
|
+
behind?: number;
|
|
22
28
|
}
|
|
23
29
|
/** numstat 子进程的最小接口(测试注入)。 */
|
|
24
30
|
export interface NumstatProcess {
|
|
@@ -45,6 +51,13 @@ export declare function parseNumstat(text: string): {
|
|
|
45
51
|
insertions: number;
|
|
46
52
|
deletions: number;
|
|
47
53
|
};
|
|
54
|
+
/** `git rev-list --left-right --count @{upstream}...HEAD` 的输出:左(上游独有)= 落后,右 = 领先。 */
|
|
55
|
+
export declare function parseLeftRight(text: string): {
|
|
56
|
+
ahead: number;
|
|
57
|
+
behind: number;
|
|
58
|
+
} | undefined;
|
|
59
|
+
/** 分支在 git 配置里有没有上游(`[branch "<名>"]` 段里的 `merge`);worktree 读主仓库的 config。 */
|
|
60
|
+
export declare function hasUpstream(cwd: string, branch: string): Promise<boolean>;
|
|
48
61
|
export declare class GitInfoWatcher {
|
|
49
62
|
private readonly cwd;
|
|
50
63
|
private info;
|
|
@@ -61,6 +74,8 @@ export declare class GitInfoWatcher {
|
|
|
61
74
|
private headAgain;
|
|
62
75
|
private disposed;
|
|
63
76
|
private diff;
|
|
77
|
+
private upstream;
|
|
78
|
+
private upstreamDisabled;
|
|
64
79
|
constructor(cwd: string, deps?: GitInfoDeps);
|
|
65
80
|
current(): GitInfo | undefined;
|
|
66
81
|
/** numstat 已因超时 / 失败 / 环境变量停用。 */
|
|
@@ -71,5 +86,9 @@ export declare class GitInfoWatcher {
|
|
|
71
86
|
dispose(): void;
|
|
72
87
|
private update;
|
|
73
88
|
private maybeNumstat;
|
|
89
|
+
/** 领先 / 落后上游:只在配置里有上游时起进程;超时本会话停用,非零退出只省略这一次。 */
|
|
90
|
+
private leftRight;
|
|
74
91
|
private numstat;
|
|
92
|
+
/** 后台起一次 git;起不来为 undefined,超时杀掉并返回 `"timeout"`。 */
|
|
93
|
+
private run;
|
|
75
94
|
}
|