Overhaul UI with chat-like interface
Major UI improvements:
- Revamp timeline messages with chat-like interface
- User messages now on right with white text on blue background
- Agent/tool messages on left with black text on grey background
- Chat bubbles extend up to 80% of screen width
- Maintain left-aligned text for code readability
- Move metadata to outer gutters
- Show turn duration for end-of-turn messages
- Integrate tool calls within agent message bubbles
- Add thinking indicator with animated dots when LLM is processing
- Replace buttons with intuitive icons (copy, info, etc.)
- Improve tool call presentation
- Simplify to single row design with all essential info
- Add clear status indicators for success/pending/error
- Fix horizontal scrolling for long commands and outputs
- Prevent tool name truncation
- Improve spacing and alignment throughout
- Enhance header and status displays
- Move Last Commit to dedicated third column in header grid
- Add proper labeling with two-row structure
- Provide consistent styling across all status elements
- Other UI refinements
- Add root URL redirection to demo page
- Fix spacing throughout the interface
- Optimize CSS for better performance
- Ensure consistent styling across components
- Improve command output display and wrapping
Co-Authored-By: sketch <hello@sketch.dev>
diff --git a/webui/src/web-components/sketch-tool-calls.ts b/webui/src/web-components/sketch-tool-calls.ts
index 4f49df9..14cb218 100644
--- a/webui/src/web-components/sketch-tool-calls.ts
+++ b/webui/src/web-components/sketch-tool-calls.ts
@@ -1,5 +1,5 @@
import { css, html, LitElement } from "lit";
-import { customElement, property } from "lit/decorators.js";
+import { customElement, property, state } from "lit/decorators.js";
import { repeat } from "lit/directives/repeat.js";
import { ToolCall } from "../types";
import "./sketch-tool-card";
@@ -12,24 +12,27 @@
@property()
open: boolean = false;
+ @state()
+ expanded: boolean = false;
+
static styles = css`
/* Tool calls container styles */
.tool-calls-container {
- /* Container for all tool calls */
- }
-
- /* Header for tool calls section */
- .tool-calls-header {
- /* Empty header - just small spacing */
+ margin-top: 8px;
+ padding-top: 4px;
}
/* Card container */
.tool-call-card {
display: flex;
flex-direction: column;
- background-color: white;
+ background-color: rgba(255, 255, 255, 0.6);
+ border-radius: 6px;
+ margin-bottom: 6px;
overflow: hidden;
cursor: pointer;
+ border-left: 2px solid rgba(0, 0, 0, 0.1);
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
/* Status indicators for tool calls */
@@ -52,6 +55,10 @@
transform: rotate(360deg);
}
}
+
+ .tool-call-cards-container {
+ display: block;
+ }
`;
constructor() {
@@ -124,23 +131,24 @@
}
render() {
+ if (!this.toolCalls || this.toolCalls.length === 0) {
+ return html``;
+ }
+
return html`<div class="tool-calls-container">
- <div class="tool-calls-header"></div>
<div class="tool-call-cards-container">
- ${this.toolCalls
- ? repeat(this.toolCalls, this.toolUseKey, (toolCall, idx) => {
- let lastCall = false;
- if (idx == this.toolCalls?.length - 1) {
- lastCall = true;
- }
- return html`<div
- id="${toolCall.tool_call_id}"
- class="tool-call-card ${toolCall.name}"
- >
- ${this.cardForToolCall(toolCall, lastCall && this.open)}
- </div>`;
- })
- : ""}
+ ${repeat(this.toolCalls, this.toolUseKey, (toolCall, idx) => {
+ let lastCall = false;
+ if (idx == this.toolCalls?.length - 1) {
+ lastCall = true;
+ }
+ return html`<div
+ id="${toolCall.tool_call_id}"
+ class="tool-call-card ${toolCall.name}"
+ >
+ ${this.cardForToolCall(toolCall, lastCall && this.open)}
+ </div>`;
+ })}
</div>
</div>`;
}