cloudaxe-opencode/packages/app/src/components/session-context-usage.tsx

112 lines
3.6 KiB
TypeScript
Raw Normal View History

2026-01-01 11:23:00 +00:00
import { Match, Show, Switch, createMemo } from "solid-js"
import { Tooltip } from "@opencode-ai/ui/tooltip"
import { ProgressCircle } from "@opencode-ai/ui/progress-circle"
2026-01-01 11:23:00 +00:00
import { Button } from "@opencode-ai/ui/button"
import { useParams } from "@solidjs/router"
2026-01-01 11:23:00 +00:00
import { useLayout } from "@/context/layout"
import { useSync } from "@/context/sync"
2026-01-20 16:20:43 +00:00
import { useLanguage } from "@/context/language"
2026-02-06 15:37:49 +00:00
import { getSessionContextMetrics } from "@/components/session/session-context-metrics"
2026-01-01 11:23:00 +00:00
interface SessionContextUsageProps {
variant?: "button" | "indicator"
}
function openSessionContext(args: {
view: ReturnType<ReturnType<typeof useLayout>["view"]>
2026-02-12 20:48:09 +00:00
layout: ReturnType<typeof useLayout>
tabs: ReturnType<ReturnType<typeof useLayout>["tabs"]>
}) {
if (!args.view.reviewPanel.opened()) args.view.reviewPanel.open()
2026-02-12 20:48:09 +00:00
if (args.layout.fileTree.opened() && args.layout.fileTree.tab() !== "all") args.layout.fileTree.setTab("all")
args.tabs.open("context")
args.tabs.setActive("context")
}
2026-01-01 11:23:00 +00:00
export function SessionContextUsage(props: SessionContextUsageProps) {
const sync = useSync()
const params = useParams()
2026-01-01 11:23:00 +00:00
const layout = useLayout()
2026-01-20 16:20:43 +00:00
const language = useLanguage()
2026-01-01 11:23:00 +00:00
const variant = createMemo(() => props.variant ?? "button")
const sessionKey = createMemo(() => `${params.dir}${params.id ? "/" + params.id : ""}`)
const tabs = createMemo(() => layout.tabs(sessionKey))
const view = createMemo(() => layout.view(sessionKey))
const messages = createMemo(() => (params.id ? (sync.data.message[params.id] ?? []) : []))
2026-01-25 12:42:33 +00:00
const usd = createMemo(
() =>
new Intl.NumberFormat(language.locale(), {
style: "currency",
currency: "USD",
}),
)
2026-02-06 15:37:49 +00:00
const metrics = createMemo(() => getSessionContextMetrics(messages(), sync.data.provider.all))
const context = createMemo(() => metrics().context)
const cost = createMemo(() => {
2026-02-06 15:37:49 +00:00
return usd().format(metrics().totalCost)
})
2026-01-01 11:23:00 +00:00
const openContext = () => {
if (!params.id) return
openSessionContext({
view: view(),
2026-02-12 20:48:09 +00:00
layout,
tabs: tabs(),
})
2026-01-01 11:23:00 +00:00
}
const circle = () => (
<div class="flex items-center justify-center">
2026-02-06 15:37:49 +00:00
<ProgressCircle size={16} strokeWidth={2} percentage={context()?.usage ?? 0} />
2026-01-01 11:23:00 +00:00
</div>
)
const tooltipValue = () => (
<div>
<Show when={context()}>
{(ctx) => (
<>
<div class="flex items-center gap-2">
2026-02-06 15:37:49 +00:00
<span class="text-text-invert-strong">{ctx().total.toLocaleString(language.locale())}</span>
2026-01-20 16:20:43 +00:00
<span class="text-text-invert-base">{language.t("context.usage.tokens")}</span>
2026-01-01 11:23:00 +00:00
</div>
<div class="flex items-center gap-2">
2026-02-06 15:37:49 +00:00
<span class="text-text-invert-strong">{ctx().usage ?? 0}%</span>
2026-01-20 16:20:43 +00:00
<span class="text-text-invert-base">{language.t("context.usage.usage")}</span>
</div>
2026-01-01 11:23:00 +00:00
</>
)}
</Show>
<div class="flex items-center gap-2">
<span class="text-text-invert-strong">{cost()}</span>
2026-01-20 16:20:43 +00:00
<span class="text-text-invert-base">{language.t("context.usage.cost")}</span>
2026-01-01 11:23:00 +00:00
</div>
</div>
)
return (
<Show when={params.id}>
<Tooltip value={tooltipValue()} placement="top">
<Switch>
<Match when={variant() === "indicator"}>{circle()}</Match>
<Match when={true}>
2026-01-22 11:36:28 +00:00
<Button
type="button"
variant="ghost"
class="size-6"
2026-01-22 11:36:28 +00:00
onClick={openContext}
aria-label={language.t("context.usage.view")}
>
2026-01-01 11:23:00 +00:00
{circle()}
</Button>
</Match>
</Switch>
</Tooltip>
</Show>
)
}