refactor(tui): simplify inline tool spacing (#33097)
This commit is contained in:
parent
95237a90a7
commit
009f3799cd
3 changed files with 62 additions and 72 deletions
|
|
@ -91,6 +91,8 @@ const GO_UPSELL_ACCOUNT_RATE_LIMIT_DONT_SHOW = "go_upsell_account_rate_limit_don
|
|||
const GO_UPSELL_WINDOW = 86_400_000 // 24 hrs
|
||||
const GO_UPSELL_PROVIDERS = new Set(["opencode", "opencode-go"])
|
||||
|
||||
export const alwaysSeparate = new WeakSet<BoxRenderable>()
|
||||
|
||||
type RetryAction = Extract<SessionStatus, { type: "retry" }>["action"]
|
||||
|
||||
function goUpsellKeys(action: RetryAction) {
|
||||
|
|
@ -160,7 +162,6 @@ const context = createContext<{
|
|||
showTimestamps: () => boolean
|
||||
showDetails: () => boolean
|
||||
showGenericToolOutput: () => boolean
|
||||
userMessageIDs: () => ReadonlySet<string>
|
||||
diffWrapMode: () => "word" | "none"
|
||||
providers: () => ReadonlyMap<string, Provider>
|
||||
sync: ReturnType<typeof useSync>
|
||||
|
|
@ -218,14 +219,6 @@ export function Session() {
|
|||
)
|
||||
: [],
|
||||
)
|
||||
const userMessageIDs = createMemo(
|
||||
() =>
|
||||
new Set(
|
||||
messages()
|
||||
.filter((message) => message.role === "user")
|
||||
.map((message) => message.id),
|
||||
),
|
||||
)
|
||||
const permissions = createMemo(() => {
|
||||
if (session()?.parentID) return []
|
||||
return children().flatMap((x) => sync.data.permission[x.id] ?? [])
|
||||
|
|
@ -1158,7 +1151,6 @@ export function Session() {
|
|||
showTimestamps,
|
||||
showDetails,
|
||||
showGenericToolOutput,
|
||||
userMessageIDs,
|
||||
diffWrapMode,
|
||||
providers,
|
||||
sync,
|
||||
|
|
@ -1395,6 +1387,7 @@ function UserMessage(props: {
|
|||
<Show when={text()}>
|
||||
<box
|
||||
id={props.message.id}
|
||||
ref={(el: BoxRenderable) => alwaysSeparate.add(el)}
|
||||
border={["left"]}
|
||||
borderColor={color()}
|
||||
customBorderChars={SplitBorder.customBorderChars}
|
||||
|
|
@ -1532,7 +1525,7 @@ function AssistantMessage(props: { message: AssistantMessage; parts: Part[]; las
|
|||
</Show>
|
||||
<Show when={props.message.error && props.message.error.name !== "MessageAbortedError"}>
|
||||
<box
|
||||
id={`assistant-error-${props.message.id}`}
|
||||
ref={(el: BoxRenderable) => alwaysSeparate.add(el)}
|
||||
border={["left"]}
|
||||
paddingTop={1}
|
||||
paddingBottom={1}
|
||||
|
|
@ -1547,7 +1540,7 @@ function AssistantMessage(props: { message: AssistantMessage; parts: Part[]; las
|
|||
</Show>
|
||||
<Switch>
|
||||
<Match when={props.last || final() || props.message.error?.name === "MessageAbortedError"}>
|
||||
<box id={`assistant-summary-${props.message.id}`} paddingLeft={3}>
|
||||
<box ref={(el: BoxRenderable) => alwaysSeparate.add(el)} paddingLeft={3}>
|
||||
<text marginTop={1}>
|
||||
<span
|
||||
style={{
|
||||
|
|
@ -1613,7 +1606,7 @@ function ReasoningPart(props: { last: boolean; part: ReasoningPart; message: Ass
|
|||
return (
|
||||
<Show when={content()}>
|
||||
<box
|
||||
id={`text-${props.part.messageID}-${props.part.id}`}
|
||||
ref={(el: BoxRenderable) => alwaysSeparate.add(el)}
|
||||
paddingLeft={3}
|
||||
marginTop={1}
|
||||
flexDirection="column"
|
||||
|
|
@ -1695,7 +1688,7 @@ function TextPart(props: { last: boolean; part: TextPart; message: AssistantMess
|
|||
const { theme, syntax } = useTheme()
|
||||
return (
|
||||
<Show when={props.part.text.trim()}>
|
||||
<box id={`text-${props.part.messageID}-${props.part.id}`} paddingLeft={3} marginTop={1} flexShrink={0}>
|
||||
<box ref={(el: BoxRenderable) => alwaysSeparate.add(el)} paddingLeft={3} marginTop={1} flexShrink={0}>
|
||||
<markdown
|
||||
syntaxStyle={syntax()}
|
||||
streaming={true}
|
||||
|
|
@ -1845,7 +1838,6 @@ function InlineTool(props: {
|
|||
pending: string
|
||||
failure?: string
|
||||
spinner?: boolean
|
||||
subagent?: boolean
|
||||
children: JSX.Element
|
||||
part: ToolPart
|
||||
onClick?: () => void
|
||||
|
|
@ -1886,7 +1878,6 @@ function InlineTool(props: {
|
|||
|
||||
return (
|
||||
<InlineToolRow
|
||||
id={`tool-inline-${props.subagent ? "subagent-" : ""}${props.part.messageID}-${props.part.id}`}
|
||||
icon={props.icon}
|
||||
iconColor={props.iconColor}
|
||||
color={fg()}
|
||||
|
|
@ -1899,8 +1890,6 @@ function InlineTool(props: {
|
|||
pending={props.pending}
|
||||
failure={props.failure}
|
||||
spinner={props.spinner}
|
||||
subagent={props.subagent}
|
||||
separateAfter={(id) => id !== undefined && ctx.userMessageIDs().has(id)}
|
||||
onMouseOver={() => clickable() && setHover(true)}
|
||||
onMouseOut={() => setHover(false)}
|
||||
onMouseUp={() => {
|
||||
|
|
@ -1918,7 +1907,6 @@ function InlineTool(props: {
|
|||
}
|
||||
|
||||
export function InlineToolRow(props: {
|
||||
id?: string
|
||||
icon: string
|
||||
iconColor?: RGBA
|
||||
color?: RGBA
|
||||
|
|
@ -1931,32 +1919,20 @@ export function InlineToolRow(props: {
|
|||
pending: string
|
||||
failure?: string
|
||||
spinner?: boolean
|
||||
subagent?: boolean
|
||||
children: JSX.Element
|
||||
separateAfter?: (id: string | undefined) => boolean
|
||||
onMouseOver?: () => void
|
||||
onMouseOut?: () => void
|
||||
onMouseUp?: () => void
|
||||
}) {
|
||||
return (
|
||||
<box
|
||||
id={props.id}
|
||||
paddingLeft={3}
|
||||
onMouseOver={props.onMouseOver}
|
||||
onMouseOut={props.onMouseOut}
|
||||
onMouseUp={props.onMouseUp}
|
||||
ref={(el: BoxRenderable) => {
|
||||
setPreLayoutSiblingMargin(el, (previous) => {
|
||||
const previousInline = previous?.id.startsWith("tool-inline-") ?? false
|
||||
const previousSubagent = previous?.id.startsWith("tool-inline-subagent-") ?? false
|
||||
return previous?.id.startsWith("text-") ||
|
||||
previous?.id.startsWith("tool-block-") ||
|
||||
previous?.id.startsWith("assistant-error-") ||
|
||||
previous?.id.startsWith("assistant-summary-") ||
|
||||
(previousInline && previousSubagent !== Boolean(props.subagent)) ||
|
||||
props.separateAfter?.(previous?.id)
|
||||
? 1
|
||||
: 0
|
||||
return previous instanceof BoxRenderable && (previous.height > 1 || alwaysSeparate.has(previous)) ? 1 : 0
|
||||
})
|
||||
}}
|
||||
>
|
||||
|
|
@ -2018,7 +1994,7 @@ function BlockTool(props: {
|
|||
const error = createMemo(() => (props.part?.state.status === "error" ? props.part.state.error : undefined))
|
||||
return (
|
||||
<box
|
||||
id={props.part ? `tool-block-${props.part.messageID}-${props.part.id}` : undefined}
|
||||
ref={(el: BoxRenderable) => alwaysSeparate.add(el)}
|
||||
border={["left"]}
|
||||
paddingTop={1}
|
||||
paddingBottom={1}
|
||||
|
|
@ -2184,8 +2160,8 @@ function Read(props: ToolProps) {
|
|||
Read {pathFormatter.format(stringValue(props.input.filePath))} {input(props.input, ["filePath"])}
|
||||
</InlineTool>
|
||||
<For each={loaded()}>
|
||||
{(filepath, index) => (
|
||||
<box id={`tool-inline-loaded-${props.part.messageID}-${props.part.id}-${index()}`} paddingLeft={3}>
|
||||
{(filepath) => (
|
||||
<box paddingLeft={3}>
|
||||
<text paddingLeft={3} fg={theme.textMuted}>
|
||||
↳ Loaded {pathFormatter.format(filepath)}
|
||||
</text>
|
||||
|
|
@ -2305,7 +2281,6 @@ function Task(props: ToolProps) {
|
|||
return (
|
||||
<InlineTool
|
||||
icon={props.part.state.status === "completed" ? "✓" : "│"}
|
||||
subagent={true}
|
||||
color={retry() ? theme.error : undefined}
|
||||
spinner={isRunning()}
|
||||
complete={stringValue(props.input.description)}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue