diff --git a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts index 7fe34db11d..46b9977968 100644 --- a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts +++ b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts @@ -573,19 +573,14 @@ declare module 'vscode' { } /** - * Represents an auto-mode model routing resolution. Displayed as a collapsible - * widget in the chat stream showing which model was selected and why. + * Explains what the "Auto" model routed a turn to, as a single status line. + * Push a part without a model for the in-flight state, then a resolved one. + * Auto may route several times in a turn; each route gets its own row. */ export class ChatResponseAutoModeResolutionPart { - /** The model ID that was selected by the router */ - resolvedModel: string; - /** The user-facing display name of the resolved model */ - resolvedModelName: string; - /** The router's classification label */ - predictedLabel: string; - /** Confidence score (0-1) from the router */ - confidence: number; - constructor(resolvedModel: string, resolvedModelName: string, predictedLabel: string, confidence: number); + /** The model the router picked, or `undefined` while routing is in flight. */ + resolvedModel: { id: string; name: string } | undefined; + constructor(resolvedModel?: { id: string; name: string }); } export interface ChatResponseStream { diff --git a/src/test/view/fileChangeModel.test.ts b/src/test/view/fileChangeModel.test.ts new file mode 100644 index 0000000000..ad67b6af6c --- /dev/null +++ b/src/test/view/fileChangeModel.test.ts @@ -0,0 +1,57 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { default as assert } from 'assert'; +import { createSandbox, SinonSandbox } from 'sinon'; +import * as vscode from 'vscode'; +import { GitChangeType, InMemFileChange } from '../../common/file'; +import { FolderRepositoryManager } from '../../github/folderRepositoryManager'; +import { PullRequestModel } from '../../github/pullRequestModel'; +import { GitFileChangeModel } from '../../view/fileChangeModel'; +import { MockRepository } from '../mocks/mockRepository'; + +describe('GitFileChangeModel', function () { + let sinon: SinonSandbox; + + beforeEach(function () { + sinon = createSandbox(); + }); + + afterEach(function () { + sinon.restore(); + }); + + it('loads base content from the previous filename for a rename', async function () { + const repository = new MockRepository(); + const baseCommit = 'base'; + const fileName = 'src/b/thing.py'; + const previousFileName = 'src/a/thing.py'; + const baseContent = 'print("unchanged")'; + const show = sinon.stub(repository, 'show').resolves(baseContent); + const change = new InMemFileChange( + baseCommit, + GitChangeType.RENAME, + fileName, + previousFileName, + '', + [], + 'https://example.com/thing.py', + ); + const model = new GitFileChangeModel( + { repository } as unknown as FolderRepositoryManager, + {} as PullRequestModel, + change, + vscode.Uri.joinPath(repository.rootUri, fileName), + vscode.Uri.joinPath(repository.rootUri, previousFileName), + 'head', + ); + + assert.strictEqual(await model.showBase(), baseContent); + assert.strictEqual(show.calledOnceWithExactly( + baseCommit, + vscode.Uri.joinPath(repository.rootUri, previousFileName).fsPath, + ), true); + }); +}); diff --git a/src/view/fileChangeModel.ts b/src/view/fileChangeModel.ts index 06661245b1..8595dac052 100644 --- a/src/view/fileChangeModel.ts +++ b/src/view/fileChangeModel.ts @@ -120,7 +120,11 @@ export class GitFileChangeModel extends FileChangeModel { async showBase(): Promise { if (!this._show && this.change.status !== GitChangeType.ADD) { const commit = ((this.change instanceof InMemFileChange || this.change instanceof SlimFileChange) ? this.change.baseCommit : this.sha!); - const absolutePath = vscode.Uri.joinPath(this.folderRepoManager.repository.rootUri, this.fileName).fsPath; + const fileName = (this.change.status === GitChangeType.RENAME) && + (this.change instanceof InMemFileChange || this.change instanceof SlimFileChange) + ? this.change.previousFileName! + : this.fileName; + const absolutePath = vscode.Uri.joinPath(this.folderRepoManager.repository.rootUri, fileName).fsPath; this._show = this.folderRepoManager.repository.show(commit, absolutePath); } return this._show;