aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA.J. Shulman <Shulman.aj@gmail.com>2025-05-21 13:11:52 -0400
committerA.J. Shulman <Shulman.aj@gmail.com>2025-05-21 13:11:52 -0400
commitc3dba47bcda10bbcd72010c177afa8fd301e87e1 (patch)
treee8fe23915a09d4a9a95afbf971bce8e852fc5619
parent0e98320d3b237f1927b9f1367494dccd7f66eda9 (diff)
feat: add codebase exploration tools for agent assistance
Add three new agent tools to improve navigation and understanding of the codebase: FileContentTool: retrieves complete content of specified files (max 3) FileNamesTool: lists all available files in the codebase CodebaseSummarySearchTool: performs semantic search across file summaries
-rw-r--r--src/client/views/nodes/chatbot/agentsystem/Agent.ts6
-rw-r--r--src/client/views/nodes/chatbot/tools/CodebaseSummarySearchTool.ts75
-rw-r--r--src/client/views/nodes/chatbot/tools/FileContentTool.ts78
-rw-r--r--src/client/views/nodes/chatbot/tools/FileNamesTool.ts34
-rw-r--r--src/client/views/nodes/chatbot/vectorstore/Vectorstore.ts6
-rw-r--r--src/server/ApiManagers/AssistantManager.ts13
6 files changed, 212 insertions, 0 deletions
diff --git a/src/client/views/nodes/chatbot/agentsystem/Agent.ts b/src/client/views/nodes/chatbot/agentsystem/Agent.ts
index 86d40864e..1a9df1a75 100644
--- a/src/client/views/nodes/chatbot/agentsystem/Agent.ts
+++ b/src/client/views/nodes/chatbot/agentsystem/Agent.ts
@@ -26,6 +26,9 @@ import { Upload } from '../../../../../server/SharedMediaTypes';
import { RAGTool } from '../tools/RAGTool';
import { AgentDocumentManager } from '../utils/AgentDocumentManager';
import { CreateLinksTool } from '../tools/CreateLinksTool';
+import { CodebaseSummarySearchTool } from '../tools/CodebaseSummarySearchTool';
+import { FileContentTool } from '../tools/FileContentTool';
+import { FileNamesTool } from '../tools/FileNamesTool';
//import { CreateTextDocTool } from '../tools/CreateTextDocumentTool';
dotenv.config();
@@ -87,6 +90,9 @@ export class Agent {
//imageCreationTool: new ImageCreationTool(createImage),
documentMetadata: new DocumentMetadataTool(this._docManager),
createLinks: new CreateLinksTool(this._docManager),
+ codebaseSummarySearch: new CodebaseSummarySearchTool(this.vectorstore),
+ fileContent: new FileContentTool(this.vectorstore),
+ fileNames: new FileNamesTool(this.vectorstore),
};
}
diff --git a/src/client/views/nodes/chatbot/tools/CodebaseSummarySearchTool.ts b/src/client/views/nodes/chatbot/tools/CodebaseSummarySearchTool.ts
new file mode 100644
index 000000000..5fdc52375
--- /dev/null
+++ b/src/client/views/nodes/chatbot/tools/CodebaseSummarySearchTool.ts
@@ -0,0 +1,75 @@
+import { Observation } from '../types/types';
+import { ParametersType, ToolInfo } from '../types/tool_types';
+import { Vectorstore } from '../vectorstore/Vectorstore';
+import { BaseTool } from './BaseTool';
+
+const codebaseSummarySearchToolParams = [
+ {
+ name: 'query',
+ type: 'string[]',
+ description: 'HIGHLY detailed (MANY SENTENCES) descriptions of the code files you want to find in the codebase.',
+ required: true,
+ },
+ {
+ name: 'top_k',
+ type: 'number',
+ description: 'Number of top matching files to return. Default is 5.',
+ required: false,
+ },
+] as const;
+
+type CodebaseSummarySearchToolParamsType = typeof codebaseSummarySearchToolParams;
+
+const codebaseSummarySearchToolInfo: ToolInfo<CodebaseSummarySearchToolParamsType> = {
+ name: 'codebaseSummarySearch',
+ description: 'Searches the Dash codebase for files that match a semantic query. Returns a list of the most relevant files with their summaries to help understand the codebase structure.',
+ citationRules: `When using the CodebaseSummarySearchTool:
+1. Present results clearly, showing filepaths and their summaries
+2. Use the file summaries to provide context about the codebase organization
+3. The results can be used to identify relevant files for deeper inspection`,
+ parameterRules: codebaseSummarySearchToolParams,
+};
+
+export class CodebaseSummarySearchTool extends BaseTool<CodebaseSummarySearchToolParamsType> {
+ constructor(private vectorstore: Vectorstore) {
+ super(codebaseSummarySearchToolInfo);
+ }
+
+ async execute(args: ParametersType<CodebaseSummarySearchToolParamsType>): Promise<Observation[]> {
+ console.log(`Executing codebase summary search with query: "${args.query}"`);
+
+ // Use the vectorstore's searchFileSummaries method
+ const topK = args.top_k || 5;
+ const results: { filepath: string; summary: string; score?: number | undefined }[] = [];
+ for (const query of args.query) {
+ const result = await this.vectorstore.searchFileSummaries(query, topK);
+ results.push(...result);
+ }
+
+ if (results.length === 0) {
+ return [
+ {
+ type: 'text',
+ text: `No files matching the query "${args.query}" were found in the codebase.`,
+ },
+ ];
+ }
+
+ // Format results as observations
+ const formattedResults: Observation[] = [
+ {
+ type: 'text',
+ text: `Found ${results.length} file(s) matching the query "${args.query}":\n\n`,
+ },
+ ];
+
+ results.forEach((result, index) => {
+ formattedResults.push({
+ type: 'text',
+ text: `File #${index + 1}: ${result.filepath}\n` + `Relevance Score: ${result.score?.toFixed(4) || 'N/A'}\n` + `Summary: ${result.summary}\n\n`,
+ });
+ });
+
+ return formattedResults;
+ }
+}
diff --git a/src/client/views/nodes/chatbot/tools/FileContentTool.ts b/src/client/views/nodes/chatbot/tools/FileContentTool.ts
new file mode 100644
index 000000000..f994aab67
--- /dev/null
+++ b/src/client/views/nodes/chatbot/tools/FileContentTool.ts
@@ -0,0 +1,78 @@
+import { Observation } from '../types/types';
+import { ParametersType, ToolInfo } from '../types/tool_types';
+import { Vectorstore } from '../vectorstore/Vectorstore';
+import { BaseTool } from './BaseTool';
+
+const fileContentToolParams = [
+ {
+ name: 'filepaths',
+ type: 'string[]',
+ description: 'Array of file paths to retrieve content for. Limited to a maximum of 3 files.',
+ required: true,
+ },
+] as const;
+
+type FileContentToolParamsType = typeof fileContentToolParams;
+
+const fileContentToolInfo: ToolInfo<FileContentToolParamsType> = {
+ name: 'fileContent',
+ description: 'Retrieves the complete content of up to 3 specified files from the Dash codebase to help understand implementation details.',
+ citationRules: `When using the FileContentTool:
+1. Present file content clearly with proper code formatting
+2. Include the file path at the beginning of each file's content
+3. Use this tool after identifying relevant files with the CodebaseSummarySearchTool
+4. Maximum of 3 files can be retrieved at once`,
+ parameterRules: fileContentToolParams,
+};
+
+export class FileContentTool extends BaseTool<FileContentToolParamsType> {
+ constructor(private vectorstore: Vectorstore) {
+ super(fileContentToolInfo);
+ }
+
+ async execute(args: ParametersType<FileContentToolParamsType>): Promise<Observation[]> {
+ console.log(`Executing file content retrieval for: ${args.filepaths.join(', ')}`);
+
+ // Enforce the limit of 3 files
+ const filepaths = args.filepaths.slice(0, 3);
+ if (args.filepaths.length > 3) {
+ console.warn(`FileContentTool: Request for ${args.filepaths.length} files was limited to 3`);
+ }
+
+ const observations: Observation[] = [];
+
+ if (filepaths.length === 0) {
+ return [
+ {
+ type: 'text',
+ text: 'No filepaths provided. Please specify at least one file path to retrieve content.',
+ },
+ ];
+ }
+
+ // Add initial message
+ observations.push({
+ type: 'text',
+ text: `Retrieving content for ${filepaths.length} file(s):\n\n`,
+ });
+
+ // Fetch content for each file
+ for (const filepath of filepaths) {
+ const content = await this.vectorstore.getFileContent(filepath);
+
+ if (content) {
+ observations.push({
+ type: 'text',
+ text: `File: ${filepath}\n\n\`\`\`\n${content}\n\`\`\`\n\n`,
+ });
+ } else {
+ observations.push({
+ type: 'text',
+ text: `Error: Could not retrieve content for file "${filepath}"\n\n`,
+ });
+ }
+ }
+
+ return observations;
+ }
+}
diff --git a/src/client/views/nodes/chatbot/tools/FileNamesTool.ts b/src/client/views/nodes/chatbot/tools/FileNamesTool.ts
new file mode 100644
index 000000000..b69874afa
--- /dev/null
+++ b/src/client/views/nodes/chatbot/tools/FileNamesTool.ts
@@ -0,0 +1,34 @@
+import { Observation } from '../types/types';
+import { ParametersType, ToolInfo } from '../types/tool_types';
+import { Vectorstore } from '../vectorstore/Vectorstore';
+import { BaseTool } from './BaseTool';
+
+const fileNamesToolParams = [] as const;
+
+type FileNamesToolParamsType = typeof fileNamesToolParams;
+
+const fileNamesToolInfo: ToolInfo<FileNamesToolParamsType> = {
+ name: 'fileNames',
+ description: 'Retrieves the names of all files in the Dash codebase to help understand the codebase structure.',
+ citationRules: `No citation needed.`,
+ parameterRules: fileNamesToolParams,
+};
+
+export class FileNamesTool extends BaseTool<FileNamesToolParamsType> {
+ constructor(private vectorstore: Vectorstore) {
+ super(fileNamesToolInfo);
+ }
+
+ async execute(args: ParametersType<FileNamesToolParamsType>): Promise<Observation[]> {
+ console.log(`Executing file names retrieval`);
+
+ const filepaths = await this.vectorstore.getFileNames();
+
+ return [
+ {
+ type: 'text',
+ text: `The file names in the codebase are: ${filepaths}`,
+ },
+ ];
+ }
+}
diff --git a/src/client/views/nodes/chatbot/vectorstore/Vectorstore.ts b/src/client/views/nodes/chatbot/vectorstore/Vectorstore.ts
index 5c2d0e5ea..72060973b 100644
--- a/src/client/views/nodes/chatbot/vectorstore/Vectorstore.ts
+++ b/src/client/views/nodes/chatbot/vectorstore/Vectorstore.ts
@@ -85,6 +85,12 @@ export class Vectorstore {
}
}
+ async getFileNames() {
+ const response = await Networking.FetchFromServer('/getFileNames');
+ const filepaths = JSON.parse(response);
+ return filepaths;
+ }
+
/**
* Initializes the Pinecone index by checking if it exists and creating it if necessary.
* Sets the index to use cosine similarity for vector similarity calculations.
diff --git a/src/server/ApiManagers/AssistantManager.ts b/src/server/ApiManagers/AssistantManager.ts
index 9d0427b52..c7c347c71 100644
--- a/src/server/ApiManagers/AssistantManager.ts
+++ b/src/server/ApiManagers/AssistantManager.ts
@@ -118,6 +118,19 @@ export default class AssistantManager extends ApiManager {
},
});
+ // Register an endpoint to retrieve file names from the file_summaries.json file
+ register({
+ method: Method.GET,
+ subscription: '/getFileNames',
+ secureHandler: async ({ res }) => {
+ const filePath = path.join(filesDirectory, Directory.vectorstore, 'file_summaries.json');
+ const data = fs.readFileSync(filePath, 'utf8');
+ console.log(Object.keys(JSON.parse(data)));
+
+ res.send(Object.keys(JSON.parse(data)));
+ },
+ });
+
// Register an endpoint to retrieve file content from the content json file
register({
method: Method.POST,