88 lines
3.7 KiB
TypeScript
88 lines
3.7 KiB
TypeScript
import { PanelFrame } from "./PanelFrame";
|
|
import { JsonView } from "./JsonView";
|
|
import type { NormalizeResultState, TabKey } from "../state/types";
|
|
|
|
interface OutputPanelProps {
|
|
tab: TabKey;
|
|
onTabChange: (tab: TabKey) => void;
|
|
result: NormalizeResultState | null;
|
|
appLogs: string[];
|
|
}
|
|
|
|
const TAB_LABELS: Record<TabKey, string> = {
|
|
normalized: "Normalized JSON",
|
|
fragments: "Fragment View",
|
|
scope: "Scope View",
|
|
flags: "Flags View",
|
|
route: "Route Simulation",
|
|
raw: "Raw model output",
|
|
validation: "Validation",
|
|
logs: "Logs"
|
|
};
|
|
|
|
function asObject(value: unknown): Record<string, unknown> | null {
|
|
return value && typeof value === "object" ? (value as Record<string, unknown>) : null;
|
|
}
|
|
|
|
export function OutputPanel({ tab, onTabChange, result, appLogs }: OutputPanelProps) {
|
|
const tabs: TabKey[] = ["normalized", "fragments", "scope", "flags", "route", "raw", "validation", "logs"];
|
|
const normalized = asObject(result?.normalized);
|
|
const schemaVersion = String(normalized?.schema_version ?? "");
|
|
const isV2 =
|
|
schemaVersion === "normalized_query_v2" ||
|
|
schemaVersion === "normalized_query_v2_0_1" ||
|
|
schemaVersion === "normalized_query_v2_0_2";
|
|
|
|
const fragmentsView = isV2
|
|
? {
|
|
fragments: normalized?.fragments ?? [],
|
|
discarded_fragments: normalized?.discarded_fragments ?? []
|
|
}
|
|
: { note: "Fragment View доступен для normalized_query_v2." };
|
|
|
|
const scopeView = isV2
|
|
? {
|
|
message_in_scope: normalized?.message_in_scope ?? null,
|
|
scope_confidence: normalized?.scope_confidence ?? null,
|
|
contains_multiple_tasks: normalized?.contains_multiple_tasks ?? null,
|
|
global_notes: normalized?.global_notes ?? null
|
|
}
|
|
: { note: "Scope View доступен для normalized_query_v2." };
|
|
|
|
const flagsView = isV2
|
|
? Array.isArray(normalized?.fragments)
|
|
? (normalized?.fragments as Array<Record<string, unknown>>).map((fragment) => ({
|
|
fragment_id: fragment.fragment_id ?? null,
|
|
domain_relevance: fragment.domain_relevance ?? null,
|
|
candidate_labels: fragment.candidate_labels ?? [],
|
|
execution_readiness: fragment.execution_readiness ?? null,
|
|
clarification_reason: fragment.clarification_reason ?? null,
|
|
soft_assumption_used: fragment.soft_assumption_used ?? [],
|
|
route_status: fragment.route_status ?? null,
|
|
no_route_reason: fragment.no_route_reason ?? null,
|
|
flags: fragment.flags ?? {}
|
|
}))
|
|
: []
|
|
: { note: "Flags View доступен для normalized_query_v2." };
|
|
|
|
return (
|
|
<PanelFrame title="Выходные данные" subtitle="Structured output и диагностические вкладки.">
|
|
<div className="tab-row">
|
|
{tabs.map((item) => (
|
|
<button key={item} type="button" className={tab === item ? "tab active" : "tab"} onClick={() => onTabChange(item)}>
|
|
{TAB_LABELS[item]}
|
|
</button>
|
|
))}
|
|
</div>
|
|
{tab === "normalized" ? <JsonView value={result?.normalized ?? { note: "Нет данных." }} /> : null}
|
|
{tab === "fragments" ? <JsonView value={fragmentsView} /> : null}
|
|
{tab === "scope" ? <JsonView value={scopeView} /> : null}
|
|
{tab === "flags" ? <JsonView value={flagsView} /> : null}
|
|
{tab === "route" ? <JsonView value={result?.route_hint_summary ?? { note: "Нет данных." }} /> : null}
|
|
{tab === "raw" ? <JsonView value={result?.raw_model_output ?? { note: "Нет данных." }} /> : null}
|
|
{tab === "validation" ? <JsonView value={result?.validation ?? { note: "Нет данных." }} /> : null}
|
|
{tab === "logs" ? <JsonView value={appLogs} /> : null}
|
|
</PanelFrame>
|
|
);
|
|
}
|