| 11 | }) |
| 12 | |
| 13 | function View(props: { api: TuiPluginApi; session_id: string }) { |
| 14 | const theme = () => props.api.theme.current |
| 15 | const msg = createMemo(() => props.api.state.session.messages(props.session_id)) |
| 16 | const session = createMemo(() => props.api.state.session.get(props.session_id)) |
| 17 | const cost = createMemo(() => session()?.cost ?? 0) |
| 18 | |
| 19 | const state = createMemo(() => { |
| 20 | const last = msg().findLast((item): item is AssistantMessage => item.role === "assistant" && item.tokens.output > 0) |
| 21 | if (!last) { |
| 22 | return { |
| 23 | tokens: 0, |
| 24 | percent: null, |
| 25 | } |
| 26 | } |
| 27 | |
| 28 | const tokens = |
| 29 | last.tokens.input + last.tokens.output + last.tokens.reasoning + last.tokens.cache.read + last.tokens.cache.write |
| 30 | const model = props.api.state.provider.find((item) => item.id === last.providerID)?.models[last.modelID] |
| 31 | return { |
| 32 | tokens, |
| 33 | percent: model?.limit.context ? Math.round((tokens / model.limit.context) * 100) : null, |
| 34 | } |
| 35 | }) |
| 36 | |
| 37 | return ( |
| 38 | <box> |
| 39 | <text fg={theme().text}> |
| 40 | <b>Context</b> |
| 41 | </text> |
| 42 | <text fg={theme().textMuted}>{state().tokens.toLocaleString()} tokens</text> |
| 43 | <text fg={theme().textMuted}>{state().percent ?? 0}% used</text> |
| 44 | <text fg={theme().textMuted}>{money.format(cost())} spent</text> |
| 45 | </box> |
| 46 | ) |
| 47 | } |
| 48 | |
| 49 | const tui: TuiPlugin = async (api) => { |
| 50 | api.slots.register({ |