diff --git a/packages/app/e2e/browser/compact-workspace-sheet.spec.ts b/packages/app/e2e/browser/compact-workspace-sheet.spec.ts
index 77a2a0882b..990d490d9b 100644
--- a/packages/app/e2e/browser/compact-workspace-sheet.spec.ts
+++ b/packages/app/e2e/browser/compact-workspace-sheet.spec.ts
@@ -71,6 +71,14 @@ test("compact opens files and subagents in a sheet, leaving the tabs for agents"
await closeSheet(page, "linked.ts");
});
+ await test.step("a subagent's row shows the facts its sheet shows", async () => {
+ await page.getByTestId("subagents-track-header").click();
+ await expect(page.getByTestId(`subagents-track-row-facts-${child.id}`)).toHaveText(
+ "Ten second stream · Low · Load test",
+ );
+ await tapSheetBackdrop(page);
+ });
+
await test.step("a subagent opens in a sheet over the subagents list", async () => {
await openSubagentFromCompactTrack(page, child.id);
diff --git a/packages/app/src/panels/agent-facts-line.ts b/packages/app/src/panels/agent-facts-line.ts
index 7d3cd80332..7c01e5ce42 100644
--- a/packages/app/src/panels/agent-facts-line.ts
+++ b/packages/app/src/panels/agent-facts-line.ts
@@ -1,7 +1,10 @@
import type { AgentMode, AgentModelDefinition } from "@getpaseo/protocol/agent-types";
+import { useShallow } from "zustand/shallow";
import { formatAgentModeLabel } from "@/agent-controls/labels";
import { formatTokenCount } from "@/components/context-window-meter.utils";
import { resolveAgentModelSelection } from "@/composer/agent-controls/utils";
+import { useProvidersSnapshot } from "@/hooks/use-providers-snapshot";
+import { useSessionStore } from "@/stores/session-store";
export interface AgentFactsInput {
models: AgentModelDefinition[] | null;
@@ -33,6 +36,32 @@ export function buildAgentFactsLine(input: AgentFactsInput): string | null {
return parts.join(" · ");
}
+/** The facts line for a Paseo agent in the session store, kept current as the agent reports. */
+export function useAgentFactsLine(serverId: string, agentId: string): string | null {
+ const agent = useSessionStore(
+ useShallow((state) => {
+ const current = state.sessions[serverId]?.agents.get(agentId);
+ return current
+ ? {
+ provider: current.provider,
+ cwd: current.cwd,
+ runtimeModelId: current.runtimeInfo?.model ?? null,
+ configuredModelId: current.model ?? null,
+ runtimeThinkingOptionId: current.runtimeInfo?.thinkingOptionId ?? null,
+ explicitThinkingOptionId: current.thinkingOptionId ?? null,
+ availableModes: current.availableModes,
+ currentModeId: current.currentModeId,
+ contextWindowUsedTokens: current.lastUsage?.contextWindowUsedTokens ?? null,
+ contextWindowMaxTokens: current.lastUsage?.contextWindowMaxTokens ?? null,
+ }
+ : null;
+ }),
+ );
+ const { entries } = useProvidersSnapshot(serverId, { cwd: agent?.cwd });
+ const models = entries?.find((entry) => entry.provider === agent?.provider)?.models ?? null;
+ return agent ? buildAgentFactsLine({ ...agent, models }) : null;
+}
+
/** The mode control shows the current mode, or the provider's first one until the agent reports. */
function resolveModeLabel(modes: AgentMode[], currentModeId: string | null | undefined) {
const mode = modes.find((candidate) => candidate.id === currentModeId) ?? modes[0];
diff --git a/packages/app/src/panels/agent-panel.tsx b/packages/app/src/panels/agent-panel.tsx
index a9e11df570..7ae7d0c470 100644
--- a/packages/app/src/panels/agent-panel.tsx
+++ b/packages/app/src/panels/agent-panel.tsx
@@ -60,9 +60,8 @@ import { useContainerWidthBelow } from "@/hooks/use-container-width";
import { reconcileMissingAgentStateWithPresentAgent } from "@/panels/agent-panel-load-state";
import { TimelineSyncStatus } from "@/timeline/sync-status";
import { usePaneContext, usePaneFocus } from "@/panels/pane-context";
-import { buildAgentFactsLine } from "@/panels/agent-facts-line";
+import { useAgentFactsLine } from "@/panels/agent-facts-line";
import { PaneSubtitle } from "@/panels/pane-subtitle";
-import { useProvidersSnapshot } from "@/hooks/use-providers-snapshot";
import { definePanel, type PanelDescriptor } from "@/panels/panel-registry";
import { RenderProfile } from "@/utils/render-profiler";
import { useHasPluginComposerPills } from "@/plugins";
@@ -1384,28 +1383,7 @@ function TimelineSyncErrorCallout({
* without its composer.
*/
function SheetAgentFacts({ serverId, agentId }: { serverId: string; agentId: string }) {
- const agent = useSessionStore(
- useShallow((state) => {
- const current = state.sessions[serverId]?.agents.get(agentId);
- return current
- ? {
- provider: current.provider,
- cwd: current.cwd,
- runtimeModelId: current.runtimeInfo?.model ?? null,
- configuredModelId: current.model ?? null,
- runtimeThinkingOptionId: current.runtimeInfo?.thinkingOptionId ?? null,
- explicitThinkingOptionId: current.thinkingOptionId ?? null,
- availableModes: current.availableModes,
- currentModeId: current.currentModeId,
- contextWindowUsedTokens: current.lastUsage?.contextWindowUsedTokens ?? null,
- contextWindowMaxTokens: current.lastUsage?.contextWindowMaxTokens ?? null,
- }
- : null;
- }),
- );
- const { entries } = useProvidersSnapshot(serverId, { cwd: agent?.cwd });
- const models = entries?.find((entry) => entry.provider === agent?.provider)?.models ?? null;
- const text = agent ? buildAgentFactsLine({ ...agent, models }) : null;
+ const text = useAgentFactsLine(serverId, agentId);
return text ? : null;
}
diff --git a/packages/app/src/subagents/track.tsx b/packages/app/src/subagents/track.tsx
index c1834587d2..1914993700 100644
--- a/packages/app/src/subagents/track.tsx
+++ b/packages/app/src/subagents/track.tsx
@@ -13,6 +13,7 @@ import {
type WorkspaceTabPresentation,
} from "@/screens/workspace/workspace-tab-presentation";
import type { Theme } from "@/styles/theme";
+import { useAgentFactsLine } from "@/panels/agent-facts-line";
import { getPanelManifest } from "@/panels/panel-manifest";
import type { SubagentRow } from "./select";
import type { ArchiveFinishedStatus } from "./use-archive-finished";
@@ -219,14 +220,16 @@ function SubagentsTrackRow({
({ active }: { active: boolean }) => (
<>
-
- {displayLabel}
-
- {presentation.subtitle ? (
-
- {presentation.subtitle}
+
+
+ {displayLabel}
- ) : null}
+ {row.kind === "paseo" ? (
+
+ ) : (
+
+ )}
+
{row.kind === "paseo" ? (
;
+}
+
+function SubagentFacts({ rowId, text }: { rowId: string; text: string | null }) {
+ if (!text) return null;
+ return (
+
+ {text}
+
+ );
+}
+
function SubagentRowActions({
rowId,
displayLabel,
@@ -360,9 +379,24 @@ const styles = StyleSheet.create((theme) => ({
fontSize: theme.fontSize.base,
color: theme.colors.foreground,
},
- // Trailing metadata — provider context on a subagent row, progress on the archive row. No width
- // cap: the panel's own ceiling bounds it. It shrinks twice as fast as the label, so a wordy
- // provider subtitle gives way first instead of squeezing the thing that names the row.
+ // Title over facts. The facts sit under the title rather than beside it, so a long task name
+ // keeps the row's full width and neither line truncates the other.
+ rowText: {
+ flexGrow: 1,
+ flexShrink: 1,
+ flexBasis: "auto",
+ minWidth: 0,
+ },
+ rowTitle: {
+ fontSize: theme.fontSize.base,
+ color: theme.colors.foreground,
+ },
+ rowFacts: {
+ fontSize: theme.fontSize.sm,
+ color: theme.colors.foregroundMuted,
+ },
+ // Progress on the archive row. It shrinks twice as fast as the label, so a long retry count
+ // gives way first instead of squeezing the thing that names the row.
rowTrailing: {
flexShrink: 2,
minWidth: 0,