Skip to content

Commit 131d4d7

Browse files
committed
emit a single line instead of accumulated output
1 parent b480a0e commit 131d4d7

2 files changed

Lines changed: 43 additions & 46 deletions

File tree

extensions/cli/src/services/SubAgentService.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,26 +172,24 @@ export class SubAgentService extends BaseService<SubAgentServiceState> {
172172
escapeEvents.on("user-escape", escapeHandler);
173173

174174
try {
175-
let accumulatedOutput = "";
176-
177175
await streamChatResponse(
178176
chatHistory,
179177
model,
180178
llmApi,
181179
abortController,
182180
{
183181
onContent: (content: string) => {
184-
accumulatedOutput += content;
185182
this.emit("subagentContent", {
186183
agentName: model?.name,
187-
content: accumulatedOutput,
184+
content,
185+
type: "content",
188186
});
189187
},
190188
onToolResult: (result: string) => {
191-
accumulatedOutput += `\n\n${result}`;
192189
this.emit("subagentContent", {
193190
agentName: model?.name,
194-
content: accumulatedOutput,
191+
content: result,
192+
type: "toolResult",
195193
});
196194
},
197195
},

extensions/cli/src/ui/components/SubAgentOutput.tsx

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,45 +5,43 @@ import { subAgentService } from "../../services/SubAgentService.js";
55
import { LoadingAnimation } from "../LoadingAnimation.js";
66
import { MarkdownRenderer } from "../MarkdownRenderer.js";
77

8-
interface SubAgentState {
9-
agentName: string | undefined;
10-
content: string;
11-
isRunning: boolean;
12-
prompt?: string;
13-
}
14-
158
export const SubAgentOutput: React.FC = () => {
16-
const [state, setState] = useState<SubAgentState>({
17-
agentName: undefined,
18-
content: "",
19-
isRunning: false,
20-
});
9+
const [agentName, setAgentName] = useState<string | undefined>(undefined);
10+
const [contentLines, setContentLines] = useState<string[]>([]);
11+
const [isRunning, setIsRunning] = useState(false);
2112

2213
useEffect(() => {
23-
const onStarted = (data: { agentName: string; prompt: string }) => {
24-
setState({
25-
agentName: data.agentName,
26-
content: "",
27-
isRunning: true,
28-
prompt: data.prompt,
29-
});
30-
};
31-
32-
const onContent = (data: { agentName: string; content: string }) => {
33-
setState((prev) => ({
34-
...prev,
35-
agentName: data.agentName,
36-
content: data.content,
37-
}));
14+
const onStarted = (data: { agentName: string }) => {
15+
setAgentName(data.agentName);
16+
setContentLines([]);
17+
setIsRunning(true);
3818
};
3919

40-
const onCompleted = () => {
41-
setState((prev) => ({ ...prev, isRunning: false }));
20+
const onContent = (data: {
21+
agentName: string;
22+
content: string;
23+
type: "content" | "toolResult";
24+
}) => {
25+
setAgentName(data.agentName);
26+
setContentLines((prev) => {
27+
const newLines = data.content.split("\n");
28+
if (data.type === "toolResult") {
29+
return [...prev, "", ...newLines];
30+
}
31+
if (prev.length === 0) {
32+
return newLines;
33+
}
34+
const lastLine = prev[prev.length - 1];
35+
return [
36+
...prev.slice(0, -1),
37+
lastLine + newLines[0],
38+
...newLines.slice(1),
39+
];
40+
});
4241
};
4342

44-
const onFailed = () => {
45-
setState((prev) => ({ ...prev, isRunning: false }));
46-
};
43+
const onCompleted = () => setIsRunning(false);
44+
const onFailed = () => setIsRunning(false);
4745

4846
subAgentService.on("subagentStarted", onStarted);
4947
subAgentService.on("subagentContent", onContent);
@@ -58,29 +56,30 @@ export const SubAgentOutput: React.FC = () => {
5856
};
5957
}, []);
6058

61-
if (!state.isRunning) {
59+
if (!isRunning) {
6260
return null;
6361
}
6462

6563
const MAX_OUTPUT_LINES = 15;
66-
const lines = state.content.split("\n");
6764
const displayContent =
68-
lines.length > MAX_OUTPUT_LINES
69-
? lines.slice(-MAX_OUTPUT_LINES).join("\n")
70-
: state.content;
65+
contentLines.length > MAX_OUTPUT_LINES
66+
? contentLines.slice(-MAX_OUTPUT_LINES).join("\n")
67+
: contentLines.join("\n");
7168
const hiddenLines =
72-
lines.length > MAX_OUTPUT_LINES ? lines.length - MAX_OUTPUT_LINES : 0;
69+
contentLines.length > MAX_OUTPUT_LINES
70+
? contentLines.length - MAX_OUTPUT_LINES
71+
: 0;
7372

7473
return (
7574
<Box flexDirection="column" paddingX={1} paddingY={1}>
7675
<Box marginBottom={1}>
7776
<LoadingAnimation color="cyan" visible={true} />
7877
<Text color="cyan" bold>
7978
{" "}
80-
Subagent: {state.agentName || "unknown"}
79+
Subagent: {agentName || "unknown"}
8180
</Text>
8281
</Box>
83-
{state.content && (
82+
{contentLines.length > 0 && (
8483
<Box flexDirection="column" paddingLeft={2}>
8584
{hiddenLines > 0 && <Text color="dim">... +{hiddenLines} lines</Text>}
8685
<MarkdownRenderer content={displayContent.trimEnd()} />

0 commit comments

Comments
 (0)