webui: add 'open' status, elapsed time to tool-cards
diff --git a/loop/webui/src/web-components/sketch-timeline-message.ts b/loop/webui/src/web-components/sketch-timeline-message.ts
index e34d61f..ef707bd 100644
--- a/loop/webui/src/web-components/sketch-timeline-message.ts
+++ b/loop/webui/src/web-components/sketch-timeline-message.ts
@@ -12,6 +12,9 @@
   @property()
   previousMessage: AgentMessage;
 
+  @property()
+  open: boolean = false;
+
   // See https://lit.dev/docs/components/styles/ for how lit-element handles CSS.
   // Note that these styles only apply to the scope of this web component's
   // shadow DOM node, so they won't leak out or collide with CSS declared in
@@ -514,6 +517,7 @@
           </div>
           <sketch-tool-calls
             .toolCalls=${this.message?.tool_calls}
+            .open=${this.open}
           ></sketch-tool-calls>
           ${this.message?.commits
             ? html`
diff --git a/loop/webui/src/web-components/sketch-timeline.ts b/loop/webui/src/web-components/sketch-timeline.ts
index 80efd0f..b630679 100644
--- a/loop/webui/src/web-components/sketch-timeline.ts
+++ b/loop/webui/src/web-components/sketch-timeline.ts
@@ -201,6 +201,7 @@
             return html`<sketch-timeline-message
               .message=${message}
               .previousMessage=${previousMessage}
+              .open=${index == this.messages.length - 1}
             ></sketch-timeline-message>`;
           })}
         </div>
diff --git a/loop/webui/src/web-components/sketch-tool-calls.ts b/loop/webui/src/web-components/sketch-tool-calls.ts
index 9461d6d..3f036c2 100644
--- a/loop/webui/src/web-components/sketch-tool-calls.ts
+++ b/loop/webui/src/web-components/sketch-tool-calls.ts
@@ -1,5 +1,6 @@
 import { css, html, LitElement } from "lit";
 import { customElement, property } from "lit/decorators.js";
+import { repeat } from "lit/directives/repeat.js";
 import { ToolCall } from "../types";
 import "./sketch-tool-card";
 
@@ -8,6 +9,9 @@
   @property()
   toolCalls: ToolCall[] = [];
 
+  @property()
+  open: boolean = false;
+
   static styles = css`
     /* Tool calls container styles */
     .tool-calls-container {
@@ -101,22 +105,37 @@
     ></sketch-tool-card-generic>`;
   }
 
+  // toolUseKey return value should change, if the toolCall gets a response.
+  toolUseKey(toolCall: ToolCall): string {
+    console.log(
+      "toolUseKey",
+      toolCall.tool_call_id,
+      toolCall.result_message?.idx,
+    );
+    if (!toolCall.result_message) {
+      return toolCall.tool_call_id;
+    }
+    return `${toolCall.tool_call_id}-${toolCall.result_message.idx}`;
+  }
+
   render() {
     return html`<div class="tool-calls-container">
       <div class="tool-calls-header"></div>
       <div class="tool-call-cards-container">
-        ${this.toolCalls?.map((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)}
-          </div>`;
-        })}
+        ${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>`;
+            })
+          : ""}
       </div>
     </div>`;
   }
diff --git a/loop/webui/src/web-components/sketch-tool-card.ts b/loop/webui/src/web-components/sketch-tool-card.ts
index 0144ba0..39fadf8 100644
--- a/loop/webui/src/web-components/sketch-tool-card.ts
+++ b/loop/webui/src/web-components/sketch-tool-card.ts
@@ -147,6 +147,13 @@
       font-style: italic;
       color: #aa0909;
     }
+
+    .elapsed {
+      font-size: 10px;
+      color: #888;
+      font-style: italic;
+      margin-left: 3px;
+    }
   `;
 
   constructor() {
@@ -193,7 +200,7 @@
       ? this.toolCall?.result_message.tool_error
         ? html`❌
             <span class="tool-error-message"
-              >${this.toolCall?.result_message.tool_error}</span
+              >${this.toolCall?.result_message.tool_result}</span
             >`
         : ""
       : "⏳";
@@ -217,12 +224,19 @@
       >${toolCallStatus}</span
     >`;
 
+    const elapsed = html`${this.toolCall?.result_message?.elapsed
+      ? html`<span class="elapsed"
+          >${(this.toolCall?.result_message?.elapsed / 1e9).toFixed(2)}s
+          elapsed</span
+        >`
+      : ""}`;
+
     const ret = html`<div class="tool-call">
       <details ?open=${this.open}>
         <summary>
           <span class="tool-name">${this.toolCall?.name}</span>
           <span class="summary-text"><slot name="summary"></slot></span>
-          ${status} ${cancelButton}
+          ${status} ${cancelButton} ${elapsed}
         </summary>
         <slot name="input"></slot>
         <slot name="result"></slot>