import { Suspense, useState } from "react"; import { CodeBlock } from "~/components/code/CodeBlock"; import { StreamdownRenderer } from "~/components/code/StreamdownRenderer"; import { Header3 } from "~/components/primitives/Headers"; import { TextLink } from "~/components/primitives/TextLink"; import { tryPrettyJson } from "./ai/aiHelpers"; import { SpanMetricRow as MetricRow } from "./ai/SpanMetricRow"; import { useEnvironment } from "~/hooks/useEnvironment"; import { useOrganization } from "~/hooks/useOrganizations"; import { useProject } from "~/hooks/useProject"; import { v3PromptPath } from "~/utils/pathBuilder"; import { TabButton, TabContainer } from "~/components/primitives/Tabs"; import type { PromptSpanData } from "~/presenters/v3/SpanPresenter.server"; import { SpanHorizontalTimeline } from "~/components/runs/v3/SpanHorizontalTimeline"; type PromptTab = "overview" | "input" | "template"; export function PromptSpanDetails({ promptData, startTime, duration, }: { promptData: PromptSpanData; startTime?: string | Date; duration?: number | null; }) { const organization = useOrganization(); const project = useProject(); const environment = useEnvironment(); const promptPath = organization && project && environment ? v3PromptPath(organization, project, environment, promptData.slug, promptData.version) : undefined; const hasInput = !!promptData.input; const hasTemplate = !!promptData.template; const availableTabs: PromptTab[] = [ "overview", ...(hasInput ? (["input"] as const) : []), ...(hasTemplate ? (["template"] as const) : []), ]; const [tab, setTab] = useState("overview"); const labels = promptData.labels ? promptData.labels .split(",") .map((l) => l.trim()) .filter(Boolean) : []; return (
{availableTabs.map((t) => ( setTab(t)} shortcut={ t === "overview" ? { key: "o" } : t === "input" ? { key: "i" } : { key: "t" } } > {t === "overview" ? "Overview" : t === "input" ? "Input" : "Template"} ))}
{tab === "overview" && (
{startTime && ( )}
{promptData.slug} ) : ( promptData.slug ) } /> {labels.length > 0 && } {promptData.model && }
{promptData.text && (
Resolved content
{promptData.text.length > 300 ? promptData.text.slice(0, 300) + "..." : promptData.text} } > {promptData.text}
)}
)} {tab === "input" && hasInput && (
)} {tab === "template" && hasTemplate && (
{promptData.template!}} > {promptData.template!}
)}
); }