fix: Ensure user written `!` is treated opaquely if not in shell mode\n\n- Addresses an issue where commands prefixed with `!` (e.g., `!ls`) were incorrectly handled by the shell command processor if the `!` was added after initially typing the command.\n- Ensures that such commands are correctly forwarded to the Gemini model.\n- Updates `useGeminiStream` to be aware of shell mode to properly manage streaming state.\n\nFixes https://buganizer.corp.google.com/issues/418761305
This commit is contained in:
parent
a756489f86
commit
323b1298f9
|
@ -145,6 +145,7 @@ export const App = ({
|
||||||
config,
|
config,
|
||||||
setDebugMessage,
|
setDebugMessage,
|
||||||
handleSlashCommand,
|
handleSlashCommand,
|
||||||
|
shellModeActive,
|
||||||
);
|
);
|
||||||
const { elapsedTime, currentLoadingPhrase } =
|
const { elapsedTime, currentLoadingPhrase } =
|
||||||
useLoadingIndicator(streamingState);
|
useLoadingIndicator(streamingState);
|
||||||
|
@ -154,16 +155,10 @@ export const App = ({
|
||||||
(submittedValue: string) => {
|
(submittedValue: string) => {
|
||||||
const trimmedValue = submittedValue.trim();
|
const trimmedValue = submittedValue.trim();
|
||||||
if (trimmedValue.length > 0) {
|
if (trimmedValue.length > 0) {
|
||||||
if (shellModeActive && !trimmedValue.startsWith('!')) {
|
|
||||||
// TODO: Don't prefix (hack) and properly submit pass throughs to a dedicated hook:
|
|
||||||
// https://b.corp.google.com/issues/418509745
|
|
||||||
submitQuery(`!${trimmedValue}`);
|
|
||||||
} else {
|
|
||||||
submitQuery(trimmedValue);
|
submitQuery(trimmedValue);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[submitQuery, shellModeActive],
|
[submitQuery],
|
||||||
);
|
);
|
||||||
|
|
||||||
const userMessages = useMemo(
|
const userMessages = useMemo(
|
||||||
|
|
|
@ -8,7 +8,6 @@ import { exec as _exec } from 'child_process';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { Config } from '@gemini-code/server';
|
import { Config } from '@gemini-code/server';
|
||||||
import { type PartListUnion } from '@google/genai';
|
import { type PartListUnion } from '@google/genai';
|
||||||
import { getCommandFromQuery } from '../utils/commandUtils.js';
|
|
||||||
import { UseHistoryManagerReturn } from './useHistoryManager.js';
|
import { UseHistoryManagerReturn } from './useHistoryManager.js';
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
@ -34,10 +33,6 @@ export const useShellCommandProcessor = (
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [symbol] = getCommandFromQuery(rawQuery);
|
|
||||||
if (symbol !== '!' && symbol !== '$') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
let commandToExecute = rawQuery.trim().slice(1).trimStart();
|
let commandToExecute = rawQuery.trim().slice(1).trimStart();
|
||||||
|
|
||||||
// wrap command to write pwd to temporary file
|
// wrap command to write pwd to temporary file
|
||||||
|
|
|
@ -60,6 +60,7 @@ export const useGeminiStream = (
|
||||||
config: Config,
|
config: Config,
|
||||||
onDebugMessage: (message: string) => void,
|
onDebugMessage: (message: string) => void,
|
||||||
handleSlashCommand: (cmd: PartListUnion) => boolean,
|
handleSlashCommand: (cmd: PartListUnion) => boolean,
|
||||||
|
shellModeActive: boolean,
|
||||||
) => {
|
) => {
|
||||||
const toolRegistry = config.getToolRegistry();
|
const toolRegistry = config.getToolRegistry();
|
||||||
const [initError, setInitError] = useState<string | null>(null);
|
const [initError, setInitError] = useState<string | null>(null);
|
||||||
|
@ -120,7 +121,7 @@ export const useGeminiStream = (
|
||||||
if (handleSlashCommand(trimmedQuery)) {
|
if (handleSlashCommand(trimmedQuery)) {
|
||||||
return { queryToSend: null, shouldProceed: false };
|
return { queryToSend: null, shouldProceed: false };
|
||||||
}
|
}
|
||||||
if (handleShellCommand(trimmedQuery)) {
|
if (shellModeActive && handleShellCommand(trimmedQuery)) {
|
||||||
return { queryToSend: null, shouldProceed: false };
|
return { queryToSend: null, shouldProceed: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,6 +609,7 @@ export const useGeminiStream = (
|
||||||
isResponding,
|
isResponding,
|
||||||
setShowHelp,
|
setShowHelp,
|
||||||
handleSlashCommand,
|
handleSlashCommand,
|
||||||
|
shellModeActive,
|
||||||
handleShellCommand,
|
handleShellCommand,
|
||||||
config,
|
config,
|
||||||
addItem,
|
addItem,
|
||||||
|
|
|
@ -24,20 +24,3 @@ export const isAtCommand = (query: string): boolean =>
|
||||||
* @returns True if the query looks like an '/' command, false otherwise.
|
* @returns True if the query looks like an '/' command, false otherwise.
|
||||||
*/
|
*/
|
||||||
export const isSlashCommand = (query: string): boolean => query.startsWith('/');
|
export const isSlashCommand = (query: string): boolean => query.startsWith('/');
|
||||||
|
|
||||||
const control_symbols: string[] = ['/', '@', '!', '?', '$'];
|
|
||||||
/**
|
|
||||||
* Returns the first word of query with optional leading slash, ampersand, bang.
|
|
||||||
*
|
|
||||||
* @param query The input query string.
|
|
||||||
* @returns optional leading symbol and first word of query
|
|
||||||
*/
|
|
||||||
export const getCommandFromQuery = (
|
|
||||||
query: string,
|
|
||||||
): [string | undefined, string] => {
|
|
||||||
const word = query.trim().split(/\s/, 1)[0];
|
|
||||||
if (word.length > 0 && control_symbols.includes(word[0])) {
|
|
||||||
return [word[0], word.slice(1)];
|
|
||||||
}
|
|
||||||
return [undefined, word];
|
|
||||||
};
|
|
||||||
|
|
Loading…
Reference in New Issue