feat(memory): P1 长期记忆升级 —— 异步攒批 Consolidate + 软删 + importance/last_seen #1

Merged
Blizzard merged 181 commits from feat/wails3 into main 2026-07-17 01:12:32 +00:00
3 changed files with 41 additions and 7 deletions
Showing only changes of commit 760ca06667 - Show all commits
+31
View File
@@ -89,3 +89,34 @@ body {
} }
/* 输入控件随主题(color-scheme 由 :root/.dark 设定,控件自动继承) */ /* 输入控件随主题(color-scheme 由 :root/.dark 设定,控件自动继承) */
/* react-flow 画布主题化:控件/连线/迷你图与设计系统对齐(colorMode 已处理大半,此处精修) */
.react-flow__controls {
box-shadow: none;
border: 1px solid rgb(var(--line));
border-radius: 8px;
overflow: hidden;
}
.react-flow__controls-button {
background: rgb(var(--ink-900));
border-bottom: 1px solid rgb(var(--line));
color: rgb(var(--slate-400));
}
.react-flow__controls-button:hover {
background: rgb(var(--ink-800));
}
.react-flow__controls-button svg {
fill: currentColor;
}
.react-flow__edge-path {
stroke: rgb(var(--slate-600));
stroke-width: 1.5;
}
.react-flow__edge.selected .react-flow__edge-path,
.react-flow__edge:focus .react-flow__edge-path {
stroke: #8b5cf6;
}
.react-flow__minimap {
border: 1px solid rgb(var(--line));
border-radius: 8px;
}
@@ -20,6 +20,7 @@ import { NODE_KINDS, NODE_ORDER } from "./nodeCatalog";
import { exportDsl, validate, type Issue, type TaskDsl } from "../lib/dsl"; import { exportDsl, validate, type Issue, type TaskDsl } from "../lib/dsl";
import type { RunPhase } from "../lib/run"; import type { RunPhase } from "../lib/run";
import { listKb, listChatModels, listAgents, saveAgent, deleteAgent, type Identity, type AgentInfo } from "../lib/api"; import { listKb, listChatModels, listAgents, saveAgent, deleteAgent, type Identity, type AgentInfo } from "../lib/api";
import { useTheme } from "../lib/theme";
import { Button, Input, cn, useToast } from "../ui"; import { Button, Input, cn, useToast } from "../ui";
let seq = 0; let seq = 0;
@@ -50,6 +51,7 @@ function buildExample(): { nodes: Node[]; edges: Edge[] } {
// 编排 Studio:左(节点面板 + 我的编排) · 中画布 · 右检查器 · 顶工具栏。 // 编排 Studio:左(节点面板 + 我的编排) · 中画布 · 右检查器 · 顶工具栏。
export function StudioView({ onRun, phase, identity }: { onRun: (dsl: TaskDsl) => void; phase: RunPhase; identity: Identity }) { export function StudioView({ onRun, phase, identity }: { onRun: (dsl: TaskDsl) => void; phase: RunPhase; identity: Identity }) {
const toast = useToast(); const toast = useToast();
const { theme } = useTheme();
const [nodes, setNodes, onNodesChange] = useNodesState<Node>([]); const [nodes, setNodes, onNodesChange] = useNodesState<Node>([]);
const [edges, setEdges, onEdgesChange] = useEdgesState<Edge>([]); const [edges, setEdges, onEdgesChange] = useEdgesState<Edge>([]);
const [selId, setSelId] = useState<string | null>(null); const [selId, setSelId] = useState<string | null>(null);
@@ -263,7 +265,8 @@ export function StudioView({ onRun, phase, identity }: { onRun: (dsl: TaskDsl) =
</div> </div>
<ReactFlow <ReactFlow
colorMode="dark" colorMode={theme}
proOptions={{ hideAttribution: true }}
nodes={nodes} nodes={nodes}
edges={edges} edges={edges}
nodeTypes={nodeTypes} nodeTypes={nodeTypes}
@@ -275,9 +278,9 @@ export function StudioView({ onRun, phase, identity }: { onRun: (dsl: TaskDsl) =
deleteKeyCode={["Backspace", "Delete"]} deleteKeyCode={["Backspace", "Delete"]}
fitView fitView
> >
<Background color="#242b3c" gap={18} /> <Background color={theme === "dark" ? "#27272a" : "#e4e4e7"} gap={18} />
<Controls /> <Controls />
<MiniMap zoomable pannable className="!bg-ink-850" /> <MiniMap zoomable pannable maskColor={theme === "dark" ? "rgba(0,0,0,0.55)" : "rgba(0,0,0,0.08)"} className="!bg-ink-850" />
</ReactFlow> </ReactFlow>
{issues && issues.length > 0 && ( {issues && issues.length > 0 && (
@@ -19,11 +19,11 @@ export function TypedNode({ data, selected }: NodeProps) {
return ( return (
<div <div
className={`relative min-w-[170px] rounded-lg border border-l-[3px] bg-ink-800 shadow-card ${k.accent} ${ className={`relative min-w-[180px] rounded-lg border border-l-[3px] bg-ink-850 shadow-card transition ${k.accent} ${
selected ? "ring-2 ring-violet-500/70" : "border-line" selected ? "ring-2 ring-brand/60 border-line" : "border-line hover:border-ink-600"
}`} }`}
> >
<Handle type="target" position={Position.Left} className="!h-2 !w-2 !border-0 !bg-slate-500" /> <Handle type="target" position={Position.Left} className="!h-2 !w-2 !border-0 !bg-slate-400" />
<div className="flex items-center justify-between gap-2 px-3 py-2"> <div className="flex items-center justify-between gap-2 px-3 py-2">
<span className={`rounded px-1.5 py-0.5 text-[10px] font-medium ${k.badge}`}>{k.label}</span> <span className={`rounded px-1.5 py-0.5 text-[10px] font-medium ${k.badge}`}>{k.label}</span>
<span className={`h-2 w-2 rounded-full ${dot}`} /> <span className={`h-2 w-2 rounded-full ${dot}`} />
@@ -41,7 +41,7 @@ export function TypedNode({ data, selected }: NodeProps) {
<span className="pointer-events-none absolute right-3 top-[66%] text-[9px] font-medium text-rose-400"></span> <span className="pointer-events-none absolute right-3 top-[66%] text-[9px] font-medium text-rose-400"></span>
</> </>
) : ( ) : (
<Handle type="source" position={Position.Right} className="!h-2 !w-2 !border-0 !bg-slate-500" /> <Handle type="source" position={Position.Right} className="!h-2 !w-2 !border-0 !bg-slate-400" />
)} )}
</div> </div>
); );