wave-code 0.0.5 → 0.0.8
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/README.md +3 -3
- package/dist/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/components/App.d.ts +1 -0
- package/dist/components/App.d.ts.map +1 -1
- package/dist/components/App.js +4 -4
- package/dist/components/BashHistorySelector.d.ts.map +1 -1
- package/dist/components/BashHistorySelector.js +17 -3
- package/dist/components/ChatInterface.d.ts.map +1 -1
- package/dist/components/ChatInterface.js +6 -24
- package/dist/components/CommandSelector.js +4 -4
- package/dist/components/Confirmation.d.ts +11 -0
- package/dist/components/Confirmation.d.ts.map +1 -0
- package/dist/components/Confirmation.js +148 -0
- package/dist/components/DiffDisplay.d.ts +8 -0
- package/dist/components/DiffDisplay.d.ts.map +1 -0
- package/dist/components/DiffDisplay.js +168 -0
- package/dist/components/FileSelector.d.ts +2 -4
- package/dist/components/FileSelector.d.ts.map +1 -1
- package/dist/components/FileSelector.js +2 -2
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +30 -50
- package/dist/components/Markdown.d.ts +6 -0
- package/dist/components/Markdown.d.ts.map +1 -0
- package/dist/components/Markdown.js +22 -0
- package/dist/components/MemoryDisplay.js +1 -1
- package/dist/components/MessageItem.d.ts +8 -0
- package/dist/components/MessageItem.d.ts.map +1 -0
- package/dist/components/MessageItem.js +15 -0
- package/dist/components/MessageList.d.ts +1 -1
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +33 -33
- package/dist/components/ReasoningDisplay.d.ts +8 -0
- package/dist/components/ReasoningDisplay.d.ts.map +1 -0
- package/dist/components/ReasoningDisplay.js +10 -0
- package/dist/components/SubagentBlock.d.ts +0 -1
- package/dist/components/SubagentBlock.d.ts.map +1 -1
- package/dist/components/SubagentBlock.js +29 -30
- package/dist/components/ToolResultDisplay.d.ts.map +1 -1
- package/dist/components/ToolResultDisplay.js +6 -5
- package/dist/contexts/useChat.d.ts +14 -2
- package/dist/contexts/useChat.d.ts.map +1 -1
- package/dist/contexts/useChat.js +128 -17
- package/dist/hooks/useInputManager.d.ts +6 -1
- package/dist/hooks/useInputManager.d.ts.map +1 -1
- package/dist/hooks/useInputManager.js +32 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -5
- package/dist/managers/InputManager.d.ts +11 -1
- package/dist/managers/InputManager.d.ts.map +1 -1
- package/dist/managers/InputManager.js +77 -26
- package/dist/print-cli.d.ts +2 -0
- package/dist/print-cli.d.ts.map +1 -1
- package/dist/print-cli.js +121 -23
- package/dist/utils/toolParameterTransforms.d.ts +23 -0
- package/dist/utils/toolParameterTransforms.d.ts.map +1 -0
- package/dist/utils/toolParameterTransforms.js +77 -0
- package/dist/utils/usageSummary.d.ts +6 -0
- package/dist/utils/usageSummary.d.ts.map +1 -1
- package/dist/utils/usageSummary.js +72 -0
- package/package.json +13 -8
- package/src/cli.tsx +3 -1
- package/src/components/App.tsx +7 -3
- package/src/components/BashHistorySelector.tsx +26 -3
- package/src/components/ChatInterface.tsx +38 -54
- package/src/components/CommandSelector.tsx +5 -5
- package/src/components/Confirmation.tsx +253 -0
- package/src/components/DiffDisplay.tsx +300 -0
- package/src/components/FileSelector.tsx +4 -6
- package/src/components/InputBox.tsx +58 -87
- package/src/components/Markdown.tsx +29 -0
- package/src/components/MemoryDisplay.tsx +1 -1
- package/src/components/MessageItem.tsx +96 -0
- package/src/components/MessageList.tsx +140 -202
- package/src/components/ReasoningDisplay.tsx +33 -0
- package/src/components/SubagentBlock.tsx +56 -84
- package/src/components/ToolResultDisplay.tsx +9 -5
- package/src/contexts/useChat.tsx +194 -21
- package/src/hooks/useInputManager.ts +40 -3
- package/src/index.ts +45 -5
- package/src/managers/InputManager.ts +101 -27
- package/src/print-cli.ts +143 -21
- package/src/utils/toolParameterTransforms.ts +104 -0
- package/src/utils/usageSummary.ts +109 -0
- package/dist/components/DiffViewer.d.ts +0 -9
- package/dist/components/DiffViewer.d.ts.map +0 -1
- package/dist/components/DiffViewer.js +0 -221
- package/dist/utils/fileSearch.d.ts +0 -20
- package/dist/utils/fileSearch.d.ts.map +0 -1
- package/dist/utils/fileSearch.js +0 -102
- package/src/components/DiffViewer.tsx +0 -321
- package/src/utils/fileSearch.ts +0 -133
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import type { Message } from "wave-agent-sdk";
|
|
4
|
+
import { MessageSource } from "wave-agent-sdk";
|
|
5
|
+
import { CommandOutputDisplay } from "./CommandOutputDisplay.js";
|
|
6
|
+
import { ToolResultDisplay } from "./ToolResultDisplay.js";
|
|
7
|
+
import { MemoryDisplay } from "./MemoryDisplay.js";
|
|
8
|
+
import { CompressDisplay } from "./CompressDisplay.js";
|
|
9
|
+
import { SubagentBlock } from "./SubagentBlock.js";
|
|
10
|
+
import { ReasoningDisplay } from "./ReasoningDisplay.js";
|
|
11
|
+
import { Markdown } from "./Markdown.js";
|
|
12
|
+
|
|
13
|
+
export interface MessageItemProps {
|
|
14
|
+
message: Message;
|
|
15
|
+
isExpanded: boolean;
|
|
16
|
+
shouldShowHeader: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const MessageItem = ({
|
|
20
|
+
message,
|
|
21
|
+
isExpanded,
|
|
22
|
+
shouldShowHeader,
|
|
23
|
+
}: MessageItemProps) => {
|
|
24
|
+
if (message.blocks.length === 0) return null;
|
|
25
|
+
return (
|
|
26
|
+
<Box flexDirection="column" gap={1} marginTop={1}>
|
|
27
|
+
{shouldShowHeader && (
|
|
28
|
+
<Box>
|
|
29
|
+
<Text color={message.role === "user" ? "cyan" : "green"} bold>
|
|
30
|
+
{message.role === "user" ? "👤 You" : "🤖 Assistant"}
|
|
31
|
+
</Text>
|
|
32
|
+
</Box>
|
|
33
|
+
)}
|
|
34
|
+
|
|
35
|
+
<Box flexDirection="column" gap={1}>
|
|
36
|
+
{message.blocks.map((block, blockIndex) => (
|
|
37
|
+
<Box key={blockIndex}>
|
|
38
|
+
{block.type === "text" && block.content.trim() && (
|
|
39
|
+
<Box>
|
|
40
|
+
{block.customCommandContent && (
|
|
41
|
+
<Text color="cyan" bold>
|
|
42
|
+
⚡{" "}
|
|
43
|
+
</Text>
|
|
44
|
+
)}
|
|
45
|
+
{block.source === MessageSource.HOOK && (
|
|
46
|
+
<Text color="magenta" bold>
|
|
47
|
+
🔗{" "}
|
|
48
|
+
</Text>
|
|
49
|
+
)}
|
|
50
|
+
<Markdown>{block.content}</Markdown>
|
|
51
|
+
</Box>
|
|
52
|
+
)}
|
|
53
|
+
|
|
54
|
+
{block.type === "error" && (
|
|
55
|
+
<Box>
|
|
56
|
+
<Text color="red">❌ Error: {block.content}</Text>
|
|
57
|
+
</Box>
|
|
58
|
+
)}
|
|
59
|
+
|
|
60
|
+
{block.type === "command_output" && (
|
|
61
|
+
<CommandOutputDisplay block={block} isExpanded={isExpanded} />
|
|
62
|
+
)}
|
|
63
|
+
|
|
64
|
+
{block.type === "tool" && (
|
|
65
|
+
<ToolResultDisplay block={block} isExpanded={isExpanded} />
|
|
66
|
+
)}
|
|
67
|
+
|
|
68
|
+
{block.type === "image" && (
|
|
69
|
+
<Box>
|
|
70
|
+
<Text color="magenta" bold>
|
|
71
|
+
📷 Image
|
|
72
|
+
</Text>
|
|
73
|
+
{block.imageUrls && block.imageUrls.length > 0 && (
|
|
74
|
+
<Text color="gray" dimColor>
|
|
75
|
+
{" "}
|
|
76
|
+
({block.imageUrls.length})
|
|
77
|
+
</Text>
|
|
78
|
+
)}
|
|
79
|
+
</Box>
|
|
80
|
+
)}
|
|
81
|
+
|
|
82
|
+
{block.type === "memory" && <MemoryDisplay block={block} />}
|
|
83
|
+
|
|
84
|
+
{block.type === "compress" && (
|
|
85
|
+
<CompressDisplay block={block} isExpanded={isExpanded} />
|
|
86
|
+
)}
|
|
87
|
+
|
|
88
|
+
{block.type === "subagent" && <SubagentBlock block={block} />}
|
|
89
|
+
|
|
90
|
+
{block.type === "reasoning" && <ReasoningDisplay block={block} />}
|
|
91
|
+
</Box>
|
|
92
|
+
))}
|
|
93
|
+
</Box>
|
|
94
|
+
</Box>
|
|
95
|
+
);
|
|
96
|
+
};
|
|
@@ -1,111 +1,7 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import { Box, Text } from "ink";
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Box, Text, Static } from "ink";
|
|
3
3
|
import type { Message } from "wave-agent-sdk";
|
|
4
|
-
import {
|
|
5
|
-
import { DiffViewer } from "./DiffViewer.js";
|
|
6
|
-
import { CommandOutputDisplay } from "./CommandOutputDisplay.js";
|
|
7
|
-
import { ToolResultDisplay } from "./ToolResultDisplay.js";
|
|
8
|
-
import { MemoryDisplay } from "./MemoryDisplay.js";
|
|
9
|
-
import { CompressDisplay } from "./CompressDisplay.js";
|
|
10
|
-
import { SubagentBlock } from "./SubagentBlock.js";
|
|
11
|
-
import { usePagination } from "../hooks/usePagination.js";
|
|
12
|
-
|
|
13
|
-
// Function to render a single message
|
|
14
|
-
const renderMessageItem = (
|
|
15
|
-
message: Message,
|
|
16
|
-
originalIndex: number,
|
|
17
|
-
isExpanded: boolean,
|
|
18
|
-
previousMessage?: Message,
|
|
19
|
-
) => {
|
|
20
|
-
const shouldShowHeader = previousMessage?.role !== message.role;
|
|
21
|
-
|
|
22
|
-
return (
|
|
23
|
-
<Box key={`message-${originalIndex}`} flexDirection="column">
|
|
24
|
-
{shouldShowHeader && (
|
|
25
|
-
<Box>
|
|
26
|
-
<Text color={message.role === "user" ? "cyan" : "green"} bold>
|
|
27
|
-
{message.role === "user" ? "👤 You" : "🤖 Assistant"}
|
|
28
|
-
<Text color="gray" dimColor>
|
|
29
|
-
{" "}
|
|
30
|
-
#{originalIndex + 1}
|
|
31
|
-
</Text>
|
|
32
|
-
</Text>
|
|
33
|
-
</Box>
|
|
34
|
-
)}
|
|
35
|
-
|
|
36
|
-
<Box
|
|
37
|
-
marginLeft={2}
|
|
38
|
-
flexDirection="column"
|
|
39
|
-
gap={1}
|
|
40
|
-
marginTop={shouldShowHeader ? 1 : 0}
|
|
41
|
-
>
|
|
42
|
-
{message.blocks.map((block, blockIndex) => (
|
|
43
|
-
<Box key={blockIndex}>
|
|
44
|
-
{block.type === "text" && block.content.trim() && (
|
|
45
|
-
<Box>
|
|
46
|
-
<Text>
|
|
47
|
-
{block.customCommandContent && (
|
|
48
|
-
<Text color="cyan" bold>
|
|
49
|
-
⚡{" "}
|
|
50
|
-
</Text>
|
|
51
|
-
)}
|
|
52
|
-
{block.source === MessageSource.HOOK && (
|
|
53
|
-
<Text color="magenta" bold>
|
|
54
|
-
🔗{" "}
|
|
55
|
-
</Text>
|
|
56
|
-
)}
|
|
57
|
-
{block.content}
|
|
58
|
-
</Text>
|
|
59
|
-
</Box>
|
|
60
|
-
)}
|
|
61
|
-
|
|
62
|
-
{block.type === "error" && (
|
|
63
|
-
<Box>
|
|
64
|
-
<Text color="red">❌ Error: {block.content}</Text>
|
|
65
|
-
</Box>
|
|
66
|
-
)}
|
|
67
|
-
|
|
68
|
-
{block.type === "diff" && (
|
|
69
|
-
<DiffViewer block={block} isExpanded={isExpanded} />
|
|
70
|
-
)}
|
|
71
|
-
|
|
72
|
-
{block.type === "command_output" && (
|
|
73
|
-
<CommandOutputDisplay block={block} isExpanded={isExpanded} />
|
|
74
|
-
)}
|
|
75
|
-
|
|
76
|
-
{block.type === "tool" && (
|
|
77
|
-
<ToolResultDisplay block={block} isExpanded={isExpanded} />
|
|
78
|
-
)}
|
|
79
|
-
|
|
80
|
-
{block.type === "image" && (
|
|
81
|
-
<Box>
|
|
82
|
-
<Text color="magenta" bold>
|
|
83
|
-
📷 Image
|
|
84
|
-
</Text>
|
|
85
|
-
{block.imageUrls && block.imageUrls.length > 0 && (
|
|
86
|
-
<Text color="gray" dimColor>
|
|
87
|
-
{" "}
|
|
88
|
-
({block.imageUrls.length})
|
|
89
|
-
</Text>
|
|
90
|
-
)}
|
|
91
|
-
</Box>
|
|
92
|
-
)}
|
|
93
|
-
|
|
94
|
-
{block.type === "memory" && <MemoryDisplay block={block} />}
|
|
95
|
-
|
|
96
|
-
{block.type === "compress" && (
|
|
97
|
-
<CompressDisplay block={block} isExpanded={isExpanded} />
|
|
98
|
-
)}
|
|
99
|
-
|
|
100
|
-
{block.type === "subagent" && (
|
|
101
|
-
<SubagentBlock block={block} isExpanded={isExpanded} />
|
|
102
|
-
)}
|
|
103
|
-
</Box>
|
|
104
|
-
))}
|
|
105
|
-
</Box>
|
|
106
|
-
</Box>
|
|
107
|
-
);
|
|
108
|
-
};
|
|
4
|
+
import { MessageItem } from "./MessageItem.js";
|
|
109
5
|
|
|
110
6
|
export interface MessageListProps {
|
|
111
7
|
messages: Message[];
|
|
@@ -116,109 +12,151 @@ export interface MessageListProps {
|
|
|
116
12
|
isExpanded?: boolean;
|
|
117
13
|
}
|
|
118
14
|
|
|
119
|
-
export const MessageList
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
15
|
+
export const MessageList = React.memo(
|
|
16
|
+
({
|
|
17
|
+
messages,
|
|
18
|
+
isLoading = false,
|
|
19
|
+
isCommandRunning = false,
|
|
20
|
+
isCompressing = false,
|
|
21
|
+
latestTotalTokens = 0,
|
|
22
|
+
isExpanded = false,
|
|
23
|
+
}: MessageListProps) => {
|
|
24
|
+
// Empty message state
|
|
25
|
+
if (messages.length === 0) {
|
|
26
|
+
return (
|
|
27
|
+
<Box flexDirection="column" paddingY={1}>
|
|
28
|
+
<Text color="gray">Welcome to WAVE Code Assistant!</Text>
|
|
29
|
+
</Box>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Limit messages when expanded to prevent long rendering times
|
|
34
|
+
const maxExpandedMessages = 20;
|
|
35
|
+
const shouldLimitMessages =
|
|
36
|
+
isExpanded && messages.length > maxExpandedMessages;
|
|
37
|
+
const displayMessages = shouldLimitMessages
|
|
38
|
+
? messages.slice(-maxExpandedMessages)
|
|
39
|
+
: messages;
|
|
40
|
+
const omittedCount = shouldLimitMessages
|
|
41
|
+
? messages.length - maxExpandedMessages
|
|
42
|
+
: 0;
|
|
43
|
+
|
|
44
|
+
// Compute which messages to render statically vs dynamically
|
|
45
|
+
const shouldRenderLastDynamic = isLoading || isCommandRunning;
|
|
46
|
+
const staticMessages = shouldRenderLastDynamic
|
|
47
|
+
? displayMessages.slice(0, -1)
|
|
48
|
+
: displayMessages;
|
|
49
|
+
const dynamicMessages =
|
|
50
|
+
shouldRenderLastDynamic && displayMessages.length > 0
|
|
51
|
+
? [displayMessages[displayMessages.length - 1]]
|
|
52
|
+
: [];
|
|
139
53
|
|
|
140
|
-
// Empty message state
|
|
141
|
-
if (messages.length === 0) {
|
|
142
54
|
return (
|
|
143
|
-
<Box flexDirection="column"
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
55
|
+
<Box flexDirection="column" paddingX={1} gap={1}>
|
|
56
|
+
{/* Show omitted message count when limiting */}
|
|
57
|
+
{omittedCount > 0 && (
|
|
58
|
+
<Box>
|
|
59
|
+
<Text color="gray" dimColor>
|
|
60
|
+
... {omittedCount} earlier message{omittedCount !== 1 ? "s" : ""}{" "}
|
|
61
|
+
omitted (showing latest {maxExpandedMessages})
|
|
62
|
+
</Text>
|
|
63
|
+
</Box>
|
|
64
|
+
)}
|
|
65
|
+
|
|
66
|
+
{/* Static messages */}
|
|
67
|
+
<Static items={staticMessages}>
|
|
68
|
+
{(message, key) => {
|
|
69
|
+
// Get previous message
|
|
70
|
+
const previousMessage =
|
|
71
|
+
key > 0 ? staticMessages[key - 1] : undefined;
|
|
72
|
+
return (
|
|
73
|
+
<MessageItem
|
|
74
|
+
key={key}
|
|
75
|
+
message={message}
|
|
76
|
+
shouldShowHeader={previousMessage?.role !== message.role}
|
|
77
|
+
isExpanded={isExpanded}
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
}}
|
|
81
|
+
</Static>
|
|
82
|
+
|
|
83
|
+
{/* Dynamic messages */}
|
|
84
|
+
{dynamicMessages.map((message, index) => {
|
|
85
|
+
const messageIndex = staticMessages.length + index;
|
|
155
86
|
const previousMessage =
|
|
156
|
-
|
|
157
|
-
return
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
87
|
+
messageIndex > 0 ? displayMessages[messageIndex - 1] : undefined;
|
|
88
|
+
return (
|
|
89
|
+
<Box key={`dynamic-${index}`} marginTop={-1}>
|
|
90
|
+
<MessageItem
|
|
91
|
+
message={message}
|
|
92
|
+
shouldShowHeader={previousMessage?.role !== message.role}
|
|
93
|
+
isExpanded={isExpanded}
|
|
94
|
+
/>
|
|
95
|
+
</Box>
|
|
162
96
|
);
|
|
163
97
|
})}
|
|
164
|
-
</Box>
|
|
165
98
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
)}
|
|
192
|
-
{isCommandRunning && (
|
|
193
|
-
<Text color="blue">🚀 Command is running...</Text>
|
|
194
|
-
)}
|
|
195
|
-
{isCompressing && (
|
|
196
|
-
<Text color="magenta">🗜️ Compressing message history...</Text>
|
|
197
|
-
)}
|
|
198
|
-
</Box>
|
|
199
|
-
)}
|
|
99
|
+
{(isLoading || isCommandRunning || isCompressing) && (
|
|
100
|
+
<Box flexDirection="column" gap={1}>
|
|
101
|
+
{isLoading && (
|
|
102
|
+
<Box>
|
|
103
|
+
<Text color="yellow">💭 AI is thinking... </Text>
|
|
104
|
+
<Text color="gray" dimColor>
|
|
105
|
+
|{" "}
|
|
106
|
+
</Text>
|
|
107
|
+
<Text color="red" bold>
|
|
108
|
+
Esc
|
|
109
|
+
</Text>
|
|
110
|
+
<Text color="gray" dimColor>
|
|
111
|
+
{" "}
|
|
112
|
+
to abort
|
|
113
|
+
</Text>
|
|
114
|
+
</Box>
|
|
115
|
+
)}
|
|
116
|
+
{isCommandRunning && (
|
|
117
|
+
<Text color="blue">🚀 Command is running...</Text>
|
|
118
|
+
)}
|
|
119
|
+
{isCompressing && (
|
|
120
|
+
<Text color="magenta">🗜️ Compressing message history...</Text>
|
|
121
|
+
)}
|
|
122
|
+
</Box>
|
|
123
|
+
)}
|
|
200
124
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
125
|
+
{/* Bottom info and shortcut key hints */}
|
|
126
|
+
{messages.length > 0 && (
|
|
127
|
+
<Box>
|
|
128
|
+
<Box justifyContent="space-between" width="100%">
|
|
129
|
+
<Box>
|
|
130
|
+
<Text color="gray">
|
|
131
|
+
Messages {messages.length}
|
|
132
|
+
{latestTotalTokens > 0 && (
|
|
133
|
+
<>
|
|
134
|
+
<Text color="gray" dimColor>
|
|
135
|
+
{" "}
|
|
136
|
+
|{" "}
|
|
137
|
+
</Text>
|
|
138
|
+
<Text color="blue" bold>
|
|
139
|
+
{latestTotalTokens.toLocaleString()}
|
|
140
|
+
</Text>
|
|
141
|
+
<Text color="gray" dimColor>
|
|
142
|
+
{" "}
|
|
143
|
+
tokens
|
|
144
|
+
</Text>
|
|
145
|
+
</>
|
|
146
|
+
)}
|
|
147
|
+
</Text>
|
|
148
|
+
</Box>
|
|
210
149
|
<Text color="gray" dimColor>
|
|
211
|
-
{" "}
|
|
212
|
-
|
|
150
|
+
<Text color="cyan">Ctrl+O</Text> Toggle{" "}
|
|
151
|
+
{isExpanded ? "Collapse" : "Expand"}
|
|
213
152
|
</Text>
|
|
214
153
|
</Box>
|
|
215
|
-
<Text color="gray" dimColor>
|
|
216
|
-
<Text color="cyan">Ctrl+O</Text> Toggle{" "}
|
|
217
|
-
{isExpanded ? "Collapse" : "Expand"}
|
|
218
|
-
</Text>
|
|
219
154
|
</Box>
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
155
|
+
)}
|
|
156
|
+
</Box>
|
|
157
|
+
);
|
|
158
|
+
},
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
// Add display name for debugging
|
|
162
|
+
MessageList.displayName = "MessageList";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Box } from "ink";
|
|
3
|
+
import type { ReasoningBlock } from "wave-agent-sdk";
|
|
4
|
+
import { Markdown } from "./Markdown.js";
|
|
5
|
+
|
|
6
|
+
interface ReasoningDisplayProps {
|
|
7
|
+
block: ReasoningBlock;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const ReasoningDisplay: React.FC<ReasoningDisplayProps> = ({
|
|
11
|
+
block,
|
|
12
|
+
}) => {
|
|
13
|
+
const { content } = block;
|
|
14
|
+
|
|
15
|
+
if (!content || !content.trim()) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<Box
|
|
21
|
+
borderRight={false}
|
|
22
|
+
borderTop={false}
|
|
23
|
+
borderBottom={false}
|
|
24
|
+
borderStyle="classic"
|
|
25
|
+
borderColor="blue"
|
|
26
|
+
paddingLeft={1}
|
|
27
|
+
>
|
|
28
|
+
<Box flexDirection="column">
|
|
29
|
+
<Markdown>{content}</Markdown>
|
|
30
|
+
</Box>
|
|
31
|
+
</Box>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
@@ -1,57 +1,18 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
Message,
|
|
6
|
-
MessageBlock,
|
|
7
|
-
} from "wave-agent-sdk";
|
|
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
|
-
const truncateText = (text: string, maxLines: number): string => {
|
|
21
|
-
const lines = text.split("\n");
|
|
22
|
-
if (lines.length <= maxLines) {
|
|
23
|
-
return text;
|
|
24
|
-
}
|
|
25
|
-
return lines.slice(0, maxLines).join("\n") + "\n...";
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
switch (block.type) {
|
|
29
|
-
case "text": {
|
|
30
|
-
const maxLines = isExpanded ? 50 : 10;
|
|
31
|
-
const truncatedContent = truncateText(block.content, maxLines);
|
|
32
|
-
return <Text>{truncatedContent}</Text>;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
case "error":
|
|
36
|
-
return <Text color="red">❌ Error: {block.content}</Text>;
|
|
37
|
-
|
|
38
|
-
case "tool":
|
|
39
|
-
return <ToolResultDisplay block={block} isExpanded={isExpanded} />;
|
|
40
|
-
|
|
41
|
-
default:
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
};
|
|
3
|
+
import type { SubagentBlock as SubagentBlockType } from "wave-agent-sdk";
|
|
4
|
+
import { useChat } from "../contexts/useChat.js";
|
|
45
5
|
|
|
46
6
|
interface SubagentBlockProps {
|
|
47
7
|
block: SubagentBlockType;
|
|
48
|
-
isExpanded?: boolean;
|
|
49
8
|
}
|
|
50
9
|
|
|
51
|
-
export const SubagentBlock: React.FC<SubagentBlockProps> = ({
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
10
|
+
export const SubagentBlock: React.FC<SubagentBlockProps> = ({ block }) => {
|
|
11
|
+
const { subagentMessages } = useChat();
|
|
12
|
+
|
|
13
|
+
// Get messages for this subagent from context
|
|
14
|
+
const messages = subagentMessages[block.subagentId] || [];
|
|
15
|
+
|
|
55
16
|
// Status indicator mapping
|
|
56
17
|
const getStatusIndicator = (status: SubagentBlockType["status"]) => {
|
|
57
18
|
switch (status) {
|
|
@@ -70,14 +31,40 @@ export const SubagentBlock: React.FC<SubagentBlockProps> = ({
|
|
|
70
31
|
|
|
71
32
|
const statusInfo = getStatusIndicator(block.status);
|
|
72
33
|
|
|
73
|
-
//
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
:
|
|
34
|
+
// Find the last 2 tool names and their compact params, and count total tools
|
|
35
|
+
const getLastTwoTools = (): {
|
|
36
|
+
tools: Array<{ name: string; compactParams?: string }>;
|
|
37
|
+
totalToolCount: number;
|
|
38
|
+
} => {
|
|
39
|
+
const tools: Array<{ name: string; compactParams?: string }> = [];
|
|
40
|
+
let totalToolCount = 0;
|
|
41
|
+
|
|
42
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
43
|
+
const message = messages[i];
|
|
44
|
+
for (let j = message.blocks.length - 1; j >= 0; j--) {
|
|
45
|
+
const messageBlock = message.blocks[j];
|
|
46
|
+
if (messageBlock.type === "tool" && messageBlock.name) {
|
|
47
|
+
totalToolCount++;
|
|
48
|
+
if (tools.length < 2) {
|
|
49
|
+
tools.push({
|
|
50
|
+
name: messageBlock.name,
|
|
51
|
+
compactParams: messageBlock.compactParams,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return { tools: tools.reverse(), totalToolCount }; // Reverse to show oldest first, newest last
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const { tools: lastTwoTools, totalToolCount } = getLastTwoTools();
|
|
77
61
|
|
|
78
62
|
return (
|
|
79
63
|
<Box
|
|
80
|
-
|
|
64
|
+
borderRight={false}
|
|
65
|
+
borderTop={false}
|
|
66
|
+
borderBottom={false}
|
|
67
|
+
borderStyle="classic"
|
|
81
68
|
borderColor="magenta"
|
|
82
69
|
paddingX={1}
|
|
83
70
|
paddingY={0}
|
|
@@ -85,54 +72,39 @@ export const SubagentBlock: React.FC<SubagentBlockProps> = ({
|
|
|
85
72
|
marginBottom={1}
|
|
86
73
|
>
|
|
87
74
|
{/* Header Section */}
|
|
88
|
-
<Box
|
|
89
|
-
flexDirection="row"
|
|
90
|
-
justifyContent="space-between"
|
|
91
|
-
alignItems="center"
|
|
92
|
-
>
|
|
75
|
+
<Box flexDirection="row" gap={1}>
|
|
93
76
|
<Box flexDirection="row" alignItems="center">
|
|
94
77
|
<Text color="cyan">🤖 {block.subagentName}</Text>
|
|
95
78
|
<Text color={statusInfo.color} dimColor={false}>
|
|
96
79
|
{" "}
|
|
97
80
|
{statusInfo.icon}
|
|
98
81
|
</Text>
|
|
99
|
-
</Box>
|
|
100
|
-
|
|
101
|
-
{!isExpanded && (
|
|
102
82
|
<Text color="gray" dimColor>
|
|
103
|
-
{
|
|
83
|
+
{" "}
|
|
84
|
+
({messages.length} messages)
|
|
104
85
|
</Text>
|
|
105
|
-
|
|
86
|
+
</Box>
|
|
106
87
|
</Box>
|
|
107
88
|
|
|
108
|
-
{/*
|
|
109
|
-
{
|
|
89
|
+
{/* Tool Names Section - Vertical List */}
|
|
90
|
+
{lastTwoTools.length > 0 && (
|
|
110
91
|
<Box flexDirection="column" marginTop={1} gap={1}>
|
|
111
|
-
{
|
|
112
|
-
<
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
92
|
+
{totalToolCount > 2 && (
|
|
93
|
+
<Text color="gray" dimColor>
|
|
94
|
+
...
|
|
95
|
+
</Text>
|
|
96
|
+
)}
|
|
97
|
+
{lastTwoTools.map((tool, index) => (
|
|
98
|
+
<Box key={index} flexDirection="row">
|
|
99
|
+
<Text color="magenta">🔧 </Text>
|
|
100
|
+
<Text color="white">{tool.name}</Text>
|
|
101
|
+
{tool.compactParams && (
|
|
102
|
+
<Text color="gray"> {tool.compactParams}</Text>
|
|
122
103
|
)}
|
|
123
104
|
</Box>
|
|
124
105
|
))}
|
|
125
106
|
</Box>
|
|
126
107
|
)}
|
|
127
|
-
|
|
128
|
-
{/* Show truncation indicator if there are more messages */}
|
|
129
|
-
{!isExpanded && block.messages.length > 2 && (
|
|
130
|
-
<Box marginTop={1}>
|
|
131
|
-
<Text color="gray" dimColor>
|
|
132
|
-
... and {block.messages.length - 2} more messages (Ctrl+O to expand)
|
|
133
|
-
</Text>
|
|
134
|
-
</Box>
|
|
135
|
-
)}
|
|
136
108
|
</Box>
|
|
137
109
|
);
|
|
138
110
|
};
|