feat: 完善知识图谱交互与 Agent/线程持久化
- 知识图谱画布、侧边栏、详情面板交互优化,新增图谱相关 API 与 hooks - Agent 卡片与详情面板调整,对话页面重构 - 线程元数据持久化增强(base/memory/sql),knowledge 仓储与导出补充 - 网关路由 agents/knowledge/threads 同步更新 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
ea78fe9726
commit
f107ebc46d
25 files changed
+929
-279
No files matched your search
@@ -1,6 +1,8 @@
|
||||
import { ChevronDown, ChevronRight, Search, X } from "lucide-react";
|
||||
import { ChevronDown, ChevronRight, Eraser, Search, X } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
|
||||
import type { GraphBlacklistItem } from "@/core/knowledge/api";
|
||||
|
||||
import type { GraphNode, GraphStats, NodeKind } from "./graphTypes";
|
||||
import {
|
||||
getEdgeInfo,
|
||||
@@ -19,16 +21,26 @@ interface GraphSidebarProps {
|
||||
stats: GraphStats;
|
||||
topNodes: Array<{ node: GraphNode; degree: number }>;
|
||||
hiddenCount: number;
|
||||
blacklistItems: GraphBlacklistItem[];
|
||||
blacklistPending: boolean;
|
||||
junkCandidateCount: number;
|
||||
onSearchChange: (keyword: string) => void;
|
||||
onSearchEnter: () => void;
|
||||
onToggleNodeKind: (kind: NodeKind) => void;
|
||||
onToggleEdgeLabel: (label: string) => void;
|
||||
onRestoreHidden: () => void;
|
||||
onRemoveBlacklist: (entryId: string) => void;
|
||||
onCleanJunk: () => void;
|
||||
onPickNode: (id: string) => void;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
type SectionKey = "nodeTypes" | "edgeTypes" | "graphStats" | "coreNodes";
|
||||
type SectionKey =
|
||||
| "nodeTypes"
|
||||
| "edgeTypes"
|
||||
| "graphStats"
|
||||
| "coreNodes"
|
||||
| "blacklist";
|
||||
|
||||
interface FilterSectionProps {
|
||||
title: string;
|
||||
@@ -69,6 +81,7 @@ export function GraphSidebar(props: GraphSidebarProps) {
|
||||
edgeTypes: true,
|
||||
graphStats: false,
|
||||
coreNodes: false,
|
||||
blacklist: true,
|
||||
});
|
||||
|
||||
const toggleFilterSection = (key: SectionKey) => {
|
||||
@@ -230,6 +243,49 @@ export function GraphSidebar(props: GraphSidebarProps) {
|
||||
))}
|
||||
</FilterSection>
|
||||
) : null}
|
||||
|
||||
<FilterSection
|
||||
title="图谱黑名单"
|
||||
extra={`${props.blacklistItems.length} 个`}
|
||||
collapsed={collapsedSections.blacklist}
|
||||
onToggle={() => toggleFilterSection("blacklist")}
|
||||
>
|
||||
<div className="kg-search-hint">
|
||||
黑名单中的主题 / 节点不会出现在图谱中。可在节点详情里加入黑名单。
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="kg-icon-button"
|
||||
disabled={props.blacklistPending || props.junkCandidateCount === 0}
|
||||
title="将单字符、纯数字符号、通用泛词等低价值主题批量加入黑名单"
|
||||
onClick={props.onCleanJunk}
|
||||
>
|
||||
<Eraser size={13} /> 清理低价值主题
|
||||
{props.junkCandidateCount > 0 ? `(${props.junkCandidateCount})` : ""}
|
||||
</button>
|
||||
{props.blacklistItems.length === 0 ? (
|
||||
<div className="kg-search-hint">暂无黑名单条目。</div>
|
||||
) : (
|
||||
props.blacklistItems.map((item) => (
|
||||
<div key={item.id} className="kg-check-row">
|
||||
<span className="kg-check-row-main">
|
||||
<span className="kg-check-label" title={item.label}>
|
||||
{item.label}
|
||||
</span>
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
className="kg-text-button"
|
||||
disabled={props.blacklistPending}
|
||||
title="移出黑名单,重新显示该节点"
|
||||
onClick={() => props.onRemoveBlacklist(item.id)}
|
||||
>
|
||||
移除
|
||||
</button>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</FilterSection>
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user