fix(core): ensure sub-agent schema and prompt refresh during runtime (#16409)

Co-authored-by: Sehoon Shon <sshon@google.com>
This commit is contained in:
Adam Weidman
2026-01-12 12:11:24 -05:00
committed by GitHub
parent 950244f6b0
commit 465ec9759d
7 changed files with 101 additions and 16 deletions
@@ -14,6 +14,7 @@ import type { Config } from '../config/config.js';
describe('CliHelpAgent', () => {
const fakeConfig = {
getMessageBus: () => ({}),
isAgentsEnabled: () => false,
} as unknown as Config;
const localAgent = CliHelpAgent(fakeConfig) as LocalAgentDefinition;
@@ -52,6 +53,22 @@ describe('CliHelpAgent', () => {
expect(query).toContain('${question}');
});
it('should include sub-agent information when agents are enabled', () => {
const enabledConfig = {
getMessageBus: () => ({}),
isAgentsEnabled: () => true,
getAgentRegistry: () => ({
getDirectoryContext: () => 'Mock Agent Directory',
}),
} as unknown as Config;
const agent = CliHelpAgent(enabledConfig) as LocalAgentDefinition;
const systemPrompt = agent.promptConfig.systemPrompt || '';
expect(systemPrompt).toContain('### Sub-Agents (Local & Remote)');
expect(systemPrompt).toContain('Remote Agent (A2A)');
expect(systemPrompt).toContain('Agent2Agent functionality');
});
it('should process output to a formatted JSON string', () => {
const mockOutput = {
answer: 'This is the answer.',
@@ -76,6 +76,12 @@ export const CliHelpAgent = (
'- **CLI Version:** ${cliVersion}\n' +
'- **Active Model:** ${activeModel}\n' +
"- **Today's Date:** ${today}\n\n" +
(config.isAgentsEnabled()
? '### Sub-Agents (Local & Remote)\n' +
'User defined sub-agents are defined in `.gemini/agents/` or `~/.gemini/agents/` using YAML frontmatter for metadata and Markdown for instructions (system_prompt). Always reference the types and properties outlined here directly when answering questions about sub-agents.\n' +
'- **Local Agent:** `kind = "local"`, `name`, `description`, `prompts.system_prompt`, and optional `tools`, `model`, `run`.\n' +
'- **Remote Agent (A2A):** `kind = "remote"`, `name`, `agent_card_url`. Multiple remotes can be defined using a `remote_agents` array. **Note:** When users ask about "remote agents", they are referring to this Agent2Agent functionality, which is completely distinct from MCP servers.\n\n'
: '') +
'### Instructions\n' +
"1. **Explore Documentation**: Use the `get_internal_docs` tool to find answers. If you don't know where to start, call `get_internal_docs()` without arguments to see the full list of available documentation files.\n" +
'2. **Be Precise**: Use the provided runtime context and documentation to give exact answers.\n' +
+17 -8
View File
@@ -46,18 +46,20 @@ export class AgentRegistry {
* Discovers and loads agents.
*/
async initialize(): Promise<void> {
coreEvents.on(CoreEvent.ModelChanged, () => {
this.refreshAgents().catch((e) => {
debugLogger.error(
'[AgentRegistry] Failed to refresh agents on model change:',
e,
);
});
});
coreEvents.on(CoreEvent.ModelChanged, this.onModelChanged);
await this.loadAgents();
}
private onModelChanged = () => {
this.refreshAgents().catch((e) => {
debugLogger.error(
'[AgentRegistry] Failed to refresh agents on model change:',
e,
);
});
};
/**
* Clears the current registry and re-scans for agents.
*/
@@ -68,6 +70,13 @@ export class AgentRegistry {
coreEvents.emitAgentsRefreshed();
}
/**
* Disposes of resources and removes event listeners.
*/
dispose(): void {
coreEvents.off(CoreEvent.ModelChanged, this.onModelChanged);
}
private async loadAgents(): Promise<void> {
this.loadBuiltInAgents();