Simple debug mode for CLI side (#66)

* Adds debug mode config flag.

* Wire through debug lines

* Add debug mode logging example

* Run format

* Run format again
This commit is contained in:
Juliette Love 2025-04-20 20:20:40 +01:00 committed by GitHub
parent 99f5ed9ecb
commit a66ad2e2af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 45 additions and 10 deletions

View File

@ -20,6 +20,7 @@ const DEFAULT_GEMINI_MODEL = 'gemini-2.5-flash-preview-04-17';
interface CliArgs { interface CliArgs {
target_dir: string | undefined; target_dir: string | undefined;
model: string | undefined; model: string | undefined;
debug_mode: boolean | undefined;
} }
function parseArguments(): CliArgs { function parseArguments(): CliArgs {
@ -36,6 +37,12 @@ function parseArguments(): CliArgs {
description: `The Gemini model to use. Defaults to ${DEFAULT_GEMINI_MODEL}.`, description: `The Gemini model to use. Defaults to ${DEFAULT_GEMINI_MODEL}.`,
default: DEFAULT_GEMINI_MODEL, default: DEFAULT_GEMINI_MODEL,
}) })
.option('debug_mode', {
alias: 'z',
type: 'boolean',
description: 'Whether to run in debug mode. Defaults to false.',
default: false,
})
.help() .help()
.alias('h', 'help') .alias('h', 'help')
.strict().argv; .strict().argv;
@ -64,6 +71,7 @@ export function loadCliConfig(): Config {
process.env.GEMINI_API_KEY, process.env.GEMINI_API_KEY,
argv.model || DEFAULT_GEMINI_MODEL, argv.model || DEFAULT_GEMINI_MODEL,
argv.target_dir || process.cwd(), argv.target_dir || process.cwd(),
argv.debug_mode || false,
); );
} }

View File

@ -31,11 +31,8 @@ interface AppProps {
export const App = ({ config }: AppProps) => { export const App = ({ config }: AppProps) => {
const [history, setHistory] = useState<HistoryItem[]>([]); const [history, setHistory] = useState<HistoryItem[]>([]);
const [startupWarnings, setStartupWarnings] = useState<string[]>([]); const [startupWarnings, setStartupWarnings] = useState<string[]>([]);
const { streamingState, submitQuery, initError } = useGeminiStream( const { streamingState, submitQuery, initError, debugMessage } =
setHistory, useGeminiStream(setHistory, config.getApiKey(), config.getModel());
config.getApiKey(),
config.getModel(),
);
const { elapsedTime, currentLoadingPhrase } = const { elapsedTime, currentLoadingPhrase } =
useLoadingIndicator(streamingState); useLoadingIndicator(streamingState);
@ -147,7 +144,11 @@ export const App = ({ config }: AppProps) => {
</> </>
)} )}
<Footer queryLength={query.length} /> <Footer
queryLength={query.length}
debugMode={config.getDebugMode()}
debugMessage={debugMessage}
/>
<ITermDetectionWarning /> <ITermDetectionWarning />
</Box> </Box>
); );

View File

@ -10,13 +10,22 @@ import { Colors } from '../colors.js';
interface FooterProps { interface FooterProps {
queryLength: number; queryLength: number;
debugMode: boolean;
debugMessage: string;
} }
export const Footer: React.FC<FooterProps> = ({ queryLength }) => ( export const Footer: React.FC<FooterProps> = ({
queryLength,
debugMode,
debugMessage,
}) => (
<Box marginTop={1} justifyContent="space-between"> <Box marginTop={1} justifyContent="space-between">
<Box minWidth={15}> <Box minWidth={15}>
<Text color={Colors.SubtleComment}> <Text color={Colors.SubtleComment}>
{queryLength === 0 ? '? for shortcuts' : ''} {queryLength === 0 ? '? for shortcuts' : ''}
{debugMode && (
<Text color="red"> {debugMessage || 'Running in debug mode.'}</Text>
)}
</Text> </Text>
</Box> </Box>
<Text color={Colors.AccentBlue}>Gemini</Text> <Text color={Colors.AccentBlue}>Gemini</Text>

View File

@ -49,6 +49,7 @@ export const useGeminiStream = (
const [streamingState, setStreamingState] = useState<StreamingState>( const [streamingState, setStreamingState] = useState<StreamingState>(
StreamingState.Idle, StreamingState.Idle,
); );
const [debugMessage, setDebugMessage] = useState<string>('');
const [initError, setInitError] = useState<string | null>(null); const [initError, setInitError] = useState<string | null>(null);
const abortControllerRef = useRef<AbortController | null>(null); const abortControllerRef = useRef<AbortController | null>(null);
const chatSessionRef = useRef<Chat | null>(null); const chatSessionRef = useRef<Chat | null>(null);
@ -104,6 +105,10 @@ export const useGeminiStream = (
if (streamingState === StreamingState.Responding) return; if (streamingState === StreamingState.Responding) return;
if (typeof query === 'string' && query.trim().length === 0) return; if (typeof query === 'string' && query.trim().length === 0) return;
if (typeof query === 'string') {
setDebugMessage(`User query: ${query}`);
}
const userMessageTimestamp = Date.now(); const userMessageTimestamp = Date.now();
const client = geminiClientRef.current; const client = geminiClientRef.current;
if (!client) { if (!client) {
@ -403,7 +408,7 @@ export const useGeminiStream = (
], ],
); );
return { streamingState, submitQuery, initError }; return { streamingState, submitQuery, initError, debugMessage };
}; };
// Define ServerTool interface here if not importing from server (circular dep issue?) // Define ServerTool interface here if not importing from server (circular dep issue?)

View File

@ -13,11 +13,18 @@ export class Config {
private apiKey: string; private apiKey: string;
private model: string; private model: string;
private targetDir: string; private targetDir: string;
private debugMode: boolean;
constructor(apiKey: string, model: string, targetDir: string) { constructor(
apiKey: string,
model: string,
targetDir: string,
debugMode: boolean,
) {
this.apiKey = apiKey; this.apiKey = apiKey;
this.model = model; this.model = model;
this.targetDir = targetDir; this.targetDir = targetDir;
this.debugMode = debugMode;
} }
getApiKey(): string { getApiKey(): string {
@ -31,6 +38,10 @@ export class Config {
getTargetDir(): string { getTargetDir(): string {
return this.targetDir; return this.targetDir;
} }
getDebugMode(): boolean {
return this.debugMode;
}
} }
function findEnvFile(startDir: string): string | null { function findEnvFile(startDir: string): string | null {
@ -60,6 +71,7 @@ export function createServerConfig(
apiKey: string, apiKey: string,
model: string, model: string,
targetDir: string, targetDir: string,
debugMode: boolean,
): Config { ): Config {
return new Config(apiKey, model, path.resolve(targetDir)); return new Config(apiKey, model, path.resolve(targetDir), debugMode);
} }