feat(ui): 实现 Agent 模式切换和 Auto Edit 功能

- 添加 AgentModeSelector 组件,支持 Build/Plan 模式切换
- Build 模式下显示 Auto Edit 开关,自动授权文件写入/编辑
- 扩展 useChat hook 添加会话级别的 agentMode/autoApprove 状态
- 服务端支持解析和应用 Agent 模式配置
- 权限处理器实现 auto-approve 检查(仅 write/edit,不含 delete)
This commit is contained in:
2025-12-15 19:42:51 +08:00
parent f09f8f2b03
commit ec3c7bccf9
13 changed files with 409 additions and 7 deletions
+27 -2
View File
@@ -13,6 +13,7 @@ import type {
ToolEndPayload,
MessagePart,
ToolMessagePart,
AgentModeType,
} from '../api/types.js';
interface UseChatOptions {
@@ -31,6 +32,10 @@ interface ChatState {
/** 流式消息对象,复用 Message 结构 */
streamingMessage: Message | null;
permissionRequest: PermissionRequest | null;
/** Agent 模式 (会话级别) */
agentMode: AgentModeType;
/** 是否自动授权文件写入/编辑 (会话级别) */
autoApprove: boolean;
}
export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdated, onConfigError }: UseChatOptions) {
@@ -40,6 +45,8 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
isLoading: false,
streamingMessage: null,
permissionRequest: null,
agentMode: 'build',
autoApprove: false,
});
const wsRef = useRef<WebSocket | null>(null);
@@ -323,11 +330,15 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
JSON.stringify({
type: 'message',
sessionId,
payload: { content },
payload: {
content,
agentMode: state.agentMode,
autoApprove: state.autoApprove,
},
})
);
},
[sessionId]
[sessionId, state.agentMode, state.autoApprove]
);
// 取消处理
@@ -401,6 +412,16 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
[respondToPermission]
);
// 设置 Agent 模式 (会话级别)
const setAgentMode = useCallback((mode: AgentModeType) => {
setState((prev) => ({ ...prev, agentMode: mode }));
}, []);
// 设置自动授权 (会话级别)
const setAutoApprove = useCallback((enabled: boolean) => {
setState((prev) => ({ ...prev, autoApprove: enabled }));
}, []);
// 初始化
useEffect(() => {
// 重置状态
@@ -411,6 +432,8 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
isLoading: false,
streamingMessage: null,
permissionRequest: null,
agentMode: 'build',
autoApprove: false,
});
reconnectAttemptsRef.current = 0;
@@ -448,5 +471,7 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
reload: loadMessages,
allowPermission,
denyPermission,
setAgentMode,
setAutoApprove,
};
}