import { type Accessor, createMemo, Match, Show, Switch } from "solid-js" import { useRouteData } from "@tui/context/route" import { useSync } from "@tui/context/sync" import { pipe, sumBy } from "remeda" import { useTheme } from "@tui/context/theme" import { SplitBorder } from "@tui/component/border" import type { AssistantMessage, Session } from "@opencode-ai/sdk/v2" import { useKeybind } from "../../context/keybind" const Title = (props: { session: Accessor }) => { const { theme } = useTheme() return ( # {props.session().title} ) } const ContextInfo = (props: { context: Accessor; cost: Accessor }) => { const { theme } = useTheme() return ( {props.context()} ({props.cost()}) ) } export function Header() { const route = useRouteData("session") const sync = useSync() const session = createMemo(() => sync.session.get(route.sessionID)!) const messages = createMemo(() => sync.data.message[route.sessionID] ?? []) const cost = createMemo(() => { const total = pipe( messages(), sumBy((x) => (x.role === "assistant" ? x.cost : 0)), ) return new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", }).format(total) }) const context = createMemo(() => { const last = messages().findLast((x) => x.role === "assistant" && x.tokens.output > 0) as AssistantMessage if (!last) return const total = last.tokens.input + last.tokens.output + last.tokens.reasoning + last.tokens.cache.read + last.tokens.cache.write const model = sync.data.provider.find((x) => x.id === last.providerID)?.models[last.modelID] let result = total.toLocaleString() if (model?.limit.context) { result += " " + Math.round((total / model.limit.context) * 100) + "%" } return result }) const { theme } = useTheme() const keybind = useKeybind() return ( Subagent session Parent {keybind.print("session_parent")} Prev {keybind.print("session_child_cycle_reverse")} Next {keybind.print("session_child_cycle")} <ContextInfo context={context} cost={cost} /> </box> </Match> </Switch> </box> </box> ) }