Skip to content

Commit 6ba9dd2

Browse files
authored
fix: filter long and invalid prompts in future messages VSCODE-614 (#861)
1 parent 0f8cfe0 commit 6ba9dd2

File tree

5 files changed

+83
-9
lines changed

5 files changed

+83
-9
lines changed

src/participant/participant.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import {
3535
} from './prompts/schema';
3636
import {
3737
chatResultFeedbackKindToTelemetryValue,
38-
ParticipantErrorTypes,
3938
TelemetryEventTypes,
4039
} from '../telemetry/telemetryService';
4140
import { DocsChatbotAIService } from './docsChatbotAIService';
@@ -44,6 +43,7 @@ import formatError from '../utils/formatError';
4443
import type { ModelInput } from './prompts/promptBase';
4544
import { processStreamWithIdentifiers } from './streamParsing';
4645
import type { PromptIntent } from './prompts/intent';
46+
import { ParticipantErrorTypes } from '../test/suite/participant/participantErrorTypes';
4747

4848
const log = createLogger('participant');
4949

src/participant/prompts/promptBase.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type {
44
InternalPromptPurpose,
55
ParticipantPromptProperties,
66
} from '../../telemetry/telemetryService';
7+
import { ParticipantErrorTypes } from '../../test/suite/participant/participantErrorTypes';
78

89
export interface PromptArgsBase {
910
request: {
@@ -188,6 +189,16 @@ export abstract class PromptBase<TArgs extends PromptArgsBase> {
188189
}
189190

190191
if (historyItem instanceof vscode.ChatResponseTurn) {
192+
if (
193+
historyItem.result.errorDetails?.message ===
194+
ParticipantErrorTypes.FILTERED
195+
) {
196+
// If the response led to a filtered error, we do not want the
197+
// error-causing message to be sent again so we remove it.
198+
messages.pop();
199+
continue;
200+
}
201+
191202
let message = '';
192203

193204
// Skip a response to an empty user prompt message or connect message.

src/telemetry/telemetryService.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type { NewConnectionTelemetryEventProperties } from './connectionTelemetr
1313
import type { ShellEvaluateResult } from '../types/playgroundType';
1414
import type { StorageController } from '../storage';
1515
import type { ParticipantResponseType } from '../participant/constants';
16+
import { ParticipantErrorTypes } from '../test/suite/participant/participantErrorTypes';
1617

1718
const log = createLogger('telemetry');
1819
// eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -193,14 +194,6 @@ export enum TelemetryEventTypes {
193194
PARTICIPANT_RESPONSE_GENERATED = 'Participant Response Generated',
194195
}
195196

196-
export enum ParticipantErrorTypes {
197-
CHAT_MODEL_OFF_TOPIC = 'Chat Model Off Topic',
198-
INVALID_PROMPT = 'Invalid Prompt',
199-
FILTERED = 'Filtered by Responsible AI Service',
200-
OTHER = 'Other',
201-
DOCS_CHATBOT_API = 'Docs Chatbot API Issue',
202-
}
203-
204197
/**
205198
* This controller manages telemetry.
206199
*/

src/test/suite/participant/participant.test.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { Prompts } from '../../../participant/prompts';
3434
import { createMarkdownLink } from '../../../participant/markdown';
3535
import EXTENSION_COMMANDS from '../../../commands';
3636
import { getContentLength } from '../../../participant/prompts/promptBase';
37+
import { ParticipantErrorTypes } from './participantErrorTypes';
3738

3839
// The Copilot's model in not available in tests,
3940
// therefore we need to mock its methods and returning values.
@@ -2125,6 +2126,68 @@ Schema:
21252126
getContentLength(messages[1])
21262127
);
21272128
});
2129+
2130+
suite('with invalid messages', function () {
2131+
test('filters disallowed messages', async function () {
2132+
const chatRequestMock = {
2133+
prompt: 'find all docs by a name example',
2134+
};
2135+
2136+
chatContextStub = {
2137+
history: [
2138+
Object.assign(Object.create(vscode.ChatRequestTurn.prototype), {
2139+
prompt: 'give me the count of all people in the prod database',
2140+
command: 'query',
2141+
references: [],
2142+
participant: CHAT_PARTICIPANT_ID,
2143+
}),
2144+
Object.assign(Object.create(vscode.ChatRequestTurn.prototype), {
2145+
prompt: 'some disallowed message',
2146+
command: 'query',
2147+
references: [],
2148+
participant: CHAT_PARTICIPANT_ID,
2149+
}),
2150+
Object.assign(Object.create(vscode.ChatResponseTurn.prototype), {
2151+
result: {
2152+
errorDetails: {
2153+
message: ParticipantErrorTypes.FILTERED,
2154+
},
2155+
},
2156+
response: [],
2157+
participant: CHAT_PARTICIPANT_ID,
2158+
}),
2159+
Object.assign(Object.create(vscode.ChatRequestTurn.prototype), {
2160+
prompt: 'ok message',
2161+
references: [],
2162+
participant: CHAT_PARTICIPANT_ID,
2163+
}),
2164+
],
2165+
};
2166+
const { messages } = await Prompts.generic.buildMessages({
2167+
context: chatContextStub,
2168+
request: chatRequestMock,
2169+
connectionNames: [],
2170+
});
2171+
2172+
expect(messages).to.have.lengthOf(4);
2173+
2174+
const messageContents = messages.map((message) => {
2175+
// There may be different types for the messages' content
2176+
const content = Array.isArray(message.content)
2177+
? message.content.map((sub) => sub.value).join('')
2178+
: message.content;
2179+
2180+
return content;
2181+
});
2182+
2183+
// Skip the preset prompt and check that the rest are correct.
2184+
expect(messageContents.slice(1)).deep.equal([
2185+
'give me the count of all people in the prod database',
2186+
'ok message',
2187+
'find all docs by a name example',
2188+
]);
2189+
});
2190+
});
21282191
});
21292192

21302193
suite('telemetry', function () {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export enum ParticipantErrorTypes {
2+
CHAT_MODEL_OFF_TOPIC = 'Chat Model Off Topic',
3+
INVALID_PROMPT = 'Invalid Prompt',
4+
FILTERED = 'Filtered by Responsible AI Service',
5+
OTHER = 'Other',
6+
DOCS_CHATBOT_API = 'Docs Chatbot API Issue',
7+
}

0 commit comments

Comments
 (0)