blob: 4f49df971d206fabcde38be74baa2bcec8422951 [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>`;
Sean McCullough485afc62025-04-28 14:28:39 -070086 case "multiplechoice":
87 return html`<sketch-tool-card-multiple-choice
88 .open=${open}
89 .toolCall=${toolCall}
90 ></sketch-tool-card-multiple-choice>`;
Sean McCulloughec3ad1a2025-04-18 13:55:16 -070091 case "patch":
92 return html`<sketch-tool-card-patch
93 .open=${open}
94 .toolCall=${toolCall}
95 ></sketch-tool-card-patch>`;
96 case "think":
97 return html`<sketch-tool-card-think
98 .open=${open}
99 .toolCall=${toolCall}
100 ></sketch-tool-card-think>`;
101 case "title":
102 return html`<sketch-tool-card-title
103 .open=${open}
104 .toolCall=${toolCall}
105 ></sketch-tool-card-title>`;
Sean McCullough86b56862025-04-18 13:04:03 -0700106 }
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700107 return html`<sketch-tool-card-generic
108 .open=${open}
109 .toolCall=${toolCall}
110 ></sketch-tool-card-generic>`;
Sean McCullough86b56862025-04-18 13:04:03 -0700111 }
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700112
Sean McCullough2deac842025-04-21 18:17:57 -0700113 // toolUseKey return value should change, if the toolCall gets a response.
114 toolUseKey(toolCall: ToolCall): string {
115 console.log(
116 "toolUseKey",
117 toolCall.tool_call_id,
118 toolCall.result_message?.idx,
119 );
120 if (!toolCall.result_message) {
121 return toolCall.tool_call_id;
122 }
123 return `${toolCall.tool_call_id}-${toolCall.result_message.idx}`;
124 }
125
Sean McCullough86b56862025-04-18 13:04:03 -0700126 render() {
Sean McCulloughec3ad1a2025-04-18 13:55:16 -0700127 return html`<div class="tool-calls-container">
Sean McCullough86b56862025-04-18 13:04:03 -0700128 <div class="tool-calls-header"></div>
129 <div class="tool-call-cards-container">
Sean McCullough2deac842025-04-21 18:17:57 -0700130 ${this.toolCalls
131 ? repeat(this.toolCalls, this.toolUseKey, (toolCall, idx) => {
132 let lastCall = false;
133 if (idx == this.toolCalls?.length - 1) {
134 lastCall = true;
135 }
136 return html`<div
137 id="${toolCall.tool_call_id}"
138 class="tool-call-card ${toolCall.name}"
139 >
140 ${this.cardForToolCall(toolCall, lastCall && this.open)}
141 </div>`;
142 })
143 : ""}
Sean McCullough86b56862025-04-18 13:04:03 -0700144 </div>
145 </div>`;
146 }
147}
148
149declare global {
150 interface HTMLElementTagNameMap {
151 "sketch-tool-calls": SketchToolCalls;
152 }
153}