@ai-zen/cli 1.0.0-alpha.3 → 1.0.0-alpha.5
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 +31 -0
- package/README.md +2 -2
- package/README.zh.md +2 -2
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/tui/chat-session.d.ts +39 -46
- package/dist/tui/chat-session.d.ts.map +1 -1
- package/dist/tui/chat-session.js +71 -66
- package/dist/tui/chat-session.js.map +1 -1
- package/dist/tui/components.d.ts +5 -2
- package/dist/tui/components.d.ts.map +1 -1
- package/dist/tui/components.js +2 -2
- package/dist/tui/components.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 +4 -4
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/screens/chat-commands.d.ts +4 -2
- package/dist/tui/screens/chat-commands.d.ts.map +1 -1
- package/dist/tui/screens/chat-commands.js +5 -8
- package/dist/tui/screens/chat-commands.js.map +1 -1
- package/dist/tui/screens/chat.d.ts +0 -4
- package/dist/tui/screens/chat.d.ts.map +1 -1
- package/dist/tui/screens/chat.js +84 -63
- 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/index.d.ts +6 -6
- package/dist/tui/screens/index.d.ts.map +1 -1
- package/dist/tui/screens/index.js +5 -5
- package/dist/tui/screens/index.js.map +1 -1
- package/dist/tui/screens/layout.d.ts +5 -3
- package/dist/tui/screens/layout.d.ts.map +1 -1
- package/dist/tui/screens/layout.js +3 -8
- package/dist/tui/screens/layout.js.map +1 -1
- package/dist/tui/screens/lines.d.ts +2 -39
- package/dist/tui/screens/lines.d.ts.map +1 -1
- package/dist/tui/screens/lines.js +2 -65
- 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 +2 -40
- package/dist/tui/screens/render.js.map +1 -1
- package/dist/tui/text.d.ts +5 -0
- package/dist/tui/text.d.ts.map +1 -1
- package/dist/tui/text.js +7 -0
- package/dist/tui/text.js.map +1 -1
- package/dist/usage.d.ts +20 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +40 -0
- package/dist/usage.js.map +1 -0
- package/package.json +3 -3
- package/dist/tui/screens/state.d.ts +0 -30
- package/dist/tui/screens/state.d.ts.map +0 -1
- package/dist/tui/screens/state.js +0 -100
- package/dist/tui/screens/state.js.map +0 -1
package/dist/tui/index.js
CHANGED
|
@@ -62,6 +62,9 @@ let activeInstance = null;
|
|
|
62
62
|
export const RENDER_OPTIONS = {
|
|
63
63
|
exitOnCtrlC: false,
|
|
64
64
|
alternateScreen: false,
|
|
65
|
+
// 只重绘「变化的行」,而不是每帧擦除 + 重写整屏(Ink 默认 false,走 createStandard)。
|
|
66
|
+
// 流式高频下把每帧输出量从 O(屏幕大小) 降到 O(变化量),显著减轻 SSH 带宽 / 背压压力。
|
|
67
|
+
incrementalRendering: true,
|
|
65
68
|
kittyKeyboard: { mode: "disabled" },
|
|
66
69
|
};
|
|
67
70
|
function mount(node) {
|
|
@@ -153,9 +156,8 @@ async function runChat(target) {
|
|
|
153
156
|
let current = target;
|
|
154
157
|
let messages = target.messages;
|
|
155
158
|
let initialInput;
|
|
156
|
-
let clearTranscript = false;
|
|
157
159
|
while (true) {
|
|
158
|
-
const result = await mount(_jsx(Chat, { modelId: current.modelId, agentId: current.agentId, messages: messages, conversationId: current.conversationId, conversationName: current.conversationName, initialInput: initialInput
|
|
160
|
+
const result = await mount(_jsx(Chat, { modelId: current.modelId, agentId: current.agentId, messages: messages, conversationId: current.conversationId, conversationName: current.conversationName, initialInput: initialInput }));
|
|
159
161
|
if (result && typeof result === "object") {
|
|
160
162
|
const value = result;
|
|
161
163
|
if (value.load) {
|
|
@@ -168,13 +170,11 @@ async function runChat(target) {
|
|
|
168
170
|
};
|
|
169
171
|
messages = value.load.messages;
|
|
170
172
|
initialInput = undefined;
|
|
171
|
-
clearTranscript = false;
|
|
172
173
|
continue;
|
|
173
174
|
}
|
|
174
175
|
if (value.restart) {
|
|
175
176
|
messages = value.messages ?? messages;
|
|
176
177
|
initialInput = value.initialInput;
|
|
177
|
-
clearTranscript = Boolean(value.clearTranscript);
|
|
178
178
|
continue;
|
|
179
179
|
}
|
|
180
180
|
}
|
package/dist/tui/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tui/index.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tui/index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -2,10 +2,12 @@ import { Dispatch, SetStateAction } from "react";
|
|
|
2
2
|
import { SelectItem } from "../components.js";
|
|
3
3
|
import { ChatSession } from "../chat-session.js";
|
|
4
4
|
import { WizardStep } from "../config-wizard/index.js";
|
|
5
|
-
import { ChatAction } from "./state.js";
|
|
6
5
|
export interface ChatCommandHost {
|
|
7
6
|
session: ChatSession;
|
|
8
|
-
|
|
7
|
+
/** 通知通道:命令反馈(保存 / 清除 / 迁移结果 …)走独立栏位,不进 messages */
|
|
8
|
+
notice: (text: string, tone?: "info" | "error") => void;
|
|
9
|
+
/** 清屏(保留上下文):把转录显示起点推到最新 */
|
|
10
|
+
clearTranscript: () => void;
|
|
9
11
|
rows: number;
|
|
10
12
|
exit: (arg?: any) => void;
|
|
11
13
|
suspendTerminal: (fn: () => void | Promise<void>) => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-commands.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/chat-commands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAMjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAgB,MAAM,oBAAoB,CAAC;AAI/D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"chat-commands.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/chat-commands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAMjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAgB,MAAM,oBAAoB,CAAC;AAI/D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAGvD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,WAAW,CAAC;IACrB,mDAAmD;IACnD,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,KAAK,IAAI,CAAC;IACxD,4BAA4B;IAC5B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC1B,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,UAAU,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,cAAc,EAAE,QAAQ,CACtB,cAAc,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC,CAC/G,CAAC;IACF,eAAe,EAAE,QAAQ,CAAC,cAAc,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1G,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAiLhG"}
|
|
@@ -9,12 +9,9 @@ import { conversationRepository, listConversations } from "../../conversation-re
|
|
|
9
9
|
import { formatShortTime } from "../../format-time.js";
|
|
10
10
|
import { truncate } from "./render.js";
|
|
11
11
|
export async function runCommand(name, raw, host) {
|
|
12
|
-
const { session,
|
|
12
|
+
const { session, notice, clearTranscript, rows, exit, suspendTerminal, openWizard, openKeyEditor, doExit, setPickerState, setConfirmState, setInputText, } = host;
|
|
13
13
|
const push = (text, tone = "info") => {
|
|
14
|
-
|
|
15
|
-
dispatch({ type: "error", text });
|
|
16
|
-
else
|
|
17
|
-
dispatch({ type: "notice", text });
|
|
14
|
+
notice(text, tone);
|
|
18
15
|
};
|
|
19
16
|
switch (name) {
|
|
20
17
|
case "config":
|
|
@@ -32,13 +29,13 @@ export async function runCommand(name, raw, host) {
|
|
|
32
29
|
break;
|
|
33
30
|
}
|
|
34
31
|
case "clear":
|
|
35
|
-
//
|
|
36
|
-
|
|
32
|
+
// 清屏但保留上下文:仅把转录显示起点推到最新
|
|
33
|
+
clearTranscript();
|
|
37
34
|
break;
|
|
38
35
|
case "new": {
|
|
39
36
|
// reset 会先归档当前对话(有内容才存),返回存档 id(无内容为 null)
|
|
40
37
|
const archivedId = await session.reset();
|
|
41
|
-
|
|
38
|
+
clearTranscript();
|
|
42
39
|
push(archivedId ? `旧对话已存档:${archivedId}\n已开始新对话` : "已开始新对话");
|
|
43
40
|
break;
|
|
44
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-commands.js","sourceRoot":"","sources":["../../../src/tui/screens/chat-commands.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAe,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC7F,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"chat-commands.js","sourceRoot":"","sources":["../../../src/tui/screens/chat-commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,8 +8,6 @@ export interface ChatScreenProps {
|
|
|
8
8
|
conversationName?: string;
|
|
9
9
|
/** 重挂载时的初始输入(/back 撤回后用于预填) */
|
|
10
10
|
initialInput?: string;
|
|
11
|
-
/** 重挂载时是否清空记录显示(/clear:清屏但保留上下文) */
|
|
12
|
-
clearTranscript?: boolean;
|
|
13
11
|
}
|
|
14
12
|
/**
|
|
15
13
|
* 计算回车时应提交的文本。
|
|
@@ -17,8 +15,6 @@ export interface ChatScreenProps {
|
|
|
17
15
|
* 斜杠候选菜单可见时(输入以 `/` 开头且尚未输入参数),回车应**直接执行高亮命令**,
|
|
18
16
|
* 而不是提交半截输入 —— 否则用户只输入 `/` 或未补全的命令名时,回车会落到
|
|
19
17
|
* 「未知命令」报错(体验很差)。非命令输入原样返回。
|
|
20
|
-
*
|
|
21
|
-
* `menuIndex` 越界时回落到最后一项,避免菜单看似有选中却回车落空。
|
|
22
18
|
*/
|
|
23
19
|
export declare function resolveSubmitText(input: string, hints: CommandHint[], menuIndex: number): string;
|
|
24
20
|
export declare function Chat(props: ChatScreenProps): import("react").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/chat.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAM9C,OAAO,EAAE,WAAW,EAAqB,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/chat.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAM9C,OAAO,EAAE,WAAW,EAAqB,MAAM,yCAAyC,CAAC;AAgBzF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAMhG;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,eAAe,+BA2lB1C"}
|
package/dist/tui/screens/chat.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
//
|
|
3
|
-
import { useEffect,
|
|
2
|
+
// 对话屏幕 —— 以 SDK 的 `agent.messages` 为唯一数据源渲染(无自定义中间模型)
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
4
|
import { Box, Text, useApp, useCursor, useInput, useWindowSize } from "ink";
|
|
5
|
+
import { AgentNS } from "@ai-zen/agents-core";
|
|
5
6
|
import { theme } from "../theme.js";
|
|
6
7
|
import { Spinner, StatusBar, SlashMenu } from "../components.js";
|
|
7
8
|
import { layoutInput, usableFrameRows, isTerminalReply } from "../text.js";
|
|
@@ -13,18 +14,18 @@ import { resolveCredential } from "../../config-editor.js";
|
|
|
13
14
|
import { ConfigWizard } from "../config-wizard/index.js";
|
|
14
15
|
import { computeInputCursorPosition, wordLeft, wordRight } from "./input.js";
|
|
15
16
|
import { computeChatLayout } from "./layout.js";
|
|
16
|
-
import {
|
|
17
|
-
import { LineView
|
|
17
|
+
import { FrameBuffer } from "./frame-buffer.js";
|
|
18
|
+
import { LineView } from "./render.js";
|
|
19
|
+
import { messageToLines, transcriptLines } from "./messages-view.js";
|
|
18
20
|
import { PickerOverlay, Confirm } from "./overlays.js";
|
|
19
21
|
import { runCommand } from "./chat-commands.js";
|
|
22
|
+
import { NoticeChannel, noticeLines } from "./notice.js";
|
|
20
23
|
/**
|
|
21
24
|
* 计算回车时应提交的文本。
|
|
22
25
|
*
|
|
23
26
|
* 斜杠候选菜单可见时(输入以 `/` 开头且尚未输入参数),回车应**直接执行高亮命令**,
|
|
24
27
|
* 而不是提交半截输入 —— 否则用户只输入 `/` 或未补全的命令名时,回车会落到
|
|
25
28
|
* 「未知命令」报错(体验很差)。非命令输入原样返回。
|
|
26
|
-
*
|
|
27
|
-
* `menuIndex` 越界时回落到最后一项,避免菜单看似有选中却回车落空。
|
|
28
29
|
*/
|
|
29
30
|
export function resolveSubmitText(input, hints, menuIndex) {
|
|
30
31
|
const slash = input.startsWith("/") && !input.includes("\n") && !input.includes(" ");
|
|
@@ -38,16 +39,10 @@ export function Chat(props) {
|
|
|
38
39
|
const { exit, suspendTerminal } = useApp();
|
|
39
40
|
const { setCursorPosition } = useCursor();
|
|
40
41
|
const { columns, rows } = useWindowSize();
|
|
41
|
-
const [state, dispatch] = useReducer(chatReducer, {
|
|
42
|
-
// 载入 / 恢复会话时也封顶:避免把落盘的超大会话整段读进内存
|
|
43
|
-
blocks: trimTranscript(props.clearTranscript ? [] : messagesToBlocks(props.messages ?? [])),
|
|
44
|
-
live: null,
|
|
45
|
-
});
|
|
46
42
|
const [input, setInput] = useState(props.initialInput ?? "");
|
|
47
43
|
/** 光标位置:以 code point 计的字符索引(0..len) */
|
|
48
44
|
const [cursor, setCursor] = useState(Array.from(props.initialInput ?? "").length);
|
|
49
45
|
const [menuIndex, setMenuIndex] = useState(0);
|
|
50
|
-
// 输入变化后候选集随之改变:高亮重置回首项,避免索引越界(看似选中实为无高亮 / 回车落空)
|
|
51
46
|
useEffect(() => {
|
|
52
47
|
setMenuIndex(0);
|
|
53
48
|
}, [input]);
|
|
@@ -56,13 +51,9 @@ export function Chat(props) {
|
|
|
56
51
|
/** 配置向导:非 null 时整屏接管(凭据设置 / 配置中心) */
|
|
57
52
|
const [wizardStep, setWizardStep] = useState(null);
|
|
58
53
|
const [wizardConfig, setWizardConfig] = useState(null);
|
|
59
|
-
/** 可用 Agent 列表(供配置中心「默认 Agent」选择) */
|
|
60
54
|
const [wizardAgents, setWizardAgents] = useState([]);
|
|
61
|
-
/** MCP 配置快照(全局 + 项目),打开向导时刷新 */
|
|
62
55
|
const [wizardMcp, setWizardMcp] = useState(null);
|
|
63
|
-
/** Agent / Sub-agent 定义仓储(快照 + 读写),打开向导时刷新 */
|
|
64
56
|
const [wizardAgentStore, setWizardAgentStore] = useState(null);
|
|
65
|
-
/** 当前会话所用端点 id(打开向导时刷新,用于判断改动是否影响本会话) */
|
|
66
57
|
const currentEndpointRef = useRef(null);
|
|
67
58
|
const [history, setHistory] = useState([]);
|
|
68
59
|
const historyIndex = useRef(-1);
|
|
@@ -73,10 +64,44 @@ export function Chat(props) {
|
|
|
73
64
|
const [viewTop, setViewTop] = useState(null);
|
|
74
65
|
/** 最近一次布局,供键盘回调读取总行数 / 视口高度(应用内翻页) */
|
|
75
66
|
const layoutRef = useRef(null);
|
|
76
|
-
|
|
67
|
+
/** 本轮是否在生成中(spinner / 输入禁用) */
|
|
68
|
+
const [busy, setBusy] = useState(false);
|
|
69
|
+
/** 乐观回显:提交后、真实 user 消息落进 messages 之前,先显示用户提问 */
|
|
70
|
+
const [pendingUser, setPendingUser] = useState(null);
|
|
71
|
+
/** 转录显示起点(/clear 清屏用:隐藏此索引之前的消息,但不改上下文) */
|
|
72
|
+
const [transcriptFrom, setTranscriptFrom] = useState(0);
|
|
73
|
+
/**
|
|
74
|
+
* 通知通道:notice / error 走独立栏位,绝不进对话转录(messages)。
|
|
75
|
+
*/
|
|
76
|
+
const noticeChannelRef = useRef(null);
|
|
77
|
+
if (noticeChannelRef.current == null)
|
|
78
|
+
noticeChannelRef.current = new NoticeChannel();
|
|
79
|
+
const noticeChannel = noticeChannelRef.current;
|
|
80
|
+
const [notice, setNotice] = useState(null);
|
|
81
|
+
useEffect(() => noticeChannel.subscribe(setNotice), [noticeChannel]);
|
|
82
|
+
/**
|
|
83
|
+
* 渲染信号 + 合帧:SDK 内容变更 → FrameBuffer 合帧 → setTick 触发重渲染。
|
|
84
|
+
* 转录内容始终从 `agent.messages` 现取,tick 只负责「告诉 React 该重画了」。
|
|
85
|
+
*/
|
|
86
|
+
const [, setTick] = useState(0);
|
|
87
|
+
const frameBufferRef = useRef(null);
|
|
88
|
+
if (frameBufferRef.current == null) {
|
|
89
|
+
frameBufferRef.current = new FrameBuffer(() => setTick((t) => t + 1));
|
|
90
|
+
}
|
|
77
91
|
// 创建会话
|
|
78
92
|
useEffect(() => {
|
|
79
93
|
let disposed = false;
|
|
94
|
+
const notifier = {
|
|
95
|
+
onChange: (immediate) => {
|
|
96
|
+
if (disposed)
|
|
97
|
+
return;
|
|
98
|
+
frameBufferRef.current?.push(null, immediate);
|
|
99
|
+
},
|
|
100
|
+
onNotice: (text, tone) => {
|
|
101
|
+
if (!disposed)
|
|
102
|
+
noticeChannel.push(text, tone);
|
|
103
|
+
},
|
|
104
|
+
};
|
|
80
105
|
ChatSession.create({
|
|
81
106
|
modelId: props.modelId,
|
|
82
107
|
agentId: props.agentId,
|
|
@@ -84,10 +109,7 @@ export function Chat(props) {
|
|
|
84
109
|
conversationId: props.conversationId,
|
|
85
110
|
conversationName: props.conversationName,
|
|
86
111
|
requestConfirm: (question) => new Promise((resolve) => setConfirmState({ question, resolve })),
|
|
87
|
-
},
|
|
88
|
-
if (!disposed)
|
|
89
|
-
dispatch(event);
|
|
90
|
-
})
|
|
112
|
+
}, notifier)
|
|
91
113
|
.then((session) => {
|
|
92
114
|
if (disposed) {
|
|
93
115
|
session.dispose();
|
|
@@ -95,10 +117,12 @@ export function Chat(props) {
|
|
|
95
117
|
}
|
|
96
118
|
sessionRef.current = session;
|
|
97
119
|
setReady(true);
|
|
120
|
+
setTick((t) => t + 1);
|
|
98
121
|
})
|
|
99
122
|
.catch((error) => setBootError(error?.message ?? String(error)));
|
|
100
123
|
return () => {
|
|
101
124
|
disposed = true;
|
|
125
|
+
frameBufferRef.current?.dispose();
|
|
102
126
|
sessionRef.current?.dispose();
|
|
103
127
|
};
|
|
104
128
|
}, [
|
|
@@ -121,7 +145,6 @@ export function Chat(props) {
|
|
|
121
145
|
});
|
|
122
146
|
};
|
|
123
147
|
// ---- 配置向导(凭据 / 配置中心)----
|
|
124
|
-
/** 打开配置向导:先取配置 / MCP / Agent 快照,再切入指定步骤 */
|
|
125
148
|
const openWizard = async (step) => {
|
|
126
149
|
try {
|
|
127
150
|
const config = await readConfig();
|
|
@@ -134,7 +157,7 @@ export function Chat(props) {
|
|
|
134
157
|
setWizardStep(step);
|
|
135
158
|
}
|
|
136
159
|
catch (error) {
|
|
137
|
-
|
|
160
|
+
noticeChannel.push(`读取配置失败:${error?.message ?? error}`, "error");
|
|
138
161
|
}
|
|
139
162
|
};
|
|
140
163
|
/** `/key`:直达「当前模型所用端点」的 API Key 编辑步骤 */
|
|
@@ -143,10 +166,7 @@ export function Chat(props) {
|
|
|
143
166
|
const config = await readConfig();
|
|
144
167
|
const credential = resolveCredential(config, props.modelId);
|
|
145
168
|
if (!credential) {
|
|
146
|
-
|
|
147
|
-
type: "error",
|
|
148
|
-
text: `模型 ${props.modelId} 未绑定可用端点,请用 /config 检查配置`,
|
|
149
|
-
});
|
|
169
|
+
noticeChannel.push(`模型 ${props.modelId} 未绑定可用端点,请用 /config 检查配置`, "error");
|
|
150
170
|
return;
|
|
151
171
|
}
|
|
152
172
|
currentEndpointRef.current = credential.endpointId;
|
|
@@ -154,7 +174,7 @@ export function Chat(props) {
|
|
|
154
174
|
setWizardStep({ kind: "edit", field: "apiKey", endpointId: credential.endpointId });
|
|
155
175
|
}
|
|
156
176
|
catch (error) {
|
|
157
|
-
|
|
177
|
+
noticeChannel.push(`读取配置失败:${error?.message ?? error}`, "error");
|
|
158
178
|
}
|
|
159
179
|
};
|
|
160
180
|
/** 向导关闭:渲染变更摘要;若改到当前端点则重建会话(消息保留) */
|
|
@@ -164,10 +184,9 @@ export function Chat(props) {
|
|
|
164
184
|
setWizardMcp(null);
|
|
165
185
|
setWizardAgentStore(null);
|
|
166
186
|
for (const line of result.summary)
|
|
167
|
-
|
|
187
|
+
noticeChannel.push(`配置已更新:${line}`);
|
|
168
188
|
if (!result.dirty)
|
|
169
189
|
return;
|
|
170
|
-
// 会话尚未建立(启动失败进入向导):重挂载对话屏重试
|
|
171
190
|
if (!sessionRef.current) {
|
|
172
191
|
exit({ restart: true, messages: props.messages });
|
|
173
192
|
return;
|
|
@@ -176,12 +195,11 @@ export function Chat(props) {
|
|
|
176
195
|
if (endpointChanged || result.mcpChanged || result.agentsChanged) {
|
|
177
196
|
sessionRef.current
|
|
178
197
|
.reload()
|
|
179
|
-
.then(() =>
|
|
180
|
-
.catch((error) =>
|
|
198
|
+
.then(() => noticeChannel.push("已按新配置重建会话(消息与上下文保留)"))
|
|
199
|
+
.catch((error) => noticeChannel.push(`重建会话失败:${error?.message ?? error}`, "error"));
|
|
181
200
|
}
|
|
182
201
|
};
|
|
183
202
|
// ---- 滚动视口控制(应用内翻页,回看历史)----
|
|
184
|
-
/** 跳到指定顶部行;越界钳制;一旦贴到底部则恢复「自动跟随」 */
|
|
185
203
|
const scrollTo = (nextTop) => {
|
|
186
204
|
const L = layoutRef.current;
|
|
187
205
|
if (!L)
|
|
@@ -190,36 +208,35 @@ export function Chat(props) {
|
|
|
190
208
|
const clamped = Math.max(0, Math.min(maxTop, nextTop));
|
|
191
209
|
setViewTop(clamped >= maxTop ? null : clamped);
|
|
192
210
|
};
|
|
193
|
-
/** 翻页滚动(dir:-1 上翻 / +1 下翻) */
|
|
194
211
|
const scrollByPage = (dir) => {
|
|
195
212
|
const L = layoutRef.current;
|
|
196
213
|
if (!L)
|
|
197
214
|
return;
|
|
198
215
|
scrollTo(L.viewTop + dir * Math.max(1, L.budget - 1));
|
|
199
216
|
};
|
|
200
|
-
/** 单行滚动(dir:-1 上 / +1 下) */
|
|
201
217
|
const scrollByLine = (dir) => {
|
|
202
218
|
const L = layoutRef.current;
|
|
203
219
|
if (!L)
|
|
204
220
|
return;
|
|
205
221
|
scrollTo(L.viewTop + dir);
|
|
206
222
|
};
|
|
207
|
-
/** 回到最新(贴底,恢复自动跟随) */
|
|
208
223
|
const scrollToBottom = () => setViewTop(null);
|
|
224
|
+
/** 清屏但保留上下文:把显示起点推到当前消息末尾 */
|
|
225
|
+
const clearTranscript = () => {
|
|
226
|
+
setTranscriptFrom(sessionRef.current?.messages.length ?? 0);
|
|
227
|
+
setNotice(null);
|
|
228
|
+
};
|
|
209
229
|
// ---- 输入编辑(光标感知)----
|
|
210
|
-
/** 替换整个输入并把光标移到末尾 */
|
|
211
230
|
const setInputText = (text) => {
|
|
212
231
|
setInput(text);
|
|
213
232
|
setCursor(Array.from(text).length);
|
|
214
233
|
};
|
|
215
|
-
/** 在光标处插入文本 */
|
|
216
234
|
const insertAtCursor = (text) => {
|
|
217
235
|
const chars = Array.from(input);
|
|
218
236
|
const cp = Math.max(0, Math.min(cursor, chars.length));
|
|
219
237
|
setInput(chars.slice(0, cp).join("") + text + chars.slice(cp).join(""));
|
|
220
238
|
setCursor(cp + Array.from(text).length);
|
|
221
239
|
};
|
|
222
|
-
/** 删除光标前一个字符(Backspace) */
|
|
223
240
|
const deleteBeforeCursor = () => {
|
|
224
241
|
const chars = Array.from(input);
|
|
225
242
|
const cp = Math.max(0, Math.min(cursor, chars.length));
|
|
@@ -228,7 +245,6 @@ export function Chat(props) {
|
|
|
228
245
|
setInput(chars.slice(0, cp - 1).join("") + chars.slice(cp).join(""));
|
|
229
246
|
setCursor(cp - 1);
|
|
230
247
|
};
|
|
231
|
-
/** 删除光标后一个字符(Delete) */
|
|
232
248
|
const deleteAfterCursor = () => {
|
|
233
249
|
const chars = Array.from(input);
|
|
234
250
|
const cp = Math.max(0, Math.min(cursor, chars.length));
|
|
@@ -236,12 +252,10 @@ export function Chat(props) {
|
|
|
236
252
|
return;
|
|
237
253
|
setInput(chars.slice(0, cp).join("") + chars.slice(cp + 1).join(""));
|
|
238
254
|
};
|
|
239
|
-
/** 以字符为单位移动光标 */
|
|
240
255
|
const moveCursor = (delta) => {
|
|
241
256
|
const len = Array.from(input).length;
|
|
242
257
|
setCursor((c) => Math.max(0, Math.min(len, c + delta)));
|
|
243
258
|
};
|
|
244
|
-
/** 光标移到当前逻辑行行首(Home) */
|
|
245
259
|
const moveCursorToLineStart = () => {
|
|
246
260
|
const chars = Array.from(input);
|
|
247
261
|
const cp = Math.max(0, Math.min(cursor, chars.length));
|
|
@@ -250,7 +264,6 @@ export function Chat(props) {
|
|
|
250
264
|
i -= 1;
|
|
251
265
|
setCursor(i);
|
|
252
266
|
};
|
|
253
|
-
/** 光标移到当前逻辑行行尾(End) */
|
|
254
267
|
const moveCursorToLineEnd = () => {
|
|
255
268
|
const chars = Array.from(input);
|
|
256
269
|
const cp = Math.max(0, Math.min(cursor, chars.length));
|
|
@@ -269,11 +282,13 @@ export function Chat(props) {
|
|
|
269
282
|
setInputText("");
|
|
270
283
|
historyIndex.current = -1;
|
|
271
284
|
scrollToBottom();
|
|
285
|
+
setNotice(null);
|
|
272
286
|
if (trimmed.startsWith("/")) {
|
|
273
287
|
const name = trimmed.slice(1).toLowerCase();
|
|
274
288
|
await runCommand(name, trimmed, {
|
|
275
289
|
session: sessionRef.current,
|
|
276
|
-
|
|
290
|
+
notice: (text, tone) => noticeChannel.push(text, tone),
|
|
291
|
+
clearTranscript,
|
|
277
292
|
rows: rows ?? 24,
|
|
278
293
|
exit,
|
|
279
294
|
suspendTerminal,
|
|
@@ -287,15 +302,22 @@ export function Chat(props) {
|
|
|
287
302
|
return;
|
|
288
303
|
}
|
|
289
304
|
setHistory((h) => [...h, trimmed]);
|
|
290
|
-
|
|
305
|
+
const base = sessionRef.current.messages.filter((m) => m.role === AgentNS.Role.User).length;
|
|
306
|
+
setPendingUser({ text: trimmed, base });
|
|
307
|
+
setBusy(true);
|
|
308
|
+
try {
|
|
309
|
+
await sessionRef.current.send(trimmed);
|
|
310
|
+
}
|
|
311
|
+
finally {
|
|
312
|
+
setBusy(false);
|
|
313
|
+
setPendingUser(null);
|
|
314
|
+
}
|
|
291
315
|
};
|
|
292
316
|
const doExit = () => {
|
|
293
|
-
// 会话已由 ConversationPersistPlugin 实时落盘,退出无需再询问是否保存
|
|
294
317
|
exit("done");
|
|
295
318
|
};
|
|
296
319
|
// 输入处理
|
|
297
320
|
useInput((char, key) => {
|
|
298
|
-
// 启动失败:给出「按 k 打开配置中心」的出路,而不是只能退出
|
|
299
321
|
if (bootError) {
|
|
300
322
|
if (char === "k" || char === "K") {
|
|
301
323
|
void openWizard({ kind: "menu" });
|
|
@@ -305,10 +327,8 @@ export function Chat(props) {
|
|
|
305
327
|
exit("done");
|
|
306
328
|
return;
|
|
307
329
|
}
|
|
308
|
-
// 终端应答序列(如 Kitty 查询应答 `[?0u`)不是用户输入,丢弃
|
|
309
330
|
if (isTerminalReply(char))
|
|
310
331
|
return;
|
|
311
|
-
// 翻页滚动(回看历史)
|
|
312
332
|
if (key.pageUp) {
|
|
313
333
|
scrollByPage(-1);
|
|
314
334
|
return;
|
|
@@ -317,9 +337,6 @@ export function Chat(props) {
|
|
|
317
337
|
scrollByPage(1);
|
|
318
338
|
return;
|
|
319
339
|
}
|
|
320
|
-
// 换行:Ctrl+Enter / Alt+Enter / Shift+Enter
|
|
321
|
-
// (仅当终端**原生**以 Kitty CSI-u 序列上报这些组合键时才生效 —— 本 CLI 不再
|
|
322
|
-
// 主动查询/开启该协议,见 tui/index.tsx 的 RENDER_OPTIONS;换行主推 Ctrl+N)
|
|
323
340
|
if (key.return && (key.ctrl || key.meta || key.shift)) {
|
|
324
341
|
insertAtCursor("\n");
|
|
325
342
|
return;
|
|
@@ -336,7 +353,7 @@ export function Chat(props) {
|
|
|
336
353
|
return;
|
|
337
354
|
}
|
|
338
355
|
if (char === "l" && key.ctrl) {
|
|
339
|
-
|
|
356
|
+
clearTranscript();
|
|
340
357
|
return;
|
|
341
358
|
}
|
|
342
359
|
if (char === "u" && key.ctrl) {
|
|
@@ -347,13 +364,11 @@ export function Chat(props) {
|
|
|
347
364
|
insertAtCursor("\n");
|
|
348
365
|
return;
|
|
349
366
|
}
|
|
350
|
-
// 换行:Ctrl+N(不依赖终端协议,兼容性最好)
|
|
351
367
|
if (char === "n" && key.ctrl) {
|
|
352
368
|
insertAtCursor("\n");
|
|
353
369
|
return;
|
|
354
370
|
}
|
|
355
371
|
if (key.return) {
|
|
356
|
-
// 斜杠候选菜单可见时回车直接执行高亮命令,避免把半截输入(如仅 `/`)当命令提交
|
|
357
372
|
void runSubmit(resolveSubmitText(input, hints, menuIndex));
|
|
358
373
|
return;
|
|
359
374
|
}
|
|
@@ -362,7 +377,6 @@ export function Chat(props) {
|
|
|
362
377
|
return;
|
|
363
378
|
}
|
|
364
379
|
if (key.upArrow || key.downArrow) {
|
|
365
|
-
// Shift / Alt + ↑↓:单行滚动(优先于历史召回)
|
|
366
380
|
if (key.shift || key.meta) {
|
|
367
381
|
scrollByLine(key.upArrow ? -1 : 1);
|
|
368
382
|
return;
|
|
@@ -371,7 +385,6 @@ export function Chat(props) {
|
|
|
371
385
|
setMenuIndex((i) => key.upArrow ? (i - 1 + hints.length) % hints.length : (i + 1) % hints.length);
|
|
372
386
|
return;
|
|
373
387
|
}
|
|
374
|
-
// 历史召回
|
|
375
388
|
if (key.upArrow && history.length > 0) {
|
|
376
389
|
const idx = historyIndex.current < 0 ? history.length - 1 : Math.max(0, historyIndex.current - 1);
|
|
377
390
|
historyIndex.current = idx;
|
|
@@ -390,7 +403,6 @@ export function Chat(props) {
|
|
|
390
403
|
}
|
|
391
404
|
return;
|
|
392
405
|
}
|
|
393
|
-
// 光标移动:← → 单字符,Ctrl/Alt+← → 跨词,Home / End 到行首 / 行尾
|
|
394
406
|
if (key.leftArrow) {
|
|
395
407
|
if (key.ctrl || key.meta)
|
|
396
408
|
setCursor(wordLeft(input, cursor));
|
|
@@ -441,16 +453,25 @@ export function Chat(props) {
|
|
|
441
453
|
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsxs(Text, { color: theme.error, wrap: "truncate", children: ["\u2716 \u65E0\u6CD5\u542F\u52A8\u5BF9\u8BDD\uFF1A", bootError] }), _jsx(Text, { color: theme.dim, wrap: "truncate", children: "\u6309 k \u6253\u5F00\u914D\u7F6E\u4E2D\u5FC3\uFF08\u53EF\u8BBE\u7F6E API Key / \u7AEF\u70B9\u5730\u5740\uFF09\u00B7 Enter \u8FD4\u56DE" })] }));
|
|
442
454
|
}
|
|
443
455
|
const session = sessionRef.current;
|
|
444
|
-
const
|
|
456
|
+
const lastTokens = session?.lastUsage?.total_tokens;
|
|
457
|
+
const totalTokens = session?.totalUsage.total_tokens;
|
|
445
458
|
const cols = columns ?? 80;
|
|
459
|
+
const messages = session?.messages ?? [];
|
|
460
|
+
const userCount = messages.filter((m) => m.role === AgentNS.Role.User).length;
|
|
461
|
+
const showPending = pendingUser != null && userCount <= pendingUser.base;
|
|
462
|
+
const transcript = transcriptLines(messages.slice(transcriptFrom), cols);
|
|
463
|
+
if (showPending) {
|
|
464
|
+
transcript.push(...messageToLines({ id: "__pending_user", role: AgentNS.Role.User, content: pendingUser.text }, cols));
|
|
465
|
+
}
|
|
466
|
+
const noticeTextLines = notice ? noticeLines(notice, cols) : [];
|
|
446
467
|
const layout = computeChatLayout({
|
|
447
468
|
columns: cols,
|
|
448
469
|
rows: usableFrameRows(rows ?? 24),
|
|
449
|
-
|
|
450
|
-
live: state.live,
|
|
470
|
+
transcript,
|
|
451
471
|
input,
|
|
452
472
|
busy,
|
|
453
473
|
hintCount: hints.length,
|
|
474
|
+
noticeCount: noticeTextLines.length,
|
|
454
475
|
overlay: confirmState ? "confirm" : pickerState ? "picker" : "none",
|
|
455
476
|
pickerItems: pickerState?.items.length ?? 0,
|
|
456
477
|
viewTop,
|
|
@@ -473,7 +494,7 @@ export function Chat(props) {
|
|
|
473
494
|
else {
|
|
474
495
|
setCursorPosition(undefined);
|
|
475
496
|
}
|
|
476
|
-
return (_jsxs(Box, { flexDirection: "column", width: cols, children: [layout.lines.map((line) => (_jsx(LineView, { line: line }, line.key))), confirmState ? (_jsx(Confirm, { question: confirmState.question, onAnswer: resolveConfirm })) : pickerState ? (_jsx(PickerOverlay, { title: pickerState.title, items: pickerState.items, columns: cols, onPick: resolvePicker })) : (_jsxs(Box, { flexDirection: "column", children: [hints.length > 0 ? _jsx(SlashMenu, { hints: hints, selected: menuIndex }) : null, _jsx(Box, { paddingX: 1, children: _jsx(Text, { color: theme.border, wrap: "truncate", children: "─".repeat(Math.max(1, cols - 2)) }) }), _jsx(Box, { flexDirection: "column", paddingX: 1, children: busy ? (_jsx(Spinner, { label: "\u601D\u8003\u4E2D\u2026" })) : (bodyLines.map((line, i) => {
|
|
497
|
+
return (_jsxs(Box, { flexDirection: "column", width: cols, children: [layout.lines.map((line) => (_jsx(LineView, { line: line }, line.key))), confirmState ? (_jsx(Confirm, { question: confirmState.question, onAnswer: resolveConfirm })) : pickerState ? (_jsx(PickerOverlay, { title: pickerState.title, items: pickerState.items, columns: cols, onPick: resolvePicker })) : (_jsxs(Box, { flexDirection: "column", children: [noticeTextLines.length > 0 ? (_jsx(Box, { flexDirection: "column", paddingX: 1, children: noticeTextLines.map((line, i) => (_jsx(Text, { color: notice?.tone === "error" ? theme.error : theme.dim, wrap: "truncate", children: line }, i))) })) : null, hints.length > 0 ? _jsx(SlashMenu, { hints: hints, selected: menuIndex }) : null, _jsx(Box, { paddingX: 1, children: _jsx(Text, { color: theme.border, wrap: "truncate", children: "─".repeat(Math.max(1, cols - 2)) }) }), _jsx(Box, { flexDirection: "column", paddingX: 1, children: busy ? (_jsx(Spinner, { label: "\u601D\u8003\u4E2D\u2026" })) : (bodyLines.map((line, i) => {
|
|
477
498
|
const prompt = i === 0 ? (_jsx(Text, { color: theme.brand[0], bold: true, children: "❯ " })) : (_jsx(Text, { children: " " }));
|
|
478
499
|
if (isPlaceholder) {
|
|
479
500
|
return (_jsxs(Text, { wrap: "truncate", children: [prompt, _jsx(Text, { color: theme.faint, children: line }), i === bodyLines.length - 1 ? (_jsx(Text, { color: theme.brand[1], children: "\u258F" })) : null] }, i));
|
|
@@ -486,7 +507,7 @@ export function Chat(props) {
|
|
|
486
507
|
return (_jsxs(Text, { wrap: "truncate", children: [prompt, _jsx(Text, { children: before }), _jsx(Text, { inverse: true, color: theme.brand[0], children: at ?? " " }), _jsx(Text, { children: after })] }, i));
|
|
487
508
|
}
|
|
488
509
|
return (_jsxs(Text, { wrap: "truncate", children: [prompt, _jsx(Text, { children: line })] }, i));
|
|
489
|
-
})) })] })), _jsx(StatusBar, { model: props.modelId, agent: props.agentId ?? "default",
|
|
510
|
+
})) })] })), _jsx(StatusBar, { model: props.modelId, agent: props.agentId ?? "default", lastTokens: lastTokens, totalTokens: totalTokens, busy: busy, hint: !ready
|
|
490
511
|
? "初始化中…"
|
|
491
512
|
: layout.scrolled
|
|
492
513
|
? "↕ 滚动中 · PgUp/PgDn 翻页 · 发送回到底部"
|