mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-22 02:54:31 -07:00
Add support for output-format stream-jsonflag for headless mode (#10883)
This commit is contained in:
@@ -8,6 +8,9 @@ import type { Config } from '@google/gemini-cli-core';
|
||||
import {
|
||||
OutputFormat,
|
||||
JsonFormatter,
|
||||
StreamJsonFormatter,
|
||||
JsonStreamEventType,
|
||||
uiTelemetryService,
|
||||
parseAndFormatApiError,
|
||||
FatalTurnLimitedError,
|
||||
FatalCancellationError,
|
||||
@@ -58,6 +61,7 @@ function getNumericExitCode(errorCode: string | number): number {
|
||||
/**
|
||||
* Handles errors consistently for both JSON and text output formats.
|
||||
* In JSON mode, outputs formatted JSON error and exits.
|
||||
* In streaming JSON mode, emits a result event with error status.
|
||||
* In text mode, outputs error message and re-throws.
|
||||
*/
|
||||
export function handleError(
|
||||
@@ -70,7 +74,24 @@ export function handleError(
|
||||
config.getContentGeneratorConfig()?.authType,
|
||||
);
|
||||
|
||||
if (config.getOutputFormat() === OutputFormat.JSON) {
|
||||
if (config.getOutputFormat() === OutputFormat.STREAM_JSON) {
|
||||
const streamFormatter = new StreamJsonFormatter();
|
||||
const errorCode = customErrorCode ?? extractErrorCode(error);
|
||||
const metrics = uiTelemetryService.getMetrics();
|
||||
|
||||
streamFormatter.emitEvent({
|
||||
type: JsonStreamEventType.RESULT,
|
||||
timestamp: new Date().toISOString(),
|
||||
status: 'error',
|
||||
error: {
|
||||
type: error instanceof Error ? error.constructor.name : 'Error',
|
||||
message: errorMessage,
|
||||
},
|
||||
stats: streamFormatter.convertToStreamStats(metrics, 0),
|
||||
});
|
||||
|
||||
process.exit(getNumericExitCode(errorCode));
|
||||
} else if (config.getOutputFormat() === OutputFormat.JSON) {
|
||||
const formatter = new JsonFormatter();
|
||||
const errorCode = customErrorCode ?? extractErrorCode(error);
|
||||
|
||||
@@ -110,7 +131,20 @@ export function handleToolError(
|
||||
|
||||
if (isFatal) {
|
||||
const toolExecutionError = new FatalToolExecutionError(errorMessage);
|
||||
if (config.getOutputFormat() === OutputFormat.JSON) {
|
||||
if (config.getOutputFormat() === OutputFormat.STREAM_JSON) {
|
||||
const streamFormatter = new StreamJsonFormatter();
|
||||
const metrics = uiTelemetryService.getMetrics();
|
||||
streamFormatter.emitEvent({
|
||||
type: JsonStreamEventType.RESULT,
|
||||
timestamp: new Date().toISOString(),
|
||||
status: 'error',
|
||||
error: {
|
||||
type: errorType ?? 'FatalToolExecutionError',
|
||||
message: toolExecutionError.message,
|
||||
},
|
||||
stats: streamFormatter.convertToStreamStats(metrics, 0),
|
||||
});
|
||||
} else if (config.getOutputFormat() === OutputFormat.JSON) {
|
||||
const formatter = new JsonFormatter();
|
||||
const formattedError = formatter.formatError(
|
||||
toolExecutionError,
|
||||
@@ -133,7 +167,21 @@ export function handleToolError(
|
||||
export function handleCancellationError(config: Config): never {
|
||||
const cancellationError = new FatalCancellationError('Operation cancelled.');
|
||||
|
||||
if (config.getOutputFormat() === OutputFormat.JSON) {
|
||||
if (config.getOutputFormat() === OutputFormat.STREAM_JSON) {
|
||||
const streamFormatter = new StreamJsonFormatter();
|
||||
const metrics = uiTelemetryService.getMetrics();
|
||||
streamFormatter.emitEvent({
|
||||
type: JsonStreamEventType.RESULT,
|
||||
timestamp: new Date().toISOString(),
|
||||
status: 'error',
|
||||
error: {
|
||||
type: 'FatalCancellationError',
|
||||
message: cancellationError.message,
|
||||
},
|
||||
stats: streamFormatter.convertToStreamStats(metrics, 0),
|
||||
});
|
||||
process.exit(cancellationError.exitCode);
|
||||
} else if (config.getOutputFormat() === OutputFormat.JSON) {
|
||||
const formatter = new JsonFormatter();
|
||||
const formattedError = formatter.formatError(
|
||||
cancellationError,
|
||||
@@ -156,7 +204,21 @@ export function handleMaxTurnsExceededError(config: Config): never {
|
||||
'Reached max session turns for this session. Increase the number of turns by specifying maxSessionTurns in settings.json.',
|
||||
);
|
||||
|
||||
if (config.getOutputFormat() === OutputFormat.JSON) {
|
||||
if (config.getOutputFormat() === OutputFormat.STREAM_JSON) {
|
||||
const streamFormatter = new StreamJsonFormatter();
|
||||
const metrics = uiTelemetryService.getMetrics();
|
||||
streamFormatter.emitEvent({
|
||||
type: JsonStreamEventType.RESULT,
|
||||
timestamp: new Date().toISOString(),
|
||||
status: 'error',
|
||||
error: {
|
||||
type: 'FatalTurnLimitedError',
|
||||
message: maxTurnsError.message,
|
||||
},
|
||||
stats: streamFormatter.convertToStreamStats(metrics, 0),
|
||||
});
|
||||
process.exit(maxTurnsError.exitCode);
|
||||
} else if (config.getOutputFormat() === OutputFormat.JSON) {
|
||||
const formatter = new JsonFormatter();
|
||||
const formattedError = formatter.formatError(
|
||||
maxTurnsError,
|
||||
|
||||
Reference in New Issue
Block a user