返回 DeepSeek-Reasonix
turn-outline.tsx
根目录 / desktop / frontend / bench / turn-outline.tsx
1 import { useSyncExternalStore } from "react";
2 import { createRoot } from "react-dom/client";
3 import { Transcript } from "../src/components/Transcript";
4 import { LocaleProvider } from "../src/lib/i18n";
5 import { ToastProvider } from "../src/lib/toast";
6 import { initialState, reducer, type Action, type State } from "../src/lib/useController";
7 import { getTranscriptStore } from "../src/lib/transcriptStore";
8 import { TranscriptSessionFollower } from "../src/lib/transcriptSessionFollower";
9 import { navigateHistoryTurn } from "../src/lib/historyTurnNavigation";
10 import { getTranscriptOutlineStore } from "../src/lib/transcriptOutlineStore";
11 import { installDesktopHostStub } from "../src/__tests__/desktopHostStub";
12 import type { FollowRequest, HistoryOutlineRequest, HistoryWindowRequest } from "../src/generated/desktopContract.generated";
13 import "../src/styles.css";
14
15 const total = 25000, store = getTranscriptStore();
16 let tab = "outline-a", state = { ...initialState, meta: { sessionPath: tab } } as State;
17 let delayed = false, resume: (() => void) | undefined;
18 let completedReads = 0;
19 const reads: HistoryWindowRequest[] = [], outlineReads: HistoryOutlineRequest[] = [];
20 function page(turn: number, count = 16) {
21 const end = Math.min(total, turn + count - 1);
22 return { status: "ready", generation: "g", snapshotSequence: total, coverageSequence: total, totalTurns: total,
23 hasOlder: turn > 1, hasNewer: end < total, olderCursor: turn > 1 ? String(turn) : "", newerCursor: end < total ? String(end + 1) : "",
24 messages: Array.from({ length: end - turn + 1 }, (_, offset) => {
25 const number = turn + offset;
26 return ["user", "assistant"].map((role, side) => ({ messageId: `${role === "user" ? "u" : "a"}${number}`, role,
27 position: number * 2 + side, version: 1, eventSequence: number, visibleTurn: number,
28 inline: { id: `${role === "user" ? "u" : "a"}${number}`, role,
29 content: role === "user" ? `Question ${number}` : `Answer ${number}\n\n${"A stable paragraph for reading and scrolling.\n\n".repeat(12)}` } }));
30 }).flat() };
31 }
32 installDesktopHostStub({
33 TranscriptFollowForTab: (_tab: string, req: FollowRequest) => req.close ? { protocolVersion: 2, subscription: _tab, changes: [], resetRequired: false }
34 : req.subscription ? new Promise(() => {}) : { protocolVersion: 2, subscription: _tab, changes: [], resetRequired: false,
35 snapshot: { protocolVersion: 1, snapshotId: "tail", identity: { sessionId: _tab, runtimeEpoch: "epoch", rewriteEpoch: 0, headId: "" },
36 projectionRevision: 1, coveredThroughSeq: total, durableSeq: total, records: [], activeRecords: [], activeAttempts: [], before: 0,
37 runtime: { status: "completed", pendingEvents: [], samplingCount: 0, toolCount: 0 }, hasOlder: true, totalRecords: 2, totalTurns: total, stale: false }, history: page(total, 1) },
38 SessionHistoryOutlineForTab: (_tab: string, req: HistoryOutlineRequest) => {
39 outlineReads.push(req); const start = req.startTurn ?? 1; const end = Math.min(total, start + (req.limit ?? 128) - 1);
40 return { status: "ready", generation: "g", snapshotSequence: total, coverageSequence: total, totalTurns: total, done: end === total, nextTurn: end + 1,
41 entries: Array.from({ length: end - start + 1 }, (_, index) => ({ messageId: `u${start + index}`, turn: start + index, position: (start + index) * 2, prompt: `Question ${start + index}`, answer: `Answer ${start + index}` })) };
42 },
43 SessionHistoryWindowForTab: async (_tab: string, req: HistoryWindowRequest) => {
44 reads.push(req); if (delayed) { delayed = false; await new Promise<void>(done => { resume = done; }); }
45 completedReads++;
46 return page(req.anchor === "newest" ? total : Number(req.messageId?.slice(1) ?? req.cursor ?? 1));
47 },
48 });
49 const dispatch = (action: Action) => { state = reducer(state, action); store.setState(tab, state); };
50 let follower = new TranscriptSessionFollower(tab, tab, false, dispatch, () => state);
51 await follower.start();
52 function Fixture() {
53 const view = useSyncExternalStore(fn => store.subscribeState(tab, fn), () => state);
54 return <div style={{ height: "100vh", display: "flex", flexDirection: "column" }}><Transcript
55 items={view.items} tabId={tab} geometrySessionKey={tab} totalTurns={view.historyTotalTurns}
56 historyStartTurn={view.historyStartTurn} historyEndTurn={view.historyEndTurn}
57 hasOlderHistory={view.historyHasOlder} hasNewerHistory={view.historyHasNewer} onPrompt={() => {}}
58 onNavigateToTurn={(target, current) => navigateHistoryTurn(tab, state, () => state, dispatch, target, current)}
59 onLoadNewerHistory={async (_latest, current) => { const projection = await store.loadLatest(tab, tab, { current }); if (projection) dispatch({ type: "transcript_records", projection: { ...projection, removeIds: [] }, confirmedUsers: [] }); return projection ? "loaded" : "empty"; }}
60 /></div>;
61 }
62 declare global { interface Window { turnOutlineFixture: { inspect(): unknown; delay(): void; resume(): void; switchSession(): Promise<void> } } }
63 window.turnOutlineFixture = {
64 inspect: () => ({ reads, completedReads, outlineReads, users: state.items.filter(item => item.kind === "user").map(item => item.messageId),
65 cacheEntries: getTranscriptOutlineStore().getView(tab).entries.size, tab, stateItems: state.items.length }),
66 delay: () => { delayed = true; }, resume: () => { resume?.(); resume = undefined; },
67 switchSession: async () => {
68 const previous = tab; follower.stop(); tab = tab === "outline-a" ? "outline-b" : "outline-a";
69 state = { ...initialState, meta: { sessionPath: tab } } as State;
70 follower = new TranscriptSessionFollower(tab, tab, false, dispatch, () => state);
71 await follower.start(); store.setState(previous, state);
72 },
73 };
74 createRoot(document.getElementById("root")!).render(<LocaleProvider><ToastProvider><Fixture /></ToastProvider></LocaleProvider>);
75
75 lines Plain Text