mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-06-12 12:26:57 -07:00
feat(core): add CompletionBehavior for background task injection control
Introduce inject/notify/silent completion behaviors that control what happens when a backgrounded execution completes: - inject: full output injected into conversation, auto-dismiss from UI - notify: short pointer message injected (e.g. log file path), auto-dismiss - silent: nothing injected, stays in Ctrl+B until manually dismissed Shell commands use 'notify' (output saved to log file), remote agents will use 'inject' (full output reinjected). Default is 'silent' when no formatInjection callback is provided.
This commit is contained in:
@@ -9,7 +9,12 @@ import type {
|
||||
IndividualToolCallDisplay,
|
||||
} from '../types.js';
|
||||
import { useCallback, useReducer, useRef, useEffect } from 'react';
|
||||
import type { AnsiOutput, Config, GeminiClient } from '@google/gemini-cli-core';
|
||||
import type {
|
||||
AnsiOutput,
|
||||
Config,
|
||||
GeminiClient,
|
||||
CompletionBehavior,
|
||||
} from '@google/gemini-cli-core';
|
||||
import {
|
||||
isBinary,
|
||||
ShellExecutionService,
|
||||
@@ -238,8 +243,19 @@ export const useShellCommandProcessor = (
|
||||
);
|
||||
|
||||
const registerBackgroundTask = useCallback(
|
||||
(pid: number, command: string, initialOutput: string | AnsiOutput) => {
|
||||
dispatch({ type: 'REGISTER_SHELL', pid, command, initialOutput });
|
||||
(
|
||||
pid: number,
|
||||
command: string,
|
||||
initialOutput: string | AnsiOutput,
|
||||
completionBehavior?: CompletionBehavior,
|
||||
) => {
|
||||
dispatch({
|
||||
type: 'REGISTER_SHELL',
|
||||
pid,
|
||||
command,
|
||||
initialOutput,
|
||||
completionBehavior,
|
||||
});
|
||||
|
||||
// Subscribe to exit via ExecutionLifecycleService (works for all execution types)
|
||||
const exitUnsubscribe = ExecutionLifecycleService.onExit(pid, (code) => {
|
||||
@@ -248,8 +264,11 @@ export const useShellCommandProcessor = (
|
||||
pid,
|
||||
update: { status: 'exited', exitCode: code },
|
||||
});
|
||||
// Auto-dismiss completed tasks from the background panel.
|
||||
dispatch({ type: 'DISMISS_SHELL', pid });
|
||||
// Auto-dismiss for inject/notify (output was delivered to conversation).
|
||||
// Silent tasks stay in the UI until manually dismissed.
|
||||
if (completionBehavior !== 'silent') {
|
||||
dispatch({ type: 'DISMISS_SHELL', pid });
|
||||
}
|
||||
const unsub = m.subscriptions.get(pid);
|
||||
if (unsub) {
|
||||
unsub();
|
||||
@@ -304,12 +323,18 @@ export const useShellCommandProcessor = (
|
||||
executionId: number;
|
||||
label: string;
|
||||
output: string;
|
||||
completionBehavior: CompletionBehavior;
|
||||
}) => {
|
||||
// Skip if already registered (e.g. shells register via their own flow)
|
||||
if (m.backgroundedPids.has(info.executionId)) {
|
||||
return;
|
||||
}
|
||||
registerBackgroundTask(info.executionId, info.label, info.output);
|
||||
registerBackgroundTask(
|
||||
info.executionId,
|
||||
info.label,
|
||||
info.output,
|
||||
info.completionBehavior,
|
||||
);
|
||||
};
|
||||
ExecutionLifecycleService.onBackground(listener);
|
||||
return () => {
|
||||
@@ -489,7 +514,12 @@ export const useShellCommandProcessor = (
|
||||
setPendingHistoryItem(null);
|
||||
|
||||
if (result.backgrounded && result.pid) {
|
||||
registerBackgroundTask(result.pid, rawQuery, cumulativeStdout);
|
||||
registerBackgroundTask(
|
||||
result.pid,
|
||||
rawQuery,
|
||||
cumulativeStdout,
|
||||
'notify',
|
||||
);
|
||||
dispatch({ type: 'SET_ACTIVE_PTY', pid: null });
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type { AnsiOutput } from '@google/gemini-cli-core';
|
||||
import type { AnsiOutput, CompletionBehavior } from '@google/gemini-cli-core';
|
||||
|
||||
export interface BackgroundShell {
|
||||
pid: number;
|
||||
@@ -14,6 +14,7 @@ export interface BackgroundShell {
|
||||
binaryBytesReceived: number;
|
||||
status: 'running' | 'exited';
|
||||
exitCode?: number;
|
||||
completionBehavior?: CompletionBehavior;
|
||||
}
|
||||
|
||||
export interface ShellState {
|
||||
@@ -33,6 +34,7 @@ export type ShellAction =
|
||||
pid: number;
|
||||
command: string;
|
||||
initialOutput: string | AnsiOutput;
|
||||
completionBehavior?: CompletionBehavior;
|
||||
}
|
||||
| { type: 'UPDATE_SHELL'; pid: number; update: Partial<BackgroundShell> }
|
||||
| { type: 'APPEND_SHELL_OUTPUT'; pid: number; chunk: string | AnsiOutput }
|
||||
@@ -72,6 +74,7 @@ export function shellReducer(
|
||||
isBinary: false,
|
||||
binaryBytesReceived: 0,
|
||||
status: 'running',
|
||||
completionBehavior: action.completionBehavior,
|
||||
});
|
||||
return { ...state, backgroundShells: nextShells };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user