diff options
Diffstat (limited to 'packages/core/src/utils/environmentContext.ts')
| -rw-r--r-- | packages/core/src/utils/environmentContext.ts | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/packages/core/src/utils/environmentContext.ts b/packages/core/src/utils/environmentContext.ts new file mode 100644 index 00000000..79fb6049 --- /dev/null +++ b/packages/core/src/utils/environmentContext.ts @@ -0,0 +1,109 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Part } from '@google/genai'; +import { Config } from '../config/config.js'; +import { getFolderStructure } from './getFolderStructure.js'; + +/** + * Generates a string describing the current workspace directories and their structures. + * @param {Config} config - The runtime configuration and services. + * @returns {Promise<string>} A promise that resolves to the directory context string. + */ +export async function getDirectoryContextString( + config: Config, +): Promise<string> { + const workspaceContext = config.getWorkspaceContext(); + const workspaceDirectories = workspaceContext.getDirectories(); + + const folderStructures = await Promise.all( + workspaceDirectories.map((dir) => + getFolderStructure(dir, { + fileService: config.getFileService(), + }), + ), + ); + + const folderStructure = folderStructures.join('\n'); + + let workingDirPreamble: string; + if (workspaceDirectories.length === 1) { + workingDirPreamble = `I'm currently working in the directory: ${workspaceDirectories[0]}`; + } else { + const dirList = workspaceDirectories.map((dir) => ` - ${dir}`).join('\n'); + workingDirPreamble = `I'm currently working in the following directories:\n${dirList}`; + } + + return `${workingDirPreamble} +Here is the folder structure of the current working directories: + +${folderStructure}`; +} + +/** + * Retrieves environment-related information to be included in the chat context. + * This includes the current working directory, date, operating system, and folder structure. + * Optionally, it can also include the full file context if enabled. + * @param {Config} config - The runtime configuration and services. + * @returns A promise that resolves to an array of `Part` objects containing environment information. + */ +export async function getEnvironmentContext(config: Config): Promise<Part[]> { + const today = new Date().toLocaleDateString(undefined, { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric', + }); + const platform = process.platform; + const directoryContext = await getDirectoryContextString(config); + + const context = ` +This is the Gemini CLI. We are setting up the context for our chat. +Today's date is ${today}. +My operating system is: ${platform} +${directoryContext} + `.trim(); + + const initialParts: Part[] = [{ text: context }]; + const toolRegistry = await config.getToolRegistry(); + + // Add full file context if the flag is set + if (config.getFullContext()) { + try { + const readManyFilesTool = toolRegistry.getTool('read_many_files'); + if (readManyFilesTool) { + const invocation = readManyFilesTool.build({ + paths: ['**/*'], // Read everything recursively + useDefaultExcludes: true, // Use default excludes + }); + + // Read all files in the target directory + const result = await invocation.execute(AbortSignal.timeout(30000)); + if (result.llmContent) { + initialParts.push({ + text: `\n--- Full File Context ---\n${result.llmContent}`, + }); + } else { + console.warn( + 'Full context requested, but read_many_files returned no content.', + ); + } + } else { + console.warn( + 'Full context requested, but read_many_files tool not found.', + ); + } + } catch (error) { + // Not using reportError here as it's a startup/config phase, not a chat/generation phase error. + console.error('Error reading full file context:', error); + initialParts.push({ + text: '\n--- Error reading full file context ---', + }); + } + } + + return initialParts; +} |
