From fb236a7ff6d1435e913ebafcf3c38f98f2d34a44 Mon Sep 17 00:00:00 2001 From: Rhys Howell Date: Wed, 2 Oct 2024 12:27:01 -0400 Subject: [PATCH] fix: show empty docs msg, schema set msg content correctly --- src/participant/participant.ts | 30 ++++++--- .../suite/participant/participant.test.ts | 67 ++++++++++++++++++- 2 files changed, 87 insertions(+), 10 deletions(-) diff --git a/src/participant/participant.ts b/src/participant/participant.ts index 79c3f16bd..cd41b32e8 100644 --- a/src/participant/participant.ts +++ b/src/participant/participant.ts @@ -792,10 +792,12 @@ export default class ParticipantController { // TODO: Remove this when the issue is fixed. messagesWithNamespace.messages[ messagesWithNamespace.messages.length - 1 - ].content = + // eslint-disable-next-line new-cap + ] = vscode.LanguageModelChatMessage.User( messagesWithNamespace.messages[ messagesWithNamespace.messages.length - 1 - ].content.trim() || 'see previous messages'; + ].content.trim() || 'see previous messages' + ); const responseContentWithNamespace = await this.getChatResponseContent({ modelInput: messagesWithNamespace, @@ -1359,13 +1361,7 @@ export default class ParticipantController { token, }); - this._streamResponseReference({ - reference: { - url: MONGODB_DOCS_LINK, - title: 'View MongoDB documentation', - }, - stream, - }); + this._streamGenericDocsLink(stream); this._telemetryService.trackCopilotParticipantResponse({ command: 'docs/copilot', @@ -1390,6 +1386,16 @@ export default class ParticipantController { stream.markdown(link); } + _streamGenericDocsLink(stream: vscode.ChatResponseStream): void { + this._streamResponseReference({ + reference: { + url: MONGODB_DOCS_LINK, + title: 'View MongoDB documentation', + }, + stream, + }); + } + async handleDocsRequest( ...args: [ vscode.ChatRequest, @@ -1400,6 +1406,12 @@ export default class ParticipantController { ): Promise { const [request, context, stream, token] = args; + if (Prompts.isPromptEmpty(request)) { + stream.markdown(Prompts.generic.getEmptyRequestResponse()); + this._streamGenericDocsLink(stream); + return emptyRequestChatResult(context.history); + } + const chatId = ChatMetadataStore.getChatIdFromHistoryOrNewChatId( context.history ); diff --git a/src/test/suite/participant/participant.test.ts b/src/test/suite/participant/participant.test.ts index 12ba8ae46..38962a84b 100644 --- a/src/test/suite/participant/participant.test.ts +++ b/src/test/suite/participant/participant.test.ts @@ -1383,6 +1383,52 @@ suite('Participant Controller Test Suite', function () { 'What is the name of the database you would like to run against?' ); }); + + test('with history, and a blank prompt, it sets a message so it does not cause model error (VSCODE-626)', async function () { + const chatRequestMock = { + prompt: '', + command: 'schema', + references: [], + }; + chatContextStub = { + history: [ + Object.assign(Object.create(vscode.ChatRequestTurn.prototype), { + prompt: + 'how do I make a find request vs favorite_fruits.pineapple?', + command: 'query', + references: [], + participant: CHAT_PARTICIPANT_ID, + }), + Object.assign( + Object.create(vscode.ChatResponseTurn.prototype), + { + participant: CHAT_PARTICIPANT_ID, + response: [ + { + value: 'some code', + }, + ], + command: 'query', + result: { + metadata: { + intent: 'query', + chatId: 'abc', + }, + }, + } + ), + ], + }; + await invokeChatHandler(chatRequestMock); + + expect(sendRequestStub.calledOnce).to.be.true; + expect(sendRequestStub.firstCall.args[0][0].content).to.include( + 'Parse all user messages to find a database name and a collection name.' + ); + expect(sendRequestStub.firstCall.args[0][3].content).to.include( + 'see previous messages' + ); + }); }); suite( @@ -1549,7 +1595,26 @@ Schema: afterEach(function () { global.fetch = initialFetch; - sinon.restore(); + }); + + test('shows a message and docs link on empty prompt', async function () { + fetchStub = sinon.stub().resolves(); + global.fetch = fetchStub; + const chatRequestMock = { + prompt: '', + command: 'docs', + references: [], + }; + const res = await invokeChatHandler(chatRequestMock); + expect(fetchStub).to.not.have.been.called; + expect(sendRequestStub).to.have.not.been.called; + expect(res?.metadata.intent).to.equal('emptyRequest'); + const defaultEmptyMsg = chatStreamStub.markdown.getCall(0).args[0]; + expect(defaultEmptyMsg).to.include( + 'Ask anything about MongoDB, from writing queries to questions a' + ); + const referenceMsg = chatStreamStub.markdown.getCall(1).args[0]; + expect(referenceMsg.value).to.include('View MongoDB documentation'); }); test('uses docs chatbot result if available', async function () {