wave-code 0.0.2 â 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/FileSelector.js +1 -1
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +4 -3
- package/dist/components/SubagentBlock.d.ts +9 -0
- package/dist/components/SubagentBlock.d.ts.map +1 -0
- package/dist/components/SubagentBlock.js +38 -0
- package/dist/plain-cli.d.ts.map +1 -1
- package/dist/plain-cli.js +2 -7
- package/package.json +2 -2
- package/src/components/FileSelector.tsx +1 -1
- package/src/components/MessageList.tsx +10 -5
- package/src/components/SubagentBlock.tsx +127 -0
- package/src/plain-cli.ts +2 -8
|
@@ -43,6 +43,6 @@ export const FileSelector = ({ files, searchQuery, onSelect, onCancel, }) => {
|
|
|
43
43
|
const actualIndex = startIndex + displayIndex;
|
|
44
44
|
const isSelected = actualIndex === selectedIndex;
|
|
45
45
|
const icon = fileItem.type === "directory" ? "đ" : "đ";
|
|
46
|
-
return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "cyan" : undefined, children: [
|
|
46
|
+
return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "cyan" : undefined, children: [" ", icon, " ", fileItem.path] }) }, fileItem.path));
|
|
47
47
|
}), endIndex < files.length && (_jsxs(Text, { dimColor: true, children: ["... ", files.length - endIndex, " more files below"] })), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate, Enter to select, Escape to cancel" }), _jsxs(Text, { dimColor: true, children: ["File ", selectedIndex + 1, " of ", files.length] })] })] }));
|
|
48
48
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAuG9C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAyGlD,CAAC"}
|
|
@@ -6,11 +6,12 @@ import { CommandOutputDisplay } from "./CommandOutputDisplay.js";
|
|
|
6
6
|
import { ToolResultDisplay } from "./ToolResultDisplay.js";
|
|
7
7
|
import { MemoryDisplay } from "./MemoryDisplay.js";
|
|
8
8
|
import { CompressDisplay } from "./CompressDisplay.js";
|
|
9
|
+
import { SubagentBlock } from "./SubagentBlock.js";
|
|
9
10
|
import { usePagination } from "../hooks/usePagination.js";
|
|
10
11
|
// Function to render a single message
|
|
11
12
|
const renderMessageItem = (message, originalIndex, isExpanded, previousMessage) => {
|
|
12
13
|
const shouldShowHeader = previousMessage?.role !== message.role;
|
|
13
|
-
return (_jsxs(Box, { flexDirection: "column",
|
|
14
|
+
return (_jsxs(Box, { flexDirection: "column", children: [shouldShowHeader && (_jsx(Box, { children: _jsxs(Text, { color: message.role === "user" ? "cyan" : "green", bold: true, children: [message.role === "user" ? "đ¤ You" : "đ¤ Assistant", _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "#", originalIndex + 1] })] }) })), _jsx(Box, { marginLeft: 2, flexDirection: "column", gap: 1, marginTop: shouldShowHeader ? 1 : 0, children: message.blocks.map((block, blockIndex) => (_jsxs(Box, { children: [block.type === "text" && block.content.trim() && (_jsx(Box, { children: _jsx(Text, { children: block.content }) })), block.type === "error" && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["\u274C Error: ", block.content] }) })), block.type === "diff" && (_jsx(DiffViewer, { block: block, isExpanded: isExpanded })), block.type === "command_output" && (_jsx(CommandOutputDisplay, { block: block, isExpanded: isExpanded })), block.type === "tool" && (_jsx(ToolResultDisplay, { block: block, isExpanded: isExpanded })), block.type === "image" && (_jsxs(Box, { children: [_jsx(Text, { color: "magenta", bold: true, children: "\uD83D\uDCF7 Image" }), block.imageUrls && block.imageUrls.length > 0 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" ", "(", block.imageUrls.length, ")"] }))] })), block.type === "memory" && _jsx(MemoryDisplay, { block: block }), block.type === "compress" && (_jsx(CompressDisplay, { block: block, isExpanded: isExpanded })), block.type === "custom_command" && (_jsxs(Box, { children: [_jsx(Text, { color: "cyan", bold: true, children: "\u26A1" }), _jsx(Text, { children: block.originalInput || `/${block.commandName}` })] })), block.type === "subagent" && (_jsx(SubagentBlock, { block: block, isExpanded: isExpanded }))] }, blockIndex))) })] }, `message-${originalIndex}`));
|
|
14
15
|
};
|
|
15
16
|
export const MessageList = ({ messages, isLoading = false, isCommandRunning = false, isCompressing = false, latestTotalTokens = 0, isExpanded = false, }) => {
|
|
16
17
|
// Use original messages for pagination calculation
|
|
@@ -28,9 +29,9 @@ export const MessageList = ({ messages, isLoading = false, isCommandRunning = fa
|
|
|
28
29
|
if (messages.length === 0) {
|
|
29
30
|
return (_jsx(Box, { flexDirection: "column", paddingY: 1, children: _jsx(Text, { color: "gray", children: "Welcome to WAVE Code Assistant!" }) }));
|
|
30
31
|
}
|
|
31
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { flexDirection: "column", children: currentMessagesWithIndex.map(({ message, originalIndex }) => {
|
|
32
|
+
return (_jsxs(Box, { flexDirection: "column", gap: 1, marginTop: 1, children: [_jsx(Box, { flexDirection: "column", gap: 1, children: currentMessagesWithIndex.map(({ message, originalIndex }) => {
|
|
32
33
|
// Get previous message
|
|
33
34
|
const previousMessage = originalIndex > 0 ? messages[originalIndex - 1] : undefined;
|
|
34
35
|
return renderMessageItem(message, originalIndex, isExpanded, previousMessage);
|
|
35
|
-
}) }), !isExpanded && (isLoading || isCommandRunning || isCompressing) && (_jsxs(Box, {
|
|
36
|
+
}) }), !isExpanded && (isLoading || isCommandRunning || isCompressing) && (_jsxs(Box, { flexDirection: "column", gap: 1, children: [isLoading && (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "\uD83D\uDCAD AI is thinking... " }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "|", " "] }), _jsx(Text, { color: "blue", bold: true, children: latestTotalTokens.toLocaleString() }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "tokens |", " "] }), _jsx(Text, { color: "red", bold: true, children: "Esc" }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "to abort"] })] })), isCommandRunning && (_jsx(Text, { color: "blue", children: "\uD83D\uDE80 Command is running..." })), isCompressing && (_jsx(Text, { color: "magenta", children: "\uD83D\uDDDC\uFE0F Compressing message history..." }))] })), messages.length > 0 && (_jsx(Box, { children: _jsxs(Box, { justifyContent: "space-between", width: "100%", children: [_jsxs(Box, { children: [_jsxs(Text, { color: "gray", children: ["Messages ", messages.length, " Page ", displayInfo.currentPage, "/", displayInfo.totalPages] }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "\u2190 ", _jsx(Text, { color: "cyan", children: "Ctrl+U/D" }), " Navigate"] })] }), _jsxs(Text, { color: "gray", dimColor: true, children: [_jsx(Text, { color: "cyan", children: "Ctrl+O" }), " Toggle", " ", isExpanded ? "Collapse" : "Expand"] })] }) }))] }));
|
|
36
37
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { SubagentBlock as SubagentBlockType } from "wave-agent-sdk/src/types.js";
|
|
3
|
+
interface SubagentBlockProps {
|
|
4
|
+
block: SubagentBlockType;
|
|
5
|
+
isExpanded?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const SubagentBlock: React.FC<SubagentBlockProps>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=SubagentBlock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubagentBlock.d.ts","sourceRoot":"","sources":["../../src/components/SubagentBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EACV,aAAa,IAAI,iBAAiB,EAGnC,MAAM,6BAA6B,CAAC;AA4BrC,UAAU,kBAAkB;IAC1B,KAAK,EAAE,iBAAiB,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAuFtD,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import { ToolResultDisplay } from "./ToolResultDisplay.js";
|
|
4
|
+
const MessageBlockRenderer = ({ block, isExpanded, }) => {
|
|
5
|
+
switch (block.type) {
|
|
6
|
+
case "text":
|
|
7
|
+
return _jsx(Text, { children: block.content });
|
|
8
|
+
case "error":
|
|
9
|
+
return _jsxs(Text, { color: "red", children: ["\u274C Error: ", block.content] });
|
|
10
|
+
case "tool":
|
|
11
|
+
return _jsx(ToolResultDisplay, { block: block, isExpanded: isExpanded });
|
|
12
|
+
default:
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
export const SubagentBlock = ({ block, isExpanded = false, }) => {
|
|
17
|
+
// Status indicator mapping
|
|
18
|
+
const getStatusIndicator = (status) => {
|
|
19
|
+
switch (status) {
|
|
20
|
+
case "active":
|
|
21
|
+
return { icon: "đ", color: "yellow" };
|
|
22
|
+
case "completed":
|
|
23
|
+
return { icon: "â
", color: "green" };
|
|
24
|
+
case "error":
|
|
25
|
+
return { icon: "â", color: "red" };
|
|
26
|
+
case "aborted":
|
|
27
|
+
return { icon: "âšī¸", color: "gray" };
|
|
28
|
+
default:
|
|
29
|
+
return { icon: "âŗ", color: "gray" };
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const statusInfo = getStatusIndicator(block.status);
|
|
33
|
+
// Determine how many messages to show
|
|
34
|
+
const messagesToShow = isExpanded
|
|
35
|
+
? block.messages.slice(-10) // Up to 10 most recent when expanded
|
|
36
|
+
: block.messages.slice(-2); // Up to 2 most recent when collapsed
|
|
37
|
+
return (_jsxs(Box, { borderStyle: "round", borderColor: "magenta", paddingX: 1, paddingY: 0, flexDirection: "column", marginBottom: 1, children: [_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", alignItems: "center", children: [_jsxs(Box, { flexDirection: "row", alignItems: "center", children: [_jsxs(Text, { color: "cyan", children: ["\uD83E\uDD16 ", block.subagentName] }), _jsxs(Text, { color: statusInfo.color, dimColor: false, children: [" ", statusInfo.icon] })] }), !isExpanded && (_jsxs(Text, { color: "gray", dimColor: true, children: [block.messages.length, " messages"] }))] }), messagesToShow.length > 0 && (_jsx(Box, { flexDirection: "column", marginTop: 1, gap: 1, children: messagesToShow.map((message, index) => (_jsx(Box, { flexDirection: "column", marginBottom: 0, gap: 1, children: message.blocks.map((messageBlock, blockIndex) => (_jsx(Box, { flexDirection: "column", children: _jsx(MessageBlockRenderer, { block: messageBlock, isExpanded: isExpanded }) }, blockIndex))) }, index))) })), !isExpanded && block.messages.length > 2 && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "gray", dimColor: true, children: ["... and ", block.messages.length - 2, " more messages (Ctrl+O to expand)"] }) }))] }));
|
|
38
|
+
};
|
package/dist/plain-cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plain-cli.d.ts","sourceRoot":"","sources":["../src/plain-cli.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"plain-cli.d.ts","sourceRoot":"","sources":["../src/plain-cli.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAkD3E"}
|
package/dist/plain-cli.js
CHANGED
|
@@ -9,13 +9,12 @@ export async function startPlainCli(options) {
|
|
|
9
9
|
process.exit(1);
|
|
10
10
|
}
|
|
11
11
|
let agent;
|
|
12
|
-
let lastAssistantMessage;
|
|
13
12
|
// Setup callbacks for agent
|
|
14
13
|
const callbacks = {
|
|
15
14
|
onAssistantMessageAdded: (content) => {
|
|
16
|
-
//
|
|
15
|
+
// Only output the content field, not tool calls
|
|
17
16
|
if (content) {
|
|
18
|
-
|
|
17
|
+
console.log(content);
|
|
19
18
|
}
|
|
20
19
|
},
|
|
21
20
|
};
|
|
@@ -31,10 +30,6 @@ export async function startPlainCli(options) {
|
|
|
31
30
|
if (message && message.trim() !== "") {
|
|
32
31
|
await agent.sendMessage(message);
|
|
33
32
|
}
|
|
34
|
-
// Output only the last assistant message
|
|
35
|
-
if (lastAssistantMessage) {
|
|
36
|
-
console.log(lastAssistantMessage);
|
|
37
|
-
}
|
|
38
33
|
// Destroy agent and exit after sendMessage completes
|
|
39
34
|
agent.destroy();
|
|
40
35
|
process.exit(0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wave-code",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "CLI-based code assistant powered by AI, built with React and Ink",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"yargs": "^17.7.2",
|
|
30
30
|
"diff": "^8.0.2",
|
|
31
31
|
"glob": "^11.0.3",
|
|
32
|
-
"wave-agent-sdk": "0.0.
|
|
32
|
+
"wave-agent-sdk": "0.0.3"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/react": "^19.1.8",
|
|
@@ -112,7 +112,7 @@ export const FileSelector: React.FC<FileSelectorProps> = ({
|
|
|
112
112
|
color={isSelected ? "black" : "white"}
|
|
113
113
|
backgroundColor={isSelected ? "cyan" : undefined}
|
|
114
114
|
>
|
|
115
|
-
{
|
|
115
|
+
{" "}
|
|
116
116
|
{icon} {fileItem.path}
|
|
117
117
|
</Text>
|
|
118
118
|
</Box>
|
|
@@ -6,6 +6,7 @@ import { CommandOutputDisplay } from "./CommandOutputDisplay.js";
|
|
|
6
6
|
import { ToolResultDisplay } from "./ToolResultDisplay.js";
|
|
7
7
|
import { MemoryDisplay } from "./MemoryDisplay.js";
|
|
8
8
|
import { CompressDisplay } from "./CompressDisplay.js";
|
|
9
|
+
import { SubagentBlock } from "./SubagentBlock.js";
|
|
9
10
|
import { usePagination } from "../hooks/usePagination.js";
|
|
10
11
|
|
|
11
12
|
// Function to render a single message
|
|
@@ -18,7 +19,7 @@ const renderMessageItem = (
|
|
|
18
19
|
const shouldShowHeader = previousMessage?.role !== message.role;
|
|
19
20
|
|
|
20
21
|
return (
|
|
21
|
-
<Box key={`message-${originalIndex}`} flexDirection="column"
|
|
22
|
+
<Box key={`message-${originalIndex}`} flexDirection="column">
|
|
22
23
|
{shouldShowHeader && (
|
|
23
24
|
<Box>
|
|
24
25
|
<Text color={message.role === "user" ? "cyan" : "green"} bold>
|
|
@@ -91,6 +92,10 @@ const renderMessageItem = (
|
|
|
91
92
|
<Text>{block.originalInput || `/${block.commandName}`}</Text>
|
|
92
93
|
</Box>
|
|
93
94
|
)}
|
|
95
|
+
|
|
96
|
+
{block.type === "subagent" && (
|
|
97
|
+
<SubagentBlock block={block} isExpanded={isExpanded} />
|
|
98
|
+
)}
|
|
94
99
|
</Box>
|
|
95
100
|
))}
|
|
96
101
|
</Box>
|
|
@@ -138,9 +143,9 @@ export const MessageList: React.FC<MessageListProps> = ({
|
|
|
138
143
|
}
|
|
139
144
|
|
|
140
145
|
return (
|
|
141
|
-
<Box flexDirection="column">
|
|
146
|
+
<Box flexDirection="column" gap={1} marginTop={1}>
|
|
142
147
|
{/* Message list */}
|
|
143
|
-
<Box flexDirection="column">
|
|
148
|
+
<Box flexDirection="column" gap={1}>
|
|
144
149
|
{currentMessagesWithIndex.map(({ message, originalIndex }) => {
|
|
145
150
|
// Get previous message
|
|
146
151
|
const previousMessage =
|
|
@@ -156,7 +161,7 @@ export const MessageList: React.FC<MessageListProps> = ({
|
|
|
156
161
|
|
|
157
162
|
{/* Loading state display - only show in non-expanded state */}
|
|
158
163
|
{!isExpanded && (isLoading || isCommandRunning || isCompressing) && (
|
|
159
|
-
<Box
|
|
164
|
+
<Box flexDirection="column" gap={1}>
|
|
160
165
|
{isLoading && (
|
|
161
166
|
<Box>
|
|
162
167
|
<Text color="yellow">đ AI is thinking... </Text>
|
|
@@ -191,7 +196,7 @@ export const MessageList: React.FC<MessageListProps> = ({
|
|
|
191
196
|
|
|
192
197
|
{/* Bottom info and shortcut key hints */}
|
|
193
198
|
{messages.length > 0 && (
|
|
194
|
-
<Box
|
|
199
|
+
<Box>
|
|
195
200
|
<Box justifyContent="space-between" width="100%">
|
|
196
201
|
<Box>
|
|
197
202
|
<Text color="gray">
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import type {
|
|
4
|
+
SubagentBlock as SubagentBlockType,
|
|
5
|
+
Message,
|
|
6
|
+
MessageBlock,
|
|
7
|
+
} from "wave-agent-sdk/src/types.js";
|
|
8
|
+
import { ToolResultDisplay } from "./ToolResultDisplay.js";
|
|
9
|
+
|
|
10
|
+
// Component to render individual message blocks
|
|
11
|
+
interface MessageBlockRendererProps {
|
|
12
|
+
block: MessageBlock;
|
|
13
|
+
isExpanded: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const MessageBlockRenderer: React.FC<MessageBlockRendererProps> = ({
|
|
17
|
+
block,
|
|
18
|
+
isExpanded,
|
|
19
|
+
}) => {
|
|
20
|
+
switch (block.type) {
|
|
21
|
+
case "text":
|
|
22
|
+
return <Text>{block.content}</Text>;
|
|
23
|
+
|
|
24
|
+
case "error":
|
|
25
|
+
return <Text color="red">â Error: {block.content}</Text>;
|
|
26
|
+
|
|
27
|
+
case "tool":
|
|
28
|
+
return <ToolResultDisplay block={block} isExpanded={isExpanded} />;
|
|
29
|
+
|
|
30
|
+
default:
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
interface SubagentBlockProps {
|
|
36
|
+
block: SubagentBlockType;
|
|
37
|
+
isExpanded?: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const SubagentBlock: React.FC<SubagentBlockProps> = ({
|
|
41
|
+
block,
|
|
42
|
+
isExpanded = false,
|
|
43
|
+
}) => {
|
|
44
|
+
// Status indicator mapping
|
|
45
|
+
const getStatusIndicator = (status: SubagentBlockType["status"]) => {
|
|
46
|
+
switch (status) {
|
|
47
|
+
case "active":
|
|
48
|
+
return { icon: "đ", color: "yellow" as const };
|
|
49
|
+
case "completed":
|
|
50
|
+
return { icon: "â
", color: "green" as const };
|
|
51
|
+
case "error":
|
|
52
|
+
return { icon: "â", color: "red" as const };
|
|
53
|
+
case "aborted":
|
|
54
|
+
return { icon: "âšī¸", color: "gray" as const };
|
|
55
|
+
default:
|
|
56
|
+
return { icon: "âŗ", color: "gray" as const };
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const statusInfo = getStatusIndicator(block.status);
|
|
61
|
+
|
|
62
|
+
// Determine how many messages to show
|
|
63
|
+
const messagesToShow = isExpanded
|
|
64
|
+
? block.messages.slice(-10) // Up to 10 most recent when expanded
|
|
65
|
+
: block.messages.slice(-2); // Up to 2 most recent when collapsed
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<Box
|
|
69
|
+
borderStyle="round"
|
|
70
|
+
borderColor="magenta"
|
|
71
|
+
paddingX={1}
|
|
72
|
+
paddingY={0}
|
|
73
|
+
flexDirection="column"
|
|
74
|
+
marginBottom={1}
|
|
75
|
+
>
|
|
76
|
+
{/* Header Section */}
|
|
77
|
+
<Box
|
|
78
|
+
flexDirection="row"
|
|
79
|
+
justifyContent="space-between"
|
|
80
|
+
alignItems="center"
|
|
81
|
+
>
|
|
82
|
+
<Box flexDirection="row" alignItems="center">
|
|
83
|
+
<Text color="cyan">đ¤ {block.subagentName}</Text>
|
|
84
|
+
<Text color={statusInfo.color} dimColor={false}>
|
|
85
|
+
{" "}
|
|
86
|
+
{statusInfo.icon}
|
|
87
|
+
</Text>
|
|
88
|
+
</Box>
|
|
89
|
+
|
|
90
|
+
{!isExpanded && (
|
|
91
|
+
<Text color="gray" dimColor>
|
|
92
|
+
{block.messages.length} messages
|
|
93
|
+
</Text>
|
|
94
|
+
)}
|
|
95
|
+
</Box>
|
|
96
|
+
|
|
97
|
+
{/* Messages Section */}
|
|
98
|
+
{messagesToShow.length > 0 && (
|
|
99
|
+
<Box flexDirection="column" marginTop={1} gap={1}>
|
|
100
|
+
{messagesToShow.map((message: Message, index: number) => (
|
|
101
|
+
<Box key={index} flexDirection="column" marginBottom={0} gap={1}>
|
|
102
|
+
{message.blocks.map(
|
|
103
|
+
(messageBlock: MessageBlock, blockIndex: number) => (
|
|
104
|
+
<Box key={blockIndex} flexDirection="column">
|
|
105
|
+
<MessageBlockRenderer
|
|
106
|
+
block={messageBlock}
|
|
107
|
+
isExpanded={isExpanded}
|
|
108
|
+
/>
|
|
109
|
+
</Box>
|
|
110
|
+
),
|
|
111
|
+
)}
|
|
112
|
+
</Box>
|
|
113
|
+
))}
|
|
114
|
+
</Box>
|
|
115
|
+
)}
|
|
116
|
+
|
|
117
|
+
{/* Show truncation indicator if there are more messages */}
|
|
118
|
+
{!isExpanded && block.messages.length > 2 && (
|
|
119
|
+
<Box marginTop={1}>
|
|
120
|
+
<Text color="gray" dimColor>
|
|
121
|
+
... and {block.messages.length - 2} more messages (Ctrl+O to expand)
|
|
122
|
+
</Text>
|
|
123
|
+
</Box>
|
|
124
|
+
)}
|
|
125
|
+
</Box>
|
|
126
|
+
);
|
|
127
|
+
};
|
package/src/plain-cli.ts
CHANGED
|
@@ -22,14 +22,13 @@ export async function startPlainCli(options: PlainCliOptions): Promise<void> {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
let agent: Agent;
|
|
25
|
-
let lastAssistantMessage: string | undefined;
|
|
26
25
|
|
|
27
26
|
// Setup callbacks for agent
|
|
28
27
|
const callbacks: AgentCallbacks = {
|
|
29
28
|
onAssistantMessageAdded: (content?: string) => {
|
|
30
|
-
//
|
|
29
|
+
// Only output the content field, not tool calls
|
|
31
30
|
if (content) {
|
|
32
|
-
|
|
31
|
+
console.log(content);
|
|
33
32
|
}
|
|
34
33
|
},
|
|
35
34
|
};
|
|
@@ -48,11 +47,6 @@ export async function startPlainCli(options: PlainCliOptions): Promise<void> {
|
|
|
48
47
|
await agent.sendMessage(message);
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
// Output only the last assistant message
|
|
52
|
-
if (lastAssistantMessage) {
|
|
53
|
-
console.log(lastAssistantMessage);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
50
|
// Destroy agent and exit after sendMessage completes
|
|
57
51
|
agent.destroy();
|
|
58
52
|
process.exit(0);
|