From 8ff1650657452e49f85066893d3ae8612f6b4a01 Mon Sep 17 00:00:00 2001 From: Aditya Gupta Date: Sun, 19 Jul 2026 20:32:27 +0530 Subject: [PATCH] feat(gui): Model Statistics now show Validators in the pipeline --- apps/gui/src/components/play/PromptModal.tsx | 53 ++++++++++- .../src/components/play/PromptSwitcher.tsx | 88 +++++++++++++------ apps/gui/src/lib/simulation-types.ts | 20 +++++ 3 files changed, 133 insertions(+), 28 deletions(-) diff --git a/apps/gui/src/components/play/PromptModal.tsx b/apps/gui/src/components/play/PromptModal.tsx index 1d91392..84e13a9 100644 --- a/apps/gui/src/components/play/PromptModal.tsx +++ b/apps/gui/src/components/play/PromptModal.tsx @@ -18,7 +18,7 @@ interface PromptModalProps { } export function PromptModal({ entry, onClose }: PromptModalProps) { - const [activeTab, setActiveTab] = useState<"actor" | "decoder">("actor"); + const [activeTab, setActiveTab] = useState("actor"); useEffect(() => { if (!entry.rawPrompt && entry.decoderPrompt) { @@ -53,6 +53,17 @@ export function PromptModal({ entry, onClose }: PromptModalProps) { const actorComponents = getComponents(entry.rawPrompt, "world"); const decoderComponents = getComponents(entry.decoderPrompt, "input"); + const isValidatorTab = activeTab.startsWith("validator-"); + const validatorIndex = isValidatorTab + ? parseInt(activeTab.substring("validator-".length), 10) + : -1; + const validatorCall = isValidatorTab + ? entry.validatorCalls?.find((c) => c.intentIndex === validatorIndex) + : null; + const validatorComponents = validatorCall + ? getComponents(validatorCall.prompt, "world") + : []; + return ( !open && onClose()}> @@ -67,6 +78,12 @@ export function PromptModal({ entry, onClose }: PromptModalProps) { onTabChange={setActiveTab} hasActor={!!entry.rawPrompt} hasDecoder={!!entry.decoderPrompt} + validatorCalls={ + entry.validatorCalls?.map((c) => ({ + intentIndex: c.intentIndex, + intentContent: c.intentContent, + })) || [] + } />
@@ -99,10 +116,42 @@ export function PromptModal({ entry, onClose }: PromptModalProps) { modelName={entry.decoderUsage?.modelName} providerInstanceName={entry.decoderUsage?.providerInstanceName} outputLabel="LLM Output (Decoded Intent Sequence)" - outputText={JSON.stringify(entry.intents, null, 2)} + outputText={JSON.stringify( + entry.decodedIntents || entry.intents, + null, + 2, + )} outputTokens={entry.decoderUsage?.outputTokens} /> )} + + {validatorCall && validatorCall.prompt && ( + + )} + + {validatorCall && !validatorCall.prompt && ( +
+ + Bypassed LLM Validation + +

+ {validatorCall.response.reason} +

+
+ )}
diff --git a/apps/gui/src/components/play/PromptSwitcher.tsx b/apps/gui/src/components/play/PromptSwitcher.tsx index a30da29..05ce8a6 100644 --- a/apps/gui/src/components/play/PromptSwitcher.tsx +++ b/apps/gui/src/components/play/PromptSwitcher.tsx @@ -1,10 +1,11 @@ "use client"; interface PromptSwitcherProps { - activeTab: "actor" | "decoder"; - onTabChange: (tab: "actor" | "decoder") => void; + activeTab: string; + onTabChange: (tab: any) => void; hasActor: boolean; hasDecoder: boolean; + validatorCalls?: { intentIndex: number; intentContent: string }[]; } export function PromptSwitcher({ @@ -12,32 +13,67 @@ export function PromptSwitcher({ onTabChange, hasActor, hasDecoder, + validatorCalls = [], }: PromptSwitcherProps) { return ( -
- - - +
+ {/* Primary Pipeline (Linear flow to the left) */} +
+ + + + + +
+ + {/* Branching Validator Column to the right of Intent Decoder */} + {validatorCalls.length > 0 && ( +
+ + +
+
+ {validatorCalls.map((call) => { + const tabKey = `validator-${call.intentIndex}`; + return ( + + ); + })} +
+
+
+ )}
); } diff --git a/apps/gui/src/lib/simulation-types.ts b/apps/gui/src/lib/simulation-types.ts index 35cb8ca..c1e53c2 100644 --- a/apps/gui/src/lib/simulation-types.ts +++ b/apps/gui/src/lib/simulation-types.ts @@ -20,6 +20,24 @@ export interface PromptBreakdown { components?: PromptComponent[]; } +export interface ValidatorCall { + intentIndex: number; + intentContent: string; + prompt?: PromptBreakdown; + response: { + isValid: boolean; + reason: string; + }; + usage?: { + inputTokens: number; + outputTokens: number; + totalTokens: number; + modelName?: string; + providerInstanceName?: string; + maxContext?: number; + }; +} + export interface LogEntry { turn: number; entityId: string; @@ -29,6 +47,8 @@ export interface LogEntry { timestamp: string; isHandoff?: boolean; handoffResult?: any; + decodedIntents?: IntentInfo[]; + validatorCalls?: ValidatorCall[]; rawPrompt?: PromptBreakdown; usage?: { inputTokens: number;