UNPKG

buroventures-harald-code-core

Version:

Harald Code Core - Core functionality for AI-powered coding assistant

547 lines 18.1 kB
/** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import * as path from 'node:path'; import process from 'node:process'; import { createContentGeneratorConfig, } from '../core/contentGenerator.js'; import { PromptRegistry } from '../prompts/prompt-registry.js'; import { ToolRegistry } from '../tools/tool-registry.js'; import { LSTool } from '../tools/ls.js'; import { ReadFileTool } from '../tools/read-file.js'; import { GrepTool } from '../tools/grep.js'; import { GlobTool } from '../tools/glob.js'; import { EditTool } from '../tools/edit.js'; import { ShellTool } from '../tools/shell.js'; import { WriteFileTool } from '../tools/write-file.js'; import { WebFetchTool } from '../tools/web-fetch.js'; import { ReadManyFilesTool } from '../tools/read-many-files.js'; import { MemoryTool, setGeminiMdFilename, GEMINI_CONFIG_DIR as GEMINI_DIR, } from '../tools/memoryTool.js'; import { WebSearchTool } from '../tools/web-search.js'; import { GeminiClient } from '../core/client.js'; import { FileDiscoveryService } from '../services/fileDiscoveryService.js'; import { GitService } from '../services/gitService.js'; import { getProjectTempDir } from '../utils/paths.js'; import { initializeTelemetry, DEFAULT_TELEMETRY_TARGET, DEFAULT_OTLP_ENDPOINT, StartSessionEvent, } from '../telemetry/index.js'; import { DEFAULT_GEMINI_EMBEDDING_MODEL, DEFAULT_GEMINI_FLASH_MODEL, } from './models.js'; import { ClearcutLogger } from '../telemetry/clearcut-logger/clearcut-logger.js'; import { shouldAttemptBrowserLaunch } from '../utils/browser.js'; import { IdeClient } from '../ide/ide-client.js'; import { WorkspaceContext } from '../utils/workspaceContext.js'; export var ApprovalMode; (function (ApprovalMode) { ApprovalMode["DEFAULT"] = "default"; ApprovalMode["AUTO_EDIT"] = "autoEdit"; ApprovalMode["YOLO"] = "yolo"; })(ApprovalMode || (ApprovalMode = {})); // For memory files export const DEFAULT_MEMORY_FILE_FILTERING_OPTIONS = { respectGitIgnore: false, respectGeminiIgnore: true, }; // For all other files export const DEFAULT_FILE_FILTERING_OPTIONS = { respectGitIgnore: true, respectGeminiIgnore: true, }; export class MCPServerConfig { command; args; env; cwd; url; httpUrl; headers; tcp; timeout; trust; description; includeTools; excludeTools; extensionName; oauth; authProviderType; constructor( // For stdio transport command, args, env, cwd, // For sse transport url, // For streamable http transport httpUrl, headers, // For websocket transport tcp, // Common timeout, trust, // Metadata description, includeTools, excludeTools, extensionName, // OAuth configuration oauth, authProviderType) { this.command = command; this.args = args; this.env = env; this.cwd = cwd; this.url = url; this.httpUrl = httpUrl; this.headers = headers; this.tcp = tcp; this.timeout = timeout; this.trust = trust; this.description = description; this.includeTools = includeTools; this.excludeTools = excludeTools; this.extensionName = extensionName; this.oauth = oauth; this.authProviderType = authProviderType; } } export var AuthProviderType; (function (AuthProviderType) { AuthProviderType["DYNAMIC_DISCOVERY"] = "dynamic_discovery"; AuthProviderType["GOOGLE_CREDENTIALS"] = "google_credentials"; })(AuthProviderType || (AuthProviderType = {})); export class Config { toolRegistry; promptRegistry; sessionId; contentGeneratorConfig; embeddingModel; sandbox; targetDir; workspaceContext; debugMode; question; fullContext; coreTools; excludeTools; toolDiscoveryCommand; toolCallCommand; mcpServerCommand; mcpServers; userMemory; geminiMdFileCount; approvalMode; showMemoryUsage; accessibility; telemetrySettings; usageStatisticsEnabled; geminiClient; fileFiltering; fileDiscoveryService = null; gitService = undefined; checkpointing; proxy; cwd; bugCommand; model; extensionContextFilePaths; noBrowser; ideModeFeature; ideMode; ideClient; inFallbackMode = false; systemPromptMappings; maxSessionTurns; sessionTokenLimit; maxFolderItems; listExtensions; _extensions; _blockedMcpServers; flashFallbackHandler; quotaErrorOccurred = false; summarizeToolOutput; experimentalAcp = false; enableOpenAILogging; sampling_params; contentGenerator; settings; // Settings object for API key rotation constructor(params) { this.sessionId = params.sessionId; this.embeddingModel = params.embeddingModel ?? DEFAULT_GEMINI_EMBEDDING_MODEL; this.sandbox = params.sandbox; this.targetDir = path.resolve(params.targetDir); this.workspaceContext = new WorkspaceContext(this.targetDir, params.includeDirectories ?? []); this.debugMode = params.debugMode; this.question = params.question; this.fullContext = params.fullContext ?? false; this.coreTools = params.coreTools; this.excludeTools = params.excludeTools; this.toolDiscoveryCommand = params.toolDiscoveryCommand; this.toolCallCommand = params.toolCallCommand; this.mcpServerCommand = params.mcpServerCommand; this.mcpServers = params.mcpServers; this.userMemory = params.userMemory ?? ''; this.geminiMdFileCount = params.geminiMdFileCount ?? 0; this.approvalMode = params.approvalMode ?? ApprovalMode.DEFAULT; this.showMemoryUsage = params.showMemoryUsage ?? false; this.accessibility = params.accessibility ?? {}; this.telemetrySettings = { enabled: params.telemetry?.enabled ?? false, target: params.telemetry?.target ?? DEFAULT_TELEMETRY_TARGET, otlpEndpoint: params.telemetry?.otlpEndpoint ?? DEFAULT_OTLP_ENDPOINT, logPrompts: params.telemetry?.logPrompts ?? true, outfile: params.telemetry?.outfile, }; this.usageStatisticsEnabled = params.usageStatisticsEnabled ?? true; this.fileFiltering = { respectGitIgnore: params.fileFiltering?.respectGitIgnore ?? true, respectGeminiIgnore: params.fileFiltering?.respectGeminiIgnore ?? true, enableRecursiveFileSearch: params.fileFiltering?.enableRecursiveFileSearch ?? true, }; this.checkpointing = params.checkpointing ?? false; this.proxy = params.proxy; this.cwd = params.cwd ?? process.cwd(); this.fileDiscoveryService = params.fileDiscoveryService ?? null; this.bugCommand = params.bugCommand; this.model = params.model; this.extensionContextFilePaths = params.extensionContextFilePaths ?? []; this.maxSessionTurns = params.maxSessionTurns ?? -1; this.sessionTokenLimit = params.sessionTokenLimit ?? 32000; this.maxFolderItems = params.maxFolderItems ?? 20; this.experimentalAcp = params.experimentalAcp ?? false; this.listExtensions = params.listExtensions ?? false; this._extensions = params.extensions ?? []; this._blockedMcpServers = params.blockedMcpServers ?? []; this.noBrowser = params.noBrowser ?? false; this.summarizeToolOutput = params.summarizeToolOutput; this.ideModeFeature = params.ideModeFeature ?? false; this.ideMode = params.ideMode ?? false; this.ideClient = params.ideClient ?? IdeClient.getInstance(this.ideMode && this.ideModeFeature); this.systemPromptMappings = params.systemPromptMappings; this.enableOpenAILogging = params.enableOpenAILogging ?? false; this.sampling_params = params.sampling_params; this.contentGenerator = params.contentGenerator; this.settings = params.settings; if (params.contextFileName) { setGeminiMdFilename(params.contextFileName); } if (this.telemetrySettings.enabled) { initializeTelemetry(this); } if (this.getUsageStatisticsEnabled()) { ClearcutLogger.getInstance(this)?.logStartSessionEvent(new StartSessionEvent(this)); } else { console.log('Data collection is disabled.'); } } async initialize() { // Initialize centralized FileDiscoveryService this.getFileService(); if (this.getCheckpointingEnabled()) { await this.getGitService(); } this.promptRegistry = new PromptRegistry(); this.toolRegistry = await this.createToolRegistry(); } async refreshAuth(authMethod) { // Save the current conversation history before creating a new client let existingHistory = []; if (this.geminiClient && this.geminiClient.isInitialized()) { existingHistory = this.geminiClient.getHistory(); } // Create new content generator config const newContentGeneratorConfig = createContentGeneratorConfig(this, authMethod); // Create and initialize new client in local variable first const newGeminiClient = new GeminiClient(this); await newGeminiClient.initialize(newContentGeneratorConfig, this.settings); // Only assign to instance properties after successful initialization this.contentGeneratorConfig = newContentGeneratorConfig; this.geminiClient = newGeminiClient; // Restore the conversation history to the new client if (existingHistory.length > 0) { this.geminiClient.setHistory(existingHistory); } // Reset the session flag since we're explicitly changing auth and using default model this.inFallbackMode = false; } getSessionId() { return this.sessionId; } getContentGeneratorConfig() { return this.contentGeneratorConfig; } getModel() { return this.contentGeneratorConfig?.model || this.model; } setModel(newModel) { if (this.contentGeneratorConfig) { this.contentGeneratorConfig.model = newModel; } } isInFallbackMode() { return this.inFallbackMode; } setFallbackMode(active) { this.inFallbackMode = active; } setFlashFallbackHandler(handler) { this.flashFallbackHandler = handler; } getMaxSessionTurns() { return this.maxSessionTurns; } getSessionTokenLimit() { return this.sessionTokenLimit; } getMaxFolderItems() { return this.maxFolderItems; } setQuotaErrorOccurred(value) { this.quotaErrorOccurred = value; } getQuotaErrorOccurred() { return this.quotaErrorOccurred; } getEmbeddingModel() { return this.embeddingModel; } getSandbox() { return this.sandbox; } isRestrictiveSandbox() { const sandboxConfig = this.getSandbox(); const seatbeltProfile = process.env.SEATBELT_PROFILE; return (!!sandboxConfig && sandboxConfig.command === 'sandbox-exec' && !!seatbeltProfile && seatbeltProfile.startsWith('restrictive-')); } getTargetDir() { return this.targetDir; } getProjectRoot() { return this.targetDir; } getWorkspaceContext() { return this.workspaceContext; } getToolRegistry() { return Promise.resolve(this.toolRegistry); } getPromptRegistry() { return this.promptRegistry; } getDebugMode() { return this.debugMode; } getQuestion() { return this.question; } getFullContext() { return this.fullContext; } getCoreTools() { return this.coreTools; } getExcludeTools() { return this.excludeTools; } getToolDiscoveryCommand() { return this.toolDiscoveryCommand; } getToolCallCommand() { return this.toolCallCommand; } getMcpServerCommand() { return this.mcpServerCommand; } getMcpServers() { return this.mcpServers; } getUserMemory() { return this.userMemory; } setUserMemory(newUserMemory) { this.userMemory = newUserMemory; } getGeminiMdFileCount() { return this.geminiMdFileCount; } setGeminiMdFileCount(count) { this.geminiMdFileCount = count; } getApprovalMode() { return this.approvalMode; } setApprovalMode(mode) { this.approvalMode = mode; } getShowMemoryUsage() { return this.showMemoryUsage; } getAccessibility() { return this.accessibility; } getTelemetryEnabled() { return this.telemetrySettings.enabled ?? false; } getTelemetryLogPromptsEnabled() { return this.telemetrySettings.logPrompts ?? true; } getTelemetryOtlpEndpoint() { return this.telemetrySettings.otlpEndpoint ?? DEFAULT_OTLP_ENDPOINT; } getTelemetryTarget() { return this.telemetrySettings.target ?? DEFAULT_TELEMETRY_TARGET; } getTelemetryOutfile() { return this.telemetrySettings.outfile; } getGeminiClient() { return this.geminiClient; } getGeminiDir() { return path.join(this.targetDir, GEMINI_DIR); } getProjectTempDir() { return getProjectTempDir(this.getProjectRoot()); } getEnableRecursiveFileSearch() { return this.fileFiltering.enableRecursiveFileSearch; } getFileFilteringRespectGitIgnore() { return this.fileFiltering.respectGitIgnore; } getFileFilteringRespectGeminiIgnore() { return this.fileFiltering.respectGeminiIgnore; } getFileFilteringOptions() { return { respectGitIgnore: this.fileFiltering.respectGitIgnore, respectGeminiIgnore: this.fileFiltering.respectGeminiIgnore, }; } getCheckpointingEnabled() { return this.checkpointing; } getProxy() { return this.proxy; } getWorkingDir() { return this.cwd; } getBugCommand() { return this.bugCommand; } getFileService() { if (!this.fileDiscoveryService) { this.fileDiscoveryService = new FileDiscoveryService(this.targetDir); } return this.fileDiscoveryService; } getUsageStatisticsEnabled() { return this.usageStatisticsEnabled; } getExtensionContextFilePaths() { return this.extensionContextFilePaths; } getExperimentalAcp() { return this.experimentalAcp; } getListExtensions() { return this.listExtensions; } getExtensions() { return this._extensions; } getBlockedMcpServers() { return this._blockedMcpServers; } getNoBrowser() { return this.noBrowser; } isBrowserLaunchSuppressed() { return this.getNoBrowser() || !shouldAttemptBrowserLaunch(); } getSummarizeToolOutputConfig() { return this.summarizeToolOutput; } getIdeModeFeature() { return this.ideModeFeature; } getIdeClient() { return this.ideClient; } getIdeMode() { return this.ideMode; } setIdeMode(value) { this.ideMode = value; } setIdeClientDisconnected() { this.ideClient.setDisconnected(); } setIdeClientConnected() { this.ideClient.reconnect(this.ideMode && this.ideModeFeature); } getEnableOpenAILogging() { return this.enableOpenAILogging; } getSamplingParams() { return this.sampling_params; } getContentGeneratorTimeout() { return this.contentGenerator?.timeout; } getContentGeneratorMaxRetries() { return this.contentGenerator?.maxRetries; } getSystemPromptMappings() { return this.systemPromptMappings; } async getGitService() { if (!this.gitService) { this.gitService = new GitService(this.targetDir); await this.gitService.initialize(); } return this.gitService; } async createToolRegistry() { const registry = new ToolRegistry(this); // helper to create & register core tools that are enabled // eslint-disable-next-line @typescript-eslint/no-explicit-any const registerCoreTool = (ToolClass, ...args) => { const className = ToolClass.name; const toolName = ToolClass.Name || className; const coreTools = this.getCoreTools(); const excludeTools = this.getExcludeTools(); let isEnabled = false; if (coreTools === undefined) { isEnabled = true; } else { isEnabled = coreTools.some((tool) => tool === className || tool === toolName || tool.startsWith(`${className}(`) || tool.startsWith(`${toolName}(`)); } if (excludeTools?.includes(className) || excludeTools?.includes(toolName)) { isEnabled = false; } if (isEnabled) { registry.registerTool(new ToolClass(...args)); } }; registerCoreTool(LSTool, this); registerCoreTool(ReadFileTool, this); registerCoreTool(GrepTool, this); registerCoreTool(GlobTool, this); registerCoreTool(EditTool, this); registerCoreTool(WriteFileTool, this); registerCoreTool(WebFetchTool, this); registerCoreTool(ReadManyFilesTool, this); registerCoreTool(ShellTool, this); registerCoreTool(MemoryTool); registerCoreTool(WebSearchTool, this); await registry.discoverAllTools(); return registry; } } // Export model constants for use in CLI export { DEFAULT_GEMINI_FLASH_MODEL }; //# sourceMappingURL=config.js.map