diff --git a/pdl-live-react/src/helpers.ts b/pdl-live-react/src/helpers.ts index 340c73f6f..685f7f3aa 100644 --- a/pdl-live-react/src/helpers.ts +++ b/pdl-live-react/src/helpers.ts @@ -187,6 +187,19 @@ export function hasModelUsage( ) } +export function completionRate( + block: ModelBlockWithUsage & PdlBlockWithTiming, +) { + return ( + block.pdl__usage.completion_tokens / + ((block.pdl__timing.end_nanos - block.pdl__timing.start_nanos) / 1000000000) + ) +} + +export function ptcRatio(block: ModelBlockWithUsage) { + return block.pdl__usage.prompt_tokens / block.pdl__usage.completion_tokens +} + /** Does the given block have context/background information? */ export function hasContextInformation( block: unknown | PdlBlock, diff --git a/pdl-live-react/src/view/detail/DrawerContentBody.tsx b/pdl-live-react/src/view/detail/DrawerContentBody.tsx index 7dd578ae0..26a2150c7 100644 --- a/pdl-live-react/src/view/detail/DrawerContentBody.tsx +++ b/pdl-live-react/src/view/detail/DrawerContentBody.tsx @@ -3,6 +3,7 @@ import { Tab, TabTitleText } from "@patternfly/react-core" const BlockNotFound = lazy(() => import("./BlockNotFound")) const DefContent = lazy(() => import("./DefContent")) +const UsageTabContent = lazy(() => import("./UsageTabContent")) const SourceTabContent = lazy(() => import("./SourceTabContent")) const ContextTabContent = lazy(() => import("./ContextTabContent")) const SummaryTabContent = lazy(() => import("./SummaryTabContent")) @@ -10,6 +11,7 @@ const RawTraceTabContent = lazy(() => import("./RawTraceTabContent")) import { hasContextInformation, + hasModelUsage, hasResult, type NonScalarPdlBlock as Model, } from "../../helpers" @@ -54,6 +56,18 @@ function blockBody(block: Model) { ) } + if (hasModelUsage(block)) { + tabs.splice( + 1, + 0, + Usage}> + + + + , + ) + } + return tabs } diff --git a/pdl-live-react/src/view/detail/UsageTabContent.tsx b/pdl-live-react/src/view/detail/UsageTabContent.tsx new file mode 100644 index 000000000..9f5663942 --- /dev/null +++ b/pdl-live-react/src/view/detail/UsageTabContent.tsx @@ -0,0 +1,55 @@ +import { + DescriptionList, + DescriptionListGroup, + DescriptionListDescription, + DescriptionListTerm, +} from "@patternfly/react-core" + +import { + completionRate, + ptcRatio, + type ModelBlockWithUsage, + type PdlBlockWithTiming, +} from "../../helpers" + +export default function UsageTabContent({ + block, +}: { + block: ModelBlockWithUsage & PdlBlockWithTiming +}) { + return {descriptionItems(block)} +} + +function descriptionItems(block: ModelBlockWithUsage & PdlBlockWithTiming) { + return ( + <> + + Completion Rate + + {completionRate(block).toFixed(0)} tokens/sec + + + + + Prompt/Completion Ratio + + {(ptcRatio(block) * 100).toFixed(2)}% + + + + + Prompt Tokens Consumed + + {block.pdl__usage.prompt_tokens} + + + + + Completion Tokens Consumed + + {block.pdl__usage.completion_tokens} + + + + ) +} diff --git a/pdl-live-react/src/view/masonry/MasonryTile.tsx b/pdl-live-react/src/view/masonry/MasonryTile.tsx index 4bef5c788..c79e15c67 100644 --- a/pdl-live-react/src/view/masonry/MasonryTile.tsx +++ b/pdl-live-react/src/view/masonry/MasonryTile.tsx @@ -53,6 +53,8 @@ export default function MasonryTile({ footer1Value, footer2Key, footer2Value, + footer3Key, + footer3Value, stability, actions: tileActions = [], block, @@ -119,6 +121,7 @@ export default function MasonryTile({ const hasFooter = (footer1Key && footer1Value) || (footer2Key && footer2Value) || + (footer3Key && footer3Value) || (stability?.length ?? 0) > 0 const footer = hasFooter && ( @@ -138,6 +141,14 @@ export default function MasonryTile({ )} + {footer3Key && ( + + {footer3Key} + + {footer3Value} + + + )} {stability && stability.map((m) => ( `T=${m.temperature} Stability`),