Skip to content

Commit 1544c2b

Browse files
committed
Quick response support for diagnostics list
Signed-off-by: Ian Bolton <[email protected]>
1 parent 38a130d commit 1544c2b

File tree

14 files changed

+860
-88
lines changed

14 files changed

+860
-88
lines changed

agentic/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export interface KaiUserInteraction {
5151
uri: string;
5252
task: string;
5353
}[];
54+
selectedIssues?: string[];
5455
};
5556
}
5657

shared/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ export * from "./transformation";
33
export * from "./labelSelector";
44
export * from "./utils/languageMapping";
55
export * from "./utils/diffUtils";
6+
7+
export type { DiagnosticIssue, DiagnosticSummary, DiagnosticMessageValue } from "./types/types";

shared/src/types/types.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export enum ChatMessageType {
8989
JSON = "JsonChatMessage",
9090
Tool = "ToolChatMessage",
9191
ModifiedFile = "ModifiedFileChatMessage",
92+
Diagnostic = "DiagnosticChatMessage",
9293
}
9394

9495
export interface QuickResponse {
@@ -283,3 +284,25 @@ export interface InputOutputCache<K, V, C, O> {
283284
invalidate(input: K, opts?: O): Promise<void>;
284285
reset(): Promise<void>;
285286
}
287+
288+
export const KONVEYOR_OUTPUT_CHANNEL_NAME = "Konveyor";
289+
290+
export interface DiagnosticIssue {
291+
id: string;
292+
message: string;
293+
uri: string;
294+
filename: string;
295+
selected?: boolean;
296+
}
297+
298+
export interface DiagnosticSummary {
299+
summary: string;
300+
issuesByFile: Record<string, DiagnosticIssue[]>;
301+
totalIssues: number;
302+
}
303+
304+
export interface DiagnosticMessageValue {
305+
message: string;
306+
diagnosticSummary: DiagnosticSummary;
307+
tasksData: { uri: string; task: string }[];
308+
}

vscode/src/taskManager/utils.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { basename } from "path";
22
import { TasksList } from "./types";
3+
import { DiagnosticIssue, DiagnosticSummary } from "@editor-extensions/shared";
34

45
/**
5-
* Summarizes the tasks into a string to be displayed to the user.
6+
* Summarizes the tasks into structured data for interactive display.
67
* @param tasks - The tasks to summarize.
78
*/
8-
export function summarizeTasks(tasks: TasksList): string {
9+
export function summarizeTasksStructured(tasks: TasksList): DiagnosticSummary {
910
const uriToTasksMap = new Map<string, string[]>();
11+
const issuesByFile: Record<string, DiagnosticIssue[]> = {};
1012

1113
tasks.currentTasks.forEach((task) => {
1214
const uri = task.getUri();
@@ -18,8 +20,21 @@ export function summarizeTasks(tasks: TasksList): string {
1820

1921
let summary = "### New issues:\n";
2022
uriToTasksMap.forEach((taskList, uri) => {
21-
summary += `- ${taskList.length} new issues in **${basename(uri)}**.\n`;
23+
const filename = basename(uri);
24+
summary += `- ${taskList.length} new issues in **${filename}**.\n`;
25+
26+
// Create structured issues for this file
2227
const uniqueTasks = Array.from(new Set(taskList));
28+
const fileIssues: DiagnosticIssue[] = uniqueTasks.map((task) => ({
29+
id: `${uri}-${task}`,
30+
message: task.length > 200 ? task.slice(0, 197) + "..." : task,
31+
uri,
32+
filename,
33+
}));
34+
35+
issuesByFile[filename] = fileIssues;
36+
37+
// Show first 2 issues in summary
2338
uniqueTasks.slice(0, Math.min(2, uniqueTasks.length)).forEach((task) => {
2439
summary += ` - ${task.length > 200 ? task.slice(0, 197) + "..." : task}\n`;
2540
});
@@ -37,7 +52,19 @@ export function summarizeTasks(tasks: TasksList): string {
3752
});
3853
}
3954

40-
return summary;
55+
return {
56+
summary,
57+
issuesByFile,
58+
totalIssues: tasks.currentTasks.length,
59+
};
60+
}
61+
62+
/**
63+
* Summarizes the tasks into a string to be displayed to the user.
64+
* @param tasks - The tasks to summarize.
65+
*/
66+
export function summarizeTasks(tasks: TasksList): string {
67+
return summarizeTasksStructured(tasks).summary;
4168
}
4269

4370
/**

vscode/src/utilities/ModifiedFiles/handleQuickResponse.ts

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export async function handleQuickResponse(
99
messageToken: string,
1010
responseId: string,
1111
state: ExtensionState,
12+
selectedIssues?: string[], // Add selected issues parameter
1213
): Promise<void> {
1314
try {
1415
try {
@@ -33,17 +34,38 @@ export async function handleQuickResponse(
3334

3435
// Create the workflow message with proper typing
3536
let interactionType = responseId.startsWith("choice-") ? "choice" : "yesNo";
36-
let responseData: { choice: number } | { yesNo: boolean } | { tasks: any; yesNo: boolean } =
37-
responseId.startsWith("choice-")
38-
? { choice: parseInt(responseId.split("-")[1]) }
39-
: { yesNo: responseId === "yes" };
37+
let responseData:
38+
| { choice: number }
39+
| { yesNo: boolean }
40+
| { tasks: any; yesNo: boolean; selectedIssues?: string[] } = responseId.startsWith(
41+
"choice-",
42+
)
43+
? { choice: parseInt(responseId.split("-")[1]) }
44+
: { yesNo: responseId === "yes" };
4045

4146
// Check if this message is related to "tasks" interaction by looking for tasksData in the message value
4247
if (msg.value && "tasksData" in msg.value) {
4348
interactionType = "tasks";
49+
50+
// Filter tasks based on selected issues if any are selected
51+
let filteredTasks = msg.value.tasksData as Array<{ uri: string; task: string }>;
52+
if (selectedIssues && selectedIssues.length > 0) {
53+
// selectedIssues contains individual issue IDs in format: "${uri}-${task}"
54+
const selectedIssueIds = new Set(selectedIssues);
55+
56+
// Filter tasks to only include those that match selected issue IDs
57+
filteredTasks = (msg.value.tasksData as Array<{ uri: string; task: string }>).filter(
58+
(task) => {
59+
const issueId = `${task.uri}-${task.task}`;
60+
return selectedIssueIds.has(issueId);
61+
},
62+
);
63+
}
64+
4465
responseData = {
45-
tasks: msg.value.tasksData,
66+
tasks: filteredTasks,
4667
yesNo: responseId === "yes",
68+
selectedIssues: selectedIssues, // Include selected issues for reference
4769
};
4870
}
4971

@@ -70,6 +92,7 @@ export async function handleQuickResponse(
7092
const resolved = state.resolvePendingInteraction(messageToken, {
7193
responseId: responseId,
7294
interactionType: interactionType,
95+
selectedIssues: selectedIssues, // Include selected issues
7396
});
7497

7598
if (!resolved) {

vscode/src/utilities/ModifiedFiles/processMessage.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import {
77
KaiWorkflowMessageType,
88
KaiUserInteraction,
99
} from "@editor-extensions/agentic";
10-
import { flattenCurrentTasks, summarizeTasks, type TasksList } from "../../taskManager";
10+
import { flattenCurrentTasks, type TasksList } from "../../taskManager";
1111
import { ExtensionState } from "../../extensionState";
1212
import { ChatMessageType, ToolMessageValue } from "@editor-extensions/shared";
1313
import { handleModifiedFileMessage } from "./handleModifiedFile";
1414
import { MessageQueueManager, handleUserInteractionComplete } from "./queueManager";
15+
import { summarizeTasksStructured } from "../../taskManager/utils";
1516

1617
// Helper function to wait for analysis completion with timeout
1718
const waitForAnalysisCompletion = async (state: ExtensionState): Promise<void> => {
@@ -47,8 +48,16 @@ const resetStuckAnalysisFlags = (state: ExtensionState): void => {
4748
};
4849

4950
// Helper function to create tasks message
50-
const createTasksMessage = (tasks: TasksList): string => {
51-
return `It appears that my fixes caused following issues:\n\n${summarizeTasks(tasks)}\n\nDo you want me to continue fixing them?`;
51+
const createTasksMessage = (tasks: TasksList): { message: string; diagnosticSummary: any } => {
52+
const diagnosticSummary = summarizeTasksStructured(tasks);
53+
return {
54+
message: `It appears that my fixes caused following issues. Please review the issues below and select which ones you'd like me to fix. `,
55+
diagnosticSummary: {
56+
summary: diagnosticSummary.summary,
57+
issuesByFile: diagnosticSummary.issuesByFile,
58+
totalIssues: diagnosticSummary.totalIssues,
59+
},
60+
};
5261
};
5362

5463
// Helper function to handle user interaction promises uniformly
@@ -111,12 +120,14 @@ const handleTasksInteraction = async (
111120
}
112121
// Show tasks to user and wait for response
113122
state.mutateData((draft) => {
123+
const tasksMessage = createTasksMessage(rawTasks);
114124
draft.chatMessages.push({
115125
kind: ChatMessageType.String,
116126
messageToken: msg.id,
117127
timestamp: new Date().toISOString(),
118128
value: {
119-
message: createTasksMessage(rawTasks),
129+
message: tasksMessage.message,
130+
diagnosticSummary: tasksMessage.diagnosticSummary,
120131
tasksData: flattenCurrentTasks(rawTasks),
121132
},
122133
quickResponses: [

vscode/src/webviewMessageHandler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,8 @@ const actions: {
173173
vscode.window.showErrorMessage(`Failed to show diff with decorations: ${error}`);
174174
}
175175
},
176-
QUICK_RESPONSE: async ({ responseId, messageToken }, state) => {
177-
handleQuickResponse(messageToken, responseId, state);
176+
QUICK_RESPONSE: async ({ responseId, messageToken, selectedIssues }, state) => {
177+
handleQuickResponse(messageToken, responseId, state, selectedIssues);
178178
},
179179
FILE_RESPONSE: async ({ responseId, messageToken, path, content }, state) => {
180180
handleFileResponse(messageToken, responseId, path, content, state);

0 commit comments

Comments
 (0)