feat(vscode): auto-send review comments when input is empty (#7442)

* feat(vscode): auto-send review comments when input is empty

When clicking 'Send all to chat' or per-comment 'Send to chat' in diff
views, comments are now sent directly to the AI if the input field is
empty, instead of requiring a manual send. If the input has text, the
existing behavior (append as chips) is preserved.

* fix(vscode): only auto-send review comments when chat is truly empty

Check for pre-existing review chips and image attachments before
auto-sending, not just the text field.
This commit is contained in:
Marius
2026-03-23 13:40:33 +01:00
committed by GitHub
parent f597677376
commit 85bc291046
9 changed files with 29 additions and 15 deletions
@@ -24,7 +24,7 @@ export class DiffViewerProvider implements vscode.Disposable {
private cachedDiffTarget: { directory: string; baseBranch: string } | undefined
private gitOps: GitOps
private outputChannel: vscode.OutputChannel
private onSendComments: ((comments: unknown[]) => void) | undefined
private onSendComments: ((comments: unknown[], autoSend: boolean) => void) | undefined
constructor(
private readonly extensionUri: vscode.Uri,
@@ -38,7 +38,7 @@ export class DiffViewerProvider implements vscode.Disposable {
appendOutput(this.outputChannel, "DiffViewer", ...args)
}
public setCommentHandler(handler: (comments: unknown[]) => void): void {
public setCommentHandler(handler: (comments: unknown[], autoSend: boolean) => void): void {
this.onSendComments = handler
}
@@ -95,7 +95,7 @@ export class DiffViewerProvider implements vscode.Disposable {
}
if (type === "diffViewer.sendComments" && Array.isArray(msg.comments)) {
this.onSendComments?.(msg.comments)
this.onSendComments?.(msg.comments, !!msg.autoSend)
return
}
+5 -5
View File
@@ -109,7 +109,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
private pending = 0
/** Cached notificationsLoaded payload */
private cachedNotificationsMessage: unknown = null
private pendingReviewComments: unknown[][] = []
private pendingReviewComments: { comments: unknown[]; autoSend: boolean }[] = []
private readyResolvers: (() => void)[] = []
private trackedSessionIds: Set<string> = new Set()
private syncedChildSessions: Set<string> = new Set()
@@ -2371,8 +2371,8 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
})
}
public async appendReviewComments(comments: unknown[]): Promise<void> {
this.pendingReviewComments.push(comments)
public async appendReviewComments(comments: unknown[], autoSend = false): Promise<void> {
this.pendingReviewComments.push({ comments, autoSend })
if (!this.webview) {
await vscode.commands.executeCommand(`${KiloProvider.viewType}.focus`)
@@ -2387,8 +2387,8 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
const pending = this.pendingReviewComments
this.pendingReviewComments = []
for (const comments of pending) {
this.postMessage({ type: "appendReviewComments", comments })
for (const entry of pending) {
this.postMessage({ type: "appendReviewComments", comments: entry.comments, autoSend: entry.autoSend })
}
}
+2 -2
View File
@@ -87,8 +87,8 @@ export function activate(context: vscode.ExtensionContext) {
// Create standalone diff viewer provider for the sidebar "Show Changes" action
const diffViewerProvider = new DiffViewerProvider(context.extensionUri, connectionService)
diffViewerProvider.setCommentHandler((comments) => {
void provider.appendReviewComments(comments)
diffViewerProvider.setCommentHandler((comments, autoSend) => {
void provider.appendReviewComments(comments, autoSend)
})
context.subscriptions.push(diffViewerProvider)
@@ -292,7 +292,9 @@ export const DiffPanel: Component<DiffPanelProps> = (props) => {
const sendAllToChat = () => {
const all = comments()
if (all.length === 0) return
window.dispatchEvent(new MessageEvent("message", { data: { type: "appendReviewComments", comments: all } }))
window.dispatchEvent(
new MessageEvent("message", { data: { type: "appendReviewComments", comments: all, autoSend: true } }),
)
preserveScroll(() => setComments([]))
props.onSendAll?.()
}
@@ -289,7 +289,9 @@ export const FullScreenDiffView: Component<FullScreenDiffViewProps> = (props) =>
const sendAllToChat = () => {
const all = comments()
if (all.length === 0) return
window.dispatchEvent(new MessageEvent("message", { data: { type: "appendReviewComments", comments: all } }))
window.dispatchEvent(
new MessageEvent("message", { data: { type: "appendReviewComments", comments: all, autoSend: true } }),
)
preserveScroll(() => setComments([]))
props.onSendAll?.()
}
@@ -221,7 +221,11 @@ export function buildReviewAnnotation(
actions.appendChild(
makeActionButton(handlers.labels.sendToChat, makeIcon("M1 1l14 7-14 7V9l10-1L1 7z"), () => {
window.dispatchEvent(new MessageEvent("message", { data: { type: "appendReviewComments", comments: [comment] } }))
window.dispatchEvent(
new MessageEvent("message", {
data: { type: "appendReviewComments", comments: [comment], autoSend: true },
}),
)
handlers.deleteComment(comment.id)
}),
)
@@ -42,7 +42,7 @@ const DiffViewerContent: Component = () => {
const handler = (event: MessageEvent) => {
const msg = event.data
if (msg?.type !== "appendReviewComments" || !Array.isArray(msg.comments)) return
post({ type: "diffViewer.sendComments", comments: msg.comments })
post({ type: "diffViewer.sendComments", comments: msg.comments, autoSend: !!msg.autoSend })
}
window.addEventListener("message", handler)
@@ -246,9 +246,14 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
}
if (message.type === "appendReviewComments") {
const empty = !text().trim() && reviewComments().length === 0 && imageAttach.images().length === 0
const merged = mergeReviewComments(reviewComments(), message.comments)
replaceReviewComments(merged)
textareaRef?.focus()
if (message.autoSend && empty && !isDisabled() && !props.blocked?.()) {
handleSend()
} else {
textareaRef?.focus()
}
}
if (message.type === "triggerTask") {
@@ -586,6 +586,7 @@ export interface ReviewComment {
export interface AppendReviewCommentsMessage {
type: "appendReviewComments"
comments: ReviewComment[]
autoSend?: boolean
}
export interface TriggerTaskMessage {