blob: 792e893e6c4134431f2b735a4d63237efed7efd7 [file] [log] [blame]
Sean McCullough86b56862025-04-18 13:04:03 -07001import { css, html, LitElement } from "lit";
Philip Zeyliger16fa8b42025-05-02 04:28:16 +00002import { customElement, property, state } from "lit/decorators.js";
Sean McCullough2deac842025-04-21 18:17:57 -07003import { repeat } from "lit/directives/repeat.js";
Sean McCulloughd9f13372025-04-21 15:08:49 -07004import { ToolCall } from "../types";
Pokey Rule7ac5ed02025-05-07 15:26:10 +01005import "./sketch-tool-card";
Philip Zeyliger80b488d2025-05-10 18:21:54 -07006import "./sketch-tool-card-take-screenshot";
Josh Bleecher Snyder74d690e2025-05-14 18:16:03 -07007import "./sketch-tool-card-about-sketch";
Josh Bleecher Snyder2d081192025-05-29 13:46:04 +00008import "./sketch-tool-card-browser-navigate";
9import "./sketch-tool-card-browser-click";
10import "./sketch-tool-card-browser-type";
11import "./sketch-tool-card-browser-wait-for";
12import "./sketch-tool-card-browser-get-text";
13import "./sketch-tool-card-browser-eval";
14import "./sketch-tool-card-browser-scroll-into-view";
15import "./sketch-tool-card-browser-resize";
16import "./sketch-tool-card-browser-read-image";
17import "./sketch-tool-card-browser-recent-console-logs";
18import "./sketch-tool-card-browser-clear-console-logs";
Sean McCullough86b56862025-04-18 13:04:03 -070019
20@customElement("sketch-tool-calls")
21export class SketchToolCalls extends LitElement {
22 @property()
23 toolCalls: ToolCall[] = [];
24
Sean McCullough2deac842025-04-21 18:17:57 -070025 @property()
26 open: boolean = false;
27
Philip Zeyliger16fa8b42025-05-02 04:28:16 +000028 @state()
29 expanded: boolean = false;
30
Sean McCullough86b56862025-04-18 13:04:03 -070031 static styles = css`
32 /* Tool calls container styles */
33 .tool-calls-container {
Philip Zeyliger16fa8b42025-05-02 04:28:16 +000034 margin-top: 8px;
35 padding-top: 4px;
Philip Zeyligere31d2a92025-05-11 15:22:35 -070036 max-width: 100%;
37 width: 100%;
38 box-sizing: border-box;
Sean McCullough86b56862025-04-18 13:04:03 -070039 }
40
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070041 /* Card container */
Sean McCullough86b56862025-04-18 13:04:03 -070042 .tool-call-card {
43 display: flex;
44 flex-direction: column;
Philip Zeyliger16fa8b42025-05-02 04:28:16 +000045 background-color: rgba(255, 255, 255, 0.6);
46 border-radius: 6px;
47 margin-bottom: 6px;
Sean McCullough86b56862025-04-18 13:04:03 -070048 overflow: hidden;
49 cursor: pointer;
Philip Zeyliger16fa8b42025-05-02 04:28:16 +000050 border-left: 2px solid rgba(0, 0, 0, 0.1);
51 box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
Philip Zeyligere31d2a92025-05-11 15:22:35 -070052 max-width: 100%;
53 overflow-wrap: break-word;
54 word-break: break-word;
Sean McCullough86b56862025-04-18 13:04:03 -070055 }
56
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070057 /* Status indicators for tool calls */
Sean McCullough86b56862025-04-18 13:04:03 -070058 .tool-call-status {
59 margin-right: 4px;
60 text-align: center;
61 }
62
63 .tool-call-status.spinner {
64 animation: spin 1s infinite linear;
65 display: inline-block;
66 width: 1em;
67 }
68
Sean McCullough86b56862025-04-18 13:04:03 -070069 @keyframes spin {
70 0% {
71 transform: rotate(0deg);
72 }
73 100% {
74 transform: rotate(360deg);
75 }
76 }
Philip Zeyliger16fa8b42025-05-02 04:28:16 +000077
78 .tool-call-cards-container {
79 display: block;
80 }
Sean McCullough86b56862025-04-18 13:04:03 -070081 `;
82
83 constructor() {
84 super();
85 }
86
Sean McCullough86b56862025-04-18 13:04:03 -070087 connectedCallback() {
88 super.connectedCallback();
89 }
90
Sean McCullough86b56862025-04-18 13:04:03 -070091 disconnectedCallback() {
92 super.disconnectedCallback();
93 }
94
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070095 cardForToolCall(toolCall: ToolCall, open: boolean) {
Sean McCullough86b56862025-04-18 13:04:03 -070096 switch (toolCall.name) {
Sean McCullough86b56862025-04-18 13:04:03 -070097 case "bash":
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070098 return html`<sketch-tool-card-bash
99 .open=${open}
100 .toolCall=${toolCall}
101 ></sketch-tool-card-bash>`;
Sean McCullough86b56862025-04-18 13:04:03 -0700102 case "codereview":
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700103 return html`<sketch-tool-card-codereview
104 .open=${open}
105 .toolCall=${toolCall}
106 ></sketch-tool-card-codereview>`;
Sean McCullough86b56862025-04-18 13:04:03 -0700107 case "done":
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700108 return html`<sketch-tool-card-done
109 .open=${open}
110 .toolCall=${toolCall}
111 ></sketch-tool-card-done>`;
Sean McCullough485afc62025-04-28 14:28:39 -0700112 case "multiplechoice":
113 return html`<sketch-tool-card-multiple-choice
114 .open=${open}
115 .toolCall=${toolCall}
116 ></sketch-tool-card-multiple-choice>`;
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700117 case "patch":
118 return html`<sketch-tool-card-patch
119 .open=${open}
120 .toolCall=${toolCall}
121 ></sketch-tool-card-patch>`;
122 case "think":
123 return html`<sketch-tool-card-think
124 .open=${open}
125 .toolCall=${toolCall}
126 ></sketch-tool-card-think>`;
127 case "title":
128 return html`<sketch-tool-card-title
129 .open=${open}
130 .toolCall=${toolCall}
131 ></sketch-tool-card-title>`;
Josh Bleecher Snydera2a31502025-05-07 12:37:18 +0000132 case "precommit":
133 return html`<sketch-tool-card-precommit
134 .open=${open}
135 .toolCall=${toolCall}
136 ></sketch-tool-card-precommit>`;
Philip Zeyliger80b488d2025-05-10 18:21:54 -0700137 case "browser_take_screenshot":
138 return html`<sketch-tool-card-take-screenshot
Philip Zeyliger33d282f2025-05-03 04:01:54 +0000139 .open=${open}
140 .toolCall=${toolCall}
Philip Zeyliger80b488d2025-05-10 18:21:54 -0700141 ></sketch-tool-card-take-screenshot>`;
Josh Bleecher Snyder74d690e2025-05-14 18:16:03 -0700142 case "about_sketch":
143 return html`<sketch-tool-card-about-sketch
Josh Bleecher Snyder31785ae2025-05-06 01:50:58 +0000144 .open=${open}
145 .toolCall=${toolCall}
Josh Bleecher Snyder74d690e2025-05-14 18:16:03 -0700146 ></sketch-tool-card-about-sketch>`;
Josh Bleecher Snyder112b9232025-05-23 11:26:33 -0700147 case "todo_write":
148 return html`<sketch-tool-card-todo-write
149 .open=${open}
150 .toolCall=${toolCall}
151 ></sketch-tool-card-todo-write>`;
152 case "todo_read":
153 return html`<sketch-tool-card-todo-read
154 .open=${open}
155 .toolCall=${toolCall}
156 ></sketch-tool-card-todo-read>`;
Josh Bleecher Snyder2d081192025-05-29 13:46:04 +0000157 case "browser_navigate":
158 return html`<sketch-tool-card-browser-navigate
159 .open=${open}
160 .toolCall=${toolCall}
161 ></sketch-tool-card-browser-navigate>`;
Josh Bleecher Snyder991164f2025-05-29 05:02:10 +0000162 case "keyword_search":
163 return html`<sketch-tool-card-keyword-search
164 .open=${open}
165 .toolCall=${toolCall}
166 ></sketch-tool-card-keyword-search>`;
Josh Bleecher Snyder2d081192025-05-29 13:46:04 +0000167 case "browser_click":
168 return html`<sketch-tool-card-browser-click
169 .open=${open}
170 .toolCall=${toolCall}
171 ></sketch-tool-card-browser-click>`;
172 case "browser_type":
173 return html`<sketch-tool-card-browser-type
174 .open=${open}
175 .toolCall=${toolCall}
176 ></sketch-tool-card-browser-type>`;
177 case "browser_wait_for":
178 return html`<sketch-tool-card-browser-wait-for
179 .open=${open}
180 .toolCall=${toolCall}
181 ></sketch-tool-card-browser-wait-for>`;
182 case "browser_get_text":
183 return html`<sketch-tool-card-browser-get-text
184 .open=${open}
185 .toolCall=${toolCall}
186 ></sketch-tool-card-browser-get-text>`;
187 case "browser_eval":
188 return html`<sketch-tool-card-browser-eval
189 .open=${open}
190 .toolCall=${toolCall}
191 ></sketch-tool-card-browser-eval>`;
192 case "browser_scroll_into_view":
193 return html`<sketch-tool-card-browser-scroll-into-view
194 .open=${open}
195 .toolCall=${toolCall}
196 ></sketch-tool-card-browser-scroll-into-view>`;
197 case "browser_resize":
198 return html`<sketch-tool-card-browser-resize
199 .open=${open}
200 .toolCall=${toolCall}
201 ></sketch-tool-card-browser-resize>`;
202 case "browser_read_image":
203 return html`<sketch-tool-card-browser-read-image
204 .open=${open}
205 .toolCall=${toolCall}
206 ></sketch-tool-card-browser-read-image>`;
207 case "browser_recent_console_logs":
208 return html`<sketch-tool-card-browser-recent-console-logs
209 .open=${open}
210 .toolCall=${toolCall}
211 ></sketch-tool-card-browser-recent-console-logs>`;
212 case "browser_clear_console_logs":
213 return html`<sketch-tool-card-browser-clear-console-logs
214 .open=${open}
215 .toolCall=${toolCall}
216 ></sketch-tool-card-browser-clear-console-logs>`;
Sean McCullough86b56862025-04-18 13:04:03 -0700217 }
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700218 return html`<sketch-tool-card-generic
219 .open=${open}
220 .toolCall=${toolCall}
221 ></sketch-tool-card-generic>`;
Sean McCullough86b56862025-04-18 13:04:03 -0700222 }
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700223
Sean McCullough2deac842025-04-21 18:17:57 -0700224 // toolUseKey return value should change, if the toolCall gets a response.
225 toolUseKey(toolCall: ToolCall): string {
Sean McCullough2deac842025-04-21 18:17:57 -0700226 if (!toolCall.result_message) {
227 return toolCall.tool_call_id;
228 }
229 return `${toolCall.tool_call_id}-${toolCall.result_message.idx}`;
230 }
231
Sean McCullough86b56862025-04-18 13:04:03 -0700232 render() {
Philip Zeyliger16fa8b42025-05-02 04:28:16 +0000233 if (!this.toolCalls || this.toolCalls.length === 0) {
234 return html``;
235 }
236
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700237 return html`<div class="tool-calls-container">
Sean McCullough86b56862025-04-18 13:04:03 -0700238 <div class="tool-call-cards-container">
Philip Zeyliger16fa8b42025-05-02 04:28:16 +0000239 ${repeat(this.toolCalls, this.toolUseKey, (toolCall, idx) => {
Philip Zeyliger33d282f2025-05-03 04:01:54 +0000240 let shouldOpen = false;
241 // Always expand screenshot tool calls, expand last tool call if this.open is true
242 if (
Philip Zeyliger80b488d2025-05-10 18:21:54 -0700243 toolCall.name === "browser_take_screenshot" ||
Philip Zeyliger33d282f2025-05-03 04:01:54 +0000244 (idx == this.toolCalls?.length - 1 && this.open)
245 ) {
246 shouldOpen = true;
Philip Zeyliger16fa8b42025-05-02 04:28:16 +0000247 }
248 return html`<div
249 id="${toolCall.tool_call_id}"
250 class="tool-call-card ${toolCall.name}"
251 >
Philip Zeyliger33d282f2025-05-03 04:01:54 +0000252 ${this.cardForToolCall(toolCall, shouldOpen)}
Philip Zeyliger16fa8b42025-05-02 04:28:16 +0000253 </div>`;
254 })}
Sean McCullough86b56862025-04-18 13:04:03 -0700255 </div>
256 </div>`;
257 }
258}
259
260declare global {
261 interface HTMLElementTagNameMap {
262 "sketch-tool-calls": SketchToolCalls;
263 }
264}