Skip to content

Commit

Permalink
Full project file path in context (#1407)
Browse files Browse the repository at this point in the history
* Full workspace file path when using @OPEN Files

* Full project file path for @Files and 'active file' context

* FileTreeContextProvider uses splitPath from util instead of local copy

* relative-to-root file paths for rag retrieval
  • Loading branch information
tijszwinkels authored and sestinj committed Jun 23, 2024
1 parent e9c8c32 commit ef31ace
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 17 deletions.
10 changes: 1 addition & 9 deletions core/context/providers/FileTreeContextProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,14 @@ import {
ContextProviderExtras,
} from "../../index.js";
import { BaseContextProvider } from "../index.js";
import { splitPath } from "../../util/index.js";

interface Directory {
name: string;
files: string[];
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) {
Expand Down
4 changes: 2 additions & 2 deletions core/context/providers/OpenFilesContextProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -27,7 +27,7 @@ class OpenFilesContextProvider extends BaseContextProvider {
openFiles.map(async (filepath: string) => {
return {
description: filepath,
content: `\`\`\`${await getRelativePath(filepath, workspaceDirs)}\n${await ide.readFile(
content: `\`\`\`${await getRelativePath(filepath, await extras.ide.getWorkspaceDirs())}\n${await ide.readFile(
filepath,
)}\n\`\`\``,
name: (filepath.split("/").pop() ?? "").split("\\").pop() ?? "",
Expand Down
4 changes: 2 additions & 2 deletions core/context/retrieval/retrieval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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,
Expand Down
24 changes: 24 additions & 0 deletions core/util/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import {
ContextProviderExtras,
} from "../index.js";

export function removeQuotesAndEscapes(output: string): string {
output = output.trim();

Expand Down Expand Up @@ -165,6 +169,26 @@ export function splitPath(path: string, withRoot?: string): string[] {
return parts;
}

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) {
Expand Down
5 changes: 3 additions & 2 deletions gui/src/components/mainInput/resolveInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 3 additions & 2 deletions gui/src/hooks/useChatHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit ef31ace

Please sign in to comment.