diff --git a/.changeset/background-subagent-reasoning-preview.md b/.changeset/background-subagent-reasoning-preview.md
new file mode 100644
index 000000000000..f6e3e3365746
--- /dev/null
+++ b/.changeset/background-subagent-reasoning-preview.md
@@ -0,0 +1,5 @@
+---
+"kilo-code": patch
+---
+
+Keep background subagent task cards collapsed and show their reasoning as a compact preview instead of expanding while the agent runs.
diff --git a/packages/kilo-ui/src/components/message-part.tsx b/packages/kilo-ui/src/components/message-part.tsx
index a5717bbbd337..4b7a43af0a3b 100644
--- a/packages/kilo-ui/src/components/message-part.tsx
+++ b/packages/kilo-ui/src/components/message-part.tsx
@@ -162,6 +162,9 @@ export interface MessagePartProps {
* lets that one nested item open instead of every file in the patch. */
forceOpenFile?: string
reasoningAutoCollapse?: boolean
+ /** Show reasoning as a capped preview that starts open and never auto-expands
+ * while streaming. Used for background subagent transcripts. */
+ reasoningCapped?: boolean
/** True when the stream has moved past this reasoning part. Encrypted
* reasoning items hold every summary's `time.end` until the whole item
* finishes, so the caller settles finished summaries from the part order. */
@@ -1081,6 +1084,7 @@ export function Part(props: MessagePartProps) {
forceOpen={props.forceOpen}
forceOpenFile={props.forceOpenFile}
reasoningAutoCollapse={props.reasoningAutoCollapse}
+ reasoningCapped={props.reasoningCapped}
settled={props.settled}
showAssistantCopyPartID={props.showAssistantCopyPartID}
showTurnDiffSummary={props.showTurnDiffSummary}
@@ -1884,12 +1888,15 @@ PART_MAPPING["reasoning"] = function ReasoningPartDisplay(props: MessagePartProp
// Auto-collapse mode: streaming or streamed this session -> open (capped),
// historical -> collapsed, unless the user toggled it. Expanded mode: open
- // unless the user explicitly collapsed this reasoning part.
- const initial = props.reasoningAutoCollapse
- ? !userCollapsed.has(id) && (streamed.has(id) || userOpened.has(id))
- : !userCollapsed.has(id)
+ // unless the user explicitly collapsed this reasoning part. Background
+ // transcripts always start open in the capped preview so they stay compact.
+ const capped = () => props.reasoningAutoCollapse || props.reasoningCapped
+ const initial =
+ props.reasoningAutoCollapse && !props.reasoningCapped
+ ? !userCollapsed.has(id) && (streamed.has(id) || userOpened.has(id))
+ : !userCollapsed.has(id)
const [open, setOpen] = createSignal(initial)
- const [manual, setManual] = createSignal(props.reasoningAutoCollapse && userOpened.has(id))
+ const [manual, setManual] = createSignal(capped() && userOpened.has(id))
const title = createMemo(() => {
const value = view().title
if (value) return value
@@ -1908,7 +1915,7 @@ PART_MAPPING["reasoning"] = function ReasoningPartDisplay(props: MessagePartProp
const track = (value: boolean) => {
if (value) userCollapsed.delete(id)
else rememberReasoningState(userCollapsed, id)
- if (props.reasoningAutoCollapse) {
+ if (capped()) {
if (value) rememberReasoningState(userOpened, id)
else userOpened.delete(id)
setManual(value)
@@ -1924,7 +1931,7 @@ PART_MAPPING["reasoning"] = function ReasoningPartDisplay(props: MessagePartProp
createEffect(() => {
if (!props.forceOpen || open()) return
userCollapsed.delete(id)
- if (props.reasoningAutoCollapse) {
+ if (capped()) {
rememberReasoningState(userOpened, id)
setManual(true)
}
@@ -2007,7 +2014,7 @@ PART_MAPPING["reasoning"] = function ReasoningPartDisplay(props: MessagePartProp
()
private providers = new Map()
+ private backgrounds = new Map()
constructor(
private readonly extensionUri: vscode.Uri,
@@ -21,10 +22,17 @@ export class SubAgentViewerProvider implements vscode.Disposable {
private readonly context: vscode.ExtensionContext,
) {}
- openPanel(sessionID: string, title?: string, directory?: string): void {
+ openPanel(sessionID: string, title?: string, directory?: string, background?: boolean): void {
const existing = this.panels.get(sessionID)
if (existing) {
if (directory) this.providers.get(sessionID)?.setSessionDirectory(sessionID, directory)
+ // A reused panel keeps its original flag. Re-post when the caller reports
+ // a different one so a transcript that first opened before the task
+ // metadata landed still gets the reasoning cap.
+ if (background !== undefined && this.backgrounds.get(sessionID) !== background) {
+ this.backgrounds.set(sessionID, background)
+ this.providers.get(sessionID)?.postMessage({ type: "viewSubAgentSession", sessionID, background })
+ }
existing.reveal(vscode.ViewColumn.One)
return
}
@@ -61,7 +69,7 @@ export class SubAgentViewerProvider implements vscode.Disposable {
if (msg.type !== "webviewReady") return
readyDisposable.dispose()
- provider.postMessage({ type: "viewSubAgentSession", sessionID })
+ provider.postMessage({ type: "viewSubAgentSession", sessionID, background })
void provider.loadMessages(sessionID)
try {
@@ -86,6 +94,7 @@ export class SubAgentViewerProvider implements vscode.Disposable {
this.panels.set(sessionID, panel)
this.providers.set(sessionID, provider)
+ this.backgrounds.set(sessionID, background === true)
panel.onDidDispose(() => {
console.log("[Kilo New] Sub-agent viewer panel disposed:", sessionID)
@@ -93,6 +102,7 @@ export class SubAgentViewerProvider implements vscode.Disposable {
provider.dispose()
this.panels.delete(sessionID)
this.providers.delete(sessionID)
+ this.backgrounds.delete(sessionID)
})
}
@@ -102,5 +112,6 @@ export class SubAgentViewerProvider implements vscode.Disposable {
}
this.panels.clear()
this.providers.clear()
+ this.backgrounds.clear()
}
}
diff --git a/packages/kilo-vscode/src/extension.ts b/packages/kilo-vscode/src/extension.ts
index 13c624e7298f..75f495769e43 100644
--- a/packages/kilo-vscode/src/extension.ts
+++ b/packages/kilo-vscode/src/extension.ts
@@ -598,8 +598,8 @@ export async function activate(context: vscode.ExtensionContext) {
),
vscode.commands.registerCommand(
"kilo-code.new.openSubAgentViewer",
- (sessionID: string, title?: string, directory?: string) => {
- subAgentViewerProvider.openPanel(sessionID, title, directory)
+ (sessionID: string, title?: string, directory?: string, background?: boolean) => {
+ subAgentViewerProvider.openPanel(sessionID, title, directory, background)
},
),
vscode.commands.registerCommand("kilo-code.new.agentManager.previousSession", () => {
diff --git a/packages/kilo-vscode/tests/unit/background-agents.test.ts b/packages/kilo-vscode/tests/unit/background-agents.test.ts
index 0c4d28fef2ec..4ad436eef29b 100644
--- a/packages/kilo-vscode/tests/unit/background-agents.test.ts
+++ b/packages/kilo-vscode/tests/unit/background-agents.test.ts
@@ -1,6 +1,7 @@
import { describe, expect, it } from "bun:test"
import {
backgroundAgents,
+ backgroundChildren,
backgroundJobAgents,
fitBackgroundAgents,
showBackgroundAgent,
@@ -73,6 +74,33 @@ describe("fitBackgroundAgents", () => {
})
})
+describe("backgroundChildren", () => {
+ it("collects only children spawned with the background flag", () => {
+ const tools = [
+ taskPart({ id: "part_1", child: "ses_a", background: true }),
+ taskPart({ id: "part_2", child: "ses_b", background: false }),
+ taskPart({ id: "part_3", child: "ses_c" }),
+ ]
+
+ expect([...backgroundChildren(tools)]).toEqual(["ses_a"])
+ })
+
+ it("reads the flag from either the state or the part metadata", () => {
+ const tools = [
+ taskPart({ id: "part_1", child: "ses_a", background: true }),
+ taskPart({ id: "part_2", child: "ses_b", background: true, onPart: true }),
+ ]
+
+ expect([...backgroundChildren(tools)].sort()).toEqual(["ses_a", "ses_b"])
+ })
+
+ it("ignores non-task tools and parts without a child session", () => {
+ const bash = { id: "part_3", type: "tool", tool: "bash", state: { status: "running", input: {} } } as ToolPart
+
+ expect([...backgroundChildren([bash, taskPart({ id: "part_4", background: true })])]).toEqual([])
+ })
+})
+
describe("backgroundAgents", () => {
it("lists a running background agent from tool state metadata", () => {
const tools = [taskPart({ child: "ses_child", background: true, description: "Audit deps", agent: "explore" })]
diff --git a/packages/kilo-vscode/webview-ui/agent-manager/SubagentPanel.tsx b/packages/kilo-vscode/webview-ui/agent-manager/SubagentPanel.tsx
index 1bef5cae1ff5..331bb0a19790 100644
--- a/packages/kilo-vscode/webview-ui/agent-manager/SubagentPanel.tsx
+++ b/packages/kilo-vscode/webview-ui/agent-manager/SubagentPanel.tsx
@@ -11,7 +11,7 @@ import { IconButton } from "@kilocode/kilo-ui/icon-button"
import { createEffect, createMemo, on, type Accessor, type Component } from "solid-js"
import { DataBridge } from "../src/App"
import { ChatView } from "../src/components/chat"
-import { children } from "../src/components/chat/background-agents"
+import { children, backgroundChildren } from "../src/components/chat/background-agents"
import { useLanguage } from "../src/context/language"
import { SessionProvider, useSession, useSessionVisibility } from "../src/context/session"
import { description, label, type Activity } from "../src/utils/session-activity"
@@ -32,7 +32,7 @@ interface Props {
onClosePanel: () => void
}
-const SubagentChat: Component<{ active: Accessor }> = (props) => {
+const SubagentChat: Component<{ active: Accessor; capped: Accessor }> = (props) => {
const session = useSession()
createEffect(
@@ -44,12 +44,22 @@ const SubagentChat: Component<{ active: Accessor }> = (props
return (
-
+
)
}
-const SubagentContent: Component Activity }> = (props) => {
+interface ContentProps extends Props {
+ activity: (id: string) => Activity
+ background: Accessor>
+}
+
+const SubagentContent: Component = (props) => {
const session = useSession()
const language = useLanguage()
const ids = () => props.tabs().map((tab) => tab.id)
@@ -131,7 +141,7 @@ const SubagentContent: Component Activity }>
}}
/>
-
+ props.background().has(props.active() ?? "")} />
)
@@ -145,10 +155,15 @@ export const SubagentPanel: Component = (props) => {
const id = session.currentSessionID()
return id ? children(session.getSessionToolParts(id)) : []
})
+ // Background subagent transcripts show reasoning as a compact capped preview.
+ const background = createMemo(() => {
+ const id = session.currentSessionID()
+ return id ? backgroundChildren(session.getSessionToolParts(id)) : new Set()
+ })
return (
-
+
)
diff --git a/packages/kilo-vscode/webview-ui/src/App.tsx b/packages/kilo-vscode/webview-ui/src/App.tsx
index 8c148bada417..a6f895c12832 100644
--- a/packages/kilo-vscode/webview-ui/src/App.tsx
+++ b/packages/kilo-vscode/webview-ui/src/App.tsx
@@ -14,6 +14,7 @@ import { ChatView } from "./components/chat"
import { SidebarEmptyState } from "./components/chat/SidebarEmptyState"
import { SidebarTopBar } from "./components/chat/SidebarTopBar"
import { openSubagent } from "./components/chat/open-subagent"
+import { backgroundChildren } from "./components/chat/background-agents"
import { registerExpandedTaskTool } from "./components/chat/TaskToolExpanded"
import { registerVscodeToolOverrides } from "./components/chat/VscodeToolOverrides"
import { useWorktreeMode } from "./context/worktree-mode"
@@ -132,10 +133,12 @@ export const DataBridge: Component<{ children: any }> = (props) => {
const openAgent = (id: string, title?: string) => {
const parent = session.sessions().find((item) => item.id === id)?.parentID ?? session.currentSessionID()
+ const background = parent ? backgroundChildren(session.getSessionToolParts(parent)).has(id) : false
openSubagent({
sessionID: id,
title,
parentSessionID: parent,
+ background,
worktree: !!worktree,
post: vscode.postMessage,
})
@@ -243,6 +246,7 @@ const AppContent: Component = () => {
const [currentView, setCurrentView] = createSignal("newTask")
const [settingsTab, setSettingsTab] = createSignal()
const [agentManagerProjectId, setAgentManagerProjectId] = createSignal()
+ const [subAgentCapped, setSubAgentCapped] = createSignal(false)
const [migration, setMigration] = createSignal(false)
const session = useSession()
const tabs = useLocalTabs()
@@ -345,6 +349,7 @@ const AppContent: Component = () => {
handleForked(message)
if (message?.type === "viewSubAgentSession" && message.sessionID) {
console.log("[Kilo New] App: 🔍 viewSubAgentSession:", message.sessionID)
+ setSubAgentCapped(message.background === true)
session.setCurrentSessionID(message.sessionID)
setCurrentView("subAgentViewer")
}
@@ -439,7 +444,7 @@ const AppContent: Component = () => {
/>
-
+
}
diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/AssistantMessage.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/AssistantMessage.tsx
index e3e0f335ca1f..e677be1a5ac7 100644
--- a/packages/kilo-vscode/webview-ui/src/components/chat/AssistantMessage.tsx
+++ b/packages/kilo-vscode/webview-ui/src/components/chat/AssistantMessage.tsx
@@ -117,6 +117,8 @@ interface AssistantMessageProps {
highlight?: () => TimelineHighlight | undefined
readonly?: boolean
interactivePrompts?: boolean
+ /** Show reasoning as a compact capped preview (background subagent transcripts). */
+ reasoningCapped?: boolean
}
type ToolStateProps = {
@@ -364,6 +366,7 @@ export const AssistantMessage: Component = (props) => {
forceOpen={forceOpen()}
forceOpenFile={forceOpen() ? props.forceOpenFile : undefined}
reasoningAutoCollapse={display.reasoningAutoCollapse()}
+ reasoningCapped={props.reasoningCapped}
settled={settled()}
feedback={props.feedback}
throughput={throughputEl()}
diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/BackgroundAgents.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/BackgroundAgents.tsx
index a6785db74a28..4f8f2158b743 100644
--- a/packages/kilo-vscode/webview-ui/src/components/chat/BackgroundAgents.tsx
+++ b/packages/kilo-vscode/webview-ui/src/components/chat/BackgroundAgents.tsx
@@ -196,6 +196,7 @@ export const BackgroundAgents: Component<{ readonly?: boolean }> = (props) => {
sessionID: agent.id,
title: agent.description,
parentSessionID: session.currentSessionID(),
+ background: true,
worktree: !!worktree,
post: vscode.postMessage,
})
diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx
index 916815bc1e01..aa2339304836 100644
--- a/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx
+++ b/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx
@@ -40,6 +40,8 @@ interface ChatViewProps {
onForkMessage?: (sessionId: string, messageId: string) => void
onForkSession?: (sessionId: string) => void
readonly?: boolean
+ /** Show reasoning as a compact capped preview (background subagent transcripts). */
+ reasoningCapped?: boolean
/** Whether this chat owns actionable prompt controls. Defaults to true. */
interactivePrompts?: boolean
/** When true, show the "Continue in Worktree" button. Defaults to true in the sidebar. */
@@ -399,6 +401,7 @@ export const ChatView: Component = (props) => {
questions={standaloneQuestions}
suggestions={standaloneSuggestions}
readonly={props.readonly}
+ reasoningCapped={props.reasoningCapped}
interactivePrompts={ownsPrompts()}
emptyState={props.emptyState}
introduction={props.introduction}
diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/MessageList.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/MessageList.tsx
index 9825c9bc0eb0..4dec2d080bfb 100644
--- a/packages/kilo-vscode/webview-ui/src/components/chat/MessageList.tsx
+++ b/packages/kilo-vscode/webview-ui/src/components/chat/MessageList.tsx
@@ -96,6 +96,8 @@ interface MessageListProps {
suggestions?: () => SuggestionRequest[]
/** When true (subagent viewer), replace the welcome screen with an initializing indicator */
readonly?: boolean
+ /** Show reasoning as a compact capped preview (background subagent transcripts). */
+ reasoningCapped?: boolean
/** Whether inline questions and suggestions are actionable on this surface. */
interactivePrompts?: boolean
queuedDisabled?: boolean
@@ -1362,6 +1364,7 @@ export const MessageList: Component = (props) => {
activeSearchPartFile={activeKey() === row.key ? activeMatch()?.partFile : undefined}
readonly={props.readonly}
interactivePrompts={props.interactivePrompts}
+ reasoningCapped={props.reasoningCapped}
/>
)}
@@ -1382,6 +1385,7 @@ export const MessageList: Component = (props) => {
activeSearchPartFile={activeKey() === key ? activeMatch()?.partFile : undefined}
readonly={props.readonly}
interactivePrompts={props.interactivePrompts}
+ reasoningCapped={props.reasoningCapped}
/>
)}
@@ -1404,6 +1408,7 @@ export const MessageList: Component = (props) => {
activeSearchPartFile={activeKey() === row.key ? activeMatch()?.partFile : undefined}
readonly={props.readonly}
interactivePrompts={props.interactivePrompts}
+ reasoningCapped={props.reasoningCapped}
/>
)}
diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/TaskToolExpanded.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/TaskToolExpanded.tsx
index c7fe361a569d..86552bb7b62f 100644
--- a/packages/kilo-vscode/webview-ui/src/components/chat/TaskToolExpanded.tsx
+++ b/packages/kilo-vscode/webview-ui/src/components/chat/TaskToolExpanded.tsx
@@ -59,6 +59,16 @@ const TaskToolRenderer: Component = (props) => {
)
const running = createMemo(() => taskRunning(props.status))
+ // Background task cards stay collapsed: they must not auto-open or show the
+ // "Starting..." status, which would flicker the transcript as the child runs.
+ // The input carries `background` from the first part update; promoted tasks
+ // only gain the state metadata flag later.
+ const backgroundTask = createMemo(
+ () =>
+ props.input.background === true ||
+ ((props.partMetadata as Record | undefined)?.background ??
+ (props.metadata as Record | undefined)?.background) === true,
+ )
const avatar = createMemo(() => {
const id = childSessionId()
return taskAvatarStatus(id, props.status, session.allStatusMap())
@@ -77,6 +87,10 @@ const TaskToolRenderer: Component = (props) => {
{ defer: true },
),
)
+ // Auto-open only once the call is running: while "pending" the streamed
+ // input cannot yet tell a background task from a foreground one, and a
+ // background card must never open on its own.
+ const auto = () => props.status === "running" && !backgroundTask()
// BasicTool's forceOpen effect only fires onOpenChange on a false->true
// transition — a virtualized remount that starts with forceOpen already
// true never transitions, so this local signal must also seed itself from
@@ -86,10 +100,27 @@ const TaskToolRenderer: Component = (props) => {
initialOpen({
tool: props.tool,
partID: props.partID,
- defaultOpen: running(),
+ defaultOpen: auto(),
forceOpen: props.forceOpen,
}),
)
+ // The open state is controlled so the card settles once the input arrives.
+ // A stored preference, a search match, or a manual toggle wins over it.
+ const [touched, setTouched] = createSignal(
+ !!props.forceOpen || initialOpen({ tool: props.tool, partID: props.partID }) !== undefined,
+ )
+ const change = (value: boolean) => {
+ setTouched(true)
+ setOpen(value)
+ }
+ createEffect(() => {
+ if (touched()) return
+ if (backgroundTask()) {
+ setOpen(false)
+ return
+ }
+ if (props.status === "running") setOpen(true)
+ })
let synced: string | undefined
createEffect(() => {
@@ -171,6 +202,7 @@ const TaskToolRenderer: Component = (props) => {
sessionID: id,
title: description(),
parentSessionID: session.currentSessionID(),
+ background: backgroundTask(),
worktree: !!worktree,
post: vscode.postMessage,
})
@@ -240,14 +272,15 @@ const TaskToolRenderer: Component = (props) => {
tool={props.tool}
partID={props.partID}
trigger={trigger()}
- defaultOpen={running()}
+ defaultOpen={auto()}
+ open={open()}
forceOpen={props.forceOpen}
defer
- onOpenChange={setOpen}
+ onOpenChange={change}
>
-
+
{language.t("session.messages.taskStarting")}
diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/TranscriptRow.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/TranscriptRow.tsx
index 45ef07287df8..222a517de285 100644
--- a/packages/kilo-vscode/webview-ui/src/components/chat/TranscriptRow.tsx
+++ b/packages/kilo-vscode/webview-ui/src/components/chat/TranscriptRow.tsx
@@ -31,6 +31,8 @@ interface TranscriptRowViewProps {
activeSearchPartFile?: string
readonly?: boolean
interactivePrompts?: boolean
+ /** Show reasoning as a compact capped preview (background subagent transcripts). */
+ reasoningCapped?: boolean
queuedDisabled?: boolean
editDisabled?: boolean
}
@@ -113,6 +115,7 @@ export const TranscriptRowView: Component = (props) => {
highlight={props.highlight}
readonly={props.readonly}
interactivePrompts={props.interactivePrompts}
+ reasoningCapped={props.reasoningCapped}
feedback={{
enabled: feedback.telemetryEnabled(),
rating: feedback.getRating(row().message.id),
diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/background-agents.ts b/packages/kilo-vscode/webview-ui/src/components/chat/background-agents.ts
index e276668f8136..48e29c8072b5 100644
--- a/packages/kilo-vscode/webview-ui/src/components/chat/background-agents.ts
+++ b/packages/kilo-vscode/webview-ui/src/components/chat/background-agents.ts
@@ -78,6 +78,18 @@ export function children(tools: ToolPart[]): string[] {
return ids
}
+/** Child session IDs spawned as background jobs, which show a capped reasoning preview. */
+export function backgroundChildren(tools: ToolPart[]): Set {
+ const ids = new Set()
+ for (const part of tools) {
+ if (part.tool !== "task") continue
+ if (meta(part, "background") !== true) continue
+ const id = text(meta(part, "sessionId"))
+ if (id) ids.add(id)
+ }
+ return ids
+}
+
function working(status: SessionStatusInfo | undefined): boolean {
return status?.type === "busy" || status?.type === "retry"
}
diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/open-subagent.ts b/packages/kilo-vscode/webview-ui/src/components/chat/open-subagent.ts
index 5d055ae0174a..e60c264d8f5f 100644
--- a/packages/kilo-vscode/webview-ui/src/components/chat/open-subagent.ts
+++ b/packages/kilo-vscode/webview-ui/src/components/chat/open-subagent.ts
@@ -12,6 +12,8 @@ interface OpenSubagent {
sessionID: string
title?: string
parentSessionID?: string
+ /** True for async background agents, whose reasoning shows a capped preview. */
+ background?: boolean
/** True inside Agent Manager, where the inspector replaces the editor tab. */
worktree: boolean
post: (message: WebviewMessage) => void
@@ -32,5 +34,6 @@ export function openSubagent(input: OpenSubagent) {
sessionID: input.sessionID,
title: input.title,
parentSessionID: input.parentSessionID,
+ background: input.background,
})
}
diff --git a/packages/kilo-vscode/webview-ui/src/types/messages/extension-messages.ts b/packages/kilo-vscode/webview-ui/src/types/messages/extension-messages.ts
index 6d312e5397e5..6fd60c9266a1 100644
--- a/packages/kilo-vscode/webview-ui/src/types/messages/extension-messages.ts
+++ b/packages/kilo-vscode/webview-ui/src/types/messages/extension-messages.ts
@@ -1296,6 +1296,8 @@ export interface EnhancePromptErrorMessage {
export interface ViewSubAgentSessionMessage {
type: "viewSubAgentSession"
sessionID: string
+ /** True for async background agents, whose reasoning shows a capped preview. */
+ background?: boolean
}
export interface DiffViewerContextMessage {
diff --git a/packages/kilo-vscode/webview-ui/src/types/messages/webview-messages.ts b/packages/kilo-vscode/webview-ui/src/types/messages/webview-messages.ts
index 2dac6ce191f4..2d338815a56a 100644
--- a/packages/kilo-vscode/webview-ui/src/types/messages/webview-messages.ts
+++ b/packages/kilo-vscode/webview-ui/src/types/messages/webview-messages.ts
@@ -1261,6 +1261,8 @@ export interface OpenSubAgentViewerRequest {
sessionID: string
title?: string
parentSessionID?: string
+ /** True for async background agents, whose reasoning shows a capped preview. */
+ background?: boolean
}
// Preview an image attachment in VS Code's built-in image viewer