115 lines · 3.8 KB · TypeScript
RawDownload
import { Match, Show, Switch, createMemo } from "solid-js"import { Tooltip } from "@synsci/ui/tooltip"import { ProgressCircle } from "@synsci/ui/progress-circle"import { Button } from "@synsci/ui/button"import { useParams } from "@solidjs/router"import { AssistantMessage } from "@synsci/sdk/v2/client"import { findLast } from "@synsci/util/array" import { useLayout } from "@/context/layout"import { useSync } from "@/context/sync"import { useLanguage } from "@/context/language" interface SessionContextUsageProps {  variant?: "button" | "indicator"} export function SessionContextUsage(props: SessionContextUsageProps) {  const sync = useSync()  const params = useParams()  const layout = useLayout()  const language = useLanguage()   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 usd = createMemo(    () =>      new Intl.NumberFormat(language.locale(), {        style: "currency",        currency: "USD",      }),  )   const cost = createMemo(() => {    const total = messages().reduce((sum, x) => sum + (x.role === "assistant" ? x.cost : 0), 0)    return usd().format(total)  })   const context = createMemo(() => {    const locale = language.locale()    const last = findLast(messages(), (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    const model = sync.data.provider.all.find((x) => x.id === last.providerID)?.models[last.modelID]    return {      tokens: total.toLocaleString(locale),      percentage: model?.limit.context ? Math.round((total / model.limit.context) * 100) : null,    }  })   const openContext = () => {    if (!params.id) return    layout.fileTree.open()    layout.fileTree.setTab("all")    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">{language.t("context.usage.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">{language.t("context.usage.usage")}</span>            </div>          </>        )}      </Show>      <div class="flex items-center gap-2">        <span class="text-text-invert-strong">{cost()}</span>        <span class="text-text-invert-base">{language.t("context.usage.cost")}</span>      </div>    </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}              aria-label={language.t("context.usage.view")}            >              {circle()}            </Button>          </Match>        </Switch>      </Tooltip>    </Show>  )}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t