mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-08-03 13:41:05 -07:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 45df40c513 | |||
| 7bcb1280ad | |||
| a39866a7cd |
@@ -104,6 +104,11 @@ export class AgentRegistry {
|
|||||||
private async loadAgents(): Promise<void> {
|
private async loadAgents(): Promise<void> {
|
||||||
this.agents.clear();
|
this.agents.clear();
|
||||||
this.allDefinitions.clear();
|
this.allDefinitions.clear();
|
||||||
|
|
||||||
|
if (this.config.isThinHarness()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.loadBuiltInAgents();
|
this.loadBuiltInAgents();
|
||||||
|
|
||||||
if (!this.config.isAgentsEnabled()) {
|
if (!this.config.isAgentsEnabled()) {
|
||||||
@@ -240,6 +245,10 @@ export class AgentRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private loadBuiltInAgents(): void {
|
private loadBuiltInAgents(): void {
|
||||||
|
if (this.config.isThinHarness()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.registerLocalAgent(CodebaseInvestigatorAgent(this.config));
|
this.registerLocalAgent(CodebaseInvestigatorAgent(this.config));
|
||||||
this.registerLocalAgent(CliHelpAgent(this.config));
|
this.registerLocalAgent(CliHelpAgent(this.config));
|
||||||
this.registerLocalAgent(GeneralistAgent(this.config));
|
this.registerLocalAgent(GeneralistAgent(this.config));
|
||||||
|
|||||||
@@ -633,6 +633,7 @@ export interface ConfigParameters {
|
|||||||
tracker?: boolean;
|
tracker?: boolean;
|
||||||
planSettings?: PlanSettings;
|
planSettings?: PlanSettings;
|
||||||
modelSteering?: boolean;
|
modelSteering?: boolean;
|
||||||
|
thinHarness?: boolean;
|
||||||
onModelChange?: (model: string) => void;
|
onModelChange?: (model: string) => void;
|
||||||
mcpEnabled?: boolean;
|
mcpEnabled?: boolean;
|
||||||
extensionsEnabled?: boolean;
|
extensionsEnabled?: boolean;
|
||||||
@@ -853,6 +854,7 @@ export class Config implements McpContext, AgentLoopContext {
|
|||||||
private readonly planEnabled: boolean;
|
private readonly planEnabled: boolean;
|
||||||
private readonly trackerEnabled: boolean;
|
private readonly trackerEnabled: boolean;
|
||||||
private readonly planModeRoutingEnabled: boolean;
|
private readonly planModeRoutingEnabled: boolean;
|
||||||
|
private readonly thinHarness: boolean;
|
||||||
private readonly modelSteering: boolean;
|
private readonly modelSteering: boolean;
|
||||||
private contextManager?: ContextManager;
|
private contextManager?: ContextManager;
|
||||||
private terminalBackground: string | undefined = undefined;
|
private terminalBackground: string | undefined = undefined;
|
||||||
@@ -996,6 +998,8 @@ export class Config implements McpContext, AgentLoopContext {
|
|||||||
modelConfigServiceConfig ?? DEFAULT_MODEL_CONFIGS,
|
modelConfigServiceConfig ?? DEFAULT_MODEL_CONFIGS,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.thinHarness =
|
||||||
|
params.thinHarness ?? process.env['GEMINI_THIN_HARNESS'] !== 'false';
|
||||||
this.experimentalJitContext = params.experimentalJitContext ?? true;
|
this.experimentalJitContext = params.experimentalJitContext ?? true;
|
||||||
this.topicUpdateNarration = params.topicUpdateNarration ?? false;
|
this.topicUpdateNarration = params.topicUpdateNarration ?? false;
|
||||||
this.modelSteering = params.modelSteering ?? false;
|
this.modelSteering = params.modelSteering ?? false;
|
||||||
@@ -1236,30 +1240,35 @@ export class Config implements McpContext, AgentLoopContext {
|
|||||||
|
|
||||||
this._toolRegistry = await this.createToolRegistry();
|
this._toolRegistry = await this.createToolRegistry();
|
||||||
discoverToolsHandle?.end();
|
discoverToolsHandle?.end();
|
||||||
this.mcpClientManager = new McpClientManager(
|
|
||||||
this.clientVersion,
|
if (this.thinHarness) {
|
||||||
this._toolRegistry,
|
this.mcpInitializationPromise = Promise.resolve();
|
||||||
this,
|
} else {
|
||||||
this.eventEmitter,
|
this.mcpClientManager = new McpClientManager(
|
||||||
);
|
this.clientVersion,
|
||||||
// We do not await this promise so that the CLI can start up even if
|
this._toolRegistry,
|
||||||
// MCP servers are slow to connect.
|
this,
|
||||||
this.mcpInitializationPromise = Promise.allSettled([
|
this.eventEmitter,
|
||||||
this.mcpClientManager.startConfiguredMcpServers(),
|
);
|
||||||
this.getExtensionLoader().start(this),
|
// We do not await this promise so that the CLI can start up even if
|
||||||
]).then((results) => {
|
// MCP servers are slow to connect.
|
||||||
for (const result of results) {
|
this.mcpInitializationPromise = Promise.allSettled([
|
||||||
if (result.status === 'rejected') {
|
this.mcpClientManager.startConfiguredMcpServers(),
|
||||||
debugLogger.error('Error initializing MCP clients:', result.reason);
|
this.getExtensionLoader().start(this),
|
||||||
|
]).then((results) => {
|
||||||
|
for (const result of results) {
|
||||||
|
if (result.status === 'rejected') {
|
||||||
|
debugLogger.error('Error initializing MCP clients:', result.reason);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
if (!this.interactive || this.acpMode) {
|
if (!this.interactive || this.acpMode) {
|
||||||
await this.mcpInitializationPromise;
|
await this.mcpInitializationPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.skillsSupport) {
|
if (this.skillsSupport && !this.thinHarness) {
|
||||||
this.getSkillManager().setAdminSettings(this.adminSkillsEnabled);
|
this.getSkillManager().setAdminSettings(this.adminSkillsEnabled);
|
||||||
if (this.adminSkillsEnabled) {
|
if (this.adminSkillsEnabled) {
|
||||||
await this.getSkillManager().discoverSkills(
|
await this.getSkillManager().discoverSkills(
|
||||||
@@ -2024,6 +2033,10 @@ export class Config implements McpContext, AgentLoopContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getUserMemory(): string | HierarchicalMemory {
|
getUserMemory(): string | HierarchicalMemory {
|
||||||
|
if (this.thinHarness) {
|
||||||
|
return { global: '', extension: '', project: '' };
|
||||||
|
}
|
||||||
|
|
||||||
if (this.experimentalJitContext && this.contextManager) {
|
if (this.experimentalJitContext && this.contextManager) {
|
||||||
return {
|
return {
|
||||||
global: this.contextManager.getGlobalMemory(),
|
global: this.contextManager.getGlobalMemory(),
|
||||||
@@ -2120,6 +2133,9 @@ export class Config implements McpContext, AgentLoopContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getGeminiMdFileCount(): number {
|
getGeminiMdFileCount(): number {
|
||||||
|
if (this.thinHarness) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (this.experimentalJitContext && this.contextManager) {
|
if (this.experimentalJitContext && this.contextManager) {
|
||||||
return this.contextManager.getLoadedPaths().size;
|
return this.contextManager.getLoadedPaths().size;
|
||||||
}
|
}
|
||||||
@@ -2131,6 +2147,9 @@ export class Config implements McpContext, AgentLoopContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getGeminiMdFilePaths(): string[] {
|
getGeminiMdFilePaths(): string[] {
|
||||||
|
if (this.thinHarness) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
if (this.experimentalJitContext && this.contextManager) {
|
if (this.experimentalJitContext && this.contextManager) {
|
||||||
return Array.from(this.contextManager.getLoadedPaths());
|
return Array.from(this.contextManager.getLoadedPaths());
|
||||||
}
|
}
|
||||||
@@ -2493,7 +2512,7 @@ export class Config implements McpContext, AgentLoopContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isAgentsEnabled(): boolean {
|
isAgentsEnabled(): boolean {
|
||||||
return this.enableAgents;
|
return this.enableAgents && !this.thinHarness;
|
||||||
}
|
}
|
||||||
|
|
||||||
isEventDrivenSchedulerEnabled(): boolean {
|
isEventDrivenSchedulerEnabled(): boolean {
|
||||||
@@ -2786,14 +2805,14 @@ export class Config implements McpContext, AgentLoopContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isSkillsSupportEnabled(): boolean {
|
isSkillsSupportEnabled(): boolean {
|
||||||
return this.skillsSupport;
|
return this.skillsSupport && !this.thinHarness;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reloads skills by re-discovering them from extensions and local directories.
|
* Reloads skills by re-discovering them from extensions and local directories.
|
||||||
*/
|
*/
|
||||||
async reloadSkills(): Promise<void> {
|
async reloadSkills(): Promise<void> {
|
||||||
if (!this.skillsSupport) {
|
if (!this.skillsSupport || this.thinHarness) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2843,6 +2862,10 @@ export class Config implements McpContext, AgentLoopContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isThinHarness(): boolean {
|
||||||
|
return this.thinHarness;
|
||||||
|
}
|
||||||
|
|
||||||
isInteractive(): boolean {
|
isInteractive(): boolean {
|
||||||
return this.interactive;
|
return this.interactive;
|
||||||
}
|
}
|
||||||
@@ -3041,6 +3064,25 @@ export class Config implements McpContext, AgentLoopContext {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.thinHarness) {
|
||||||
|
const allowedTools = [
|
||||||
|
'LSTool',
|
||||||
|
'ReadFileTool',
|
||||||
|
'RipGrepTool',
|
||||||
|
'GrepTool',
|
||||||
|
'GlobTool',
|
||||||
|
'EditTool',
|
||||||
|
'WriteFileTool',
|
||||||
|
'WebFetchTool',
|
||||||
|
'ShellTool',
|
||||||
|
'WebSearchTool',
|
||||||
|
'AskUserTool',
|
||||||
|
];
|
||||||
|
if (!allowedTools.includes(normalizedClassName)) {
|
||||||
|
isEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isEnabled) {
|
if (isEnabled) {
|
||||||
registerFn();
|
registerFn();
|
||||||
}
|
}
|
||||||
@@ -3144,7 +3186,9 @@ export class Config implements McpContext, AgentLoopContext {
|
|||||||
// Register Subagents as Tools
|
// Register Subagents as Tools
|
||||||
this.registerSubAgentTools(registry);
|
this.registerSubAgentTools(registry);
|
||||||
|
|
||||||
await registry.discoverAllTools();
|
if (!this.thinHarness) {
|
||||||
|
await registry.discoverAllTools();
|
||||||
|
}
|
||||||
registry.sortTools();
|
registry.sortTools();
|
||||||
return registry;
|
return registry;
|
||||||
}
|
}
|
||||||
@@ -3153,6 +3197,10 @@ export class Config implements McpContext, AgentLoopContext {
|
|||||||
* Registers SubAgentTools for all available agents.
|
* Registers SubAgentTools for all available agents.
|
||||||
*/
|
*/
|
||||||
private registerSubAgentTools(registry: ToolRegistry): void {
|
private registerSubAgentTools(registry: ToolRegistry): void {
|
||||||
|
if (this.thinHarness) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const agentsOverrides = this.getAgentsSettings().overrides ?? {};
|
const agentsOverrides = this.getAgentsSettings().overrides ?? {};
|
||||||
const definitions = this.agentRegistry.getAllDefinitions();
|
const definitions = this.agentRegistry.getAllDefinitions();
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ export class PromptProvider {
|
|||||||
userMemory?: string | HierarchicalMemory,
|
userMemory?: string | HierarchicalMemory,
|
||||||
interactiveOverride?: boolean,
|
interactiveOverride?: boolean,
|
||||||
): string {
|
): string {
|
||||||
|
const config = context.config;
|
||||||
|
if (config.isThinHarness()) {
|
||||||
|
return 'You are Gemini CLI, a helpful assistant specializing in software engineering tasks.';
|
||||||
|
}
|
||||||
|
|
||||||
const systemMdResolution = resolvePathFromEnv(
|
const systemMdResolution = resolvePathFromEnv(
|
||||||
process.env['GEMINI_SYSTEM_MD'],
|
process.env['GEMINI_SYSTEM_MD'],
|
||||||
);
|
);
|
||||||
@@ -216,11 +221,13 @@ export class PromptProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- Finalization (Shell) ---
|
// --- Finalization (Shell) ---
|
||||||
const finalPrompt = activeSnippets.renderFinalShell(
|
const finalPrompt = context.config.isThinHarness()
|
||||||
basePrompt,
|
? basePrompt
|
||||||
userMemory,
|
: activeSnippets.renderFinalShell(
|
||||||
contextFilenames,
|
basePrompt,
|
||||||
);
|
userMemory,
|
||||||
|
contextFilenames,
|
||||||
|
);
|
||||||
|
|
||||||
// Sanitize erratic newlines from composition
|
// Sanitize erratic newlines from composition
|
||||||
const sanitizedPrompt = finalPrompt.replace(/\n{3,}/g, '\n\n');
|
const sanitizedPrompt = finalPrompt.replace(/\n{3,}/g, '\n\n');
|
||||||
|
|||||||
@@ -699,6 +699,18 @@ export async function loadServerHierarchicalMemory(
|
|||||||
* Returns the result of the call to `loadHierarchicalGeminiMemory`.
|
* Returns the result of the call to `loadHierarchicalGeminiMemory`.
|
||||||
*/
|
*/
|
||||||
export async function refreshServerHierarchicalMemory(config: Config) {
|
export async function refreshServerHierarchicalMemory(config: Config) {
|
||||||
|
if (config.isThinHarness()) {
|
||||||
|
const emptyResult: LoadServerHierarchicalMemoryResponse = {
|
||||||
|
memoryContent: { global: '', extension: '', project: '' },
|
||||||
|
fileCount: 0,
|
||||||
|
filePaths: [],
|
||||||
|
};
|
||||||
|
config.setUserMemory(emptyResult.memoryContent);
|
||||||
|
config.setGeminiMdFileCount(0);
|
||||||
|
config.setGeminiMdFilePaths([]);
|
||||||
|
return emptyResult;
|
||||||
|
}
|
||||||
|
|
||||||
const result = await loadServerHierarchicalMemory(
|
const result = await loadServerHierarchicalMemory(
|
||||||
config.getWorkingDir(),
|
config.getWorkingDir(),
|
||||||
config.shouldLoadMemoryFromIncludeDirectories()
|
config.shouldLoadMemoryFromIncludeDirectories()
|
||||||
|
|||||||
Reference in New Issue
Block a user