import { createMemo, createSignal, Show } from "solid-js" import { useRouteData } from "@tui/context/route" import { useSync } from "@tui/context/sync" import { useTheme } from "@tui/context/theme" import { SplitBorder } from "@tui/component/border" import type { AssistantMessage } from "@opencode-ai/sdk/v2" import { Locale } from "@/util/locale" import { useTerminalDimensions } from "@opentui/solid" import { useCommandPalette } from "../../context/command-palette" import { useCommandShortcut } from "../../keymap" export function SubagentFooter() { const route = useRouteData("session") const sync = useSync() const messages = createMemo(() => sync.data.message[route.sessionID] ?? []) const session = createMemo(() => sync.session.get(route.sessionID)) const subagentInfo = createMemo(() => { const s = session() if (!s) return { label: "Subagent", index: 0, total: 0 } const agentMatch = s.title.match(/@(\w+) subagent/) const label = agentMatch ? Locale.titlecase(agentMatch[1]) : "Subagent" if (!s.parentID) return { label, index: 0, total: 0 } const siblings = sync.data.session .filter((x) => x.parentID === s.parentID) .toSorted((a, b) => a.time.created - b.time.created) const index = siblings.findIndex((x) => x.id === s.id) return { label, index: index + 1, total: siblings.length } }) const usage = createMemo(() => { const msg = messages() const last = msg.findLast((item): item is AssistantMessage => item.role === "assistant" && item.tokens.output > 0) if (!last) return const tokens = last.tokens.input + last.tokens.output + last.tokens.reasoning + last.tokens.cache.read + last.tokens.cache.write if (tokens <= 0) return const model = sync.data.provider.find((item) => item.id === last.providerID)?.models[last.modelID] const pct = model?.limit.context ? `${Math.round((tokens / model.limit.context) * 100)}%` : undefined const cost = msg.reduce((sum, item) => sum + (item.role === "assistant" ? item.cost : 0), 0) const money = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", }) return { context: pct ? `${Locale.number(tokens)} (${pct})` : Locale.number(tokens), cost: cost > 0 ? money.format(cost) : undefined, } }) const { theme } = useTheme() const command = useCommandPalette() const parentShortcut = useCommandShortcut("session.parent") const previousShortcut = useCommandShortcut("session.child.previous") const nextShortcut = useCommandShortcut("session.child.next") const [hover, setHover] = createSignal<"parent" | "prev" | "next" | null>(null) useTerminalDimensions() return ( {subagentInfo().label} 0}> ({subagentInfo().index} of {subagentInfo().total}) {(item) => ( {[item().context, item().cost].filter(Boolean).join(" ยท ")} )} setHover("parent")} onMouseOut={() => setHover(null)} onMouseUp={() => command.run("session.parent")} backgroundColor={hover() === "parent" ? theme.backgroundElement : theme.backgroundPanel} > Parent {parentShortcut()} setHover("prev")} onMouseOut={() => setHover(null)} onMouseUp={() => command.run("session.child.previous")} backgroundColor={hover() === "prev" ? theme.backgroundElement : theme.backgroundPanel} > Prev {previousShortcut()} setHover("next")} onMouseOut={() => setHover(null)} onMouseUp={() => command.run("session.child.next")} backgroundColor={hover() === "next" ? theme.backgroundElement : theme.backgroundPanel} > Next {nextShortcut()} ) }