From c6dc8e5d9e30685e2cda879d950e273bca5eb600 Mon Sep 17 00:00:00 2001 From: Tijs Zwinkels Date: Sat, 1 Jun 2024 11:53:17 +0200 Subject: [PATCH 1/4] Full workspace file path when using @Open Files --- .../providers/OpenFilesContextProvider.ts | 4 ++-- core/util/index.ts | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/core/context/providers/OpenFilesContextProvider.ts b/core/context/providers/OpenFilesContextProvider.ts index 77203e01df..b592ced7a2 100644 --- a/core/context/providers/OpenFilesContextProvider.ts +++ b/core/context/providers/OpenFilesContextProvider.ts @@ -3,7 +3,7 @@ import { ContextProviderDescription, ContextProviderExtras, } from "../../index.js"; -import { getBasename } from "../../util/index.js"; +import { getBasename, getRelativePath } from "../../util/index.js"; import { BaseContextProvider } from "../index.js"; class OpenFilesContextProvider extends BaseContextProvider { @@ -26,7 +26,7 @@ class OpenFilesContextProvider extends BaseContextProvider { openFiles.map(async (filepath: string) => { return { description: filepath, - content: `\`\`\`${getBasename(filepath)}\n${await ide.readFile( + content: `\`\`\`${await getRelativePath(filepath, await extras.ide.getWorkspaceDirs())}\n${await ide.readFile( filepath, )}\n\`\`\``, name: (filepath.split("/").pop() ?? "").split("\\").pop() ?? "", diff --git a/core/util/index.ts b/core/util/index.ts index ad6db9af55..49a299655f 100644 --- a/core/util/index.ts +++ b/core/util/index.ts @@ -1,3 +1,7 @@ +import { + ContextProviderExtras, + } from "../index.js"; + export function removeQuotesAndEscapes(output: string): string { output = output.trim(); @@ -97,6 +101,26 @@ export function getLastNPathParts(filepath: string, n: number): string { return filepath.split(/[\\/]/).slice(-n).join("/"); } +export function getRelativePath(filepath: string, workspaceDirs: string[]): string { + for (const workspaceDir of workspaceDirs) { + const filepathParts = splitPath(filepath); + const workspaceDirParts = splitPath(workspaceDir); + if (filepathParts.slice(0, workspaceDirParts.length).join('/') === workspaceDirParts.join('/')) { + return filepathParts.slice(workspaceDirParts.length).join('/'); + } + } + return splitPath(filepath).pop() ?? ''; // If the file is not in any of the workspaces, return the plain filename +} + +export function splitPath(path: string, withRoot?: string): string[] { + let parts = path.includes("/") ? path.split("/") : path.split("\\"); + if (withRoot !== undefined) { + const rootParts = splitPath(withRoot); + parts = parts.slice(rootParts.length - 1); + } + return parts; +} + export function getMarkdownLanguageTagForFile(filepath: string): string { const ext = filepath.split(".").pop(); switch (ext) { From 89d92af3a951a12fc7560877c26e842a5ebf1ac8 Mon Sep 17 00:00:00 2001 From: Tijs Zwinkels Date: Sat, 1 Jun 2024 12:15:55 +0200 Subject: [PATCH 2/4] Full project file path for @Files and 'active file' context --- gui/src/components/mainInput/resolveInput.ts | 5 +++-- gui/src/hooks/useChatHandler.ts | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/gui/src/components/mainInput/resolveInput.ts b/gui/src/components/mainInput/resolveInput.ts index 5f36e82f28..14ac3bf4e3 100644 --- a/gui/src/components/mainInput/resolveInput.ts +++ b/gui/src/components/mainInput/resolveInput.ts @@ -7,7 +7,7 @@ import { RangeInFile, } from "core"; import { stripImages } from "core/llm/countTokens"; -import { getBasename } from "core/util"; +import { getBasename, getRelativePath } from "core/util"; import { IIdeMessenger } from "../../context/IdeMessenger"; interface MentionAttrs { @@ -96,8 +96,9 @@ async function resolveEditorContent( if (item.itemType === "file") { // This is a quick way to resolve @file references const basename = getBasename(item.id); + const relativeFilePath = getRelativePath(item.id, await ideMessenger.ide.getWorkspaceDirs()); const rawContent = await ideMessenger.ide.readFile(item.id); - const content = `\`\`\`title="${basename}"\n${rawContent}\n\`\`\`\n`; + const content = `\`\`\`${relativeFilePath}\n${rawContent}\n\`\`\`\n`; contextItemsText += content; contextItems.push({ name: basename, diff --git a/gui/src/hooks/useChatHandler.ts b/gui/src/hooks/useChatHandler.ts index b57b8c4b74..789f73266b 100644 --- a/gui/src/hooks/useChatHandler.ts +++ b/gui/src/hooks/useChatHandler.ts @@ -13,7 +13,7 @@ import { } from "core"; import { constructMessages } from "core/llm/constructMessages"; import { stripImages } from "core/llm/countTokens"; -import { getBasename } from "core/util"; +import { getBasename, getRelativePath } from "core/util"; import { usePostHog } from "posthog-js/react"; import { useEffect, useRef } from "react"; import { useSelector } from "react-redux"; @@ -179,8 +179,9 @@ function useChatHandler(dispatch: Dispatch, ideMessenger: IIdeMessenger) { .join("\n"); } contextItems.unshift({ - content: `The following file is currently open. Don't reference it if it's not relevant to the user's message.\n\n\`\`\`${getBasename( + content: `The following file is currently open. Don't reference it if it's not relevant to the user's message.\n\n\`\`\`${getRelativePath( currentFilePath, + await ideMessenger.ide.getWorkspaceDirs(), )}\n${currentFileContents}\n\`\`\``, name: `Active file: ${getBasename(currentFilePath)}`, description: currentFilePath, From 7217ab7754e3bd3580ec96300f8c8816b8e5a6d0 Mon Sep 17 00:00:00 2001 From: Tijs Zwinkels Date: Sat, 1 Jun 2024 12:22:53 +0200 Subject: [PATCH 3/4] FileTreeContextProvider uses splitPath from util instead of local copy --- core/context/providers/FileTreeContextProvider.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/core/context/providers/FileTreeContextProvider.ts b/core/context/providers/FileTreeContextProvider.ts index c098d61ab0..1470b67a74 100644 --- a/core/context/providers/FileTreeContextProvider.ts +++ b/core/context/providers/FileTreeContextProvider.ts @@ -4,6 +4,7 @@ import { ContextProviderExtras, } from "../../index.js"; import { BaseContextProvider } from "../index.js"; +import { splitPath } from "../../util/index.js"; interface Directory { name: string; @@ -11,15 +12,6 @@ interface Directory { directories: Directory[]; } -function splitPath(path: string, withRoot?: string): string[] { - let parts = path.includes("/") ? path.split("/") : path.split("\\"); - if (withRoot !== undefined) { - const rootParts = splitPath(withRoot); - parts = parts.slice(rootParts.length - 1); - } - return parts; -} - function formatFileTree(tree: Directory, indentation = ""): string { let result = ""; for (const file of tree.files) { From 3d326cff3cd663aad211b48fad57b8b6c5ad3d24 Mon Sep 17 00:00:00 2001 From: Tijs Zwinkels Date: Sat, 1 Jun 2024 12:56:29 +0200 Subject: [PATCH 4/4] relative-to-root file paths for rag retrieval --- core/context/retrieval/retrieval.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/context/retrieval/retrieval.ts b/core/context/retrieval/retrieval.ts index c950e5671d..f3218685bc 100644 --- a/core/context/retrieval/retrieval.ts +++ b/core/context/retrieval/retrieval.ts @@ -6,7 +6,7 @@ import { } from "../../index.js"; import { LanceDbIndex } from "../../indexing/LanceDbIndex.js"; -import { deduplicateArray, getBasename } from "../../util/index.js"; +import { deduplicateArray, getRelativePath } from "../../util/index.js"; import { RETRIEVAL_PARAMS } from "../../util/parameters.js"; import { retrieveFts } from "./fullTextSearch.js"; @@ -149,7 +149,7 @@ export async function retrieveContextItemsFromEmbeddings( return [ ...results.map((r) => { - const name = `${getBasename(r.filepath)} (${r.startLine}-${r.endLine})`; + const name = `${getRelativePath(r.filepath, workspaceDirs)} (${r.startLine}-${r.endLine})`; const description = `${r.filepath} (${r.startLine}-${r.endLine})`; return { name,