diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 5c9a3e7044..1955507c62 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -1606,6 +1606,12 @@ their corresponding top-level category object in your `settings.json` file. - **Default:** `false` - **Requires restart:** Yes +- **`experimental.adk.agentSessionInteractiveEnabled`** (boolean): + - **Description:** Enable the agent session implementation for the interactive + CLI. + - **Default:** `false` + - **Requires restart:** Yes + - **`experimental.enableAgents`** (boolean): - **Description:** Enable local and remote subagents. - **Default:** `true` diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts index 9343be6b02..730bd4b939 100644 --- a/packages/cli/src/config/settingsSchema.ts +++ b/packages/cli/src/config/settingsSchema.ts @@ -1970,6 +1970,16 @@ const SETTINGS_SCHEMA = { description: 'Enable non-interactive agent sessions.', showInDialog: false, }, + agentSessionInteractiveEnabled: { + type: 'boolean', + label: 'Interactive Agent Session Enabled', + category: 'Experimental', + requiresRestart: true, + default: false, + description: + 'Enable the agent session implementation for the interactive CLI.', + showInDialog: false, + }, }, }, enableAgents: { diff --git a/packages/cli/src/nonInteractiveCliAgentSession.ts b/packages/cli/src/nonInteractiveCliAgentSession.ts index 78fc18be4e..fe5fbceba2 100644 --- a/packages/cli/src/nonInteractiveCliAgentSession.ts +++ b/packages/cli/src/nonInteractiveCliAgentSession.ts @@ -37,6 +37,7 @@ import { LegacyAgentSession, ToolErrorType, geminiPartsToContentParts, + debugLogger, } from '@google/gemini-cli-core'; import type { Part } from '@google/genai'; @@ -599,6 +600,7 @@ export async function runNonInteractive({ // Explicitly ignore these non-interactive events break; default: + debugLogger.error('Unknown agent event type:', event); event satisfies never; break; } diff --git a/packages/core/src/agent/event-translator.ts b/packages/core/src/agent/event-translator.ts index 00b5d12b4f..cb299b494c 100644 --- a/packages/core/src/agent/event-translator.ts +++ b/packages/core/src/agent/event-translator.ts @@ -432,6 +432,7 @@ function isStructuredError(error: unknown): error is StructuredError { return ( typeof error === 'object' && error !== null && + 'status' in error && 'message' in error && typeof error.message === 'string' ); diff --git a/packages/core/src/agent/types.ts b/packages/core/src/agent/types.ts index 9bc3e81e0f..19837c138e 100644 --- a/packages/core/src/agent/types.ts +++ b/packages/core/src/agent/types.ts @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +import type { Kind } from '../tools/tools.js'; + export type WithMeta = { _meta?: Record }; export type Unsubscribe = () => void; @@ -180,6 +182,16 @@ export interface ToolRequest { name: string; /** The arguments for the tool. */ args: Record; + /** UI specific metadata */ + _meta?: { + legacyState?: { + displayName?: string; + isOutputMarkdown?: boolean; + description?: string; + kind?: Kind; + }; + [key: string]: unknown; + }; } /** @@ -192,6 +204,18 @@ export interface ToolUpdate { displayContent?: ContentPart[]; content?: ContentPart[]; data?: Record; + /** UI specific metadata */ + _meta?: { + legacyState?: { + status?: string; + progressMessage?: string; + progress?: number; + progressTotal?: number; + pid?: number; + description?: string; + }; + [key: string]: unknown; + }; } export interface ToolResponse { @@ -205,6 +229,13 @@ export interface ToolResponse { data?: Record; /** When true, the tool call encountered an error that will be sent to the model. */ isError?: boolean; + /** UI specific metadata */ + _meta?: { + legacyState?: { + outputFile?: string; + }; + [key: string]: unknown; + }; } export type ElicitationRequest = { diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index a36d3b7a02..4ec526569f 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -225,6 +225,7 @@ export interface GemmaModelRouterSettings { export interface ADKSettings { agentSessionNoninteractiveEnabled?: boolean; + agentSessionInteractiveEnabled?: boolean; } export interface ExtensionSetting { @@ -894,6 +895,7 @@ export class Config implements McpContext, AgentLoopContext { private readonly gemmaModelRouter: GemmaModelRouterSettings; private readonly agentSessionNoninteractiveEnabled: boolean; + private readonly agentSessionInteractiveEnabled: boolean; private readonly continueOnFailedApiCall: boolean; private readonly retryFetchErrors: boolean; @@ -1325,6 +1327,8 @@ export class Config implements McpContext, AgentLoopContext { this.agentSessionNoninteractiveEnabled = params.adk?.agentSessionNoninteractiveEnabled ?? false; + this.agentSessionInteractiveEnabled = + params.adk?.agentSessionInteractiveEnabled ?? false; this.retryFetchErrors = params.retryFetchErrors ?? true; this.maxAttempts = Math.min( params.maxAttempts ?? DEFAULT_MAX_ATTEMPTS, @@ -3396,6 +3400,10 @@ export class Config implements McpContext, AgentLoopContext { return this.agentSessionNoninteractiveEnabled; } + getAgentSessionInteractiveEnabled(): boolean { + return this.agentSessionInteractiveEnabled; + } + /** * Get override settings for a specific agent. * Reads from agents.overrides.. diff --git a/schemas/settings.schema.json b/schemas/settings.schema.json index 71172717e4..5179263596 100644 --- a/schemas/settings.schema.json +++ b/schemas/settings.schema.json @@ -2775,6 +2775,13 @@ "markdownDescription": "Enable non-interactive agent sessions.\n\n- Category: `Experimental`\n- Requires restart: `yes`\n- Default: `false`", "default": false, "type": "boolean" + }, + "agentSessionInteractiveEnabled": { + "title": "Interactive Agent Session Enabled", + "description": "Enable the agent session implementation for the interactive CLI.", + "markdownDescription": "Enable the agent session implementation for the interactive CLI.\n\n- Category: `Experimental`\n- Requires restart: `yes`\n- Default: `false`", + "default": false, + "type": "boolean" } }, "additionalProperties": false