mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-13 15:40:57 -07:00
170 lines
4.4 KiB
TypeScript
170 lines
4.4 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import * as fs from 'node:fs';
|
|
import * as path from 'node:path';
|
|
import { CoderAgentEvent, type AgentSettings } from '../types.js';
|
|
import { performInit } from '@google/gemini-cli-core';
|
|
import type {
|
|
Command,
|
|
CommandContext,
|
|
CommandExecutionResponse,
|
|
} from './types.js';
|
|
import type { CoderAgentExecutor } from '../agent/executor.js';
|
|
import type {
|
|
ExecutionEventBus,
|
|
RequestContext,
|
|
AgentExecutionEvent,
|
|
} from '@a2a-js/sdk/server';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
import { logger } from '../utils/logger.js';
|
|
|
|
export class InitCommand implements Command {
|
|
name = 'init';
|
|
description = 'Analyzes the project and creates a tailored GEMINI.md file';
|
|
requiresWorkspace = true;
|
|
streaming = true;
|
|
|
|
private handleMessageResult(
|
|
result: { content: string; messageType: 'info' | 'error' },
|
|
context: CommandContext,
|
|
eventBus: ExecutionEventBus,
|
|
taskId: string,
|
|
contextId: string,
|
|
): CommandExecutionResponse {
|
|
const statusState = result.messageType === 'error' ? 'failed' : 'completed';
|
|
const eventType =
|
|
result.messageType === 'error'
|
|
? CoderAgentEvent.StateChangeEvent
|
|
: CoderAgentEvent.TextContentEvent;
|
|
|
|
const event: AgentExecutionEvent = {
|
|
kind: 'status-update',
|
|
taskId,
|
|
contextId,
|
|
status: {
|
|
state: statusState,
|
|
message: {
|
|
kind: 'message',
|
|
role: 'agent',
|
|
parts: [{ kind: 'text', text: result.content }],
|
|
messageId: uuidv4(),
|
|
taskId,
|
|
contextId,
|
|
},
|
|
timestamp: new Date().toISOString(),
|
|
},
|
|
final: true,
|
|
metadata: {
|
|
coderAgent: { kind: eventType },
|
|
model: context.config.getModel(),
|
|
},
|
|
};
|
|
|
|
logger.info('[EventBus event]: ', event);
|
|
eventBus.publish(event);
|
|
return {
|
|
name: this.name,
|
|
data: result,
|
|
};
|
|
}
|
|
|
|
private async handleSubmitPromptResult(
|
|
result: { content: unknown },
|
|
context: CommandContext,
|
|
geminiMdPath: string,
|
|
eventBus: ExecutionEventBus,
|
|
taskId: string,
|
|
contextId: string,
|
|
): Promise<CommandExecutionResponse> {
|
|
fs.writeFileSync(geminiMdPath, '', 'utf8');
|
|
|
|
if (!context.agentExecutor) {
|
|
throw new Error('Agent executor not found in context.');
|
|
}
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
const agentExecutor = context.agentExecutor as CoderAgentExecutor;
|
|
|
|
const agentSettings: AgentSettings = {
|
|
kind: CoderAgentEvent.StateAgentSettingsEvent,
|
|
workspacePath: process.env['CODER_AGENT_WORKSPACE_PATH']!,
|
|
autoExecute: true,
|
|
};
|
|
|
|
if (typeof result.content !== 'string') {
|
|
throw new Error('Init command content must be a string.');
|
|
}
|
|
const promptText = result.content;
|
|
|
|
const requestContext: RequestContext = {
|
|
userMessage: {
|
|
kind: 'message',
|
|
role: 'user',
|
|
parts: [{ kind: 'text', text: promptText }],
|
|
messageId: uuidv4(),
|
|
taskId,
|
|
contextId,
|
|
metadata: {
|
|
coderAgent: agentSettings,
|
|
},
|
|
},
|
|
taskId,
|
|
contextId,
|
|
};
|
|
|
|
// The executor will handle the entire agentic loop, including
|
|
// creating the task, streaming responses, and handling tools.
|
|
await agentExecutor.execute(requestContext, eventBus);
|
|
return {
|
|
name: this.name,
|
|
data: geminiMdPath,
|
|
};
|
|
}
|
|
|
|
async execute(
|
|
context: CommandContext,
|
|
_args: string[] = [],
|
|
): Promise<CommandExecutionResponse> {
|
|
if (!context.eventBus) {
|
|
return {
|
|
name: this.name,
|
|
data: 'Use executeStream to get streaming results.',
|
|
};
|
|
}
|
|
|
|
const geminiMdPath = path.join(
|
|
process.env['CODER_AGENT_WORKSPACE_PATH']!,
|
|
'GEMINI.md',
|
|
);
|
|
const result = performInit(fs.existsSync(geminiMdPath));
|
|
|
|
const taskId = uuidv4();
|
|
const contextId = uuidv4();
|
|
|
|
switch (result.type) {
|
|
case 'message':
|
|
return this.handleMessageResult(
|
|
result,
|
|
context,
|
|
context.eventBus,
|
|
taskId,
|
|
contextId,
|
|
);
|
|
case 'submit_prompt':
|
|
return this.handleSubmitPromptResult(
|
|
result,
|
|
context,
|
|
geminiMdPath,
|
|
context.eventBus,
|
|
taskId,
|
|
contextId,
|
|
);
|
|
default:
|
|
throw new Error('Unknown result type from performInit');
|
|
}
|
|
}
|
|
}
|