fix(studio): live-refresh wizard progress + remove dead onOpenFilm + token/height polish

This commit is contained in:
Ma
2026-06-26 14:47:24 +08:00
parent 098096eaad
commit 04f49813ec
4 changed files with 24 additions and 13 deletions
@@ -630,13 +630,11 @@ function PipelineExecution({
exec,
onProposedAction,
onRejectProposedAction,
onOpenFilm,
onOpenFilmStudio,
}: {
exec: ToolExecution;
onProposedAction?: (details: ProposedActionDetails) => void;
onRejectProposedAction?: (details: ProposedActionDetails) => void;
onOpenFilm?: (projectId: string) => void;
onOpenFilmStudio?: (projectId: string) => void;
}) {
const isActive = exec.status === "running" || exec.status === "processing";
@@ -780,7 +778,6 @@ export interface ToolExecutionStepsProps {
executions: ToolExecution[];
onProposedAction?: (details: ProposedActionDetails) => void;
onRejectProposedAction?: (details: ProposedActionDetails) => void;
onOpenFilm?: (projectId: string) => void;
onOpenFilmStudio?: (projectId: string) => void;
}
@@ -815,7 +812,7 @@ export function groupToolExecutionsChronologically(executions: ToolExecution[]):
return groups;
}
export const ToolExecutionSteps = memo(function ToolExecutionSteps({ executions, onProposedAction, onRejectProposedAction, onOpenFilm, onOpenFilmStudio }: ToolExecutionStepsProps) {
export const ToolExecutionSteps = memo(function ToolExecutionSteps({ executions, onProposedAction, onRejectProposedAction, onOpenFilmStudio }: ToolExecutionStepsProps) {
const groups = useMemo(() => groupToolExecutionsChronologically(executions), [executions]);
return (
@@ -828,7 +825,6 @@ export const ToolExecutionSteps = memo(function ToolExecutionSteps({ executions,
exec={g.exec}
onProposedAction={onProposedAction}
onRejectProposedAction={onRejectProposedAction}
onOpenFilm={onOpenFilm}
onOpenFilmStudio={onOpenFilmStudio}
/>
)
-1
View File
@@ -690,7 +690,6 @@ export function ChatPage({ activeBookId, mode = activeBookId ? "book" : "book-cr
executions={item.parts.map(p => p.execution)}
onProposedAction={handleProposedAction}
onRejectProposedAction={handleRejectProposedAction}
onOpenFilm={nav.toFilm}
onOpenFilmStudio={nav.toFilmStudio}
/>
);
+22 -6
View File
@@ -1,7 +1,8 @@
import { useState, useMemo } from "react";
import { useState, useMemo, useEffect, useCallback } from "react";
import type { Theme } from "../hooks/use-theme";
import type { TFunction } from "../hooks/use-i18n";
import type { SSEMessage } from "../hooks/use-sse";
import { useNewSSEMessages } from "../hooks/use-sse";
import { useColors } from "../hooks/use-colors";
import { useApi } from "../hooks/use-api";
import {
@@ -226,7 +227,7 @@ function ValidateView({
? "text-red-500"
: issue.level === "warning"
? "text-amber-500"
: "text-slate-400"
: "text-muted-foreground"
}
>
[{issue.level}]
@@ -257,11 +258,26 @@ export default function FilmWizard({
const [subViews, setSubViews] = useState<Record<Phase, string>>({ ...DEFAULT_SUBVIEW });
const [showPreview, setShowPreview] = useState(false);
const { data: graph } = useApi<StoryGraph>(`/projects/${projectId}/story-graph`);
const { data: validation } = useApi<ValidationReport>(
const { data: graph, refetch: refetchGraph } = useApi<StoryGraph>(`/projects/${projectId}/story-graph`);
const { data: validation, refetch: refetchValidation } = useApi<ValidationReport>(
`/projects/${projectId}/story-graph/validation`,
);
useEffect(() => {
void refetchGraph();
void refetchValidation();
}, [phase, refetchGraph, refetchValidation]);
const handleSseMessage = useCallback((msg: SSEMessage) => {
if (msg.event !== "agent:complete") return;
const data = msg.data as { activeBookId?: string } | null;
if (data?.activeBookId !== projectId) return;
void refetchGraph();
void refetchValidation();
}, [projectId, refetchGraph, refetchValidation]);
useNewSSEMessages(sse.messages, handleSseMessage);
const progress = useMemo<Record<Phase, PhaseStatus>>(
() => (graph ? computePhaseProgress(graph) : EMPTY_PROGRESS),
[graph],
@@ -408,7 +424,7 @@ function MainArea({
if (phase === "world" && subView === "chat") {
return (
<div className="h-[calc(100vh-180px)] relative overflow-hidden">
<div className="h-full relative overflow-hidden">
<ChatPage
activeBookId={projectId}
mode="interactive-film-authoring"
@@ -442,7 +458,7 @@ function MainArea({
if (phase === "workshop" && subView === "chat") {
return (
<div className="h-[calc(100vh-180px)] relative overflow-hidden">
<div className="h-full relative overflow-hidden">
<ChatPage
activeBookId={projectId}
mode="interactive-film-authoring"
+1 -1
View File
@@ -125,7 +125,7 @@ export function StoryGraphTree({
{validation.issues.map((issue, i) => (
<li key={i} data-testid={`validation-issue-${issue.code}`} className="text-xs flex gap-2">
<span className={
issue.level === "error" ? "text-red-500" : issue.level === "warning" ? "text-amber-500" : "text-slate-400"
issue.level === "error" ? "text-red-500" : issue.level === "warning" ? "text-amber-500" : "text-muted-foreground"
}>[{issue.level}]</span>
<span>{issue.message}</span>
</li>