blob: 5f416e1c780ce170dde0ab730980685fed9c88c8 [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";
Sean McCullough86b56862025-04-18 13:04:03 -07007
8@customElement("sketch-tool-calls")
9export class SketchToolCalls extends LitElement {
10 @property()
11 toolCalls: ToolCall[] = [];
12
Sean McCullough2deac842025-04-21 18:17:57 -070013 @property()
14 open: boolean = false;
15
Philip Zeyliger16fa8b42025-05-02 04:28:16 +000016 @state()
17 expanded: boolean = false;
18
Sean McCullough86b56862025-04-18 13:04:03 -070019 static styles = css`
20 /* Tool calls container styles */
21 .tool-calls-container {
Philip Zeyliger16fa8b42025-05-02 04:28:16 +000022 margin-top: 8px;
23 padding-top: 4px;
Philip Zeyligere31d2a92025-05-11 15:22:35 -070024 max-width: 100%;
25 width: 100%;
26 box-sizing: border-box;
Sean McCullough86b56862025-04-18 13:04:03 -070027 }
28
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070029 /* Card container */
Sean McCullough86b56862025-04-18 13:04:03 -070030 .tool-call-card {
31 display: flex;
32 flex-direction: column;
Philip Zeyliger16fa8b42025-05-02 04:28:16 +000033 background-color: rgba(255, 255, 255, 0.6);
34 border-radius: 6px;
35 margin-bottom: 6px;
Sean McCullough86b56862025-04-18 13:04:03 -070036 overflow: hidden;
37 cursor: pointer;
Philip Zeyliger16fa8b42025-05-02 04:28:16 +000038 border-left: 2px solid rgba(0, 0, 0, 0.1);
39 box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
Philip Zeyligere31d2a92025-05-11 15:22:35 -070040 max-width: 100%;
41 overflow-wrap: break-word;
42 word-break: break-word;
Sean McCullough86b56862025-04-18 13:04:03 -070043 }
44
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070045 /* Status indicators for tool calls */
Sean McCullough86b56862025-04-18 13:04:03 -070046 .tool-call-status {
47 margin-right: 4px;
48 text-align: center;
49 }
50
51 .tool-call-status.spinner {
52 animation: spin 1s infinite linear;
53 display: inline-block;
54 width: 1em;
55 }
56
Sean McCullough86b56862025-04-18 13:04:03 -070057 @keyframes spin {
58 0% {
59 transform: rotate(0deg);
60 }
61 100% {
62 transform: rotate(360deg);
63 }
64 }
Philip Zeyliger16fa8b42025-05-02 04:28:16 +000065
66 .tool-call-cards-container {
67 display: block;
68 }
Sean McCullough86b56862025-04-18 13:04:03 -070069 `;
70
71 constructor() {
72 super();
73 }
74
Sean McCullough86b56862025-04-18 13:04:03 -070075 connectedCallback() {
76 super.connectedCallback();
77 }
78
Sean McCullough86b56862025-04-18 13:04:03 -070079 disconnectedCallback() {
80 super.disconnectedCallback();
81 }
82
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070083 cardForToolCall(toolCall: ToolCall, open: boolean) {
Sean McCullough86b56862025-04-18 13:04:03 -070084 switch (toolCall.name) {
Sean McCullough86b56862025-04-18 13:04:03 -070085 case "bash":
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070086 return html`<sketch-tool-card-bash
87 .open=${open}
88 .toolCall=${toolCall}
89 ></sketch-tool-card-bash>`;
Sean McCullough86b56862025-04-18 13:04:03 -070090 case "codereview":
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070091 return html`<sketch-tool-card-codereview
92 .open=${open}
93 .toolCall=${toolCall}
94 ></sketch-tool-card-codereview>`;
Sean McCullough86b56862025-04-18 13:04:03 -070095 case "done":
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070096 return html`<sketch-tool-card-done
97 .open=${open}
98 .toolCall=${toolCall}
99 ></sketch-tool-card-done>`;
Sean McCullough485afc62025-04-28 14:28:39 -0700100 case "multiplechoice":
101 return html`<sketch-tool-card-multiple-choice
102 .open=${open}
103 .toolCall=${toolCall}
104 ></sketch-tool-card-multiple-choice>`;
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700105 case "patch":
106 return html`<sketch-tool-card-patch
107 .open=${open}
108 .toolCall=${toolCall}
109 ></sketch-tool-card-patch>`;
110 case "think":
111 return html`<sketch-tool-card-think
112 .open=${open}
113 .toolCall=${toolCall}
114 ></sketch-tool-card-think>`;
115 case "title":
116 return html`<sketch-tool-card-title
117 .open=${open}
118 .toolCall=${toolCall}
119 ></sketch-tool-card-title>`;
Josh Bleecher Snydera2a31502025-05-07 12:37:18 +0000120 case "precommit":
121 return html`<sketch-tool-card-precommit
122 .open=${open}
123 .toolCall=${toolCall}
124 ></sketch-tool-card-precommit>`;
Philip Zeyliger80b488d2025-05-10 18:21:54 -0700125 case "browser_take_screenshot":
126 return html`<sketch-tool-card-take-screenshot
Philip Zeyliger33d282f2025-05-03 04:01:54 +0000127 .open=${open}
128 .toolCall=${toolCall}
Philip Zeyliger80b488d2025-05-10 18:21:54 -0700129 ></sketch-tool-card-take-screenshot>`;
Sean McCullough86b56862025-04-18 13:04:03 -0700130 }
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700131 return html`<sketch-tool-card-generic
132 .open=${open}
133 .toolCall=${toolCall}
134 ></sketch-tool-card-generic>`;
Sean McCullough86b56862025-04-18 13:04:03 -0700135 }
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700136
Sean McCullough2deac842025-04-21 18:17:57 -0700137 // toolUseKey return value should change, if the toolCall gets a response.
138 toolUseKey(toolCall: ToolCall): string {
Sean McCullough2deac842025-04-21 18:17:57 -0700139 if (!toolCall.result_message) {
140 return toolCall.tool_call_id;
141 }
142 return `${toolCall.tool_call_id}-${toolCall.result_message.idx}`;
143 }
144
Sean McCullough86b56862025-04-18 13:04:03 -0700145 render() {
Philip Zeyliger16fa8b42025-05-02 04:28:16 +0000146 if (!this.toolCalls || this.toolCalls.length === 0) {
147 return html``;
148 }
149
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700150 return html`<div class="tool-calls-container">
Sean McCullough86b56862025-04-18 13:04:03 -0700151 <div class="tool-call-cards-container">
Philip Zeyliger16fa8b42025-05-02 04:28:16 +0000152 ${repeat(this.toolCalls, this.toolUseKey, (toolCall, idx) => {
Philip Zeyliger33d282f2025-05-03 04:01:54 +0000153 let shouldOpen = false;
154 // Always expand screenshot tool calls, expand last tool call if this.open is true
155 if (
Philip Zeyliger80b488d2025-05-10 18:21:54 -0700156 toolCall.name === "browser_take_screenshot" ||
Philip Zeyliger33d282f2025-05-03 04:01:54 +0000157 (idx == this.toolCalls?.length - 1 && this.open)
158 ) {
159 shouldOpen = true;
Philip Zeyliger16fa8b42025-05-02 04:28:16 +0000160 }
161 return html`<div
162 id="${toolCall.tool_call_id}"
163 class="tool-call-card ${toolCall.name}"
164 >
Philip Zeyliger33d282f2025-05-03 04:01:54 +0000165 ${this.cardForToolCall(toolCall, shouldOpen)}
Philip Zeyliger16fa8b42025-05-02 04:28:16 +0000166 </div>`;
167 })}
Sean McCullough86b56862025-04-18 13:04:03 -0700168 </div>
169 </div>`;
170 }
171}
172
173declare global {
174 interface HTMLElementTagNameMap {
175 "sketch-tool-calls": SketchToolCalls;
176 }
177}