summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/components
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-02-18 08:26:15 -0600
committerGitHub <[email protected]>2026-02-18 08:26:15 -0600
commit00c238777ae11dfd61c6249426cd201fc3612f1b (patch)
tree32c0a3c9a2c42734a2d9c3886b7c92d0b62eeee3 /packages/app/src/components
parente4b548fa768a59cea7e5c8279e327d990cd36c27 (diff)
downloadopencode-00c238777ae11dfd61c6249426cd201fc3612f1b.tar.gz
opencode-00c238777ae11dfd61c6249426cd201fc3612f1b.zip
chore: cleanup (#14113)
Diffstat (limited to 'packages/app/src/components')
-rw-r--r--packages/app/src/components/session/session-context-tab.tsx66
1 files changed, 47 insertions, 19 deletions
diff --git a/packages/app/src/components/session/session-context-tab.tsx b/packages/app/src/components/session/session-context-tab.tsx
index 81220b3ad..162e016c6 100644
--- a/packages/app/src/components/session/session-context-tab.tsx
+++ b/packages/app/src/components/session/session-context-tab.tsx
@@ -5,6 +5,7 @@ import { useSync } from "@/context/sync"
import { useLayout } from "@/context/layout"
import { checksum } from "@opencode-ai/util/encode"
import { findLast } from "@opencode-ai/util/array"
+import { same } from "@/utils/same"
import { Icon } from "@opencode-ai/ui/icon"
import { Accordion } from "@opencode-ai/ui/accordion"
import { StickyAccordionHeader } from "@opencode-ai/ui/sticky-accordion-header"
@@ -16,13 +17,6 @@ import { getSessionContextMetrics } from "./session-context-metrics"
import { estimateSessionContextBreakdown, type SessionContextBreakdownKey } from "./session-context-breakdown"
import { createSessionContextFormatter } from "./session-context-format"
-interface SessionContextTabProps {
- messages: () => Message[]
- visibleUserMessages: () => UserMessage[]
- view: () => ReturnType<ReturnType<typeof useLayout>["view"]>
- info: () => ReturnType<ReturnType<typeof useSync>["session"]["get"]>
-}
-
const BREAKDOWN_COLOR: Record<SessionContextBreakdownKey, string> = {
system: "var(--syntax-info)",
user: "var(--syntax-success)",
@@ -91,11 +85,45 @@ function RawMessage(props: {
)
}
-export function SessionContextTab(props: SessionContextTabProps) {
+const emptyMessages: Message[] = []
+const emptyUserMessages: UserMessage[] = []
+
+export function SessionContextTab() {
const params = useParams()
const sync = useSync()
+ const layout = useLayout()
const language = useLanguage()
+ const sessionKey = createMemo(() => `${params.dir}${params.id ? "/" + params.id : ""}`)
+ const view = createMemo(() => layout.view(sessionKey))
+ const info = createMemo(() => (params.id ? sync.session.get(params.id) : undefined))
+
+ const messages = createMemo(
+ () => {
+ const id = params.id
+ if (!id) return emptyMessages
+ return (sync.data.message[id] ?? []) as Message[]
+ },
+ emptyMessages,
+ { equals: same },
+ )
+
+ const userMessages = createMemo(
+ () => messages().filter((m) => m.role === "user") as UserMessage[],
+ emptyUserMessages,
+ { equals: same },
+ )
+
+ const visibleUserMessages = createMemo(
+ () => {
+ const revert = info()?.revert?.messageID
+ if (!revert) return userMessages()
+ return userMessages().filter((m) => m.id < revert)
+ },
+ emptyUserMessages,
+ { equals: same },
+ )
+
const usd = createMemo(
() =>
new Intl.NumberFormat(language.locale(), {
@@ -104,7 +132,7 @@ export function SessionContextTab(props: SessionContextTabProps) {
}),
)
- const metrics = createMemo(() => getSessionContextMetrics(props.messages(), sync.data.provider.all))
+ const metrics = createMemo(() => getSessionContextMetrics(messages(), sync.data.provider.all))
const ctx = createMemo(() => metrics().context)
const formatter = createMemo(() => createSessionContextFormatter(language.locale()))
@@ -113,7 +141,7 @@ export function SessionContextTab(props: SessionContextTabProps) {
})
const counts = createMemo(() => {
- const all = props.messages()
+ const all = messages()
const user = all.reduce((count, x) => count + (x.role === "user" ? 1 : 0), 0)
const assistant = all.reduce((count, x) => count + (x.role === "assistant" ? 1 : 0), 0)
return {
@@ -124,7 +152,7 @@ export function SessionContextTab(props: SessionContextTabProps) {
})
const systemPrompt = createMemo(() => {
- const msg = findLast(props.visibleUserMessages(), (m) => !!m.system)
+ const msg = findLast(visibleUserMessages(), (m) => !!m.system)
const system = msg?.system
if (!system) return
const trimmed = system.trim()
@@ -146,12 +174,12 @@ export function SessionContextTab(props: SessionContextTabProps) {
const breakdown = createMemo(
on(
- () => [ctx()?.message.id, ctx()?.input, props.messages().length, systemPrompt()],
+ () => [ctx()?.message.id, ctx()?.input, messages().length, systemPrompt()],
() => {
const c = ctx()
if (!c?.input) return []
return estimateSessionContextBreakdown({
- messages: props.messages(),
+ messages: messages(),
parts: sync.data.part as Record<string, Part[] | undefined>,
input: c.input,
systemPrompt: systemPrompt(),
@@ -169,7 +197,7 @@ export function SessionContextTab(props: SessionContextTabProps) {
}
const stats = [
- { label: "context.stats.session", value: () => props.info()?.title ?? params.id ?? "—" },
+ { label: "context.stats.session", value: () => info()?.title ?? params.id ?? "—" },
{ label: "context.stats.messages", value: () => counts().all.toLocaleString(language.locale()) },
{ label: "context.stats.provider", value: providerLabel },
{ label: "context.stats.model", value: modelLabel },
@@ -186,7 +214,7 @@ export function SessionContextTab(props: SessionContextTabProps) {
{ label: "context.stats.userMessages", value: () => counts().user.toLocaleString(language.locale()) },
{ label: "context.stats.assistantMessages", value: () => counts().assistant.toLocaleString(language.locale()) },
{ label: "context.stats.totalCost", value: cost },
- { label: "context.stats.sessionCreated", value: () => formatter().time(props.info()?.time.created) },
+ { label: "context.stats.sessionCreated", value: () => formatter().time(info()?.time.created) },
{ label: "context.stats.lastActivity", value: () => formatter().time(ctx()?.message.time.created) },
] satisfies { label: string; value: () => JSX.Element }[]
@@ -199,7 +227,7 @@ export function SessionContextTab(props: SessionContextTabProps) {
const el = scroll
if (!el) return
- const s = props.view()?.scroll("context")
+ const s = view().scroll("context")
if (!s) return
if (el.scrollTop !== s.y) el.scrollTop = s.y
@@ -220,13 +248,13 @@ export function SessionContextTab(props: SessionContextTabProps) {
pending = undefined
if (!next) return
- props.view().setScroll("context", next)
+ view().setScroll("context", next)
})
}
createEffect(
on(
- () => props.messages().length,
+ () => messages().length,
() => {
requestAnimationFrame(restoreScroll)
},
@@ -300,7 +328,7 @@ export function SessionContextTab(props: SessionContextTabProps) {
<div class="flex flex-col gap-2">
<div class="text-12-regular text-text-weak">{language.t("context.rawMessages.title")}</div>
<Accordion multiple>
- <For each={props.messages()}>
+ <For each={messages()}>
{(message) => (
<RawMessage message={message} getParts={getParts} onRendered={restoreScroll} time={formatter().time} />
)}