mirror of
https://github.com/Narcooo/inkos.git
synced 2026-08-30 17:22:02 +08:00
fix(studio): live-refresh wizard progress + remove dead onOpenFilm + token/height polish
This commit is contained in:
@@ -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}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user