优化项目对话、刷新续流、实时滚动与工具状态恢复 (#245)

* feat(chat): add project-based conversation sidebar

* feat(chat): refine Codex-style conversation UI

* feat(chat): add Codex-style conversation workflow

* feat(ui): 优化对话框与项目侧边栏交互

* fix(chat): 修复暗色输入框圆角填色

* fix(chat): 恢复输入区分层错位布局

* fix(hitl): isolate reviewer state per conversation

* feat(hitl): 增加双入口审批与倒计时进度

* fix(hitl): 汇总项目审批并隔离对话状态

* fix(ui): 修复审批状态与无项目新任务

* fix(ui): 优化审批状态与对话切换性能

* fix(ui): 修复中断任务审批仍计时

* fix(ui): 修复多对话并发切换卡顿

* fix(hitl): 主动同步审批并关闭中断状态

* fix(ui): 固定项目审批汇总为绿色

* feat(ui): 同步系统模型与推理强度

* feat(ui): 完善项目侧栏预览与新建入口

* fix(ui): 防止无项目文件夹误展开

* fix(ui): 防止长历史对话滚动误触审批

* fix(ui): 修复对话操作并补充项目置顶

* fix(ui): 移除对话分组并调整项目置顶排序

* feat(ui): 优化迭代导航与审批交互

* fix(hitl): 将 write_file 加入内置免审批工具

* fix(chat): 支持回车发送与 Shift 回车换行

* fix(chat): 优化对话刷新与 Codex 风格交互

* fix(ui): 显示对话具体更新时间

* fix(ui): 优化对话刷新与项目加载

* fix(ui): 修复 Agent 审查文字裁切

* fix(chat): 修复刷新续流与多标签页同步

* fix(chat): 修复滚动跟随与中断任务终态

* fix(ui): 修复流式滚动跳动与工具状态恢复

* fix(ui): 修复刷新后流式输出停止粘底
This commit is contained in:
RuoJi6
2026-08-13 21:28:37 +08:00
committed by GitHub
parent b170f2c4b1
commit eb6bab574f
31 changed files with 10763 additions and 886 deletions
@@ -8,13 +8,15 @@ import (
const toolSearchToolName = "tool_search"
// HitlExemptMetaTools 为编排/元工具:不直接执行攻击动作,但会阻塞 agent 控制流
// tool_search 必须免审批,否则其 HITL 拒绝结果与 Eino toolsearch 中间件不兼容(会硬崩 ChatModel)
// HitlExemptMetaTools 为 HITL 内置免审批工具:包括编排/元工具,以及模型输出修复链路依赖的 write_file
// tool_search 必须免审批,否则其 HITL 拒绝结果与 Eino toolsearch 中间件不兼容(会硬崩 ChatModel)
// write_file 必须免审批,否则长脚本或请求体无法先安全落盘,模型输出修复链路会被再次阻塞。
var HitlExemptMetaTools = []string{
toolSearchToolName,
"skill",
"task",
"write_todos",
"write_file",
"transfer_to_agent",
"exit",
"TaskCreate",
@@ -33,29 +33,30 @@ func TestHitlRejectToolResult_otherToolKeepsLegacyText(t *testing.T) {
}
}
func TestMergeHitlExemptMetaTools_includesToolSearch(t *testing.T) {
func TestMergeHitlExemptMetaTools_includesBuiltInExemptTools(t *testing.T) {
merged := MergeHitlExemptMetaTools([]string{"read_file"})
found := false
foundToolSearch := false
for _, name := range merged {
if IsToolSearchTool(name) {
found = true
foundToolSearch = true
break
}
}
if !found {
if !foundToolSearch {
t.Fatalf("tool_search missing from %v", merged)
}
foundProjectFactTools := map[string]bool{
foundBuiltInTools := map[string]bool{
"write_file": false,
"upsert_project_fact": false,
"get_project_fact": false,
}
for _, name := range merged {
normalized := strings.ToLower(strings.TrimSpace(name))
if _, ok := foundProjectFactTools[normalized]; ok {
foundProjectFactTools[normalized] = true
if _, ok := foundBuiltInTools[normalized]; ok {
foundBuiltInTools[normalized] = true
}
}
for name, found := range foundProjectFactTools {
for name, found := range foundBuiltInTools {
if !found {
t.Fatalf("%s missing from %v", name, merged)
}