Use codemapper when applying edits to notebook (#246674)

* Address code review comments

* Updates

* Updates

* Updates

* Updates

* Updates

* updates
This commit is contained in:
Don Jayamanne
2025-05-07 23:32:32 +10:00
committed by GitHub
parent f6963b9cb9
commit f63c3e0f4e
2 changed files with 133 additions and 11 deletions

View File

@@ -60,6 +60,8 @@ import { observableConfigValue } from '../../../../platform/observable/common/pl
import { ISharedWebContentExtractorService } from '../../../../platform/webContentExtractor/common/webContentExtractor.js';
import { IFileService } from '../../../../platform/files/common/files.js';
import { resolveImageEditorAttachContext } from '../../chat/browser/chatAttachmentResolve.js';
import { INotebookService } from '../../notebook/common/notebookService.js';
import { ICellEditOperation } from '../../notebook/common/notebookCommon.js';
export const enum State {
CREATE_SESSION = 'CREATE_SESSION',
@@ -1529,6 +1531,64 @@ export async function reviewEdits(accessor: ServicesAccessor, editor: ICodeEdito
chatModel.completeResponse(chatRequest);
}
const isSettled = derived(r => {
const entry = editSession?.readEntry(uri, r);
if (!entry) {
return false;
}
const state = entry.state.read(r);
return state === ModifiedFileEntryState.Accepted || state === ModifiedFileEntryState.Rejected;
});
const whenDecided = waitForState(isSettled, Boolean);
await raceCancellation(whenDecided, token);
store.dispose();
return true;
}
export async function reviewNotebookEdits(accessor: ServicesAccessor, uri: URI, stream: AsyncIterable<[URI, TextEdit[]] | ICellEditOperation[]>, token: CancellationToken): Promise<boolean> {
const chatService = accessor.get(IChatService);
const notebookService = accessor.get(INotebookService);
const isNotebook = notebookService.hasSupportedNotebooks(uri);
const chatModel = chatService.startSession(ChatAgentLocation.Editor, token, false);
chatModel.startEditingSession(true);
const editSession = await chatModel.editingSessionObs?.promise;
const store = new DisposableStore();
store.add(chatModel);
// STREAM
const chatRequest = chatModel?.addRequest({ text: '', parts: [] }, { variables: [] }, 0);
assertType(chatRequest.response);
if (isNotebook) {
chatRequest.response.updateContent({ kind: 'notebookEdit', uri, edits: [], done: false });
} else {
chatRequest.response.updateContent({ kind: 'textEdit', uri, edits: [], done: false });
}
for await (const chunk of stream) {
if (token.isCancellationRequested) {
chatRequest.response.cancel();
break;
}
if (chunk.every(isCellEditOperation)) {
chatRequest.response.updateContent({ kind: 'notebookEdit', uri, edits: chunk, done: false });
} else {
chatRequest.response.updateContent({ kind: 'textEdit', uri: chunk[0], edits: chunk[1], done: false });
}
}
if (isNotebook) {
chatRequest.response.updateContent({ kind: 'notebookEdit', uri, edits: [], done: true });
} else {
chatRequest.response.updateContent({ kind: 'textEdit', uri, edits: [], done: true });
}
if (!token.isCancellationRequested) {
chatRequest.response.complete();
}
const isSettled = derived(r => {
const entry = editSession?.readEntry(uri, r);
if (!entry) {
@@ -1547,6 +1607,15 @@ export async function reviewEdits(accessor: ServicesAccessor, editor: ICodeEdito
return true;
}
function isCellEditOperation(edit: URI | TextEdit[] | ICellEditOperation): edit is ICellEditOperation {
if (URI.isUri(edit)) {
return false;
}
if (Array.isArray(edit)) {
return false;
}
return true;
}
async function moveToPanelChat(accessor: ServicesAccessor, model: ChatModel | undefined) {