Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(chat-participant): refactor prompt locations #777

Merged
merged 1 commit into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/participant/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const CHAT_PARTICIPANT_ID = 'mongodb.participant';
alenakhineika marked this conversation as resolved.
Show resolved Hide resolved
63 changes: 15 additions & 48 deletions src/participant/participant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import * as vscode from 'vscode';
import { createLogger } from '../logging';
import type ConnectionController from '../connectionController';
import EXTENSION_COMMANDS from '../commands';
import { GenericPrompt } from './prompts/generic';
import { CHAT_PARTICIPANT_ID } from './constants';
import { QueryPrompt } from './prompts/query';

const log = createLogger('participant');

Expand All @@ -17,7 +20,6 @@ interface ChatResult extends vscode.ChatResult {
stream?: vscode.ChatResponseStream;
}

export const CHAT_PARTICIPANT_ID = 'mongodb.participant';
export const CHAT_PARTICIPANT_MODEL = 'gpt-4o';

export function getRunnableContentFromString(responseContent: string) {
Expand Down Expand Up @@ -148,41 +150,11 @@ export class ParticipantController {
stream: vscode.ChatResponseStream;
token: vscode.CancellationToken;
}) {
const messages = [
// eslint-disable-next-line new-cap
vscode.LanguageModelChatMessage.Assistant(`You are a MongoDB expert!
You create MongoDB queries and aggregation pipelines,
and you are very good at it. The user will provide the basis for the query.
Keep your response concise. Respond with markdown, code snippets are possible with '''javascript.
You can imagine the schema, collection, and database name.
Respond in MongoDB shell syntax using the '''javascript code style.`),
];

context.history.map((historyItem) => {
if (
historyItem.participant === CHAT_PARTICIPANT_ID &&
historyItem instanceof vscode.ChatRequestTurn
) {
// eslint-disable-next-line new-cap
messages.push(vscode.LanguageModelChatMessage.User(historyItem.prompt));
}

if (
historyItem.participant === CHAT_PARTICIPANT_ID &&
historyItem instanceof vscode.ChatResponseTurn
) {
let res = '';
for (const fragment of historyItem.response) {
res += fragment;
}
// eslint-disable-next-line new-cap
messages.push(vscode.LanguageModelChatMessage.Assistant(res));
}
const messages = GenericPrompt.buildMessages({
request,
context,
});

// eslint-disable-next-line new-cap
messages.push(vscode.LanguageModelChatMessage.User(request.prompt));

const abortController = new AbortController();
token.onCancellationRequested(() => {
abortController.abort();
Expand Down Expand Up @@ -222,11 +194,12 @@ export class ParticipantController {
// @MongoDB /query find all documents where the "address" has the word Broadway in it.
async handleQueryRequest({
request,
context,
stream,
token,
}: {
request: vscode.ChatRequest;
context?: vscode.ChatContext;
context: vscode.ChatContext;
stream: vscode.ChatResponseStream;
token: vscode.CancellationToken;
}) {
Expand Down Expand Up @@ -265,17 +238,11 @@ export class ParticipantController {
abortController.abort();
});

const messages = [
// eslint-disable-next-line new-cap
vscode.LanguageModelChatMessage.Assistant(`You are a MongoDB expert!
You create MongoDB queries and aggregation pipelines,
and you are very good at it. The user will provide the basis for the query.
Keep your response concise. Respond with markdown, code snippets are possible with '''javascript.
You can imagine the schema, collection, and database name.
Respond in MongoDB shell syntax using the '''javascript code style.`),
// eslint-disable-next-line new-cap
vscode.LanguageModelChatMessage.User(request.prompt),
];
const messages = QueryPrompt.buildMessages({
context,
request,
});

const responseContent = await this.getChatResponseContent({
messages,
stream,
Expand Down Expand Up @@ -320,9 +287,9 @@ export class ParticipantController {
});
return this._chatResult;
} else if (request.command === 'docs') {
// TODO: Implement this.
// TODO(VSCODE-570): Implement this.
} else if (request.command === 'schema') {
// TODO: Implement this.
// TODO(VSCODE-571): Implement this.
}

return await this.handleGenericRequest({
Expand Down
41 changes: 41 additions & 0 deletions src/participant/prompts/generic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import * as vscode from 'vscode';

import { getHistoryMessages } from './history';

export class GenericPrompt {
static getSystemPrompt(): vscode.LanguageModelChatMessage {
const prompt = `You are a MongoDB expert.
Your task is to help the user craft MongoDB queries and aggregation pipelines that perform their task.
Keep your response concise.
You should suggest queries that are performant and correct.
Respond with markdown, suggest code in a Markdown code block that begins with \'\'\'javascript and ends with \`\`\`.
You can imagine the schema, collection, and database name.
Respond in MongoDB shell syntax using the \'\'\'javascript code block syntax.`;

// eslint-disable-next-line new-cap
return vscode.LanguageModelChatMessage.Assistant(prompt);
}

static getUserPrompt(
request: vscode.ChatRequest
): vscode.LanguageModelChatMessage {
// eslint-disable-next-line new-cap
return vscode.LanguageModelChatMessage.User(request.prompt);
}

static buildMessages({
context,
request,
}: {
request: vscode.ChatRequest;
context: vscode.ChatContext;
}): vscode.LanguageModelChatMessage[] {
const messages = [
GenericPrompt.getSystemPrompt(),
...getHistoryMessages({ context }),
GenericPrompt.getUserPrompt(request),
];

return messages;
}
}
35 changes: 35 additions & 0 deletions src/participant/prompts/history.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as vscode from 'vscode';

import { CHAT_PARTICIPANT_ID } from '../constants';

export function getHistoryMessages({
context,
}: {
context: vscode.ChatContext;
}): vscode.LanguageModelChatMessage[] {
const messages: vscode.LanguageModelChatMessage[] = [];

context.history.map((historyItem) => {
if (
historyItem.participant === CHAT_PARTICIPANT_ID &&
historyItem instanceof vscode.ChatRequestTurn
) {
// eslint-disable-next-line new-cap
messages.push(vscode.LanguageModelChatMessage.User(historyItem.prompt));
}

if (
historyItem.participant === CHAT_PARTICIPANT_ID &&
historyItem instanceof vscode.ChatResponseTurn
) {
let res = '';
for (const fragment of historyItem.response) {
res += fragment;
}
// eslint-disable-next-line new-cap
messages.push(vscode.LanguageModelChatMessage.Assistant(res));
}
});

return messages;
}
41 changes: 41 additions & 0 deletions src/participant/prompts/query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import * as vscode from 'vscode';

import { getHistoryMessages } from './history';

export class QueryPrompt {
static getSystemPrompt(): vscode.LanguageModelChatMessage {
const prompt = `You are a MongoDB expert.
Your task is to help the user craft MongoDB queries and aggregation pipelines that perform their task.
Keep your response concise.
You should suggest queries that are performant and correct.
Respond with markdown, suggest code in a Markdown code block that begins with \'\'\'javascript and ends with \`\`\`.
You can imagine the schema, collection, and database name.
Respond in MongoDB shell syntax using the \'\'\'javascript code block syntax.`;

// eslint-disable-next-line new-cap
return vscode.LanguageModelChatMessage.Assistant(prompt);
}

static getUserPrompt(
request: vscode.ChatRequest
): vscode.LanguageModelChatMessage {
// eslint-disable-next-line new-cap
return vscode.LanguageModelChatMessage.User(request.prompt);
}

static buildMessages({
context,
request,
}: {
request: vscode.ChatRequest;
context: vscode.ChatContext;
}): vscode.LanguageModelChatMessage[] {
const messages = [
QueryPrompt.getSystemPrompt(),
...getHistoryMessages({ context }),
QueryPrompt.getUserPrompt(request),
];

return messages;
}
}
Loading