blob: 3f036c294a3afcc10c2da0e91d831ec7fbf8cdaa [file] [log] [blame]
Sean McCullough86b56862025-04-18 13:04:03 -07001import { css, html, LitElement } from "lit";
Sean McCullough86b56862025-04-18 13:04:03 -07002import { customElement, property } 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";
Sean McCulloughec3ad1a2025-04-18 13:55:16 -07005import "./sketch-tool-card";
Sean McCullough86b56862025-04-18 13:04:03 -07006
7@customElement("sketch-tool-calls")
8export class SketchToolCalls extends LitElement {
9 @property()
10 toolCalls: ToolCall[] = [];
11
Sean McCullough2deac842025-04-21 18:17:57 -070012 @property()
13 open: boolean = false;
14
Sean McCullough86b56862025-04-18 13:04:03 -070015 static styles = css`
16 /* Tool calls container styles */
17 .tool-calls-container {
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070018 /* Container for all tool calls */
Sean McCullough86b56862025-04-18 13:04:03 -070019 }
20
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070021 /* Header for tool calls section */
Sean McCullough86b56862025-04-18 13:04:03 -070022 .tool-calls-header {
23 /* Empty header - just small spacing */
24 }
25
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070026 /* Card container */
Sean McCullough86b56862025-04-18 13:04:03 -070027 .tool-call-card {
28 display: flex;
29 flex-direction: column;
30 background-color: white;
31 overflow: hidden;
32 cursor: pointer;
33 }
34
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070035 /* Status indicators for tool calls */
Sean McCullough86b56862025-04-18 13:04:03 -070036 .tool-call-status {
37 margin-right: 4px;
38 text-align: center;
39 }
40
41 .tool-call-status.spinner {
42 animation: spin 1s infinite linear;
43 display: inline-block;
44 width: 1em;
45 }
46
Sean McCullough86b56862025-04-18 13:04:03 -070047 @keyframes spin {
48 0% {
49 transform: rotate(0deg);
50 }
51 100% {
52 transform: rotate(360deg);
53 }
54 }
Sean McCullough86b56862025-04-18 13:04:03 -070055 `;
56
57 constructor() {
58 super();
59 }
60
Sean McCullough86b56862025-04-18 13:04:03 -070061 connectedCallback() {
62 super.connectedCallback();
63 }
64
Sean McCullough86b56862025-04-18 13:04:03 -070065 disconnectedCallback() {
66 super.disconnectedCallback();
67 }
68
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070069 cardForToolCall(toolCall: ToolCall, open: boolean) {
Sean McCullough86b56862025-04-18 13:04:03 -070070 switch (toolCall.name) {
Sean McCullough86b56862025-04-18 13:04:03 -070071 case "bash":
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070072 return html`<sketch-tool-card-bash
73 .open=${open}
74 .toolCall=${toolCall}
75 ></sketch-tool-card-bash>`;
Sean McCullough86b56862025-04-18 13:04:03 -070076 case "codereview":
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070077 return html`<sketch-tool-card-codereview
78 .open=${open}
79 .toolCall=${toolCall}
80 ></sketch-tool-card-codereview>`;
Sean McCullough86b56862025-04-18 13:04:03 -070081 case "done":
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070082 return html`<sketch-tool-card-done
83 .open=${open}
84 .toolCall=${toolCall}
85 ></sketch-tool-card-done>`;
86 case "patch":
87 return html`<sketch-tool-card-patch
88 .open=${open}
89 .toolCall=${toolCall}
90 ></sketch-tool-card-patch>`;
91 case "think":
92 return html`<sketch-tool-card-think
93 .open=${open}
94 .toolCall=${toolCall}
95 ></sketch-tool-card-think>`;
96 case "title":
97 return html`<sketch-tool-card-title
98 .open=${open}
99 .toolCall=${toolCall}
100 ></sketch-tool-card-title>`;
Sean McCullough86b56862025-04-18 13:04:03 -0700101 }
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700102 return html`<sketch-tool-card-generic
103 .open=${open}
104 .toolCall=${toolCall}
105 ></sketch-tool-card-generic>`;
Sean McCullough86b56862025-04-18 13:04:03 -0700106 }
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700107
Sean McCullough2deac842025-04-21 18:17:57 -0700108 // toolUseKey return value should change, if the toolCall gets a response.
109 toolUseKey(toolCall: ToolCall): string {
110 console.log(
111 "toolUseKey",
112 toolCall.tool_call_id,
113 toolCall.result_message?.idx,
114 );
115 if (!toolCall.result_message) {
116 return toolCall.tool_call_id;
117 }
118 return `${toolCall.tool_call_id}-${toolCall.result_message.idx}`;
119 }
120
Sean McCullough86b56862025-04-18 13:04:03 -0700121 render() {
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700122 return html`<div class="tool-calls-container">
Sean McCullough86b56862025-04-18 13:04:03 -0700123 <div class="tool-calls-header"></div>
124 <div class="tool-call-cards-container">
Sean McCullough2deac842025-04-21 18:17:57 -0700125 ${this.toolCalls
126 ? repeat(this.toolCalls, this.toolUseKey, (toolCall, idx) => {
127 let lastCall = false;
128 if (idx == this.toolCalls?.length - 1) {
129 lastCall = true;
130 }
131 return html`<div
132 id="${toolCall.tool_call_id}"
133 class="tool-call-card ${toolCall.name}"
134 >
135 ${this.cardForToolCall(toolCall, lastCall && this.open)}
136 </div>`;
137 })
138 : ""}
Sean McCullough86b56862025-04-18 13:04:03 -0700139 </div>
140 </div>`;
141 }
142}
143
144declare global {
145 interface HTMLElementTagNameMap {
146 "sketch-tool-calls": SketchToolCalls;
147 }
148}