summaryrefslogtreecommitdiff
path: root/packages/core/src/utils/environmentContext.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/core/src/utils/environmentContext.ts')
-rw-r--r--packages/core/src/utils/environmentContext.ts109
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;
+}