Files
deerflow-code/frontend-web/src/roundtable-planning/hooks/step2-engine-context.ts
T
2026-07-19 16:08:40 +08:00

124 lines
4.0 KiB
TypeScript

import type { Dispatch, MutableRefObject, SetStateAction } from "react";
import type {
ClarificationPayload,
ModelSwitchInfo,
StreamPhase,
ThreadIdMap,
} from "@/roundtable-planning/api/multi-agent";
import type { Step2ExecutionRefs } from "@/roundtable-planning/hooks/useStep2ExecutionRefs";
import type { ParallelSeatView } from "@/roundtable-planning/hooks/step2-types";
import type { ChainNodeState } from "@/roundtable-planning/lib/job-types";
type EngineExecutionRefName =
| "isOrchestratingRef"
| "orchestrationCancelRef"
| "orchestrationEpochRef"
| "selectedAgentsRef"
| "agentNameToRoleRef"
| "activeAbortersRef"
| "pendingInjectFilesRef"
| "selectedModelRef"
| "agentConfigsRef"
| "gatheredDeliveriesRef"
| "seatModesRef"
| "selectedModeRef"
| "seatSkillDirectivesRef"
| "orchestrationPlanRef"
| "dagExecModeRef"
| "dagPlanExecutedRef";
export interface Step2EngineRuntimePort {
refs: Pick<Step2ExecutionRefs, EngineExecutionRefName>;
resolveSeatThreadId: (ids: ThreadIdMap, agentName: string) => string | undefined;
}
export interface Step2EngineDialoguePort {
appendStreamingDialogue: (card: {
sender: string;
avatarType: string;
initialContent?: string;
confidence?: string;
agentThreadId?: string;
}) => number;
appendToDialogue: (id: number, deltaText: string) => void;
setDialogueContent: (id: number, fullText: string) => void;
appendStepIfNew: (
bubbleId: number,
label: string,
key: string,
args?: Record<string, unknown>,
) => void;
setDialogueConfidence: (id: number, confidence: string) => void;
phaseLabel: (
phase: StreamPhase,
agentType: "leader" | "special",
toolName?: string,
) => string;
finalizeDialogue: (id: number, finalContent: string, confidence?: string) => void;
makeModelSwitchHandler: (
bubbleId: number,
isParallel: boolean,
) => (info: ModelSwitchInfo) => void;
}
export interface Step2EngineSpeakerPort {
highlightSpeaker: (speakerId: number | null) => void;
markSpeakerStreaming: (speakerId: number) => void;
markSpeakerIdle: (speakerId: number) => void;
markParallelSpeakers: (speakerIds: number[]) => void;
clearAllStreamingSpeakers: () => void;
}
export interface Step2EngineParallelPort {
recommendParallelRef: MutableRefObject<boolean>;
parallelStreamRef: MutableRefObject<
Map<number, { text: string; charCount: number }>
>;
ingestParallelDelta: (bubbleId: number, deltaText: string) => void;
resetParallelStreams: () => void;
setParallelBatch: Dispatch<SetStateAction<ParallelSeatView[]>>;
setSelectedParallelSeats: Dispatch<SetStateAction<string[]>>;
}
export interface Step2EngineDagPort {
setDagNodeStates: Dispatch<
SetStateAction<Record<string, ChainNodeState>>
>;
}
export interface Step2EngineArtifactPort {
handleArtifactToolPhase: (
phase: StreamPhase,
toolName: string | undefined,
args: Record<string, unknown> | undefined,
seatThreadId: string | undefined,
) => void;
handleUpstreamFrame: (frame: unknown, seatThreadId: string | undefined) => void;
ingestSubagentTaskFrame: (frame: unknown, bubbleId: number) => void;
}
export interface Step2EngineControlPort {
setIsOrchestrating: Dispatch<SetStateAction<boolean>>;
setPendingClarification: Dispatch<SetStateAction<ClarificationPayload | null>>;
setClarificationDraft: Dispatch<SetStateAction<string>>;
setLastLeaderContent: Dispatch<SetStateAction<string>>;
setConsensusPercentage: Dispatch<SetStateAction<number>>;
setHasConsensus: Dispatch<SetStateAction<boolean>>;
triggerToast: (message: string) => void;
}
/**
* Shared boundary for Step 2 orchestration engines.
* Engines depend on grouped capabilities instead of closing over the whole page hook.
*/
export interface Step2EngineContext {
runtime: Step2EngineRuntimePort;
dialogue: Step2EngineDialoguePort;
speakers: Step2EngineSpeakerPort;
parallel: Step2EngineParallelPort;
dag: Step2EngineDagPort;
artifacts: Step2EngineArtifactPort;
control: Step2EngineControlPort;
}