From 886417efc14f9d59b74b929bfd57152e904b6823 Mon Sep 17 00:00:00 2001 From: mkorwel Date: Wed, 11 Feb 2026 17:33:38 -0600 Subject: [PATCH] fix(core/cli): resolve build errors and integrate SubagentActivity event #18267 --- .gemini/settings.json | 3 ++- packages/cli/src/config/settingsSchema.ts | 9 +++++++++ packages/cli/src/ui/hooks/useGeminiStream.ts | 3 +++ packages/core/src/agents/harness.test.ts | 10 +++++++++- packages/core/src/agents/harness.ts | 16 ++++++++++------ packages/core/src/agents/local-invocation.ts | 6 ++++-- 6 files changed, 37 insertions(+), 10 deletions(-) diff --git a/.gemini/settings.json b/.gemini/settings.json index c4deb2c10f..de148ee0c2 100644 --- a/.gemini/settings.json +++ b/.gemini/settings.json @@ -1,6 +1,7 @@ { "experimental": { - "plan": true + "plan": true, + "enableAgentHarness": true }, "general": { "devtools": true diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts index 07d2faec49..508cd6e113 100644 --- a/packages/cli/src/config/settingsSchema.ts +++ b/packages/cli/src/config/settingsSchema.ts @@ -1528,6 +1528,15 @@ const SETTINGS_SCHEMA = { 'Enable local and remote subagents. Warning: Experimental feature, uses YOLO mode for subagents', showInDialog: false, }, + enableAgentHarness: { + type: 'boolean', + label: 'Enable Agent Harness', + category: 'Experimental', + requiresRestart: true, + default: false, + description: 'Enable the new unified agent harness (experimental).', + showInDialog: false, + }, extensionManagement: { type: 'boolean', label: 'Extension Management', diff --git a/packages/cli/src/ui/hooks/useGeminiStream.ts b/packages/cli/src/ui/hooks/useGeminiStream.ts index bba6977ffa..74e6e635b9 100644 --- a/packages/cli/src/ui/hooks/useGeminiStream.ts +++ b/packages/cli/src/ui/hooks/useGeminiStream.ts @@ -1168,6 +1168,9 @@ export const useGeminiStream = ( case ServerGeminiEventType.InvalidStream: // Will add the missing logic later break; + case ServerGeminiEventType.SubagentActivity: + // TODO: UI implementation for subagent activity + break; default: { // enforces exhaustive switch-case const unreachable: never = event; diff --git a/packages/core/src/agents/harness.test.ts b/packages/core/src/agents/harness.test.ts index cabd25bcd2..72682f9f0b 100644 --- a/packages/core/src/agents/harness.test.ts +++ b/packages/core/src/agents/harness.test.ts @@ -55,17 +55,25 @@ describe('AgentHarness', () => { name: 'test-agent', displayName: 'Test Agent', description: 'A test agent', + inputConfig: { + inputSchema: { type: 'object', properties: {}, required: [] }, + }, + modelConfig: { + model: 'gemini-test-model', + }, runConfig: { maxTurns: 5, maxTimeMinutes: 5 }, promptConfig: { systemPrompt: 'You are a test agent.' }, outputConfig: { outputName: 'result', + description: 'The final result.', schema: z.string(), }, }; const harness = new AgentHarness({ config: mockConfig, - definition, + + definition: definition as unknown as AgentDefinition, inputs: {}, }); diff --git a/packages/core/src/agents/harness.ts b/packages/core/src/agents/harness.ts index f701992183..91e94d9c26 100644 --- a/packages/core/src/agents/harness.ts +++ b/packages/core/src/agents/harness.ts @@ -209,14 +209,13 @@ export class AgentHarness { if (def.outputConfig) { const schema = zodToJsonSchema(def.outputConfig.schema); - + const { $schema: _, definitions: __, ...cleanSchema } = schema as Record; completeTool.parameters!.properties![def.outputConfig.outputName] = - cleanSchema as Schema; completeTool.parameters!.required!.push(def.outputConfig.outputName); } else { @@ -274,6 +273,11 @@ export class AgentHarness { }; } + await this.toolOutputMaskingService.mask( + this.chat!.getHistory(), + this.config, + ); + // 2. Loop Detection if (await this.loopDetector.turnStarted(signal)) { terminateReason = AgentTerminateMode.ERROR; @@ -341,7 +345,7 @@ export class AgentHarness { ); if (completeCall) { // Check for validation errors in complete_task - if (completeCall.part.functionResponse?.response?.error) { + if (completeCall.part.functionResponse?.response?.['error']) { // The model messed up complete_task, it will receive the error as currentRequest and try again currentRequest = [completeCall.part]; } else { @@ -446,8 +450,8 @@ export class AgentHarness { }); return completedCalls.map((call) => ({ - name: call.request.name, - part: call.response.responseParts[0], - })); + name: call.request.name, + part: call.response.responseParts[0], + })); } } diff --git a/packages/core/src/agents/local-invocation.ts b/packages/core/src/agents/local-invocation.ts index 8e5fecd87d..fabc12fe87 100644 --- a/packages/core/src/agents/local-invocation.ts +++ b/packages/core/src/agents/local-invocation.ts @@ -16,7 +16,9 @@ import type { } from './types.js'; import type { MessageBus } from '../confirmation-bus/message-bus.js'; import { AgentFactory } from './agent-factory.js'; +import type { Turn } from '../core/turn.js'; import { GeminiEventType } from '../core/turn.js'; +import { promptIdContext } from '../utils/promptIdContext.js'; const INPUT_PREVIEW_MAX_LENGTH = 50; const DESCRIPTION_MAX_LENGTH = 200; @@ -169,8 +171,8 @@ ${output.result} while (true) { const { value, done } = await stream.next(); if (done) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion - turn = value as Turn; + + turn = value; break; } const event = value;