diff --git a/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.tsx b/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.tsx
index 4552545bf7..30c93d4964 100644
--- a/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.tsx
+++ b/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.tsx
@@ -540,6 +540,7 @@ export function GoalResearchHistory({goalId, active, zh, refreshRevision = 0, re
{value?.events.length ? setRecordsOpen(event.currentTarget.open)}>{zh ? "全部已读记录" : "All loaded records"} · {value.events.length}
{recordsOpen ? : null}
: null}
diff --git a/apps/presentation/dashboard/src/features/personal-workspace/research-record-browser.tsx b/apps/presentation/dashboard/src/features/personal-workspace/research-record-browser.tsx
index 03bc5f7090..70b3001352 100644
--- a/apps/presentation/dashboard/src/features/personal-workspace/research-record-browser.tsx
+++ b/apps/presentation/dashboard/src/features/personal-workspace/research-record-browser.tsx
@@ -3,14 +3,15 @@ import {CircleHelp, TriangleAlert} from "lucide-react";
import {ContextHelp} from "./context-help";
import {useMemo, useState, type ReactNode} from "react";
import type {ExploreHistoryEvent} from "../../../../../../loopx/control_plane/presentation/explore_history.ts";
-import {searchResearchRecords} from "./research-record-search";
+import {searchResearchRecords, type ResearchRecordDisplay} from "./research-record-search";
import {exportResearchRecords} from "./research-record-export";
import {downloadReport} from "./report-download";
/** Local read controls over the existing validated history snapshot. */
-export function ResearchRecordSearch({goalId, events, displayEvents, renderBody, complete, stale, busy, zh, stateLabel, timeLabel}: {
+export function ResearchRecordSearch({goalId, events, displayEvents, displaySections, renderBody, complete, stale, busy, zh, stateLabel, timeLabel}: {
goalId: string;
displayEvents?: readonly ExploreHistoryEvent[]; renderBody?: (event: ExploreHistoryEvent) => ReactNode;
+ displaySections?: ResearchRecordDisplay["sections"];
events: readonly ExploreHistoryEvent[]; complete: boolean; stale: boolean; busy: boolean; zh: boolean;
stateLabel: (status: string) => string; timeLabel: (at: string) => string;
}) {
@@ -18,8 +19,9 @@ export function ResearchRecordSearch({goalId, events, displayEvents, renderBody,
const [status, setStatus] = useState("");
const [limit, setLimit] = useState(50);
const [downloadFailed, setDownloadFailed] = useState(false);
- const matches = useMemo(() => searchResearchRecords(events, query, status), [events, query, status]);
const displayed = useMemo(() => new Map(displayEvents?.map(event => [event.event_id, event])), [displayEvents]);
+ const display = useMemo(() => ({events: displayed, sections: displaySections}), [displayed, displaySections]);
+ const matches = useMemo(() => searchResearchRecords(events, query, status, display), [events, query, status, display]);
const statuses = [...new Set(events.map(event => event.status).filter(Boolean))].sort();
const countLabel = zh ? `匹配 ${matches.length} / ${events.length} 条已读记录` : `${matches.length} matches in ${events.length} loaded records`;
const readState = busy ? (zh ? "读取中" : "Reading") : stale ? (zh ? "刷新失败" : "Refresh failed") : "";
@@ -27,7 +29,7 @@ export function ResearchRecordSearch({goalId, events, displayEvents, renderBody,
return
{setQuery(event.target.value); setLimit(50);}}/>