




















@@ -1,6 +1,16 @@
11import { html, nothing } from "lit";
2+import { icons } from "../icons.ts";
23import type { GatewaySessionRow } from "../types.ts";
345+const CONTEXT_NOTICE_RATIO = 0.85;
6+const CONTEXT_COMPACT_RATIO = 0.9;
7+8+export type ContextNoticeOptions = {
9+compactBusy?: boolean;
10+compactDisabled?: boolean;
11+onCompact?: () => void | Promise<void>;
12+};
13+414/** Parse a 6-digit CSS hex color string to [r, g, b] integer components. */
515function parseHexRgb(hex: string): [number, number, number] | null {
616const h = hex.trim().replace(/^#/, "");
@@ -49,6 +59,7 @@ export function getContextNoticeViewModel(
4959detail: string;
5060color: string;
5161bg: string;
62+compactRecommended: boolean;
5263} | null {
5364if (session?.totalTokensFresh === false) {
5465return null;
@@ -59,7 +70,7 @@ export function getContextNoticeViewModel(
5970return null;
6071}
6172const ratio = used / limit;
62-if (ratio < 0.85) {
73+if (ratio < CONTEXT_NOTICE_RATIO) {
6374return null;
6475}
6576const pct = Math.min(Math.round(ratio * 100), 100);
@@ -79,17 +90,21 @@ export function getContextNoticeViewModel(
7990detail: `${formatTokensCompact(used)} / ${formatTokensCompact(limit)}`,
8091 color,
8192 bg,
93+compactRecommended: ratio >= CONTEXT_COMPACT_RATIO,
8294};
8395}
84968597export function renderContextNotice(
8698session: GatewaySessionRow | undefined,
8799defaultContextTokens: number | null,
100+options: ContextNoticeOptions = {},
88101) {
89102const model = getContextNoticeViewModel(session, defaultContextTokens);
90103if (!model) {
91104return nothing;
92105}
106+const canRenderCompact = model.compactRecommended && options.onCompact;
107+const compactDisabled = options.compactDisabled === true || options.compactBusy === true;
93108return html`
94109 <div
95110 class="context-notice"
@@ -113,6 +128,30 @@ export function renderContextNotice(
113128 </svg>
114129 <span>${model.pct}% context used</span>
115130 <span class="context-notice__detail">${model.detail}</span>
131+ ${canRenderCompact
132+ ? html`
133+ <button
134+ class="context-notice__action ${options.compactBusy
135+ ? "context-notice__action--busy"
136+ : ""}"
137+ type="button"
138+ title="Compact session context"
139+ aria-label="Compact recommended session context"
140+ ?disabled=${compactDisabled}
141+ @click=${(event: Event) => {
142+ event.preventDefault();
143+ event.stopPropagation();
144+ if (compactDisabled) {
145+ return;
146+ }
147+ void options.onCompact?.();
148+ }}
149+ >
150+ ${options.compactBusy ? icons.loader : icons.minimize}
151+ <span>${options.compactBusy ? "Compacting" : "Compact"}</span>
152+ </button>
153+ `
154+ : nothing}
116155 </div>
117156 `;
118157}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。