diff options
| author | Adam <[email protected]> | 2026-01-01 05:23:00 -0600 |
|---|---|---|
| committer | Adam <[email protected]> | 2026-01-01 05:23:07 -0600 |
| commit | 6e7fc30f9407f48074852415e2c35958b82b78ed (patch) | |
| tree | 9d2c0d8bddac44d80e4a6f51df4182e94e84c895 /packages/app/src/components | |
| parent | 03733b0505989cf23538cdbb4f1644fae109b4b7 (diff) | |
| download | opencode-6e7fc30f9407f48074852415e2c35958b82b78ed.tar.gz opencode-6e7fc30f9407f48074852415e2c35958b82b78ed.zip | |
feat(app): context window window
Diffstat (limited to 'packages/app/src/components')
| -rw-r--r-- | packages/app/src/components/session-context-usage.tsx | 100 |
1 files changed, 70 insertions, 30 deletions
diff --git a/packages/app/src/components/session-context-usage.tsx b/packages/app/src/components/session-context-usage.tsx index ece1f8695..53e578214 100644 --- a/packages/app/src/components/session-context-usage.tsx +++ b/packages/app/src/components/session-context-usage.tsx @@ -1,13 +1,25 @@ -import { createMemo, Show } from "solid-js" +import { Match, Show, Switch, createMemo } from "solid-js" import { Tooltip } from "@opencode-ai/ui/tooltip" import { ProgressCircle } from "@opencode-ai/ui/progress-circle" -import { useSync } from "@/context/sync" +import { Button } from "@opencode-ai/ui/button" import { useParams } from "@solidjs/router" import { AssistantMessage } from "@opencode-ai/sdk/v2/client" -export function SessionContextUsage() { +import { useLayout } from "@/context/layout" +import { useSync } from "@/context/sync" + +interface SessionContextUsageProps { + variant?: "button" | "indicator" +} + +export function SessionContextUsage(props: SessionContextUsageProps) { const sync = useSync() const params = useParams() + const layout = useLayout() + + const variant = createMemo(() => props.variant ?? "button") + const sessionKey = createMemo(() => `${params.dir}${params.id ? "/" + params.id : ""}`) + const tabs = createMemo(() => layout.tabs(sessionKey())) const messages = createMemo(() => (params.id ? (sync.data.message[params.id] ?? []) : [])) const cost = createMemo(() => { @@ -19,7 +31,11 @@ export function SessionContextUsage() { }) const context = createMemo(() => { - const last = messages().findLast((x) => x.role === "assistant" && x.tokens.output > 0) as AssistantMessage + const last = messages().findLast((x) => { + if (x.role !== "assistant") return false + const total = x.tokens.input + x.tokens.output + x.tokens.reasoning + x.tokens.cache.read + x.tokens.cache.write + return total > 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 @@ -30,33 +46,57 @@ export function SessionContextUsage() { } }) - return ( - <Show when={context?.()}> - {(ctx) => ( - <Tooltip - value={ - <div class=""> - <div class="flex items-center gap-2"> - <span class="text-text-invert-strong">{ctx().tokens}</span> - <span class="text-text-invert-base">Tokens</span> - </div> - <div class="flex items-center gap-2"> - <span class="text-text-invert-strong">{ctx().percentage ?? 0}%</span> - <span class="text-text-invert-base">Usage</span> - </div> - <div class="flex items-center gap-2"> - <span class="text-text-invert-strong">{cost()}</span> - <span class="text-text-invert-base">Cost</span> - </div> + const openContext = () => { + if (!params.id) return + layout.review.open() + tabs().open("context") + tabs().setActive("context") + } + + const circle = () => ( + <div class="p-1"> + <ProgressCircle size={16} strokeWidth={2} percentage={context()?.percentage ?? 0} /> + </div> + ) + + const tooltipValue = () => ( + <div> + <Show when={context()}> + {(ctx) => ( + <> + <div class="flex items-center gap-2"> + <span class="text-text-invert-strong">{ctx().tokens}</span> + <span class="text-text-invert-base">Tokens</span> + </div> + <div class="flex items-center gap-2"> + <span class="text-text-invert-strong">{ctx().percentage ?? 0}%</span> + <span class="text-text-invert-base">Usage</span> </div> - } - placement="top" - > - <div class="p-1"> - <ProgressCircle size={16} strokeWidth={2} percentage={ctx().percentage ?? 0} /> - </div> - </Tooltip> - )} + </> + )} + </Show> + <div class="flex items-center gap-2"> + <span class="text-text-invert-strong">{cost()}</span> + <span class="text-text-invert-base">Cost</span> + </div> + <Show when={variant() === "button"}> + <div class="text-11-regular text-text-invert-base mt-1">Click to view context</div> + </Show> + </div> + ) + + return ( + <Show when={params.id}> + <Tooltip value={tooltipValue()} placement="top"> + <Switch> + <Match when={variant() === "indicator"}>{circle()}</Match> + <Match when={true}> + <Button type="button" variant="ghost" class="size-6" onClick={openContext}> + {circle()} + </Button> + </Match> + </Switch> + </Tooltip> </Show> ) } |
