-
Notifications
You must be signed in to change notification settings - Fork 358
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
wip: add diagnostic context and edit mode
This commit introduces the following changes: - Adds `DIAGNOSTIC_CONTEXT_MENTION_PROVIDER` to `lib/shared/src/mentions/api.ts`, enabling the retrieval of diagnostic information as context in chat. - Integrates diagnostic context into `vscode/src/chat/context/chatContext.ts` and `vscode/src/chat/chat-view/handlers/registry.ts`. - Adds a new `AgenticEditHandler` in `vscode/src/chat/chat-view/handlers/AgenticEditHandler.ts` to handle edit mode requests from the agent. - Implements `chatDiff` function in `vscode/src/non-stop/line-diff.ts` to display the diff in chat. - Updates `vscode/src/chat/agentic/DeepCody.ts` to include `OmniboxAgentResponse` and `OmniboxModes` for agent responses. - Updates `vscode/src/chat/chat-view/handlers/AgenticHandler.ts` to integrate the new `AgenticEditHandler` and handle edit mode. - Updates `vscode/webviews/chat/Transcript.tsx` to remove the `DeepCodyAgentID` check. - Adds `vscode/src/commands/context/diagnostic.ts` to retrieve context from diagnostics. - Adds the ability to show the diff in the chat UI. This change enables the agent to provide code edits and use diagnostic information as context. Test plan: - Verify that diagnostic information is correctly retrieved and displayed as context in chat. - Verify that the agent can successfully execute edit commands. - Verify that the diff is displayed correctly in the chat UI.
- Loading branch information
Showing
10 changed files
with
358 additions
and
319 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
vscode/src/chat/chat-view/handlers/AgenticEditHandler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import { type ContextItem, PromptString, ps } from '@sourcegraph/cody-shared' | ||
import * as vscode from 'vscode' | ||
import { getDiagnosticsTextBlock, getUpdatedDiagnostics } from '../../../commands/context/diagnostic' | ||
import { executeEdit } from '../../../edit/execute' | ||
import { getEditor } from '../../../editor/active-editor' | ||
import { chatDiff } from '../../../non-stop/line-diff' | ||
import type { AgentHandler, AgentHandlerDelegate, AgentRequest } from './interfaces' | ||
|
||
export class AgenticEditHandler implements AgentHandler { | ||
constructor(protected modelId: string) {} | ||
|
||
public async handle( | ||
req: AgentRequest, | ||
delegate: AgentHandlerDelegate, | ||
context?: ContextItem[] | ||
): Promise<void> { | ||
const editor = getEditor()?.active | ||
if (!editor?.document) { | ||
delegate.postError(new Error('No active editor'), 'transcript') | ||
delegate.postDone() | ||
return | ||
} | ||
const abortSignal = req.signal | ||
const postProgressToWebview = (msgs: string[]) => { | ||
const message = msgs.join('\n\n') | ||
delegate.postMessageInProgress({ | ||
speaker: 'assistant', | ||
text: PromptString.unsafe_fromLLMResponse(message), | ||
model: this.modelId, | ||
}) | ||
} | ||
|
||
const document = editor.document | ||
const fullRange = document.validateRange(new vscode.Range(0, 0, document.lineCount, 0)) | ||
let currentDiagnostics = vscode.languages.getDiagnostics() | ||
|
||
let attempts = 0 | ||
const MAX_ATTEMPTS = 5 | ||
let currentInstruction = req.inputText | ||
|
||
const messageInProgress = [] | ||
|
||
while (attempts < MAX_ATTEMPTS) { | ||
abortSignal.throwIfAborted() | ||
attempts++ | ||
const task = await executeEdit({ | ||
configuration: { | ||
document, | ||
range: fullRange, | ||
userContextFiles: context, | ||
instruction: currentInstruction, | ||
mode: 'edit', | ||
intent: currentInstruction?.includes(ps`unit test`) ? 'edit' : 'edit', | ||
}, | ||
}) | ||
|
||
if (!task) { | ||
delegate.postError(new Error('Failed to execute edit command'), 'transcript') | ||
delegate.postDone() | ||
return | ||
} | ||
|
||
const diffs = | ||
task.diff || | ||
(task.replacement | ||
? [ | ||
{ | ||
type: 'insertion', | ||
text: task.replacement, | ||
range: task.originalRange, | ||
}, | ||
] | ||
: []) | ||
|
||
messageInProgress.push(chatDiff(diffs, document, { showFullFile: false })) | ||
postProgressToWebview(messageInProgress) | ||
|
||
abortSignal.throwIfAborted() | ||
|
||
// We need to give it time for the | ||
const latestDiagnostics = vscode.languages.getDiagnostics() | ||
const problems = getUpdatedDiagnostics(currentDiagnostics, latestDiagnostics) | ||
|
||
if (!problems.length) { | ||
break // Success! No more problems | ||
} | ||
|
||
if (attempts < MAX_ATTEMPTS) { | ||
const problemText = getDiagnosticsTextBlock(problems) | ||
const diagnosticsBlock = PromptString.unsafe_fromLLMResponse(problemText) | ||
const retryMessage = `Attempt ${attempts}/${MAX_ATTEMPTS}: Found issues, trying to fix:\n${problemText}` | ||
messageInProgress.push(retryMessage) | ||
postProgressToWebview(messageInProgress) | ||
|
||
// Update instruction with current problems for next attempt | ||
currentInstruction = currentInstruction.concat( | ||
ps`\nPrevious attempt resulted in these issues:\n${diagnosticsBlock}` | ||
) | ||
currentDiagnostics = latestDiagnostics | ||
} | ||
} | ||
|
||
if (attempts === MAX_ATTEMPTS) { | ||
messageInProgress.push( | ||
`Reached maximum number of attempts (${MAX_ATTEMPTS}). Some issues may remain.` | ||
) | ||
} | ||
|
||
postProgressToWebview(messageInProgress) | ||
delegate.postDone() | ||
} | ||
} |
Oops, something went wrong.