From 42fb6456f64df153e44342cd0b5f4aa3589334ac Mon Sep 17 00:00:00 2001 From: restlessronin <88921269+restlessronin@users.noreply.github.com> Date: Tue, 28 Nov 2023 12:43:14 +0530 Subject: [PATCH 1/2] first test of custom chat with context --- app/vscode/asset/package.json | 2 +- .../conversation/ConversationTypesProvider.ts | 2 + .../src/conversation/input/getOpenFiles.ts | 16 +++ .../src/conversation/input/resolveVariable.ts | 3 + .../template/RubberduckTemplate.ts | 4 + template/task/explain-code-w-context.rdt.md | 134 ++++++++++++++++++ 6 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 lib/extension/src/conversation/input/getOpenFiles.ts create mode 100644 template/task/explain-code-w-context.rdt.md diff --git a/app/vscode/asset/package.json b/app/vscode/asset/package.json index 5472df0..c36b654 100644 --- a/app/vscode/asset/package.json +++ b/app/vscode/asset/package.json @@ -221,7 +221,7 @@ }, "rubberduck.model": { "type": "string", - "default": "gpt-3.5-turbo", + "default": "gpt-3.5-turbo-16k", "enum": [ "gpt-3.5-turbo", "gpt-3.5-turbo-16k", diff --git a/lib/extension/src/conversation/ConversationTypesProvider.ts b/lib/extension/src/conversation/ConversationTypesProvider.ts index 2efc00e..d310dc0 100644 --- a/lib/extension/src/conversation/ConversationTypesProvider.ts +++ b/lib/extension/src/conversation/ConversationTypesProvider.ts @@ -42,6 +42,7 @@ export class ConversationTypesProvider { await this.loadBuiltinTemplate("task", "document-code.rdt.md"), await this.loadBuiltinTemplate("task", "edit-code.rdt.md"), await this.loadBuiltinTemplate("task", "explain-code.rdt.md"), + await this.loadBuiltinTemplate("task", "explain-code-w-context.rdt.md"), await this.loadBuiltinTemplate("task", "find-bugs.rdt.md"), await this.loadBuiltinTemplate("task", "generate-code.rdt.md"), await this.loadBuiltinTemplate("task", "generate-unit-test.rdt.md"), @@ -58,6 +59,7 @@ export class ConversationTypesProvider { const result = await loadConversationFromFile(fileUri); if (result.type === "error") { + debugger; throw new Error( `Failed to load chat template '${fileUri.toString()}': ${result.error}` ); diff --git a/lib/extension/src/conversation/input/getOpenFiles.ts b/lib/extension/src/conversation/input/getOpenFiles.ts new file mode 100644 index 0000000..677771a --- /dev/null +++ b/lib/extension/src/conversation/input/getOpenFiles.ts @@ -0,0 +1,16 @@ +import * as vscode from "vscode"; +import { getActiveEditor } from "../../vscode/getActiveEditor"; + +export const getOpenFiles = async () => { + const contextDocuments = vscode.workspace.textDocuments.filter( + (document) => document.uri.scheme === "file" + ); + + return contextDocuments.map((document) => { + return { + name: document.fileName, + language: document.languageId, + content: document.getText(), + }; + }); +}; diff --git a/lib/extension/src/conversation/input/resolveVariable.ts b/lib/extension/src/conversation/input/resolveVariable.ts index d4d8c2d..c5ff69e 100644 --- a/lib/extension/src/conversation/input/resolveVariable.ts +++ b/lib/extension/src/conversation/input/resolveVariable.ts @@ -5,6 +5,7 @@ import { Variable } from "../template/RubberduckTemplate"; import { Message } from "../Message"; import { getSelectedLocationText } from "./getSelectedLocationText"; import { getSelectedTextWithDiagnostics } from "./getSelectionWithDiagnostics"; +import { getOpenFiles } from "./getOpenFiles"; export async function resolveVariable( variable: Variable, @@ -12,6 +13,8 @@ export async function resolveVariable( ): Promise { const variableType = variable.type; switch (variableType) { + case "context": + return getOpenFiles(); case "constant": return variable.value; case "message": diff --git a/lib/extension/src/conversation/template/RubberduckTemplate.ts b/lib/extension/src/conversation/template/RubberduckTemplate.ts index 5624196..4dedf85 100644 --- a/lib/extension/src/conversation/template/RubberduckTemplate.ts +++ b/lib/extension/src/conversation/template/RubberduckTemplate.ts @@ -70,6 +70,10 @@ const variableSchema = zod.discriminatedUnion("type", [ index: zod.number(), property: zod.enum(["content"]), }), + variableBaseSchema.extend({ + type: zod.literal("context"), + time: zod.enum(["conversation-start"]), + }), variableBaseSchema.extend({ type: zod.literal("selected-text"), time: zod.enum(["conversation-start", "message"]), diff --git a/template/task/explain-code-w-context.rdt.md b/template/task/explain-code-w-context.rdt.md new file mode 100644 index 0000000..a177b1d --- /dev/null +++ b/template/task/explain-code-w-context.rdt.md @@ -0,0 +1,134 @@ +# Explain Code + +Explain the selected code. + +## Template + +### Configuration + +```json conversation-template +{ + "id": "explain-code-with-context", + "engineVersion": 0, + "label": "Explain Code with Context", + "description": "Explain the selected code in context of all the open files.", + "tags": ["debug", "understand"], + "header": { + "title": "Explain Code ({{location}}) in context", + "icon": { + "type": "codicon", + "value": "book" + } + }, + "variables": [ + { + "name": "openFiles", + "time": "conversation-start", + "type": "context" + }, + { + "name": "selectedText", + "time": "conversation-start", + "type": "selected-text", + "constraints": [{ "type": "text-length", "min": 1 }] + }, + { + "name": "location", + "time": "conversation-start", + "type": "selected-location-text" + }, + { + "name": "firstMessage", + "time": "message", + "type": "message", + "property": "content", + "index": 0 + }, + { + "name": "lastMessage", + "time": "message", + "type": "message", + "property": "content", + "index": -1 + } + ], + "initialMessage": { + "placeholder": "Generating explanation", + "maxTokens": 2048 + }, + "response": { + "maxTokens": 2048, + "stop": ["Bot:", "Developer:"] + } +} +``` + +### Initial Message Prompt + +```template-initial-message +## Instructions +Summarize the code below (emphasizing its key functionality) using the contents of the open files as context. + +## Selected Code +\`\`\`{{language}} +{{selectedText}} +\`\`\` + +## Open Files +{{#each openFiles}} +### File: {{name}} +\`\`\`{{language}} +{{content}} +\`\`\` +{{/each}} + +## Task +Summarize the code at a high level (including goal and purpose) with an emphasis on its key functionality. Use the contents of the open files as context. + +## Response + +``` + +### Response Prompt + +```template-response +## Instructions +Continue the conversation below. +Pay special attention to the current developer request. + +## Current Request +Developer: {{lastMessage}} + +{{#if selectedText}} +## Selected Code +\`\`\`{{language}} +{{selectedText}} +\`\`\` +{{/if}} + +## Code Summary +{{firstMessage}} + +## Conversation +{{#each messages}} +{{#if (neq @index 0)}} +{{#if (eq author "bot")}} +Bot: {{content}} +{{else}} +Developer: {{content}} +{{/if}} +{{/if}} +{{/each}} + +## Task +Write a response that continues the conversation. +Stay focused on current developer request. +Consider the possibility that there might not be a solution. +Ask for clarification if the message does not make sense or more input is needed. +Use the style of a documentation article. +Omit any links. +Include code snippets (using Markdown) and examples where appropriate. + +## Response +Bot: +``` From 22e50cd84c9272e82d26e7f30c87235805fedc96 Mon Sep 17 00:00:00 2001 From: restlessronin <88921269+restlessronin@users.noreply.github.com> Date: Tue, 28 Nov 2023 12:53:42 +0530 Subject: [PATCH 2/2] remove debug code --- lib/extension/src/conversation/ConversationTypesProvider.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/extension/src/conversation/ConversationTypesProvider.ts b/lib/extension/src/conversation/ConversationTypesProvider.ts index d310dc0..09b3651 100644 --- a/lib/extension/src/conversation/ConversationTypesProvider.ts +++ b/lib/extension/src/conversation/ConversationTypesProvider.ts @@ -59,7 +59,6 @@ export class ConversationTypesProvider { const result = await loadConversationFromFile(fileUri); if (result.type === "error") { - debugger; throw new Error( `Failed to load chat template '${fileUri.toString()}': ${result.error}` );