feat(core): Enable AgentRegistry to track all discovered subagents (#17253)

This commit is contained in:
Sandy Tao
2026-01-21 16:19:04 -08:00
committed by GitHub
parent 61040d0eb8
commit b24544c80e
2 changed files with 86 additions and 1 deletions

View File

@@ -603,7 +603,9 @@ describe('AgentRegistry', () => {
expect(clearCacheSpy).toHaveBeenCalled();
expect(registry.getDefinition('InitialAgent')).toBeUndefined();
expect(registry.getDiscoveredDefinition('InitialAgent')).toBeUndefined();
expect(registry.getDefinition('NewAgent')).toBeDefined();
expect(registry.getDiscoveredDefinition('NewAgent')).toBeDefined();
expect(emitSpy).toHaveBeenCalled();
});
});
@@ -697,6 +699,65 @@ describe('AgentRegistry', () => {
expect.arrayContaining([MOCK_AGENT_V1, ANOTHER_AGENT]),
);
});
it('getAllDiscoveredAgentNames should return all names including disabled ones', async () => {
const configWithDisabled = makeMockedConfig({
agents: {
overrides: {
DisabledAgent: { enabled: false },
},
},
});
const registryWithDisabled = new TestableAgentRegistry(
configWithDisabled,
);
const enabledAgent = { ...MOCK_AGENT_V1, name: 'EnabledAgent' };
const disabledAgent = { ...MOCK_AGENT_V1, name: 'DisabledAgent' };
await registryWithDisabled.testRegisterAgent(enabledAgent);
await registryWithDisabled.testRegisterAgent(disabledAgent);
const discoveredNames = registryWithDisabled.getAllDiscoveredAgentNames();
expect(discoveredNames).toContain('EnabledAgent');
expect(discoveredNames).toContain('DisabledAgent');
expect(discoveredNames).toHaveLength(2);
const activeNames = registryWithDisabled.getAllAgentNames();
expect(activeNames).toContain('EnabledAgent');
expect(activeNames).not.toContain('DisabledAgent');
expect(activeNames).toHaveLength(1);
});
it('getDiscoveredDefinition should return the definition for a disabled agent', async () => {
const configWithDisabled = makeMockedConfig({
agents: {
overrides: {
DisabledAgent: { enabled: false },
},
},
});
const registryWithDisabled = new TestableAgentRegistry(
configWithDisabled,
);
const disabledAgent = {
...MOCK_AGENT_V1,
name: 'DisabledAgent',
description: 'I am disabled',
};
await registryWithDisabled.testRegisterAgent(disabledAgent);
expect(
registryWithDisabled.getDefinition('DisabledAgent'),
).toBeUndefined();
const discovered =
registryWithDisabled.getDiscoveredDefinition('DisabledAgent');
expect(discovered).toBeDefined();
expect(discovered?.description).toBe('I am disabled');
});
});
describe('overrides', () => {

View File

@@ -45,6 +45,8 @@ export function getModelConfigAlias<TOutput extends z.ZodTypeAny>(
export class AgentRegistry {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private readonly agents = new Map<string, AgentDefinition<any>>();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private readonly allDefinitions = new Map<string, AgentDefinition<any>>();
constructor(private readonly config: Config) {}
@@ -73,6 +75,7 @@ export class AgentRegistry {
A2AClientManager.getInstance().clearCache();
await this.config.reloadAgents();
this.agents.clear();
this.allDefinitions.clear();
await this.loadAgents();
coreEvents.emitAgentsRefreshed();
}
@@ -85,6 +88,8 @@ export class AgentRegistry {
}
private async loadAgents(): Promise<void> {
this.agents.clear();
this.allDefinitions.clear();
this.loadBuiltInAgents();
if (!this.config.isAgentsEnabled()) {
@@ -251,6 +256,8 @@ export class AgentRegistry {
return;
}
this.allDefinitions.set(definition.name, definition);
const settingsOverrides =
this.config.getAgentsSettings().overrides?.[definition.name];
@@ -305,6 +312,8 @@ export class AgentRegistry {
return;
}
this.allDefinitions.set(definition.name, definition);
const overrides =
this.config.getAgentsSettings().overrides?.[definition.name];
@@ -417,7 +426,8 @@ export class AgentRegistry {
/**
* Retrieves an agent definition by name.
*/
getDefinition(name: string): AgentDefinition | undefined {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
getDefinition(name: string): AgentDefinition<any> | undefined {
return this.agents.get(name);
}
@@ -435,6 +445,20 @@ export class AgentRegistry {
return Array.from(this.agents.keys());
}
/**
* Returns a list of all discovered agent names, regardless of whether they are enabled.
*/
getAllDiscoveredAgentNames(): string[] {
return Array.from(this.allDefinitions.keys());
}
/**
* Retrieves a discovered agent definition by name.
*/
getDiscoveredDefinition(name: string): AgentDefinition | undefined {
return this.allDefinitions.get(name);
}
/**
* Generates a description for the delegate_to_agent tool.
* Unlike getDirectoryContext() which is for system prompts,