Files
deerflow-code/frontend-web/src/components/workspace/workspace-nav-chat-list.tsx
T
xuhdandClaude Opus 4.7 62d525dae7 feat(skills): 自我进化 - 软归档/恢复 + Agent 归属 + 状态分层 UI
后端:
- 新增 PUT /api/skills/custom/{name}/state 与 /pinned 软归档/恢复 + 钉选 API
- skill_manage 工具: agent 创建写 DB 归属; 删除清理 .usage.json + DB row + cascade 引用; 加 ownership 预校验
- curator 全部软归档(文件保留在 custom/), 加 reason 必填(中文), 修 user_context 跨线程传播 / 协程泄漏 / archive 文件不再移动
- LLM 评审接 ToolErrorHandlingMiddleware, 工具异常自动重试不中止本轮; 替换 create_react_agent 为 create_agent
- skill_list 按当前 agent config.yaml 的 skills 字段过滤(custom agent), lead agent 仍可见全部
- 自我进化提示词对齐 Hermes 风格: 主动询问保存, reason 强制中文且面向用户
- 控制台日志增强: 自动归档/标过时/LLM 合并/删减建议 都按条目输出原因

前端:
- 技能管理页 Tab 改「全部 / 我的」, 正确包含他人发布的 custom 技能(修复 isCustom 互斥 bug)
- 新增「过时 N / 归档 N」右侧抽屉(恢复/查看/立即归档 ⋯ 菜单)
- 新增徽章: 钉选 / 来源(Agent 创建 / 用户上传) / 使用次数展示
- 内置技能徽章修复(原 isBuiltin && isCustom 永远 false)
- 自我进化日志 run_started sentinel 在前端展示为中文分隔条
- 移除冗余 enabled 开关(归档已覆盖此能力, 减少术语)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 00:00:52 +08:00

94 lines
3.0 KiB
TypeScript

"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import {
SidebarGroup,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/components/ui/sidebar";
import { getStoredAuth } from "@/core/auth";
import { useI18n } from "@/core/i18n/hooks";
import { BotIcon, ListChecks, MessageSquarePlus, MessagesSquare, SparklesIcon, UsersIcon } from "lucide-react";
export function WorkspaceNavChatList() {
const { t } = useI18n();
const pathname = usePathname();
const isAdmin = getStoredAuth()?.system_role === "admin";
return (
<SidebarGroup className="px-2 pt-2">
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton
isActive={pathname === "/page/workspace/chats/new"}
asChild
>
<Link className="text-sidebar-foreground" href="/page/workspace/chats/new">
<MessageSquarePlus />
<span>{t.sidebar.newChat}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton isActive={pathname === "/page/workspace/chats"} asChild>
<Link className="text-sidebar-foreground" href="/page/workspace/chats">
<MessagesSquare />
<span>{t.sidebar.chats}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton
isActive={pathname.startsWith("/page/workspace/agents")}
asChild
>
<Link className="text-sidebar-foreground" href="/page/workspace/agents">
<BotIcon />
<span>{t.sidebar.agents}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton
isActive={pathname.startsWith("/page/workspace/skills")}
asChild
>
<Link className="text-sidebar-foreground" href="/page/workspace/skills">
<SparklesIcon />
<span>技能</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton
isActive={pathname === "/page/workspace/scheduled/tasks"}
asChild
>
<Link className="text-sidebar-foreground" href="/page/workspace/scheduled/tasks">
<ListChecks />
<span>任务管理</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
{isAdmin && (
<SidebarMenuItem>
<SidebarMenuButton
isActive={pathname.startsWith("/page/workspace/admin")}
asChild
>
<Link className="text-sidebar-foreground" href="/page/workspace/admin/users">
<UsersIcon />
<span>{t.sidebar.users}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
)}
</SidebarMenu>
</SidebarGroup>
);
}