feat(core): support authenticated A2A agent card discovery (#20622)

Co-authored-by: Adam Weidman <adamfweidman@google.com>
Co-authored-by: Adam Weidman <65992621+adamfweidman@users.noreply.github.com>
This commit is contained in:
Sandy Tao
2026-03-02 13:29:31 -08:00
committed by GitHub
parent 31ca57ec94
commit 18d0375a7f
2 changed files with 69 additions and 7 deletions

View File

@@ -664,6 +664,30 @@ describe('AgentRegistry', () => {
);
});
it('should surface an error if remote agent registration fails', async () => {
const remoteAgent: AgentDefinition = {
kind: 'remote',
name: 'FailingRemoteAgent',
description: 'A remote agent',
agentCardUrl: 'https://example.com/card',
inputConfig: { inputSchema: { type: 'object' } },
};
const error = new Error('401 Unauthorized');
vi.mocked(A2AClientManager.getInstance).mockReturnValue({
loadAgent: vi.fn().mockRejectedValue(error),
} as unknown as A2AClientManager);
const feedbackSpy = vi.spyOn(coreEvents, 'emitFeedback');
await registry.testRegisterAgent(remoteAgent);
expect(feedbackSpy).toHaveBeenCalledWith(
'error',
`Error loading A2A agent "FailingRemoteAgent": 401 Unauthorized`,
);
});
it('should merge user and agent description and skills when registering a remote agent', async () => {
const remoteAgent: AgentDefinition = {
kind: 'remote',

View File

@@ -119,7 +119,20 @@ export class AgentRegistry {
coreEvents.emitFeedback('error', `Agent loading error: ${error.message}`);
}
await Promise.allSettled(
userAgents.agents.map((agent) => this.registerAgent(agent)),
userAgents.agents.map(async (agent) => {
try {
await this.registerAgent(agent);
} catch (e) {
debugLogger.warn(
`[AgentRegistry] Error registering user agent "${agent.name}":`,
e,
);
coreEvents.emitFeedback(
'error',
`Error registering user agent "${agent.name}": ${e instanceof Error ? e.message : String(e)}`,
);
}
}),
);
// Load project-level agents: .gemini/agents/ (relative to Project Root)
@@ -174,7 +187,20 @@ export class AgentRegistry {
}
await Promise.allSettled(
agentsToRegister.map((agent) => this.registerAgent(agent)),
agentsToRegister.map(async (agent) => {
try {
await this.registerAgent(agent);
} catch (e) {
debugLogger.warn(
`[AgentRegistry] Error registering project agent "${agent.name}":`,
e,
);
coreEvents.emitFeedback(
'error',
`Error registering project agent "${agent.name}": ${e instanceof Error ? e.message : String(e)}`,
);
}
}),
);
} else {
coreEvents.emitFeedback(
@@ -187,7 +213,20 @@ export class AgentRegistry {
for (const extension of this.config.getExtensions()) {
if (extension.isActive && extension.agents) {
await Promise.allSettled(
extension.agents.map((agent) => this.registerAgent(agent)),
extension.agents.map(async (agent) => {
try {
await this.registerAgent(agent);
} catch (e) {
debugLogger.warn(
`[AgentRegistry] Error registering extension agent "${agent.name}":`,
e,
);
coreEvents.emitFeedback(
'error',
`Error registering extension agent "${agent.name}": ${e instanceof Error ? e.message : String(e)}`,
);
}
}),
);
}
}
@@ -424,10 +463,9 @@ export class AgentRegistry {
this.agents.set(definition.name, definition);
this.addAgentPolicy(definition);
} catch (e) {
debugLogger.warn(
`[AgentRegistry] Error loading A2A agent "${definition.name}":`,
e,
);
const errorMessage = `Error loading A2A agent "${definition.name}": ${e instanceof Error ? e.message : String(e)}`;
debugLogger.warn(`[AgentRegistry] ${errorMessage}`, e);
coreEvents.emitFeedback('error', errorMessage);
}
}