fix(core/cli): resolve build errors and integrate SubagentActivity event #18267

This commit is contained in:
mkorwel
2026-02-11 17:33:38 -06:00
parent e650c10cf5
commit 886417efc1
6 changed files with 37 additions and 10 deletions
+2 -1
View File
@@ -1,6 +1,7 @@
{
"experimental": {
"plan": true
"plan": true,
"enableAgentHarness": true
},
"general": {
"devtools": true
@@ -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',
@@ -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;
+9 -1
View File
@@ -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: {},
});
+10 -6
View File
@@ -209,14 +209,13 @@ export class AgentHarness {
if (def.outputConfig) {
const schema = zodToJsonSchema(def.outputConfig.schema);
const {
$schema: _,
definitions: __,
...cleanSchema
} = schema as Record<string, unknown>;
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],
}));
}
}
+4 -2
View File
@@ -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;