58 | {message.parts?.map((part, i) => {
59 | switch (part.type) {
60 | case "text":
61 | return (
62 |
68 |
74 | {part.text}
75 |
76 |
77 | );
78 | case "tool-invocation":
79 | const { toolName, toolCallId, state, args } =
80 | part.toolInvocation;
81 |
82 | if (toolName === "computer") {
83 | const {
84 | action,
85 | coordinate,
86 | text,
87 | duration,
88 | scroll_amount,
89 | scroll_direction,
90 | } = args;
91 | let actionLabel = "";
92 | let actionDetail = "";
93 | let ActionIcon = null;
94 |
95 | switch (action) {
96 | case "screenshot":
97 | actionLabel = "Taking screenshot";
98 | ActionIcon = Camera;
99 | break;
100 | case "left_click":
101 | actionLabel = "Left clicking";
102 | actionDetail = coordinate
103 | ? `at (${coordinate[0]}, ${coordinate[1]})`
104 | : "";
105 | ActionIcon = MousePointer;
106 | break;
107 | case "right_click":
108 | actionLabel = "Right clicking";
109 | actionDetail = coordinate
110 | ? `at (${coordinate[0]}, ${coordinate[1]})`
111 | : "";
112 | ActionIcon = MousePointerClick;
113 | break;
114 | case "double_click":
115 | actionLabel = "Double clicking";
116 | actionDetail = coordinate
117 | ? `at (${coordinate[0]}, ${coordinate[1]})`
118 | : "";
119 | ActionIcon = MousePointerClick;
120 | break;
121 | case "mouse_move":
122 | actionLabel = "Moving mouse";
123 | actionDetail = coordinate
124 | ? `to (${coordinate[0]}, ${coordinate[1]})`
125 | : "";
126 | ActionIcon = MousePointer;
127 | break;
128 | case "type":
129 | actionLabel = "Typing";
130 | actionDetail = text ? `"${text}"` : "";
131 | ActionIcon = Keyboard;
132 | break;
133 | case "key":
134 | actionLabel = "Pressing key";
135 | actionDetail = text ? `"${text}"` : "";
136 | ActionIcon = KeyRound;
137 | break;
138 | case "wait":
139 | actionLabel = "Waiting";
140 | actionDetail = duration ? `${duration} seconds` : "";
141 | ActionIcon = Clock;
142 | break;
143 | case "scroll":
144 | actionLabel = "Scrolling";
145 | actionDetail =
146 | scroll_direction && scroll_amount
147 | ? `${scroll_direction} by ${scroll_amount}`
148 | : "";
149 | ActionIcon = ScrollText;
150 | break;
151 | default:
152 | actionLabel = action;
153 | ActionIcon = MousePointer;
154 | break;
155 | }
156 |
157 | return (
158 |
164 |
165 |
166 | {ActionIcon &&
}
167 |
168 |
169 |
170 | {actionLabel}
171 | {actionDetail && (
172 |
173 | {actionDetail}
174 |
175 | )}
176 |
177 |
178 |
179 | {state === "call" ? (
180 | isLatestMessage && status !== "ready" ? (
181 |
182 | ) : (
183 |
184 | )
185 | ) : state === "result" ? (
186 | part.toolInvocation.result === ABORTED ? (
187 | ) : (
191 |
195 | )
196 | ) : null}
197 |
198 |
199 | {state === "result" ? (
200 | part.toolInvocation.result.type === "image" && (
201 |
202 | {/* eslint-disable-next-line @next/next/no-img-element */}
203 |

208 |
209 | )
210 | ) : action === "screenshot" ? (
211 |
212 | ) : null}
213 |
214 | );
215 | }
216 | if (toolName === "bash") {
217 | const { command } = args;
218 |
219 | return (
220 |
226 |
227 |
228 |
229 |
230 |
231 | Running command
232 |
233 | {command.slice(0, 40)}...
234 |
235 |
236 |
237 |
238 | {state === "call" ? (
239 | isLatestMessage && status !== "ready" ? (
240 |
241 | ) : (
242 |
243 | )
244 | ) : state === "result" ? (
245 |
246 | ) : null}
247 |
248 |
249 | );
250 | }
251 | return (
252 |
253 |
254 | {toolName}: {state}
255 |
256 |
{JSON.stringify(args, null, 2)}
257 |
258 | );
259 |
260 | default:
261 | return null;
262 | }
263 | })}
264 |