@ai-zen/cli 1.0.0-alpha.2 → 1.0.0-alpha.20
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 +356 -0
- package/README.md +99 -28
- package/README.zh.md +99 -28
- package/dist/agent-creator.d.ts +11 -0
- package/dist/agent-creator.d.ts.map +1 -1
- package/dist/agent-creator.js +20 -11
- package/dist/agent-creator.js.map +1 -1
- package/dist/agents-store.d.ts.map +1 -1
- package/dist/agents-store.js +40 -3
- package/dist/agents-store.js.map +1 -1
- package/dist/auto-migrate-confirm.d.ts +43 -0
- package/dist/auto-migrate-confirm.d.ts.map +1 -0
- package/dist/auto-migrate-confirm.js +46 -0
- package/dist/auto-migrate-confirm.js.map +1 -0
- package/dist/config-editor.d.ts +4 -4
- package/dist/config-editor.d.ts.map +1 -1
- package/dist/config-editor.js +6 -8
- package/dist/config-editor.js.map +1 -1
- package/dist/config.d.ts +23 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +26 -2
- package/dist/config.js.map +1 -1
- package/dist/conversation-commands/registry.d.ts.map +1 -1
- package/dist/conversation-commands/registry.js +4 -1
- package/dist/conversation-commands/registry.js.map +1 -1
- package/dist/conversation-persist-plugin.d.ts +0 -1
- package/dist/conversation-persist-plugin.d.ts.map +1 -1
- package/dist/conversation-persist-plugin.js +2 -3
- package/dist/conversation-persist-plugin.js.map +1 -1
- package/dist/conversation-repository.d.ts +5 -1
- package/dist/conversation-repository.d.ts.map +1 -1
- package/dist/conversation-repository.js +1 -2
- package/dist/conversation-repository.js.map +1 -1
- package/dist/handoff-service.d.ts +19 -0
- package/dist/handoff-service.d.ts.map +1 -0
- package/dist/handoff-service.js +86 -0
- package/dist/handoff-service.js.map +1 -0
- package/dist/index.js +21 -3
- package/dist/index.js.map +1 -1
- package/dist/model-switch.d.ts +58 -0
- package/dist/model-switch.d.ts.map +1 -0
- package/dist/model-switch.js +61 -0
- package/dist/model-switch.js.map +1 -0
- package/dist/reasoning-effort.d.ts +77 -0
- package/dist/reasoning-effort.d.ts.map +1 -0
- package/dist/reasoning-effort.js +137 -0
- package/dist/reasoning-effort.js.map +1 -0
- package/dist/reasoning-presets.d.ts +34 -0
- package/dist/reasoning-presets.d.ts.map +1 -0
- package/dist/reasoning-presets.js +85 -0
- package/dist/reasoning-presets.js.map +1 -0
- package/dist/sdk-log.d.ts +48 -0
- package/dist/sdk-log.d.ts.map +1 -0
- package/dist/sdk-log.js +67 -0
- package/dist/sdk-log.js.map +1 -0
- package/dist/session-pointer.d.ts +22 -9
- package/dist/session-pointer.d.ts.map +1 -1
- package/dist/session-pointer.js +55 -23
- package/dist/session-pointer.js.map +1 -1
- package/dist/stdio-runner.d.ts.map +1 -1
- package/dist/stdio-runner.js +15 -13
- package/dist/stdio-runner.js.map +1 -1
- package/dist/sub-agent-guard-plugin.d.ts +5 -5
- package/dist/sub-agent-guard-plugin.d.ts.map +1 -1
- package/dist/sub-agent-guard-plugin.js +7 -7
- package/dist/sub-agent-guard-plugin.js.map +1 -1
- package/dist/tui/chat-session.d.ts +83 -59
- package/dist/tui/chat-session.d.ts.map +1 -1
- package/dist/tui/chat-session.js +161 -105
- package/dist/tui/chat-session.js.map +1 -1
- package/dist/tui/components.d.ts +7 -2
- package/dist/tui/components.d.ts.map +1 -1
- package/dist/tui/components.js +3 -3
- package/dist/tui/components.js.map +1 -1
- package/dist/tui/config-wizard/engine.js +1 -1
- package/dist/tui/config-wizard/engine.js.map +1 -1
- package/dist/tui/config-wizard/fields.d.ts +3 -1
- package/dist/tui/config-wizard/fields.d.ts.map +1 -1
- package/dist/tui/config-wizard/fields.js +58 -6
- package/dist/tui/config-wizard/fields.js.map +1 -1
- package/dist/tui/config-wizard/menu.d.ts.map +1 -1
- package/dist/tui/config-wizard/menu.js +2 -3
- package/dist/tui/config-wizard/menu.js.map +1 -1
- package/dist/tui/config-wizard/step-defaults.d.ts.map +1 -1
- package/dist/tui/config-wizard/step-defaults.js +4 -11
- package/dist/tui/config-wizard/step-defaults.js.map +1 -1
- package/dist/tui/config-wizard/types.d.ts +18 -3
- package/dist/tui/config-wizard/types.d.ts.map +1 -1
- package/dist/tui/config-wizard/wizard.d.ts.map +1 -1
- package/dist/tui/config-wizard/wizard.js +4 -3
- package/dist/tui/config-wizard/wizard.js.map +1 -1
- package/dist/tui/highlight.d.ts +3 -2
- package/dist/tui/highlight.d.ts.map +1 -1
- package/dist/tui/highlight.js +3 -2
- package/dist/tui/highlight.js.map +1 -1
- package/dist/tui/index.d.ts +1 -0
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +87 -40
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/input-editing.d.ts +49 -0
- package/dist/tui/input-editing.d.ts.map +1 -0
- package/dist/tui/input-editing.js +87 -0
- package/dist/tui/input-editing.js.map +1 -0
- package/dist/tui/key-debug.d.ts +62 -0
- package/dist/tui/key-debug.d.ts.map +1 -0
- package/dist/tui/key-debug.js +92 -0
- package/dist/tui/key-debug.js.map +1 -0
- package/dist/tui/mouse.d.ts +55 -0
- package/dist/tui/mouse.d.ts.map +1 -0
- package/dist/tui/mouse.js +74 -0
- package/dist/tui/mouse.js.map +1 -0
- package/dist/tui/screens/chat-commands.d.ts +12 -2
- package/dist/tui/screens/chat-commands.d.ts.map +1 -1
- package/dist/tui/screens/chat-commands.js +204 -17
- package/dist/tui/screens/chat-commands.js.map +1 -1
- package/dist/tui/screens/chat.d.ts +2 -5
- package/dist/tui/screens/chat.d.ts.map +1 -1
- package/dist/tui/screens/chat.js +460 -98
- package/dist/tui/screens/chat.js.map +1 -1
- package/dist/tui/screens/frame-buffer.d.ts +47 -0
- package/dist/tui/screens/frame-buffer.d.ts.map +1 -0
- package/dist/tui/screens/frame-buffer.js +78 -0
- package/dist/tui/screens/frame-buffer.js.map +1 -0
- package/dist/tui/screens/handoff-choice.d.ts +37 -0
- package/dist/tui/screens/handoff-choice.d.ts.map +1 -0
- package/dist/tui/screens/handoff-choice.js +41 -0
- package/dist/tui/screens/handoff-choice.js.map +1 -0
- package/dist/tui/screens/index.d.ts +8 -8
- package/dist/tui/screens/index.d.ts.map +1 -1
- package/dist/tui/screens/index.js +7 -7
- package/dist/tui/screens/index.js.map +1 -1
- package/dist/tui/screens/input.d.ts +35 -0
- package/dist/tui/screens/input.d.ts.map +1 -1
- package/dist/tui/screens/input.js +66 -0
- package/dist/tui/screens/input.js.map +1 -1
- package/dist/tui/screens/layout.d.ts +13 -3
- package/dist/tui/screens/layout.d.ts.map +1 -1
- package/dist/tui/screens/layout.js +15 -8
- package/dist/tui/screens/layout.js.map +1 -1
- package/dist/tui/screens/lines.d.ts +12 -41
- package/dist/tui/screens/lines.d.ts.map +1 -1
- package/dist/tui/screens/lines.js +87 -95
- package/dist/tui/screens/lines.js.map +1 -1
- package/dist/tui/screens/messages-view.d.ts +10 -0
- package/dist/tui/screens/messages-view.d.ts.map +1 -0
- package/dist/tui/screens/messages-view.js +115 -0
- package/dist/tui/screens/messages-view.js.map +1 -0
- package/dist/tui/screens/notice.d.ts +32 -0
- package/dist/tui/screens/notice.d.ts.map +1 -0
- package/dist/tui/screens/notice.js +46 -0
- package/dist/tui/screens/notice.js.map +1 -0
- package/dist/tui/screens/render.d.ts +2 -4
- package/dist/tui/screens/render.d.ts.map +1 -1
- package/dist/tui/screens/render.js +7 -43
- package/dist/tui/screens/render.js.map +1 -1
- package/dist/tui/screens/splash.d.ts.map +1 -1
- package/dist/tui/screens/splash.js +7 -1
- package/dist/tui/screens/splash.js.map +1 -1
- package/dist/tui/text.d.ts +12 -2
- package/dist/tui/text.d.ts.map +1 -1
- package/dist/tui/text.js +17 -3
- package/dist/tui/text.js.map +1 -1
- package/dist/tui/theme.d.ts +7 -1
- package/dist/tui/theme.d.ts.map +1 -1
- package/dist/tui/theme.js +15 -3
- package/dist/tui/theme.js.map +1 -1
- package/dist/types.d.ts +7 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/auto-migrate-confirm-plugin.d.ts +0 -58
- package/dist/auto-migrate-confirm-plugin.d.ts.map +0 -1
- package/dist/auto-migrate-confirm-plugin.js +0 -61
- package/dist/auto-migrate-confirm-plugin.js.map +0 -1
- package/dist/migration-service.d.ts +0 -15
- package/dist/migration-service.d.ts.map +0 -1
- package/dist/migration-service.js +0 -59
- package/dist/migration-service.js.map +0 -1
- package/dist/tui/screens/state.d.ts +0 -13
- package/dist/tui/screens/state.d.ts.map +0 -1
- package/dist/tui/screens/state.js +0 -75
- package/dist/tui/screens/state.js.map +0 -1
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 模型切换 —— `/model` 的写配置策略(纯逻辑,可单测)
|
|
3
|
+
*
|
|
4
|
+
* ## 唯一真相源
|
|
5
|
+
*
|
|
6
|
+
* 模型只写在 **`AgentDefinition.modelId`** 上:
|
|
7
|
+
*
|
|
8
|
+
* - 配置层没有 `defaultModel`(`AppConfig` 已无此字段);
|
|
9
|
+
* - 会话存档不记模型(`Conversation` 已无 `modelId`);
|
|
10
|
+
* - 运行期 `createAgent` 只读 `definition.modelId`,缺了直接报错。
|
|
11
|
+
*
|
|
12
|
+
* 于是「切换模型」只有一种写法和一种读法,不存在两层分歧导致的
|
|
13
|
+
* 「状态栏显示 A、实际请求发 B」。
|
|
14
|
+
*
|
|
15
|
+
* ## 切换即重置思考强度
|
|
16
|
+
*
|
|
17
|
+
* `AgentDefinition.modelParams` 里的思考参数(`thinking` / `reasoning_effort` 等)是
|
|
18
|
+
* **模型相关**的:DeepSeek 的 `off` 档是 `thinking: { type: "disabled" }`,而智谱 GLM-5.3
|
|
19
|
+
* 根本不接受关闭思考。把旧模型的档位带到新模型上,轻则无意义,重则直接报错。
|
|
20
|
+
*
|
|
21
|
+
* 所以换模型时**直接清空 `modelParams`**(不保留、不迁移、不逐键剔除),让 Agent
|
|
22
|
+
* 回到「不填思考强度」的状态,由目标模型自己的 `defaultParams` 决定。用户想调就
|
|
23
|
+
* 再用 `/think` 选一次。
|
|
24
|
+
*
|
|
25
|
+
* ## 注意
|
|
26
|
+
*
|
|
27
|
+
* **Agent 定义的其它字段不可丢**:SDK 初始化时只同步出厂提示词,
|
|
28
|
+
* 其余字段(权限、`custom` 等)以用户文件为准,因此写入是「读 → 改字段 → 写回」。
|
|
29
|
+
*/
|
|
30
|
+
import { AgentRepository } from "@ai-zen/agents-sdk";
|
|
31
|
+
import { AGENTS_DIR } from "./config.js";
|
|
32
|
+
/**
|
|
33
|
+
* 切换模型:把目标模型写进 Agent 定义的 `modelId`,并把思考强度重置为模型默认。
|
|
34
|
+
*
|
|
35
|
+
* 抛错场景:模型不存在、Agent 定义缺失。
|
|
36
|
+
*/
|
|
37
|
+
export async function switchModel(options) {
|
|
38
|
+
const { config, modelId } = options;
|
|
39
|
+
const agentId = options.agentId || "default";
|
|
40
|
+
const now = options.now ?? new Date();
|
|
41
|
+
const model = (config.models ?? []).find((item) => item.id === modelId);
|
|
42
|
+
if (!model)
|
|
43
|
+
throw new Error(`模型 "${modelId}" 不存在`);
|
|
44
|
+
const readAgent = options.readAgent ?? ((id) => new AgentRepository(AGENTS_DIR).read(id));
|
|
45
|
+
const writeAgent = options.writeAgent ??
|
|
46
|
+
((definition) => new AgentRepository(AGENTS_DIR).write(definition));
|
|
47
|
+
const definition = await readAgent(agentId);
|
|
48
|
+
if (!definition)
|
|
49
|
+
throw new Error(`Agent "${agentId}" 不存在`);
|
|
50
|
+
const next = { ...definition, modelId, updatedAt: now.toISOString() };
|
|
51
|
+
// 换模型 = 重置思考强度:旧模型的档位参数对新模型可能非法(如 GLM-5.3 不接受
|
|
52
|
+
// `thinking.disabled`),所以直接清空,让目标模型走自己的 defaultParams。
|
|
53
|
+
delete next.modelParams;
|
|
54
|
+
await writeAgent(next);
|
|
55
|
+
const resetHint = definition.modelParams ? " · 思考强度已重置为模型默认" : "";
|
|
56
|
+
return {
|
|
57
|
+
summary: `已切换模型:${model.name}(${model.id})· 已写入 Agent「${agentId}」${resetHint}`,
|
|
58
|
+
definition: next,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=model-switch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-switch.js","sourceRoot":"","sources":["../src/model-switch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA0BzC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAA2B;IAC3D,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,SAAS,CAAC;IAC7C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;IAEtC,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IACxE,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,OAAO,OAAO,CAAC,CAAC;IAEnD,MAAM,SAAS,GACb,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAClF,MAAM,UAAU,GACd,OAAO,CAAC,UAAU;QAClB,CAAC,CAAC,UAA2B,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IAEvF,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,OAAO,CAAC,CAAC;IAE3D,MAAM,IAAI,GAAoB,EAAE,GAAG,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;IACvF,8CAA8C;IAC9C,uDAAuD;IACvD,OAAO,IAAI,CAAC,WAAW,CAAC;IACxB,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IAEvB,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,OAAO;QACL,OAAO,EAAE,SAAS,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE,gBAAgB,OAAO,IAAI,SAAS,EAAE;QAC9E,UAAU,EAAE,IAAI;KACjB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 思考档位(reasoning level)—— CLI 侧读写
|
|
3
|
+
*
|
|
4
|
+
* ## 三层,边界很硬
|
|
5
|
+
*
|
|
6
|
+
* - **协议差异在策略表**(`~/.ai-zen/reasoning-presets.json`):档位名 → 请求参数补丁,
|
|
7
|
+
* 由这张 CLI 自有的表声明,模型用 `reasoningPreset` 引用它。
|
|
8
|
+
* - **档位值存在 Agent 定义**(`AgentDefinition.modelParams`):**存的是展开后的参数**,
|
|
9
|
+
* 不是档位名。于是「配置即事实」——运行期 SDK 只做一次浅合并,不查表、不推导。
|
|
10
|
+
* - **本模块只管 UI 语义**:列可选档位、把参数反查成档位名、写回 Agent 定义。
|
|
11
|
+
*
|
|
12
|
+
* 代价(刻意接受):改了策略表**不会追溯**已配置的 Agent —— 它们存的是当时的参数。
|
|
13
|
+
* 这正是「配置即事实」的含义:表只是写配置那一刻的模板。
|
|
14
|
+
*/
|
|
15
|
+
import type { AgentDefinition, AppConfig, Model } from "@ai-zen/agents-sdk";
|
|
16
|
+
import { type ReasoningPreset, type ReasoningPresets } from "./reasoning-presets.js";
|
|
17
|
+
/**
|
|
18
|
+
* 已知档位的中文标签。
|
|
19
|
+
*
|
|
20
|
+
* 不设成穷举映射:档位名由策略表定义(用户可自建策略、自定档位名),
|
|
21
|
+
* 未知名字直接显示原文,比显示「?」有用得多。
|
|
22
|
+
*/
|
|
23
|
+
export declare const EFFORT_LABELS: Record<string, string>;
|
|
24
|
+
/** 档位 → 显示文案(未知档位名原样显示) */
|
|
25
|
+
export declare function effortLabel(level: string): string;
|
|
26
|
+
/** 模型关联的策略 */
|
|
27
|
+
export declare function presetOf(model: Model | null | undefined, presets: ReasoningPresets): ReasoningPreset | undefined;
|
|
28
|
+
/** 模型可选档位(空数组 = 不可调档) */
|
|
29
|
+
export declare function effortChoices(model?: Model | null, presets?: ReasoningPresets | null): string[];
|
|
30
|
+
/** 一档都用不了的模型 */
|
|
31
|
+
export declare function isAdjustable(model?: Model | null, presets?: ReasoningPresets | null): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* 生效中的模型参数 = 模型默认参数 + Agent 级覆盖(与 SDK 的合并语义一致,浅合并)。
|
|
34
|
+
*
|
|
35
|
+
* 注意这里复刻的是**同一份事实**,不是另一套推导:状态栏显示的就是真正会发给 API 的
|
|
36
|
+
* 那几个参数里匹配到的那一档。
|
|
37
|
+
*/
|
|
38
|
+
export declare function effectiveParams(model?: Model | null, definition?: Pick<AgentDefinition, "modelParams"> | null): Record<string, unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* 状态栏文案。
|
|
41
|
+
*
|
|
42
|
+
* - 模型不可调档 → `—`
|
|
43
|
+
* - 生效参数命中某档 → 「低」「中」「高」…(按 `EFFORT_LABELS`)
|
|
44
|
+
* - 有 Agent 级覆盖但不匹配任何档位 → 「自定义」(用户手改过参数)
|
|
45
|
+
* - 没有任何声明 → 「默认」(跟随模型 `defaultParams`,如 DeepSeek 出厂只开思考不指定档位)
|
|
46
|
+
*/
|
|
47
|
+
export declare function describeEffort(model?: Model | null, presets?: ReasoningPresets | null, definition?: Pick<AgentDefinition, "modelParams"> | null): string;
|
|
48
|
+
export interface SetAgentEffortOptions {
|
|
49
|
+
config: AppConfig;
|
|
50
|
+
/** 思考策略表(`readReasoningPresets()` 的结果) */
|
|
51
|
+
presets: ReasoningPresets;
|
|
52
|
+
/** 目标 Agent(缺省 default) */
|
|
53
|
+
agentId?: string;
|
|
54
|
+
/** 目标档位;`null` 表示清除思考参数、恢复跟随模型默认 */
|
|
55
|
+
effort: string | null;
|
|
56
|
+
/** 注入用(测试) */
|
|
57
|
+
readAgent?: (agentId: string) => Promise<AgentDefinition | null>;
|
|
58
|
+
writeAgent?: (definition: AgentDefinition) => Promise<void>;
|
|
59
|
+
now?: Date;
|
|
60
|
+
}
|
|
61
|
+
export interface SetAgentEffortResult {
|
|
62
|
+
definition: AgentDefinition;
|
|
63
|
+
/** 生效模型 */
|
|
64
|
+
model: Model;
|
|
65
|
+
summary: string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 设置某 Agent 的思考档位:查表拿补丁 → 写进 `definition.modelParams`。
|
|
69
|
+
*
|
|
70
|
+
* 写入前先剔除「整张表出现过的键」,所以 `max` → `off` 不会残留上一档的
|
|
71
|
+
* `reasoning_effort`;`effort: null` 就是剔除后若为空则删掉整个 `modelParams`。
|
|
72
|
+
*
|
|
73
|
+
* 抛错场景:Agent 不存在、未绑定可用模型、模型未关联策略、策略里没有该档位。
|
|
74
|
+
* 这些都属于「用户明确要求了一件做不到的事」,宁可报错也不要静默降级。
|
|
75
|
+
*/
|
|
76
|
+
export declare function setAgentEffort(options: SetAgentEffortOptions): Promise<SetAgentEffortResult>;
|
|
77
|
+
//# sourceMappingURL=reasoning-effort.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reasoning-effort.d.ts","sourceRoot":"","sources":["../src/reasoning-effort.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAEhC;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAShD,CAAC;AAEF,2BAA2B;AAC3B,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,cAAc;AACd,wBAAgB,QAAQ,CACtB,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,EAC/B,OAAO,EAAE,gBAAgB,GACxB,eAAe,GAAG,SAAS,CAE7B;AAED,yBAAyB;AACzB,wBAAgB,aAAa,CAC3B,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,EACpB,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAChC,MAAM,EAAE,CAGV;AAED,gBAAgB;AAChB,wBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,OAAO,CAE7F;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,EACpB,UAAU,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,GAAG,IAAI,GACvD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,EACpB,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,EACjC,UAAU,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,GAAG,IAAI,GACvD,MAAM,CAQR;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,SAAS,CAAC;IAClB,0CAA0C;IAC1C,OAAO,EAAE,gBAAgB,CAAC;IAC1B,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc;IACd,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACjE,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,eAAe,CAAC;IAC5B,WAAW;IACX,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAwD/B"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 思考档位(reasoning level)—— CLI 侧读写
|
|
3
|
+
*
|
|
4
|
+
* ## 三层,边界很硬
|
|
5
|
+
*
|
|
6
|
+
* - **协议差异在策略表**(`~/.ai-zen/reasoning-presets.json`):档位名 → 请求参数补丁,
|
|
7
|
+
* 由这张 CLI 自有的表声明,模型用 `reasoningPreset` 引用它。
|
|
8
|
+
* - **档位值存在 Agent 定义**(`AgentDefinition.modelParams`):**存的是展开后的参数**,
|
|
9
|
+
* 不是档位名。于是「配置即事实」——运行期 SDK 只做一次浅合并,不查表、不推导。
|
|
10
|
+
* - **本模块只管 UI 语义**:列可选档位、把参数反查成档位名、写回 Agent 定义。
|
|
11
|
+
*
|
|
12
|
+
* 代价(刻意接受):改了策略表**不会追溯**已配置的 Agent —— 它们存的是当时的参数。
|
|
13
|
+
* 这正是「配置即事实」的含义:表只是写配置那一刻的模板。
|
|
14
|
+
*/
|
|
15
|
+
import { AgentRepository } from "@ai-zen/agents-sdk";
|
|
16
|
+
import { AGENTS_DIR } from "./config.js";
|
|
17
|
+
import { levelsOf, matchLevel, ownedKeys, patchOf, presetFor, } from "./reasoning-presets.js";
|
|
18
|
+
/**
|
|
19
|
+
* 已知档位的中文标签。
|
|
20
|
+
*
|
|
21
|
+
* 不设成穷举映射:档位名由策略表定义(用户可自建策略、自定档位名),
|
|
22
|
+
* 未知名字直接显示原文,比显示「?」有用得多。
|
|
23
|
+
*/
|
|
24
|
+
export const EFFORT_LABELS = {
|
|
25
|
+
off: "关",
|
|
26
|
+
none: "关",
|
|
27
|
+
minimal: "极低",
|
|
28
|
+
low: "低",
|
|
29
|
+
medium: "中",
|
|
30
|
+
high: "高",
|
|
31
|
+
xhigh: "极高",
|
|
32
|
+
max: "最高",
|
|
33
|
+
};
|
|
34
|
+
/** 档位 → 显示文案(未知档位名原样显示) */
|
|
35
|
+
export function effortLabel(level) {
|
|
36
|
+
return EFFORT_LABELS[level] ?? level;
|
|
37
|
+
}
|
|
38
|
+
/** 模型关联的策略 */
|
|
39
|
+
export function presetOf(model, presets) {
|
|
40
|
+
return presetFor(model?.id, model?.reasoningPreset, presets);
|
|
41
|
+
}
|
|
42
|
+
/** 模型可选档位(空数组 = 不可调档) */
|
|
43
|
+
export function effortChoices(model, presets) {
|
|
44
|
+
if (!presets)
|
|
45
|
+
return [];
|
|
46
|
+
return levelsOf(presetOf(model, presets));
|
|
47
|
+
}
|
|
48
|
+
/** 一档都用不了的模型 */
|
|
49
|
+
export function isAdjustable(model, presets) {
|
|
50
|
+
return effortChoices(model, presets).length > 0;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 生效中的模型参数 = 模型默认参数 + Agent 级覆盖(与 SDK 的合并语义一致,浅合并)。
|
|
54
|
+
*
|
|
55
|
+
* 注意这里复刻的是**同一份事实**,不是另一套推导:状态栏显示的就是真正会发给 API 的
|
|
56
|
+
* 那几个参数里匹配到的那一档。
|
|
57
|
+
*/
|
|
58
|
+
export function effectiveParams(model, definition) {
|
|
59
|
+
return { ...(model?.defaultParams ?? {}), ...(definition?.modelParams ?? {}) };
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 状态栏文案。
|
|
63
|
+
*
|
|
64
|
+
* - 模型不可调档 → `—`
|
|
65
|
+
* - 生效参数命中某档 → 「低」「中」「高」…(按 `EFFORT_LABELS`)
|
|
66
|
+
* - 有 Agent 级覆盖但不匹配任何档位 → 「自定义」(用户手改过参数)
|
|
67
|
+
* - 没有任何声明 → 「默认」(跟随模型 `defaultParams`,如 DeepSeek 出厂只开思考不指定档位)
|
|
68
|
+
*/
|
|
69
|
+
export function describeEffort(model, presets, definition) {
|
|
70
|
+
if (!presets || !isAdjustable(model, presets))
|
|
71
|
+
return "—";
|
|
72
|
+
const params = effectiveParams(model, definition);
|
|
73
|
+
const matched = matchLevel(presetOf(model, presets), params);
|
|
74
|
+
if (matched)
|
|
75
|
+
return effortLabel(matched);
|
|
76
|
+
return definition?.modelParams && Object.keys(definition.modelParams).length > 0
|
|
77
|
+
? "自定义"
|
|
78
|
+
: "默认";
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* 设置某 Agent 的思考档位:查表拿补丁 → 写进 `definition.modelParams`。
|
|
82
|
+
*
|
|
83
|
+
* 写入前先剔除「整张表出现过的键」,所以 `max` → `off` 不会残留上一档的
|
|
84
|
+
* `reasoning_effort`;`effort: null` 就是剔除后若为空则删掉整个 `modelParams`。
|
|
85
|
+
*
|
|
86
|
+
* 抛错场景:Agent 不存在、未绑定可用模型、模型未关联策略、策略里没有该档位。
|
|
87
|
+
* 这些都属于「用户明确要求了一件做不到的事」,宁可报错也不要静默降级。
|
|
88
|
+
*/
|
|
89
|
+
export async function setAgentEffort(options) {
|
|
90
|
+
const { config, presets, effort } = options;
|
|
91
|
+
const agentId = options.agentId || "default";
|
|
92
|
+
const now = options.now ?? new Date();
|
|
93
|
+
const readAgent = options.readAgent ?? ((id) => new AgentRepository(AGENTS_DIR).read(id));
|
|
94
|
+
const writeAgent = options.writeAgent ??
|
|
95
|
+
((definition) => new AgentRepository(AGENTS_DIR).write(definition));
|
|
96
|
+
const definition = await readAgent(agentId);
|
|
97
|
+
if (!definition)
|
|
98
|
+
throw new Error(`Agent "${agentId}" 不存在`);
|
|
99
|
+
const modelId = definition.modelId;
|
|
100
|
+
if (!modelId) {
|
|
101
|
+
throw new Error(`Agent "${agentId}" 未绑定模型,请先为它选择模型`);
|
|
102
|
+
}
|
|
103
|
+
const model = (config.models ?? []).find((item) => item.id === modelId);
|
|
104
|
+
if (!model)
|
|
105
|
+
throw new Error(`模型 "${modelId}" 不存在,请先用 /model 或 /config 检查`);
|
|
106
|
+
const preset = presetOf(model, presets);
|
|
107
|
+
const allowed = levelsOf(preset);
|
|
108
|
+
if (allowed.length === 0) {
|
|
109
|
+
throw new Error(`模型 "${model.id}" 未关联可用的思考策略(reasoningPreset),无法设置思考强度`);
|
|
110
|
+
}
|
|
111
|
+
const patch = effort === null ? undefined : patchOf(preset, effort);
|
|
112
|
+
if (effort !== null && !patch) {
|
|
113
|
+
throw new Error(`策略 "${model.reasoningPreset}" 没有档位 "${effort}"(可选:${allowed.join(" / ")})`);
|
|
114
|
+
}
|
|
115
|
+
// 先剔除思考相关键,再合并新补丁(`null` 即只剔除)
|
|
116
|
+
const owned = ownedKeys(presets);
|
|
117
|
+
const params = {};
|
|
118
|
+
for (const [key, value] of Object.entries(definition.modelParams ?? {})) {
|
|
119
|
+
if (!owned.has(key))
|
|
120
|
+
params[key] = value;
|
|
121
|
+
}
|
|
122
|
+
if (patch)
|
|
123
|
+
Object.assign(params, patch);
|
|
124
|
+
const next = { ...definition, updatedAt: now.toISOString() };
|
|
125
|
+
if (Object.keys(params).length > 0)
|
|
126
|
+
next.modelParams = params;
|
|
127
|
+
else
|
|
128
|
+
delete next.modelParams;
|
|
129
|
+
await writeAgent(next);
|
|
130
|
+
const label = effort === null ? "跟随模型默认" : `「${effortLabel(effort)}」`;
|
|
131
|
+
return {
|
|
132
|
+
definition: next,
|
|
133
|
+
model,
|
|
134
|
+
summary: `思考强度已设为 ${label} · 写入 Agent「${agentId}」(模型 ${model.id})`,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=reasoning-effort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reasoning-effort.js","sourceRoot":"","sources":["../src/reasoning-effort.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 思考预设 —— CLI 侧的表操作(纯函数)
|
|
3
|
+
*
|
|
4
|
+
* 表的**定义、出厂内容、读写**都在 SDK(`@ai-zen/agents-sdk` 的 `ReasoningPresets` /
|
|
5
|
+
* `FACTORY_REASONING_PRESETS` / `ConfigManager.readReasoningPresets()`),因为桌面端等
|
|
6
|
+
* 其它客户端也要用同一套档位知识。
|
|
7
|
+
*
|
|
8
|
+
* 本模块只负责「**利用**这张表」:CLI 用它限制 `/think` 的可选档位、把选中的档位展开成
|
|
9
|
+
* 请求参数写进 `AgentDefinition.modelParams`、以及把现有参数反查成档位名做展示。
|
|
10
|
+
*
|
|
11
|
+
* 全部是纯函数、不碰文件——SDK 不替我们决定这些,客户端自己掌握「怎么用表」。
|
|
12
|
+
*/
|
|
13
|
+
import type { ReasoningPreset, ReasoningPresets } from "@ai-zen/agents-sdk";
|
|
14
|
+
export type { ReasoningPatch, ReasoningPreset, ReasoningPresets } from "@ai-zen/agents-sdk";
|
|
15
|
+
/** 模型关联的策略(未声明 `reasoningPreset` 或名字不存在 → `undefined`) */
|
|
16
|
+
export declare function presetFor(modelId: string | undefined, presetName: string | undefined, presets: ReasoningPresets): ReasoningPreset | undefined;
|
|
17
|
+
/** 某策略的全部档位(= `levels` 的键,顺序即声明顺序) */
|
|
18
|
+
export declare function levelsOf(preset: ReasoningPreset | undefined): string[];
|
|
19
|
+
/** 某策略某档的参数补丁 */
|
|
20
|
+
export declare function patchOf(preset: ReasoningPreset | undefined, level: string): Record<string, unknown> | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* 整张表出现过的参数键。
|
|
23
|
+
*
|
|
24
|
+
* 换档时按此剔除旧值 —— 这样 `max` → `off` 不会残留上一个档位的 `reasoning_effort`,
|
|
25
|
+
* 而「哪些键属于思考」由表自己声明,代码零硬编码。「表里没有的键」一律当普通参数保留。
|
|
26
|
+
*/
|
|
27
|
+
export declare function ownedKeys(presets: ReasoningPresets): Set<string>;
|
|
28
|
+
/**
|
|
29
|
+
* 反查:现有参数命中哪个档位(多张补丁同时命中取最具体的)。
|
|
30
|
+
*
|
|
31
|
+
* 纯展示用途 —— 状态栏要显示「当前是第几档」。命中不了返回 `undefined`。
|
|
32
|
+
*/
|
|
33
|
+
export declare function matchLevel(preset: ReasoningPreset | undefined, params: Record<string, unknown> | undefined | null): string | undefined;
|
|
34
|
+
//# sourceMappingURL=reasoning-presets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reasoning-presets.d.ts","sourceRoot":"","sources":["../src/reasoning-presets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE5E,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAQ5F,0DAA0D;AAC1D,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,gBAAgB,GACxB,eAAe,GAAG,SAAS,CAG7B;AAED,sCAAsC;AACtC,wBAAgB,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,EAAE,CAEtE;AAED,iBAAiB;AACjB,wBAAgB,OAAO,CACrB,MAAM,EAAE,eAAe,GAAG,SAAS,EACnC,KAAK,EAAE,MAAM,GACZ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAErC;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,GAAG,CAAC,MAAM,CAAC,CAQhE;AAgBD;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,eAAe,GAAG,SAAS,EACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,GACjD,MAAM,GAAG,SAAS,CAYpB"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 思考预设 —— CLI 侧的表操作(纯函数)
|
|
3
|
+
*
|
|
4
|
+
* 表的**定义、出厂内容、读写**都在 SDK(`@ai-zen/agents-sdk` 的 `ReasoningPresets` /
|
|
5
|
+
* `FACTORY_REASONING_PRESETS` / `ConfigManager.readReasoningPresets()`),因为桌面端等
|
|
6
|
+
* 其它客户端也要用同一套档位知识。
|
|
7
|
+
*
|
|
8
|
+
* 本模块只负责「**利用**这张表」:CLI 用它限制 `/think` 的可选档位、把选中的档位展开成
|
|
9
|
+
* 请求参数写进 `AgentDefinition.modelParams`、以及把现有参数反查成档位名做展示。
|
|
10
|
+
*
|
|
11
|
+
* 全部是纯函数、不碰文件——SDK 不替我们决定这些,客户端自己掌握「怎么用表」。
|
|
12
|
+
*/
|
|
13
|
+
/** 安全取自有属性(策略名来自用户配置,可能是 `constructor` / `__proto__`) */
|
|
14
|
+
function own(bag, key) {
|
|
15
|
+
if (!bag || !Object.prototype.hasOwnProperty.call(bag, key))
|
|
16
|
+
return undefined;
|
|
17
|
+
return bag[key];
|
|
18
|
+
}
|
|
19
|
+
/** 模型关联的策略(未声明 `reasoningPreset` 或名字不存在 → `undefined`) */
|
|
20
|
+
export function presetFor(modelId, presetName, presets) {
|
|
21
|
+
if (!modelId || !presetName)
|
|
22
|
+
return undefined;
|
|
23
|
+
return own(presets, presetName);
|
|
24
|
+
}
|
|
25
|
+
/** 某策略的全部档位(= `levels` 的键,顺序即声明顺序) */
|
|
26
|
+
export function levelsOf(preset) {
|
|
27
|
+
return preset ? Object.keys(preset.levels ?? {}) : [];
|
|
28
|
+
}
|
|
29
|
+
/** 某策略某档的参数补丁 */
|
|
30
|
+
export function patchOf(preset, level) {
|
|
31
|
+
return own(preset?.levels, level);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 整张表出现过的参数键。
|
|
35
|
+
*
|
|
36
|
+
* 换档时按此剔除旧值 —— 这样 `max` → `off` 不会残留上一个档位的 `reasoning_effort`,
|
|
37
|
+
* 而「哪些键属于思考」由表自己声明,代码零硬编码。「表里没有的键」一律当普通参数保留。
|
|
38
|
+
*/
|
|
39
|
+
export function ownedKeys(presets) {
|
|
40
|
+
const keys = new Set();
|
|
41
|
+
for (const preset of Object.values(presets ?? {})) {
|
|
42
|
+
for (const patch of Object.values(preset?.levels ?? {})) {
|
|
43
|
+
for (const key of Object.keys(patch ?? {}))
|
|
44
|
+
keys.add(key);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return keys;
|
|
48
|
+
}
|
|
49
|
+
/** 结构化相等 —— 补丁是纯 JSON,逐层比对即可 */
|
|
50
|
+
function sameValue(a, b) {
|
|
51
|
+
if (a === b)
|
|
52
|
+
return true;
|
|
53
|
+
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null)
|
|
54
|
+
return false;
|
|
55
|
+
if (Array.isArray(a) !== Array.isArray(b))
|
|
56
|
+
return false;
|
|
57
|
+
const left = a;
|
|
58
|
+
const right = b;
|
|
59
|
+
const leftKeys = Object.keys(left);
|
|
60
|
+
if (leftKeys.length !== Object.keys(right).length)
|
|
61
|
+
return false;
|
|
62
|
+
return leftKeys.every((k) => Object.prototype.hasOwnProperty.call(right, k) && sameValue(left[k], right[k]));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 反查:现有参数命中哪个档位(多张补丁同时命中取最具体的)。
|
|
66
|
+
*
|
|
67
|
+
* 纯展示用途 —— 状态栏要显示「当前是第几档」。命中不了返回 `undefined`。
|
|
68
|
+
*/
|
|
69
|
+
export function matchLevel(preset, params) {
|
|
70
|
+
if (!preset || !params)
|
|
71
|
+
return undefined;
|
|
72
|
+
let best;
|
|
73
|
+
let bestSize = 0;
|
|
74
|
+
for (const [level, patch] of Object.entries(preset.levels ?? {})) {
|
|
75
|
+
const keys = Object.keys(patch ?? {});
|
|
76
|
+
if (keys.length === 0 || keys.length <= bestSize)
|
|
77
|
+
continue;
|
|
78
|
+
if (!keys.every((k) => sameValue(params[k], patch[k])))
|
|
79
|
+
continue;
|
|
80
|
+
best = level;
|
|
81
|
+
bestSize = keys.length;
|
|
82
|
+
}
|
|
83
|
+
return best;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=reasoning-presets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reasoning-presets.js","sourceRoot":"","sources":["../src/reasoning-presets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK 全局日志接管 —— 关掉库自带的 `console` 兜底。
|
|
3
|
+
*
|
|
4
|
+
* 背景:SDK 的 `getLogger()` 默认实现是 `console.log / console.warn / console.error`
|
|
5
|
+
* (`@ai-zen/agents-sdk` 的 `shared/logger.ts`)。对通用库来说这是合理兜底,对 Ink TUI
|
|
6
|
+
* 却是灾难 —— `console.log` 直接写 stdout,会穿到 Ink 的渲染区外面把界面撕成乱码。
|
|
7
|
+
* 例如 `load_mcp` 有一行 `log.info(JSON.stringify(manifest, null, 2))`,未接管时整份
|
|
8
|
+
* tools / resources 清单会砸在界面上。
|
|
9
|
+
*
|
|
10
|
+
* 所以 TUI 启动第一件事就是接管:
|
|
11
|
+
* - 默认**全部丢弃**(界面上不该出现库的内部日志,用户也读不懂);
|
|
12
|
+
* - 需要排查时用 `AIZ_DEBUG_SDK=1` 落盘,既不污染渲染也不丢信息。
|
|
13
|
+
*
|
|
14
|
+
* 用法:
|
|
15
|
+
* aiz → SDK 日志静默
|
|
16
|
+
* AIZ_DEBUG_SDK=1 aiz → 追加写到 <tmp>/aiz-sdk.log
|
|
17
|
+
* AIZ_DEBUG_SDK=1 AIZ_SDK_LOG_FILE=/path aiz → 写到指定文件
|
|
18
|
+
*
|
|
19
|
+
* 与 `key-debug.ts` 同一套约定(环境变量开关 + tmp 下日志文件),免得排查时记两套。
|
|
20
|
+
*
|
|
21
|
+
* 注意 stdio 模式不需要本模块:`stdio-runner.ts` 已把日志改道 stderr —— 那里 stdout
|
|
22
|
+
* 只留给结果,日志本身是有用的。本模块只服务「界面被占用」的 TUI。
|
|
23
|
+
*/
|
|
24
|
+
import { type Logger } from "@ai-zen/agents-sdk";
|
|
25
|
+
/** 是否把 SDK 日志落盘(默认关闭) */
|
|
26
|
+
export declare const SDK_LOG_ENABLED: boolean;
|
|
27
|
+
/** 日志落盘路径(测试与用户都可能改写,故导出常量) */
|
|
28
|
+
export declare const SDK_LOG_FILE: string;
|
|
29
|
+
/** 单行日志格式:`<ISO 时间> [level] message` */
|
|
30
|
+
export declare function formatSdkLogLine(level: keyof Logger, message: string, at?: Date): string;
|
|
31
|
+
/**
|
|
32
|
+
* 落盘版日志器。
|
|
33
|
+
*
|
|
34
|
+
* 写失败要吞掉:日志是旁路能力,磁盘满 / 权限不足时绝不能把 TUI 拖垮。
|
|
35
|
+
*/
|
|
36
|
+
export declare function createFileLogger(file: string): Logger;
|
|
37
|
+
/** 全静默日志器(TUI 默认) */
|
|
38
|
+
export declare function createSilentLogger(): Logger;
|
|
39
|
+
/**
|
|
40
|
+
* 接管 SDK 全局日志:默认静默,`AIZ_DEBUG_SDK=1` 时改为落盘。
|
|
41
|
+
*
|
|
42
|
+
* 返回实际安装的日志器,便于测试断言 / 上层复用。
|
|
43
|
+
*/
|
|
44
|
+
export declare function installSdkLogger(options?: {
|
|
45
|
+
enabled?: boolean;
|
|
46
|
+
file?: string;
|
|
47
|
+
}): Logger;
|
|
48
|
+
//# sourceMappingURL=sdk-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-log.d.ts","sourceRoot":"","sources":["../src/sdk-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAa,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5D,yBAAyB;AACzB,eAAO,MAAM,eAAe,SAAoC,CAAC;AAEjE,+BAA+B;AAC/B,eAAO,MAAM,YAAY,QAAqD,CAAC;AAE/E,wCAAwC;AACxC,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,EAAE,GAAE,IAAiB,GACpB,MAAM,CAER;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWrD;AAED,qBAAqB;AACrB,wBAAgB,kBAAkB,IAAI,MAAM,CAG3C;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACjD,MAAM,CAMR"}
|
package/dist/sdk-log.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK 全局日志接管 —— 关掉库自带的 `console` 兜底。
|
|
3
|
+
*
|
|
4
|
+
* 背景:SDK 的 `getLogger()` 默认实现是 `console.log / console.warn / console.error`
|
|
5
|
+
* (`@ai-zen/agents-sdk` 的 `shared/logger.ts`)。对通用库来说这是合理兜底,对 Ink TUI
|
|
6
|
+
* 却是灾难 —— `console.log` 直接写 stdout,会穿到 Ink 的渲染区外面把界面撕成乱码。
|
|
7
|
+
* 例如 `load_mcp` 有一行 `log.info(JSON.stringify(manifest, null, 2))`,未接管时整份
|
|
8
|
+
* tools / resources 清单会砸在界面上。
|
|
9
|
+
*
|
|
10
|
+
* 所以 TUI 启动第一件事就是接管:
|
|
11
|
+
* - 默认**全部丢弃**(界面上不该出现库的内部日志,用户也读不懂);
|
|
12
|
+
* - 需要排查时用 `AIZ_DEBUG_SDK=1` 落盘,既不污染渲染也不丢信息。
|
|
13
|
+
*
|
|
14
|
+
* 用法:
|
|
15
|
+
* aiz → SDK 日志静默
|
|
16
|
+
* AIZ_DEBUG_SDK=1 aiz → 追加写到 <tmp>/aiz-sdk.log
|
|
17
|
+
* AIZ_DEBUG_SDK=1 AIZ_SDK_LOG_FILE=/path aiz → 写到指定文件
|
|
18
|
+
*
|
|
19
|
+
* 与 `key-debug.ts` 同一套约定(环境变量开关 + tmp 下日志文件),免得排查时记两套。
|
|
20
|
+
*
|
|
21
|
+
* 注意 stdio 模式不需要本模块:`stdio-runner.ts` 已把日志改道 stderr —— 那里 stdout
|
|
22
|
+
* 只留给结果,日志本身是有用的。本模块只服务「界面被占用」的 TUI。
|
|
23
|
+
*/
|
|
24
|
+
import { appendFileSync } from "node:fs";
|
|
25
|
+
import { setLogger } from "@ai-zen/agents-sdk";
|
|
26
|
+
/** 是否把 SDK 日志落盘(默认关闭) */
|
|
27
|
+
export const SDK_LOG_ENABLED = process.env.AIZ_DEBUG_SDK === "1";
|
|
28
|
+
/** 日志落盘路径(测试与用户都可能改写,故导出常量) */
|
|
29
|
+
export const SDK_LOG_FILE = process.env.AIZ_SDK_LOG_FILE || "/tmp/aiz-sdk.log";
|
|
30
|
+
/** 单行日志格式:`<ISO 时间> [level] message` */
|
|
31
|
+
export function formatSdkLogLine(level, message, at = new Date()) {
|
|
32
|
+
return `${at.toISOString()} [${level}] ${message}`;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 落盘版日志器。
|
|
36
|
+
*
|
|
37
|
+
* 写失败要吞掉:日志是旁路能力,磁盘满 / 权限不足时绝不能把 TUI 拖垮。
|
|
38
|
+
*/
|
|
39
|
+
export function createFileLogger(file) {
|
|
40
|
+
const write = (level) => (message) => {
|
|
41
|
+
try {
|
|
42
|
+
appendFileSync(file, `${formatSdkLogLine(level, message)}\n`);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
/* 诊断失败绝不能影响主流程 */
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
return { info: write("info"), warn: write("warn"), error: write("error") };
|
|
49
|
+
}
|
|
50
|
+
/** 全静默日志器(TUI 默认) */
|
|
51
|
+
export function createSilentLogger() {
|
|
52
|
+
const noop = () => { };
|
|
53
|
+
return { info: noop, warn: noop, error: noop };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 接管 SDK 全局日志:默认静默,`AIZ_DEBUG_SDK=1` 时改为落盘。
|
|
57
|
+
*
|
|
58
|
+
* 返回实际安装的日志器,便于测试断言 / 上层复用。
|
|
59
|
+
*/
|
|
60
|
+
export function installSdkLogger(options = {}) {
|
|
61
|
+
const enabled = options.enabled ?? SDK_LOG_ENABLED;
|
|
62
|
+
const file = options.file ?? SDK_LOG_FILE;
|
|
63
|
+
const logger = enabled ? createFileLogger(file) : createSilentLogger();
|
|
64
|
+
setLogger(logger);
|
|
65
|
+
return logger;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=sdk-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-log.js","sourceRoot":"","sources":["../src/sdk-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,SAAS,EAAe,MAAM,oBAAoB,CAAC;AAE5D,yBAAyB;AACzB,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,GAAG,CAAC;AAEjE,+BAA+B;AAC/B,MAAM,CAAC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,kBAAkB,CAAC;AAE/E,wCAAwC;AACxC,MAAM,UAAU,gBAAgB,CAC9B,KAAmB,EACnB,OAAe,EACf,KAAW,IAAI,IAAI,EAAE;IAErB,OAAO,GAAG,EAAE,CAAC,WAAW,EAAE,KAAK,KAAK,KAAK,OAAO,EAAE,CAAC;AACrD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,KAAK,GACT,CAAC,KAAmB,EAAE,EAAE,CACxB,CAAC,OAAe,EAAQ,EAAE;QACxB,IAAI,CAAC;YACH,cAAc,CAAC,IAAI,EAAE,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAChE,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;IACH,CAAC,CAAC;IACJ,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;AAC7E,CAAC;AAED,qBAAqB;AACrB,MAAM,UAAU,kBAAkB;IAChC,MAAM,IAAI,GAAG,GAAS,EAAE,GAAE,CAAC,CAAC;IAC5B,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,UAAgD,EAAE;IAElD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,eAAe,CAAC;IACnD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,YAAY,CAAC;IAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC;IACvE,SAAS,CAAC,MAAM,CAAC,CAAC;IAClB,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1,22 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI 会话指针 —
|
|
2
|
+
* CLI 会话指针 — 按「工作目录(cwd)」记录各自的「上一轮会话 id」。
|
|
3
3
|
*
|
|
4
4
|
* 取代原草稿机制:不再维护单独的单文件草稿(`drafts/_current.json`),
|
|
5
5
|
* 而是让每个会话直接落盘为 `conversations/<id>.json`,再用本指针记住
|
|
6
|
-
*
|
|
6
|
+
* 「每个目录最近活动的会话 id」,供下次在该目录启动时自动续接。
|
|
7
7
|
*
|
|
8
|
-
* 存储位置:`$AI_ZEN_DIR/cli/last-session.json
|
|
8
|
+
* 存储位置:`$AI_ZEN_DIR/cli/last-session.json`,结构为 cwd → 续接记录的 map:
|
|
9
|
+
*
|
|
10
|
+
* {
|
|
11
|
+
* "version": 1,
|
|
12
|
+
* "sessions": {
|
|
13
|
+
* "/abs/path/to/proj-a": { "id": "对话_...", "updatedAt": "..." },
|
|
14
|
+
* "/abs/path/to/proj-b": { "id": "对话_...", "updatedAt": "..." }
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* 以 `process.cwd()` 的**精确字符串**为键:不同目录各记各的,互不干扰。
|
|
19
|
+
* 旧版单指针文件(顶层 `{ id, updatedAt }`)无法归属到具体目录,一律视为
|
|
20
|
+
* 「无记录」——宁可丢一次续接,也不把别的目录的历史错认到当前目录。
|
|
9
21
|
*/
|
|
22
|
+
/** 单个工作目录的续接记录 */
|
|
10
23
|
export interface SessionPointer {
|
|
11
24
|
/** 上一轮(最近活动)会话 id */
|
|
12
25
|
id: string;
|
|
13
26
|
/** 最后活动时间(ISO 字符串) */
|
|
14
27
|
updatedAt: string;
|
|
15
28
|
}
|
|
16
|
-
/**
|
|
17
|
-
export declare function readLastSession(): Promise<SessionPointer | null>;
|
|
18
|
-
/**
|
|
19
|
-
export declare function writeLastSession(id: string): Promise<void>;
|
|
20
|
-
/**
|
|
21
|
-
export declare function clearLastSession(): Promise<void>;
|
|
29
|
+
/** 读取指定工作目录的「上一轮会话 id」;无记录时返回 null */
|
|
30
|
+
export declare function readLastSession(cwd: string): Promise<SessionPointer | null>;
|
|
31
|
+
/** 更新指定工作目录的「上一轮会话 id」(保留其它目录的记录,原子写) */
|
|
32
|
+
export declare function writeLastSession(cwd: string, id: string): Promise<void>;
|
|
33
|
+
/** 清除指定工作目录的指针(会话被删除等场景使用) */
|
|
34
|
+
export declare function clearLastSession(cwd: string): Promise<void>;
|
|
22
35
|
//# sourceMappingURL=session-pointer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-pointer.d.ts","sourceRoot":"","sources":["../src/session-pointer.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"session-pointer.d.ts","sourceRoot":"","sources":["../src/session-pointer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AASH,kBAAkB;AAClB,MAAM,WAAW,cAAc;IAC7B,qBAAqB;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AA2CD,sCAAsC;AACtC,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAGjF;AAED,yCAAyC;AACzC,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7E;AAED,8BAA8B;AAC9B,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKjE"}
|