Adding a new parameter for model, and updating the default to 2.5 Flash. (#18)

This commit is contained in:
Evan Senter 2025-04-18 17:06:16 +01:00 committed by GitHub
parent b56d9c8639
commit cb30351403
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 81 additions and 7 deletions

View File

@ -1,8 +1,11 @@
import yargs from 'yargs/yargs'; import yargs from 'yargs/yargs';
import { hideBin } from 'yargs/helpers'; import { hideBin } from 'yargs/helpers';
const DEFAULT_GEMINI_MODEL = 'gemini-2.5-flash-preview-04-17';
export interface CliArgs { export interface CliArgs {
target_dir: string | undefined; target_dir: string | undefined;
model: string | undefined;
_: (string | number)[]; // Captures positional arguments _: (string | number)[]; // Captures positional arguments
// Add other expected args here if needed // Add other expected args here if needed
// e.g., verbose?: boolean; // e.g., verbose?: boolean;
@ -16,6 +19,12 @@ export async function parseArguments(): Promise<CliArgs> {
description: description:
'The target directory for Gemini operations. Defaults to the current working directory.', 'The target directory for Gemini operations. Defaults to the current working directory.',
}) })
.option('model', {
alias: 'm',
type: 'string',
description: `The Gemini model to use. Defaults to ${DEFAULT_GEMINI_MODEL}.`,
default: DEFAULT_GEMINI_MODEL,
})
.help() .help()
.alias('h', 'help') .alias('h', 'help')
.strict() // Keep strict mode to error on unknown options .strict() // Keep strict mode to error on unknown options

View File

@ -0,0 +1,50 @@
import { CliArgs } from './args.js'; // Assuming CliArgs contains the needed fields
interface GlobalConfig {
model: string;
// Add other global config values here if needed
// e.g., targetDir?: string;
}
let config: GlobalConfig | null = null;
/**
* Initializes the global configuration. Should only be called once at application startup.
* @param args The parsed command-line arguments.
*/
export function initializeConfig(args: Pick<CliArgs, 'model'>): void {
if (config) {
console.warn('Global configuration already initialized.');
return;
}
if (!args.model) {
// This shouldn't happen if default is set correctly in args.ts
throw new Error('Model not provided during config initialization.');
}
config = {
model: args.model,
// Initialize other config values from args here
};
}
/**
* Retrieves the globally stored configuration.
* Throws an error if the configuration has not been initialized.
* @returns The global configuration object.
*/
export function getConfig(): GlobalConfig {
if (!config) {
throw new Error(
'Global configuration accessed before initialization. Call initializeConfig() first.',
);
}
return config;
}
/**
* Helper function to get the configured Gemini model name.
* @returns The model name string.
*/
export function getModel(): string {
return getConfig().model;
}

View File

@ -9,6 +9,7 @@ import {
Content, Content,
} from '@google/genai'; } from '@google/genai';
import { getApiKey } from '../config/env.js'; import { getApiKey } from '../config/env.js';
import { getModel } from '../config/globalConfig.js';
import { CoreSystemPrompt } from './prompts.js'; import { CoreSystemPrompt } from './prompts.js';
import { import {
type ToolCallEvent, type ToolCallEvent,
@ -45,6 +46,7 @@ export class GeminiClient {
public async startChat(): Promise<Chat> { public async startChat(): Promise<Chat> {
const tools = toolRegistry.getToolSchemas(); const tools = toolRegistry.getToolSchemas();
const model = getModel();
// --- Get environmental information --- // --- Get environmental information ---
const cwd = process.cwd(); const cwd = process.cwd();
@ -73,7 +75,7 @@ ${folderStructure}
try { try {
const chat = this.ai.chats.create({ const chat = this.ai.chats.create({
model: 'gemini-2.0-flash', //'gemini-2.0-flash', model: model,
config: { config: {
systemInstruction: CoreSystemPrompt, systemInstruction: CoreSystemPrompt,
...this.defaultHyperParameters, ...this.defaultHyperParameters,
@ -446,9 +448,10 @@ Respond *only* in JSON format according to the following schema. Do not include
contents: Content[], contents: Content[],
schema: SchemaUnion, schema: SchemaUnion,
): Promise<any> { ): Promise<any> {
const model = getModel();
try { try {
const result = await this.ai.models.generateContent({ const result = await this.ai.models.generateContent({
model: 'gemini-2.0-flash', // Using flash for potentially faster structured output model: model,
config: { config: {
...this.defaultHyperParameters, ...this.defaultHyperParameters,
systemInstruction: CoreSystemPrompt, systemInstruction: CoreSystemPrompt,

View File

@ -3,6 +3,7 @@ import { render } from 'ink';
import App from './ui/App.js'; import App from './ui/App.js';
import { parseArguments } from './config/args.js'; import { parseArguments } from './config/args.js';
import { loadEnvironment } from './config/env.js'; import { loadEnvironment } from './config/env.js';
import { initializeConfig } from './config/globalConfig.js';
import { getTargetDirectory } from './utils/paths.js'; import { getTargetDirectory } from './utils/paths.js';
import { toolRegistry } from './tools/tool-registry.js'; import { toolRegistry } from './tools/tool-registry.js';
import { LSTool } from './tools/ls.tool.js'; import { LSTool } from './tools/ls.tool.js';
@ -16,14 +17,19 @@ import { WriteFileTool } from './tools/write-file.tool.js';
async function main() { async function main() {
// 1. Configuration // 1. Configuration
loadEnvironment(); loadEnvironment();
const argv = await parseArguments(); // Ensure args.ts imports printWarning from ui/display const argv = await parseArguments();
initializeConfig({ model: argv.model as string });
const targetDir = getTargetDirectory(argv.target_dir); const targetDir = getTargetDirectory(argv.target_dir);
// 2. Configure tools // 2. Configure tools
registerTools(targetDir); registerTools(targetDir);
// 3. Render UI // 3. Render UI
render(React.createElement(App, { directory: targetDir })); render(
React.createElement(App, {
directory: targetDir,
}),
);
} }
// --- Global Unhandled Rejection Handler --- // --- Global Unhandled Rejection Handler ---

View File

@ -142,7 +142,10 @@ export class TerminalTool extends BaseTool<
private rejectShellReady: ((reason?: any) => void) | undefined; // Definite assignment assertion private rejectShellReady: ((reason?: any) => void) | undefined; // Definite assignment assertion
private readonly backgroundTerminalAnalyzer: BackgroundTerminalAnalyzer; private readonly backgroundTerminalAnalyzer: BackgroundTerminalAnalyzer;
constructor(rootDirectory: string, outputLimit: number = MAX_OUTPUT_LENGTH) { constructor(
rootDirectory: string,
outputLimit: number = MAX_OUTPUT_LENGTH,
) {
const toolDisplayName = 'Terminal'; const toolDisplayName = 'Terminal';
// --- LLM-Facing Description --- // --- LLM-Facing Description ---
// Updated description for background tasks to mention polling and LLM analysis // Updated description for background tasks to mention polling and LLM analysis

View File

@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import { Box, Text } from 'ink'; import { Box, Text } from 'ink';
import TextInput from 'ink-text-input'; import TextInput from 'ink-text-input';
import { getModel } from '../../config/globalConfig.js';
interface InputPromptProps { interface InputPromptProps {
query: string; query: string;
@ -14,6 +15,8 @@ const InputPrompt: React.FC<InputPromptProps> = ({
setQuery, setQuery,
onSubmit, onSubmit,
}) => { }) => {
const model = getModel();
return ( return (
<Box marginTop={1} borderStyle="round" borderColor={'white'} paddingX={1}> <Box marginTop={1} borderStyle="round" borderColor={'white'} paddingX={1}>
<Text color={'white'}>&gt; </Text> <Text color={'white'}>&gt; </Text>
@ -24,7 +27,7 @@ const InputPrompt: React.FC<InputPromptProps> = ({
onSubmit={onSubmit} onSubmit={onSubmit}
showCursor={true} showCursor={true}
focus={true} focus={true}
placeholder={'Ask Gemini... (try "/init" or "/help")'} placeholder={`Ask Gemini (${model})... (try "/init" or "/help")`}
/> />
</Box> </Box>
</Box> </Box>

View File

@ -60,7 +60,7 @@ export class BackgroundTerminalAnalyzer {
initialDelayMs?: number; initialDelayMs?: number;
} = {}, // Provide default options } = {}, // Provide default options
) { ) {
this.ai = aiClient || new GeminiClient(); // Use injected client or default this.ai = aiClient || new GeminiClient(); // Call constructor without model
this.pollIntervalMs = options.pollIntervalMs ?? 5000; // Default 5 seconds this.pollIntervalMs = options.pollIntervalMs ?? 5000; // Default 5 seconds
this.maxAttempts = options.maxAttempts ?? 6; // Default 6 attempts (approx 30s total) this.maxAttempts = options.maxAttempts ?? 6; // Default 6 attempts (approx 30s total)
this.initialDelayMs = options.initialDelayMs ?? 500; // Default 0.5s initial delay this.initialDelayMs = options.initialDelayMs ?? 500; // Default 0.5s initial delay