From 2ebf805f9621f668a537e7c6a41878636a220676 Mon Sep 17 00:00:00 2001
From: Prateek
Date: Mon, 16 Feb 2026 06:16:45 +0530
Subject: [PATCH] fix: improve "Ask Agent to Fix" button UX and remove outdated
TODO
Replaced browser alerts with proper visual feedback:
- Added loading state ("Sending...") with disabled button during request
- Show success state ("Sent!") in green for 3 seconds
- Show error state ("Failed") in red for 3 seconds
- Prevent multiple clicks while processing
Also removed outdated TODO comment - the API endpoint is already implemented.
Co-Authored-By: Claude Sonnet 4.5
---
packages/web/src/components/SessionDetail.tsx | 64 +++++++++++++++++--
1 file changed, 57 insertions(+), 7 deletions(-)
diff --git a/packages/web/src/components/SessionDetail.tsx b/packages/web/src/components/SessionDetail.tsx
index 0b12bc898..8c6f74afc 100644
--- a/packages/web/src/components/SessionDetail.tsx
+++ b/packages/web/src/components/SessionDetail.tsx
@@ -1,12 +1,13 @@
"use client";
-import { useState, useEffect } from "react";
+import { useState, useEffect, useRef } from "react";
import { useSearchParams } from "next/navigation";
import {
type DashboardSession,
type DashboardPR,
} from "@/lib/types";
import { CI_STATUS } from "@composio/ao-core/types";
+import { cn } from "@/lib/cn";
import { CICheckList } from "./CIBadge";
import { DirectTerminal } from "./DirectTerminal";
@@ -83,12 +84,13 @@ function buildGitHubRepoUrl(pr: DashboardPR): string {
async function askAgentToFix(
sessionId: string,
comment: { url: string; path: string; body: string },
+ onSuccess: () => void,
+ onError: () => void,
) {
try {
const { title, description } = cleanBugbotComment(comment.body);
const message = `Please address this review comment:\n\nFile: ${comment.path}\nComment: ${title}\nDescription: ${description}\n\nComment URL: ${comment.url}\n\nAfter fixing, mark the comment as resolved at ${comment.url}`;
- // TODO: Implement API endpoint to send message to agent session
const res = await fetch(`/api/sessions/${sessionId}/message`, {
method: "POST",
headers: { "Content-Type": "application/json" },
@@ -99,10 +101,10 @@ async function askAgentToFix(
throw new Error(`HTTP ${res.status}`);
}
- alert("Message sent to agent");
+ onSuccess();
} catch (err) {
console.error("Failed to send message to agent:", err);
- alert("Failed to send message to agent");
+ onError();
}
}
@@ -288,6 +290,40 @@ function ClientTimestamps({
// ── PR Card ──────────────────────────────────────────────────────────
function PRCard({ pr, sessionId }: { pr: DashboardPR; sessionId: string }) {
+ const [sendingCommentUrl, setSendingCommentUrl] = useState(null);
+ const [sentCommentUrl, setSentCommentUrl] = useState(null);
+ const [errorCommentUrl, setErrorCommentUrl] = useState(null);
+ const timerRef = useRef | null>(null);
+
+ useEffect(() => {
+ return () => {
+ if (timerRef.current) clearTimeout(timerRef.current);
+ };
+ }, []);
+
+ const handleAskAgentToFix = async (comment: { url: string; path: string; body: string }) => {
+ setSendingCommentUrl(comment.url);
+ setErrorCommentUrl(null);
+ setSentCommentUrl(null);
+
+ await askAgentToFix(
+ sessionId,
+ comment,
+ () => {
+ setSendingCommentUrl(null);
+ setSentCommentUrl(comment.url);
+ if (timerRef.current) clearTimeout(timerRef.current);
+ timerRef.current = setTimeout(() => setSentCommentUrl(null), 3000);
+ },
+ () => {
+ setSendingCommentUrl(null);
+ setErrorCommentUrl(comment.url);
+ if (timerRef.current) clearTimeout(timerRef.current);
+ timerRef.current = setTimeout(() => setErrorCommentUrl(null), 3000);
+ },
+ );
+ };
+
const allGreen =
pr.mergeability.mergeable &&
pr.mergeability.ciPassing &&
@@ -396,10 +432,24 @@ function PRCard({ pr, sessionId }: { pr: DashboardPR; sessionId: string }) {
{description}