diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index debc0341a2..1461da0aee 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -54,6 +54,7 @@ import { useRenderer, useTerminalDimensions, type JSX } from "@opentui/solid" import { useSDK } from "@tui/context/sdk" import { useEditorContext } from "@tui/context/editor" import { useDialog } from "../../ui/dialog" +import { DialogAlert } from "../../ui/dialog-alert" import { TodoItem } from "../../component/todo-item" import { DialogMessage } from "./dialog-message" import type { PromptInfo } from "../../component/prompt/history" @@ -409,15 +410,19 @@ export function Session() { const local = useLocal() + function enterChild(sessionID: string) { + navigate({ + type: "session", + sessionID, + }) + const status = sync.data.session_status[sessionID] + if (status?.type === "retry") void DialogAlert.show(dialog, "Retry Error", status.message) + } + function moveFirstChild() { if (children().length === 1) return const next = children().find((x) => !!x.parentID) - if (next) { - navigate({ - type: "session", - sessionID: next.id, - }) - } + if (next) enterChild(next.id) } function moveChild(direction: number) { @@ -428,12 +433,7 @@ export function Session() { if (next >= sessions.length) next = 0 if (next < 0) next = sessions.length - 1 - if (sessions[next]) { - navigate({ - type: "session", - sessionID: sessions[next].id, - }) - } + if (sessions[next]) enterChild(sessions[next].id) } function childSessionHandler(func: () => void) { @@ -1007,8 +1007,8 @@ export function Session() { category: "Session", hidden: true, run: () => { - moveFirstChild() dialog.clear() + moveFirstChild() }, }, { @@ -1035,8 +1035,8 @@ export function Session() { hidden: true, enabled: !!session()?.parentID, run: childSessionHandler(() => { - moveChild(1) dialog.clear() + moveChild(1) }), }, { @@ -1046,8 +1046,8 @@ export function Session() { hidden: true, enabled: !!session()?.parentID, run: childSessionHandler(() => { - moveChild(-1) dialog.clear() + moveChild(-1) }), }, ]) @@ -1758,6 +1758,7 @@ function GenericTool(props: ToolProps) { function InlineTool(props: { icon: string iconColor?: RGBA + color?: RGBA complete: any pending: string spinner?: boolean @@ -1779,6 +1780,7 @@ function InlineTool(props: { }) const fg = createMemo(() => { + if (props.color) return props.color if (permission()) return theme.warning if (hover() && props.onClick) return theme.text if (props.complete) return theme.textMuted @@ -2063,8 +2065,10 @@ function WebSearch(props: ToolProps) { } function Task(props: ToolProps) { + const { theme } = useTheme() const { navigate } = useRoute() const sync = useSync() + const dialog = useDialog() onMount(() => { if (props.metadata.sessionId && !sync.data.message[props.metadata.sessionId]?.length) @@ -2086,6 +2090,11 @@ function Task(props: ToolProps) { ) const isRunning = createMemo(() => props.part.state.status === "running") + const retry = createMemo(() => { + const status = sync.data.session_status[props.metadata.sessionId ?? ""] + if (status?.type !== "retry") return + return status + }) const duration = createMemo(() => { const first = messages().find((x) => x.role === "user")?.time.created @@ -2100,7 +2109,10 @@ function Task(props: ToolProps) { props.metadata.background === true ? `${props.input.description} (background)` : props.input.description let content = [`${Locale.titlecase(props.input.subagent_type ?? "General")} Task — ${description}`] - if (isRunning() && tools().length > 0) { + const retrying = retry() + if (isRunning() && retrying) { + content.push(`↳ ${Locale.truncate(retrying.message, 80)} [retrying attempt #${retrying.attempt}]`) + } else if (isRunning() && tools().length > 0) { // content[0] += ` · ${tools().length} toolcalls` if (current()) { const state = current()!.state @@ -2123,6 +2135,7 @@ function Task(props: ToolProps) { return ( ) { if (props.metadata.sessionId) { navigate({ type: "session", sessionID: props.metadata.sessionId }) } + const status = retry() + if (status) void DialogAlert.show(dialog, "Retry Error", status.message) }} > {content()}