fix: address console review findings

This commit is contained in:
lda
2026-07-03 08:27:36 +07:00 Verified
parent 47ac422965
commit b0b2cba7ab
23 changed files with 351 additions and 107 deletions
@@ -1,16 +1,24 @@
import { useMemo, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { ldaReportSetupCommands } from "./ldaReportDemoConfig.js";
import { DemoTimelineControls } from "./DemoTimelineControls.js";
import { DemoTimeline } from "./DemoTimeline.js";
import type { DemoTimelineController } from "./useDemoTimeline.js";
const DEFAULT_REVIEW_COMMENT = "Create selected issues before the defense.";
export const LdaReportDemoPanel = ({ controller }: { readonly controller: DemoTimelineController }) => {
const { state } = controller;
const [selectedIds, setSelectedIds] = useState<ReadonlySet<string>>(new Set());
const [comment, setComment] = useState("Create selected issues before the defense.");
const [comment, setComment] = useState(DEFAULT_REVIEW_COMMENT);
const proposedIssues = controller.interruptPayload?.proposed_issues ?? [];
const selectedIssueIds = useMemo(() => [...selectedIds], [selectedIds]);
useEffect(() => {
setSelectedIds(new Set());
setComment(DEFAULT_REVIEW_COMMENT);
}, [state.mode, state.phase, controller.interruptPayload]);
return (
<section aria-label="lda report workflow demo" className="demo-panel">
<div className="demo-panel__header">
+35 -21
View File
@@ -51,6 +51,25 @@ export type LiveStepResult = {
readonly events: ReadonlyArray<DemoEvent>;
};
const baseDemoEvent = (
context: LiveDemoContext,
stage: DemoEventStage,
runId: string | null,
sequenceOffset = 0,
): Pick<DemoEvent, "id" | "sequence" | "stage" | "resultingIds" | "recordedAt"> => {
const sequence = context.nextSequence + sequenceOffset;
return {
id: `live-${sequence}-${stage}-${runId ?? "pending"}`,
sequence,
stage,
resultingIds: {
deploymentId: LDA_REPORT_DEPLOYMENT_ID,
runId,
},
recordedAt: new Date().toISOString(),
};
};
const eventFromResult = (
context: LiveDemoContext,
stage: DemoEventStage,
@@ -60,9 +79,7 @@ const eventFromResult = (
result: RpcResponse,
runId: string | null,
): DemoEvent => ({
id: `live-${context.nextSequence}-${stage}-${runId ?? "pending"}`,
sequence: context.nextSequence,
stage,
...baseDemoEvent(context, stage, runId),
operation,
reason: result.ok ? reason : result.error.message,
equivalentCli: result.ok ? result.equivalentCli : null,
@@ -70,11 +87,6 @@ const eventFromResult = (
rawResponse: result.exchange.response,
interpreted: result.ok ? result.interpreted : null,
durationMs: result.ok ? result.durationMs : 0,
resultingIds: {
deploymentId: LDA_REPORT_DEPLOYMENT_ID,
runId,
},
recordedAt: new Date().toISOString(),
});
const syntheticEvent = (
@@ -85,9 +97,7 @@ const syntheticEvent = (
runId: string | null,
sequenceOffset = 0,
): DemoEvent => ({
id: `live-${context.nextSequence + sequenceOffset}-${stage}-${runId ?? "pending"}`,
sequence: context.nextSequence + sequenceOffset,
stage,
...baseDemoEvent(context, stage, runId, sequenceOffset),
operation: null,
reason,
equivalentCli: null,
@@ -95,8 +105,6 @@ const syntheticEvent = (
rawResponse: null,
interpreted,
durationMs: 0,
resultingIds: { deploymentId: LDA_REPORT_DEPLOYMENT_ID, runId },
recordedAt: new Date().toISOString(),
});
const operationForStage = (stage: LiveDemoStage): string | null => {
@@ -118,9 +126,7 @@ export const failedLiveDemoEvent = (
context: LiveDemoContext,
reason: string,
): DemoEvent => ({
id: `live-${context.nextSequence}-failed-${context.runId ?? "pending"}`,
sequence: context.nextSequence,
stage: "failed",
...baseDemoEvent(context, "failed", context.runId),
operation: operationForStage(context.nextStage),
reason,
equivalentCli: null,
@@ -128,11 +134,6 @@ export const failedLiveDemoEvent = (
rawResponse: null,
interpreted: null,
durationMs: 0,
resultingIds: {
deploymentId: LDA_REPORT_DEPLOYMENT_ID,
runId: context.runId,
},
recordedAt: new Date().toISOString(),
});
export const executeLiveDemoStep = async (
@@ -238,6 +239,19 @@ export const executeLiveDemoStep = async (
};
}
const detail = decodeRunDetail(result.interpreted);
if (detail.status !== "completed") {
const failed = syntheticEvent(
context,
"failed",
`Demo resume returned ${detail.status} instead of completed.`,
result.interpreted,
detail.runId,
);
return {
events: [failed],
context: { ...context, nextStage: "done", runId: detail.runId, nextSequence: context.nextSequence + 1 },
};
}
const output = parseLdaReportOutput(detail.output);
return {
events: [eventFromResult(context, "run_resume", "workflow.runs.resume", "Resume the interrupted run.", params, result, context.runId)],
+28 -17
View File
@@ -63,6 +63,7 @@ export const useDemoTimeline = (
const recordEvidenceRef = useRef(recordEvidence);
recordEvidenceRef.current = recordEvidence;
const inFlightRef = useRef(false);
const generationRef = useRef(0);
const [inFlight, setInFlight] = useState(false);
const approvalRef = useRef<DemoApproval | null>(null);
const activeRecording = useRef(loadCanonicalDemoRecording());
@@ -71,9 +72,25 @@ export const useDemoTimeline = (
const [output, setOutput] = useState<LdaReportOutput | null>(null);
const [trace, setTrace] = useState<TracePage | null>(null);
const resetRuntime = useCallback(() => {
generationRef.current++;
inFlightRef.current = false;
setInFlight(false);
liveContextRef.current = initialLiveDemoContext;
approvalRef.current = null;
setInterruptPayload(null);
setOutput(null);
setTrace(null);
}, []);
useEffect(() => {
resetRuntime();
}, [target, resetRuntime]);
const step = useCallback(async () => {
if (inFlightRef.current) return;
if (state.appliedCount >= state.events.length && state.mode === "replay") return;
const generation = generationRef.current;
inFlightRef.current = true;
setInFlight(true);
try {
@@ -102,6 +119,7 @@ export const useDemoTimeline = (
const approval = approvalRef.current;
approvalRef.current = null;
const result = await executeLiveDemoStep(target, liveContextRef.current, approval ?? undefined);
if (generation !== generationRef.current) return;
liveContextRef.current = result.context;
for (const event of result.events) {
dispatch({ type: "append_live_event", event });
@@ -162,8 +180,10 @@ export const useDemoTimeline = (
dispatch({ type: "fail", message });
}
} finally {
inFlightRef.current = false;
setInFlight(false);
if (generation === generationRef.current) {
inFlightRef.current = false;
setInFlight(false);
}
}
}, [state.mode, state.appliedCount, state.events, target]);
@@ -177,25 +197,19 @@ export const useDemoTimeline = (
}, [state.phase, state.autoplay, state.appliedCount, step]);
const setMode = useCallback((mode: DemoMode) => {
resetRuntime();
dispatch({ type: "set_mode", mode });
liveContextRef.current = initialLiveDemoContext;
setInterruptPayload(null);
setOutput(null);
setTrace(null);
}, []);
}, [resetRuntime]);
const start = useCallback(() => {
resetRuntime();
if (state.mode === "replay") {
const recording = activeRecording.current;
dispatch({ type: "start", mode: "replay", events: recording.events });
} else {
liveContextRef.current = initialLiveDemoContext;
dispatch({ type: "start", mode: "live", events: [] });
}
setInterruptPayload(null);
setOutput(null);
setTrace(null);
}, [state.mode]);
}, [resetRuntime, state.mode]);
const pause = useCallback(() => dispatch({ type: "pause" }), []);
const play = useCallback(() => dispatch({ type: "play" }), []);
@@ -229,12 +243,9 @@ export const useDemoTimeline = (
}, []);
const restart = useCallback(() => {
resetRuntime();
dispatch({ type: "restart" });
liveContextRef.current = initialLiveDemoContext;
setInterruptPayload(null);
setOutput(null);
setTrace(null);
}, []);
}, [resetRuntime]);
return {
state,