@google/gemini-cli-core 0.24.0-preview.0 → 0.25.0-nightly.20260112.15891721a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/docs/changelogs/index.md +22 -0
- package/dist/docs/changelogs/latest.md +137 -209
- package/dist/docs/changelogs/preview.md +116 -114
- package/dist/docs/changelogs/releases.md +273 -7
- package/dist/docs/cli/model-routing.md +1 -1
- package/dist/docs/cli/model.md +1 -1
- package/dist/docs/cli/settings.md +67 -53
- package/dist/docs/core/policy-engine.md +3 -2
- package/dist/docs/extensions/index.md +57 -7
- package/dist/docs/get-started/configuration.md +13 -7
- package/dist/docs/get-started/gemini-3.md +2 -17
- package/dist/docs/hooks/best-practices.md +1 -1
- package/dist/docs/hooks/index.md +47 -11
- package/dist/docs/hooks/reference.md +19 -9
- package/dist/docs/hooks/writing-hooks.md +19 -1
- package/dist/docs/troubleshooting.md +9 -3
- package/dist/google-gemini-cli-core-0.25.0-nightly.20260107.59a18e710.tgz +0 -0
- package/dist/src/agents/a2a-client-manager.d.ts +4 -0
- package/dist/src/agents/a2a-client-manager.js +22 -22
- package/dist/src/agents/a2a-client-manager.js.map +1 -1
- package/dist/src/agents/a2a-client-manager.test.js +44 -0
- package/dist/src/agents/a2a-client-manager.test.js.map +1 -1
- package/dist/src/agents/agentLoader.d.ts +68 -0
- package/dist/src/agents/{toml-loader.js → agentLoader.js} +83 -78
- package/dist/src/agents/agentLoader.js.map +1 -0
- package/dist/src/agents/agentLoader.test.js +283 -0
- package/dist/src/agents/agentLoader.test.js.map +1 -0
- package/dist/src/agents/{introspection-agent.d.ts → cli-help-agent.d.ts} +3 -2
- package/dist/src/agents/{introspection-agent.js → cli-help-agent.js} +17 -11
- package/dist/src/agents/cli-help-agent.js.map +1 -0
- package/dist/src/agents/{introspection-agent.test.js → cli-help-agent.test.js} +25 -7
- package/dist/src/agents/cli-help-agent.test.js.map +1 -0
- package/dist/src/agents/delegate-to-agent-tool.js +17 -10
- package/dist/src/agents/delegate-to-agent-tool.js.map +1 -1
- package/dist/src/agents/delegate-to-agent-tool.test.js +52 -10
- package/dist/src/agents/delegate-to-agent-tool.test.js.map +1 -1
- package/dist/src/agents/local-executor.js +35 -1
- package/dist/src/agents/local-executor.js.map +1 -1
- package/dist/src/agents/local-executor.test.js +53 -0
- package/dist/src/agents/local-executor.test.js.map +1 -1
- package/dist/src/agents/registry.d.ts +10 -0
- package/dist/src/agents/registry.js +61 -26
- package/dist/src/agents/registry.js.map +1 -1
- package/dist/src/agents/registry.test.js +66 -11
- package/dist/src/agents/registry.test.js.map +1 -1
- package/dist/src/agents/remote-invocation.js +4 -2
- package/dist/src/agents/remote-invocation.js.map +1 -1
- package/dist/src/agents/remote-invocation.test.js +1 -1
- package/dist/src/agents/remote-invocation.test.js.map +1 -1
- package/dist/src/availability/fallbackIntegration.test.js +58 -0
- package/dist/src/availability/fallbackIntegration.test.js.map +1 -0
- package/dist/src/code_assist/experiments/experiments.d.ts +1 -1
- package/dist/src/code_assist/experiments/experiments.js +21 -0
- package/dist/src/code_assist/experiments/experiments.js.map +1 -1
- package/dist/src/code_assist/experiments/experiments_local.test.d.ts +6 -0
- package/dist/src/code_assist/experiments/experiments_local.test.js +110 -0
- package/dist/src/code_assist/experiments/experiments_local.test.js.map +1 -0
- package/dist/src/code_assist/oauth-credential-storage.js +3 -4
- package/dist/src/code_assist/oauth-credential-storage.js.map +1 -1
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/oauth2.test.js +44 -19
- package/dist/src/code_assist/oauth2.test.js.map +1 -1
- package/dist/src/code_assist/telemetry.js +2 -1
- package/dist/src/code_assist/telemetry.js.map +1 -1
- package/dist/src/code_assist/telemetry.test.js +2 -1
- package/dist/src/code_assist/telemetry.test.js.map +1 -1
- package/dist/src/code_assist/types.d.ts +7 -0
- package/dist/src/code_assist/types.js +7 -0
- package/dist/src/code_assist/types.js.map +1 -1
- package/dist/src/config/config.d.ts +26 -6
- package/dist/src/config/config.js +79 -37
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +13 -3
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/models.d.ts +7 -0
- package/dist/src/config/models.js +11 -0
- package/dist/src/config/models.js.map +1 -1
- package/dist/src/config/models.test.js +17 -1
- package/dist/src/config/models.test.js.map +1 -1
- package/dist/src/config/storage.d.ts +1 -0
- package/dist/src/config/storage.js +5 -2
- package/dist/src/config/storage.js.map +1 -1
- package/dist/src/core/client.js +27 -8
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +98 -42
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/coreToolHookTriggers.d.ts +8 -4
- package/dist/src/core/coreToolHookTriggers.js +43 -5
- package/dist/src/core/coreToolHookTriggers.js.map +1 -1
- package/dist/src/core/coreToolScheduler.d.ts +1 -8
- package/dist/src/core/coreToolScheduler.js +54 -60
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +30 -8
- package/dist/src/core/coreToolScheduler.test.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +26 -1
- package/dist/src/core/geminiChat.js +74 -8
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/geminiChat.test.js +109 -0
- package/dist/src/core/geminiChat.test.js.map +1 -1
- package/dist/src/core/geminiChatHookTriggers.d.ts +8 -4
- package/dist/src/core/geminiChatHookTriggers.js +31 -9
- package/dist/src/core/geminiChatHookTriggers.js.map +1 -1
- package/dist/src/core/geminiChatHookTriggers.test.d.ts +6 -0
- package/dist/src/core/geminiChatHookTriggers.test.js +153 -0
- package/dist/src/core/geminiChatHookTriggers.test.js.map +1 -0
- package/dist/src/core/loggingContentGenerator.js +5 -0
- package/dist/src/core/loggingContentGenerator.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.test.js +30 -0
- package/dist/src/core/loggingContentGenerator.test.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.test.js +4 -2
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
- package/dist/src/core/prompts.js +8 -8
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/prompts.test.js +4 -2
- package/dist/src/core/prompts.test.js.map +1 -1
- package/dist/src/core/tokenLimits.js +6 -12
- package/dist/src/core/tokenLimits.js.map +1 -1
- package/dist/src/core/tokenLimits.test.js +8 -4
- package/dist/src/core/tokenLimits.test.js.map +1 -1
- package/dist/src/core/turn.d.ts +2 -0
- package/dist/src/core/turn.js +14 -0
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/hooks/hookEventHandler.d.ts +3 -3
- package/dist/src/hooks/hookEventHandler.js +27 -8
- package/dist/src/hooks/hookEventHandler.js.map +1 -1
- package/dist/src/hooks/hookEventHandler.test.js +145 -0
- package/dist/src/hooks/hookEventHandler.test.js.map +1 -1
- package/dist/src/hooks/hookSystem.d.ts +12 -0
- package/dist/src/hooks/hookSystem.js +36 -0
- package/dist/src/hooks/hookSystem.js.map +1 -1
- package/dist/src/hooks/hookTranslator.js +2 -1
- package/dist/src/hooks/hookTranslator.js.map +1 -1
- package/dist/src/hooks/index.d.ts +0 -1
- package/dist/src/hooks/index.js +0 -2
- package/dist/src/hooks/index.js.map +1 -1
- package/dist/src/hooks/types.d.ts +21 -0
- package/dist/src/hooks/types.js +0 -15
- package/dist/src/hooks/types.js.map +1 -1
- package/dist/src/hooks/types.test.js +4 -28
- package/dist/src/hooks/types.test.js.map +1 -1
- package/dist/src/ide/detect-ide.d.ts +4 -0
- package/dist/src/ide/detect-ide.js +7 -2
- package/dist/src/ide/detect-ide.js.map +1 -1
- package/dist/src/ide/detect-ide.test.js +10 -0
- package/dist/src/ide/detect-ide.test.js.map +1 -1
- package/dist/src/ide/ide-installer.js +2 -2
- package/dist/src/ide/ide-installer.js.map +1 -1
- package/dist/src/ide/ide-installer.test.js +11 -2
- package/dist/src/ide/ide-installer.test.js.map +1 -1
- package/dist/src/index.d.ts +8 -1
- package/dist/src/index.js +10 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/token-storage/file-token-storage.js +2 -2
- package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -1
- package/dist/src/policy/persistence.test.js +1 -1
- package/dist/src/policy/persistence.test.js.map +1 -1
- package/dist/src/policy/policies/agent.toml +1 -1
- package/dist/src/policy/policies/yolo.toml +1 -0
- package/dist/src/policy/policy-updater.test.js +3 -3
- package/dist/src/policy/policy-updater.test.js.map +1 -1
- package/dist/src/policy/utils.js +4 -1
- package/dist/src/policy/utils.js.map +1 -1
- package/dist/src/policy/utils.test.js +34 -6
- package/dist/src/policy/utils.test.js.map +1 -1
- package/dist/src/routing/routingStrategy.d.ts +2 -0
- package/dist/src/routing/strategies/classifierStrategy.js +1 -1
- package/dist/src/routing/strategies/classifierStrategy.js.map +1 -1
- package/dist/src/routing/strategies/classifierStrategy.test.js +16 -0
- package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -1
- package/dist/src/routing/strategies/fallbackStrategy.d.ts +1 -1
- package/dist/src/routing/strategies/fallbackStrategy.js +2 -2
- package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -1
- package/dist/src/routing/strategies/fallbackStrategy.test.js +13 -0
- package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -1
- package/dist/src/routing/strategies/overrideStrategy.d.ts +1 -1
- package/dist/src/routing/strategies/overrideStrategy.js +5 -5
- package/dist/src/routing/strategies/overrideStrategy.js.map +1 -1
- package/dist/src/routing/strategies/overrideStrategy.test.js +14 -0
- package/dist/src/routing/strategies/overrideStrategy.test.js.map +1 -1
- package/dist/src/scheduler/tool-executor.js +2 -2
- package/dist/src/scheduler/tool-executor.js.map +1 -1
- package/dist/src/scheduler/tool-modifier.d.ts +23 -0
- package/dist/src/scheduler/tool-modifier.js +50 -0
- package/dist/src/scheduler/tool-modifier.js.map +1 -0
- package/dist/src/scheduler/tool-modifier.test.d.ts +6 -0
- package/dist/src/scheduler/tool-modifier.test.js +159 -0
- package/dist/src/scheduler/tool-modifier.test.js.map +1 -0
- package/dist/src/services/chatCompressionService.js +3 -10
- package/dist/src/services/chatCompressionService.js.map +1 -1
- package/dist/src/services/chatCompressionService.test.js +1 -0
- package/dist/src/services/chatCompressionService.test.js.map +1 -1
- package/dist/src/services/chatRecordingService.d.ts +7 -1
- package/dist/src/services/chatRecordingService.js +20 -2
- package/dist/src/services/chatRecordingService.js.map +1 -1
- package/dist/src/services/chatRecordingService.test.js +43 -0
- package/dist/src/services/chatRecordingService.test.js.map +1 -1
- package/dist/src/services/environmentSanitization.js +4 -3
- package/dist/src/services/environmentSanitization.js.map +1 -1
- package/dist/src/services/gitService.test.js +10 -2
- package/dist/src/services/gitService.test.js.map +1 -1
- package/dist/src/services/modelConfig.integration.test.js +2 -2
- package/dist/src/services/modelConfig.integration.test.js.map +1 -1
- package/dist/src/services/modelConfigService.d.ts +29 -1
- package/dist/src/services/modelConfigService.js +116 -69
- package/dist/src/services/modelConfigService.js.map +1 -1
- package/dist/src/services/modelConfigService.test.js +116 -0
- package/dist/src/services/modelConfigService.test.js.map +1 -1
- package/dist/src/services/shellExecutionService.js +1 -1
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.test.js +43 -2
- package/dist/src/services/shellExecutionService.test.js.map +1 -1
- package/dist/src/skills/skillLoader.d.ts +3 -0
- package/dist/src/skills/skillLoader.js +2 -2
- package/dist/src/skills/skillLoader.js.map +1 -1
- package/dist/src/skills/skillLoader.test.js +4 -2
- package/dist/src/skills/skillLoader.test.js.map +1 -1
- package/dist/src/skills/skillManager.d.ts +9 -0
- package/dist/src/skills/skillManager.js +24 -5
- package/dist/src/skills/skillManager.js.map +1 -1
- package/dist/src/skills/skillManager.test.js +36 -0
- package/dist/src/skills/skillManager.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +4 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +12 -8
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +43 -4
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +1 -0
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/types.js +4 -2
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/tools/activate-skill.js +23 -10
- package/dist/src/tools/activate-skill.js.map +1 -1
- package/dist/src/tools/activate-skill.test.js +24 -6
- package/dist/src/tools/activate-skill.test.js.map +1 -1
- package/dist/src/tools/edit.js +2 -0
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/get-internal-docs.js +11 -18
- package/dist/src/tools/get-internal-docs.js.map +1 -1
- package/dist/src/tools/mcp-tool.d.ts +18 -3
- package/dist/src/tools/mcp-tool.js +1 -1
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/tool-error.d.ts +4 -0
- package/dist/src/tools/tool-error.js +4 -0
- package/dist/src/tools/tool-error.js.map +1 -1
- package/dist/src/tools/tools.d.ts +2 -0
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/write-file.js +2 -0
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/utils/apiConversionUtils.d.ts +12 -0
- package/dist/src/utils/apiConversionUtils.js +46 -0
- package/dist/src/utils/apiConversionUtils.js.map +1 -0
- package/dist/src/utils/apiConversionUtils.test.d.ts +6 -0
- package/dist/src/utils/apiConversionUtils.test.js +150 -0
- package/dist/src/utils/apiConversionUtils.test.js.map +1 -0
- package/dist/src/utils/editor.d.ts +2 -2
- package/dist/src/utils/editor.js +19 -2
- package/dist/src/utils/editor.js.map +1 -1
- package/dist/src/utils/editor.test.js +27 -4
- package/dist/src/utils/editor.test.js.map +1 -1
- package/dist/src/utils/events.d.ts +7 -1
- package/dist/src/utils/events.js +7 -0
- package/dist/src/utils/events.js.map +1 -1
- package/dist/src/utils/fileDiffUtils.d.ts +18 -0
- package/dist/src/utils/fileDiffUtils.js +37 -0
- package/dist/src/utils/fileDiffUtils.js.map +1 -0
- package/dist/src/utils/fileDiffUtils.test.d.ts +6 -0
- package/dist/src/utils/fileDiffUtils.test.js +84 -0
- package/dist/src/utils/fileDiffUtils.test.js.map +1 -0
- package/dist/src/utils/gitIgnoreParser.js +9 -10
- package/dist/src/utils/gitIgnoreParser.js.map +1 -1
- package/dist/src/utils/installationManager.test.js +11 -3
- package/dist/src/utils/installationManager.test.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.js +1 -2
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.test.js +9 -0
- package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
- package/dist/src/utils/paths.d.ts +10 -0
- package/dist/src/utils/paths.js +20 -1
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/userAccountManager.test.js +5 -5
- package/dist/src/utils/userAccountManager.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/dist/docs/cli/configuration.md +0 -780
- package/dist/docs/get-started/deployment.md +0 -143
- package/dist/src/agents/introspection-agent.js.map +0 -1
- package/dist/src/agents/introspection-agent.test.js.map +0 -1
- package/dist/src/agents/toml-loader.d.ts +0 -74
- package/dist/src/agents/toml-loader.js.map +0 -1
- package/dist/src/agents/toml-loader.test.js +0 -309
- package/dist/src/agents/toml-loader.test.js.map +0 -1
- package/dist/src/core/sessionHookTriggers.d.ts +0 -29
- package/dist/src/core/sessionHookTriggers.js +0 -75
- package/dist/src/core/sessionHookTriggers.js.map +0 -1
- package/dist/src/utils/shell-permissions.d.ts +0 -52
- package/dist/src/utils/shell-permissions.js +0 -188
- package/dist/src/utils/shell-permissions.js.map +0 -1
- package/dist/src/utils/shell-permissions.test.js +0 -369
- package/dist/src/utils/shell-permissions.test.js.map +0 -1
- /package/dist/src/agents/{introspection-agent.test.d.ts → agentLoader.test.d.ts} +0 -0
- /package/dist/src/agents/{toml-loader.test.d.ts → cli-help-agent.test.d.ts} +0 -0
- /package/dist/src/{utils/shell-permissions.test.d.ts → availability/fallbackIntegration.test.d.ts} +0 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
7
|
+
import * as fs from 'node:fs/promises';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import * as os from 'node:os';
|
|
10
|
+
import { parseAgentMarkdown, markdownToAgentDefinition, loadAgentsFromDirectory, AgentLoadError, } from './agentLoader.js';
|
|
11
|
+
import { GEMINI_MODEL_ALIAS_PRO } from '../config/models.js';
|
|
12
|
+
describe('loader', () => {
|
|
13
|
+
let tempDir;
|
|
14
|
+
beforeEach(async () => {
|
|
15
|
+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'agent-test-'));
|
|
16
|
+
});
|
|
17
|
+
afterEach(async () => {
|
|
18
|
+
if (tempDir) {
|
|
19
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
async function writeAgentMarkdown(content, fileName = 'test.md') {
|
|
23
|
+
const filePath = path.join(tempDir, fileName);
|
|
24
|
+
await fs.writeFile(filePath, content);
|
|
25
|
+
return filePath;
|
|
26
|
+
}
|
|
27
|
+
describe('parseAgentMarkdown', () => {
|
|
28
|
+
it('should parse a valid markdown agent file', async () => {
|
|
29
|
+
const filePath = await writeAgentMarkdown(`---
|
|
30
|
+
name: test-agent-md
|
|
31
|
+
description: A markdown agent
|
|
32
|
+
---
|
|
33
|
+
You are a markdown agent.`);
|
|
34
|
+
const result = await parseAgentMarkdown(filePath);
|
|
35
|
+
expect(result).toHaveLength(1);
|
|
36
|
+
expect(result[0]).toMatchObject({
|
|
37
|
+
name: 'test-agent-md',
|
|
38
|
+
description: 'A markdown agent',
|
|
39
|
+
kind: 'local',
|
|
40
|
+
system_prompt: 'You are a markdown agent.',
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
it('should parse frontmatter with tools and model config', async () => {
|
|
44
|
+
const filePath = await writeAgentMarkdown(`---
|
|
45
|
+
name: complex-agent
|
|
46
|
+
description: A complex markdown agent
|
|
47
|
+
tools:
|
|
48
|
+
- run_shell_command
|
|
49
|
+
model: gemini-pro
|
|
50
|
+
temperature: 0.7
|
|
51
|
+
---
|
|
52
|
+
System prompt content.`);
|
|
53
|
+
const result = await parseAgentMarkdown(filePath);
|
|
54
|
+
expect(result).toHaveLength(1);
|
|
55
|
+
expect(result[0]).toMatchObject({
|
|
56
|
+
name: 'complex-agent',
|
|
57
|
+
description: 'A complex markdown agent',
|
|
58
|
+
tools: ['run_shell_command'],
|
|
59
|
+
model: 'gemini-pro',
|
|
60
|
+
temperature: 0.7,
|
|
61
|
+
system_prompt: 'System prompt content.',
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
it('should throw AgentLoadError if frontmatter is missing', async () => {
|
|
65
|
+
const filePath = await writeAgentMarkdown(`Just some markdown content.`);
|
|
66
|
+
await expect(parseAgentMarkdown(filePath)).rejects.toThrow(AgentLoadError);
|
|
67
|
+
await expect(parseAgentMarkdown(filePath)).rejects.toThrow('Invalid markdown format');
|
|
68
|
+
});
|
|
69
|
+
it('should throw AgentLoadError if frontmatter is invalid YAML', async () => {
|
|
70
|
+
const filePath = await writeAgentMarkdown(`---
|
|
71
|
+
name: [invalid yaml
|
|
72
|
+
---
|
|
73
|
+
Body`);
|
|
74
|
+
await expect(parseAgentMarkdown(filePath)).rejects.toThrow(AgentLoadError);
|
|
75
|
+
await expect(parseAgentMarkdown(filePath)).rejects.toThrow('YAML frontmatter parsing failed');
|
|
76
|
+
});
|
|
77
|
+
it('should throw AgentLoadError if validation fails (missing required field)', async () => {
|
|
78
|
+
const filePath = await writeAgentMarkdown(`---
|
|
79
|
+
name: test-agent
|
|
80
|
+
# missing description
|
|
81
|
+
---
|
|
82
|
+
Body`);
|
|
83
|
+
await expect(parseAgentMarkdown(filePath)).rejects.toThrow(/Validation failed/);
|
|
84
|
+
});
|
|
85
|
+
it('should throw AgentLoadError if tools list includes forbidden tool', async () => {
|
|
86
|
+
const filePath = await writeAgentMarkdown(`---
|
|
87
|
+
name: test-agent
|
|
88
|
+
description: Test
|
|
89
|
+
tools:
|
|
90
|
+
- delegate_to_agent
|
|
91
|
+
---
|
|
92
|
+
Body`);
|
|
93
|
+
await expect(parseAgentMarkdown(filePath)).rejects.toThrow(/tools list cannot include 'delegate_to_agent'/);
|
|
94
|
+
});
|
|
95
|
+
it('should parse a valid remote agent markdown file', async () => {
|
|
96
|
+
const filePath = await writeAgentMarkdown(`---
|
|
97
|
+
kind: remote
|
|
98
|
+
name: remote-agent
|
|
99
|
+
description: A remote agent
|
|
100
|
+
agent_card_url: https://example.com/card
|
|
101
|
+
---
|
|
102
|
+
`);
|
|
103
|
+
const result = await parseAgentMarkdown(filePath);
|
|
104
|
+
expect(result).toHaveLength(1);
|
|
105
|
+
expect(result[0]).toEqual({
|
|
106
|
+
kind: 'remote',
|
|
107
|
+
name: 'remote-agent',
|
|
108
|
+
description: 'A remote agent',
|
|
109
|
+
agent_card_url: 'https://example.com/card',
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
it('should infer remote agent kind from agent_card_url', async () => {
|
|
113
|
+
const filePath = await writeAgentMarkdown(`---
|
|
114
|
+
name: inferred-remote
|
|
115
|
+
description: Inferred
|
|
116
|
+
agent_card_url: https://example.com/inferred
|
|
117
|
+
---
|
|
118
|
+
`);
|
|
119
|
+
const result = await parseAgentMarkdown(filePath);
|
|
120
|
+
expect(result).toHaveLength(1);
|
|
121
|
+
expect(result[0]).toEqual({
|
|
122
|
+
kind: 'remote',
|
|
123
|
+
name: 'inferred-remote',
|
|
124
|
+
description: 'Inferred',
|
|
125
|
+
agent_card_url: 'https://example.com/inferred',
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
it('should parse a remote agent with no body', async () => {
|
|
129
|
+
const filePath = await writeAgentMarkdown(`---
|
|
130
|
+
kind: remote
|
|
131
|
+
name: no-body-remote
|
|
132
|
+
agent_card_url: https://example.com/card
|
|
133
|
+
---
|
|
134
|
+
`);
|
|
135
|
+
const result = await parseAgentMarkdown(filePath);
|
|
136
|
+
expect(result).toHaveLength(1);
|
|
137
|
+
expect(result[0]).toEqual({
|
|
138
|
+
kind: 'remote',
|
|
139
|
+
name: 'no-body-remote',
|
|
140
|
+
agent_card_url: 'https://example.com/card',
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
it('should parse multiple remote agents in a list', async () => {
|
|
144
|
+
const filePath = await writeAgentMarkdown(`---
|
|
145
|
+
- kind: remote
|
|
146
|
+
name: remote-1
|
|
147
|
+
agent_card_url: https://example.com/1
|
|
148
|
+
- kind: remote
|
|
149
|
+
name: remote-2
|
|
150
|
+
agent_card_url: https://example.com/2
|
|
151
|
+
---
|
|
152
|
+
`);
|
|
153
|
+
const result = await parseAgentMarkdown(filePath);
|
|
154
|
+
expect(result).toHaveLength(2);
|
|
155
|
+
expect(result[0]).toEqual({
|
|
156
|
+
kind: 'remote',
|
|
157
|
+
name: 'remote-1',
|
|
158
|
+
agent_card_url: 'https://example.com/1',
|
|
159
|
+
});
|
|
160
|
+
expect(result[1]).toEqual({
|
|
161
|
+
kind: 'remote',
|
|
162
|
+
name: 'remote-2',
|
|
163
|
+
agent_card_url: 'https://example.com/2',
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
describe('markdownToAgentDefinition', () => {
|
|
168
|
+
it('should convert valid Markdown DTO to AgentDefinition with defaults', () => {
|
|
169
|
+
const markdown = {
|
|
170
|
+
kind: 'local',
|
|
171
|
+
name: 'test-agent',
|
|
172
|
+
description: 'A test agent',
|
|
173
|
+
system_prompt: 'You are a test agent.',
|
|
174
|
+
};
|
|
175
|
+
const result = markdownToAgentDefinition(markdown);
|
|
176
|
+
expect(result).toMatchObject({
|
|
177
|
+
name: 'test-agent',
|
|
178
|
+
description: 'A test agent',
|
|
179
|
+
promptConfig: {
|
|
180
|
+
systemPrompt: 'You are a test agent.',
|
|
181
|
+
query: '${query}',
|
|
182
|
+
},
|
|
183
|
+
modelConfig: {
|
|
184
|
+
model: 'inherit',
|
|
185
|
+
top_p: 0.95,
|
|
186
|
+
},
|
|
187
|
+
runConfig: {
|
|
188
|
+
max_time_minutes: 5,
|
|
189
|
+
},
|
|
190
|
+
inputConfig: {
|
|
191
|
+
inputs: {
|
|
192
|
+
query: {
|
|
193
|
+
type: 'string',
|
|
194
|
+
required: false,
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
it('should pass through model aliases', () => {
|
|
201
|
+
const markdown = {
|
|
202
|
+
kind: 'local',
|
|
203
|
+
name: 'test-agent',
|
|
204
|
+
description: 'A test agent',
|
|
205
|
+
model: GEMINI_MODEL_ALIAS_PRO,
|
|
206
|
+
system_prompt: 'You are a test agent.',
|
|
207
|
+
};
|
|
208
|
+
const result = markdownToAgentDefinition(markdown);
|
|
209
|
+
expect(result.modelConfig.model).toBe(GEMINI_MODEL_ALIAS_PRO);
|
|
210
|
+
});
|
|
211
|
+
it('should pass through unknown model names (e.g. auto)', () => {
|
|
212
|
+
const markdown = {
|
|
213
|
+
kind: 'local',
|
|
214
|
+
name: 'test-agent',
|
|
215
|
+
description: 'A test agent',
|
|
216
|
+
model: 'auto',
|
|
217
|
+
system_prompt: 'You are a test agent.',
|
|
218
|
+
};
|
|
219
|
+
const result = markdownToAgentDefinition(markdown);
|
|
220
|
+
expect(result.modelConfig.model).toBe('auto');
|
|
221
|
+
});
|
|
222
|
+
it('should convert remote agent definition', () => {
|
|
223
|
+
const markdown = {
|
|
224
|
+
kind: 'remote',
|
|
225
|
+
name: 'remote-agent',
|
|
226
|
+
description: 'A remote agent',
|
|
227
|
+
agent_card_url: 'https://example.com/card',
|
|
228
|
+
};
|
|
229
|
+
const result = markdownToAgentDefinition(markdown);
|
|
230
|
+
expect(result).toEqual({
|
|
231
|
+
kind: 'remote',
|
|
232
|
+
name: 'remote-agent',
|
|
233
|
+
description: 'A remote agent',
|
|
234
|
+
displayName: undefined,
|
|
235
|
+
agentCardUrl: 'https://example.com/card',
|
|
236
|
+
inputConfig: {
|
|
237
|
+
inputs: {
|
|
238
|
+
query: {
|
|
239
|
+
type: 'string',
|
|
240
|
+
description: 'The task for the agent.',
|
|
241
|
+
required: false,
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
describe('loadAgentsFromDirectory', () => {
|
|
249
|
+
it('should load definitions from a directory (Markdown only)', async () => {
|
|
250
|
+
await writeAgentMarkdown(`---
|
|
251
|
+
name: agent-1
|
|
252
|
+
description: Agent 1
|
|
253
|
+
---
|
|
254
|
+
Prompt 1`, 'valid.md');
|
|
255
|
+
// Create a non-supported file
|
|
256
|
+
await fs.writeFile(path.join(tempDir, 'other.txt'), 'content');
|
|
257
|
+
// Create a hidden file
|
|
258
|
+
await writeAgentMarkdown(`---
|
|
259
|
+
name: hidden
|
|
260
|
+
description: Hidden
|
|
261
|
+
---
|
|
262
|
+
Hidden`, '_hidden.md');
|
|
263
|
+
const result = await loadAgentsFromDirectory(tempDir);
|
|
264
|
+
expect(result.agents).toHaveLength(1);
|
|
265
|
+
expect(result.agents[0].name).toBe('agent-1');
|
|
266
|
+
expect(result.errors).toHaveLength(0);
|
|
267
|
+
});
|
|
268
|
+
it('should return empty result if directory does not exist', async () => {
|
|
269
|
+
const nonExistentDir = path.join(tempDir, 'does-not-exist');
|
|
270
|
+
const result = await loadAgentsFromDirectory(nonExistentDir);
|
|
271
|
+
expect(result.agents).toHaveLength(0);
|
|
272
|
+
expect(result.errors).toHaveLength(0);
|
|
273
|
+
});
|
|
274
|
+
it('should capture errors for malformed individual files', async () => {
|
|
275
|
+
// Create a malformed Markdown file
|
|
276
|
+
await writeAgentMarkdown('invalid markdown', 'malformed.md');
|
|
277
|
+
const result = await loadAgentsFromDirectory(tempDir);
|
|
278
|
+
expect(result.agents).toHaveLength(0);
|
|
279
|
+
expect(result.errors).toHaveLength(1);
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
//# sourceMappingURL=agentLoader.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentLoader.test.js","sourceRoot":"","sources":["../../../src/agents/agentLoader.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,uBAAuB,EACvB,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAG7D,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,IAAI,OAAe,CAAC;IAEpB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,KAAK,UAAU,kBAAkB,CAAC,OAAe,EAAE,QAAQ,GAAG,SAAS;QACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC9C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACtC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC;;;;0BAItB,CAAC,CAAC;YAEtB,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAClD,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;gBAC9B,IAAI,EAAE,eAAe;gBACrB,WAAW,EAAE,kBAAkB;gBAC/B,IAAI,EAAE,OAAO;gBACb,aAAa,EAAE,2BAA2B;aAC3C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;YACpE,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC;;;;;;;;uBAQzB,CAAC,CAAC;YAEnB,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAClD,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;gBAC9B,IAAI,EAAE,eAAe;gBACrB,WAAW,EAAE,0BAA0B;gBACvC,KAAK,EAAE,CAAC,mBAAmB,CAAC;gBAC5B,KAAK,EAAE,YAAY;gBACnB,WAAW,EAAE,GAAG;gBAChB,aAAa,EAAE,wBAAwB;aACxC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;YACrE,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,6BAA6B,CAAC,CAAC;YACzE,MAAM,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACxD,cAAc,CACf,CAAC;YACF,MAAM,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACxD,yBAAyB,CAC1B,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;YAC1E,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC;;;KAG3C,CAAC,CAAC;YACD,MAAM,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACxD,cAAc,CACf,CAAC;YACF,MAAM,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACxD,iCAAiC,CAClC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;YACxF,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC;;;;KAI3C,CAAC,CAAC;YACD,MAAM,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACxD,mBAAmB,CACpB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;YACjF,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC;;;;;;KAM3C,CAAC,CAAC;YACD,MAAM,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACxD,+CAA+C,CAChD,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC/D,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC;;;;;;CAM/C,CAAC,CAAC;YACG,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAClD,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;gBACxB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,cAAc;gBACpB,WAAW,EAAE,gBAAgB;gBAC7B,cAAc,EAAE,0BAA0B;aAC3C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;YAClE,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC;;;;;CAK/C,CAAC,CAAC;YACG,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAClD,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;gBACxB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,iBAAiB;gBACvB,WAAW,EAAE,UAAU;gBACvB,cAAc,EAAE,8BAA8B;aAC/C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC;;;;;CAK/C,CAAC,CAAC;YACG,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAClD,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;gBACxB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,gBAAgB;gBACtB,cAAc,EAAE,0BAA0B;aAC3C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;YAC7D,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC;;;;;;;;CAQ/C,CAAC,CAAC;YACG,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAClD,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;gBACxB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,UAAU;gBAChB,cAAc,EAAE,uBAAuB;aACxC,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;gBACxB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,UAAU;gBAChB,cAAc,EAAE,uBAAuB;aACxC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACzC,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;YAC5E,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,OAAgB;gBACtB,IAAI,EAAE,YAAY;gBAClB,WAAW,EAAE,cAAc;gBAC3B,aAAa,EAAE,uBAAuB;aACvC,CAAC;YAEF,MAAM,MAAM,GAAG,yBAAyB,CAAC,QAAQ,CAAC,CAAC;YACnD,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC;gBAC3B,IAAI,EAAE,YAAY;gBAClB,WAAW,EAAE,cAAc;gBAC3B,YAAY,EAAE;oBACZ,YAAY,EAAE,uBAAuB;oBACrC,KAAK,EAAE,UAAU;iBAClB;gBACD,WAAW,EAAE;oBACX,KAAK,EAAE,SAAS;oBAChB,KAAK,EAAE,IAAI;iBACZ;gBACD,SAAS,EAAE;oBACT,gBAAgB,EAAE,CAAC;iBACpB;gBACD,WAAW,EAAE;oBACX,MAAM,EAAE;wBACN,KAAK,EAAE;4BACL,IAAI,EAAE,QAAQ;4BACd,QAAQ,EAAE,KAAK;yBAChB;qBACF;iBACF;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,OAAgB;gBACtB,IAAI,EAAE,YAAY;gBAClB,WAAW,EAAE,cAAc;gBAC3B,KAAK,EAAE,sBAAsB;gBAC7B,aAAa,EAAE,uBAAuB;aACvC,CAAC;YAEF,MAAM,MAAM,GAAG,yBAAyB,CACtC,QAAQ,CACe,CAAC;YAC1B,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;YAC7D,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,OAAgB;gBACtB,IAAI,EAAE,YAAY;gBAClB,WAAW,EAAE,cAAc;gBAC3B,KAAK,EAAE,MAAM;gBACb,aAAa,EAAE,uBAAuB;aACvC,CAAC;YAEF,MAAM,MAAM,GAAG,yBAAyB,CACtC,QAAQ,CACe,CAAC;YAC1B,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,QAAiB;gBACvB,IAAI,EAAE,cAAc;gBACpB,WAAW,EAAE,gBAAgB;gBAC7B,cAAc,EAAE,0BAA0B;aAC3C,CAAC;YAEF,MAAM,MAAM,GAAG,yBAAyB,CAAC,QAAQ,CAAC,CAAC;YACnD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,cAAc;gBACpB,WAAW,EAAE,gBAAgB;gBAC7B,WAAW,EAAE,SAAS;gBACtB,YAAY,EAAE,0BAA0B;gBACxC,WAAW,EAAE;oBACX,MAAM,EAAE;wBACN,KAAK,EAAE;4BACL,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,yBAAyB;4BACtC,QAAQ,EAAE,KAAK;yBAChB;qBACF;iBACF;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACvC,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;YACxE,MAAM,kBAAkB,CACtB;;;;SAIC,EACD,UAAU,CACX,CAAC;YAEF,8BAA8B;YAC9B,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,SAAS,CAAC,CAAC;YAE/D,uBAAuB;YACvB,MAAM,kBAAkB,CACtB;;;;OAID,EACC,YAAY,CACb,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC,CAAC;YACtD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACtC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;YACtE,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;YAC5D,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAC,cAAc,CAAC,CAAC;YAC7D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACtC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;YACpE,mCAAmC;YACnC,MAAM,kBAAkB,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;YAE7D,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC,CAAC;YACtD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACtC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { AgentDefinition } from './types.js';
|
|
7
7
|
import { z } from 'zod';
|
|
8
|
-
|
|
8
|
+
import type { Config } from '../config/config.js';
|
|
9
|
+
declare const CliHelpReportSchema: z.ZodObject<{
|
|
9
10
|
answer: z.ZodString;
|
|
10
11
|
sources: z.ZodArray<z.ZodString, "many">;
|
|
11
12
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -19,5 +20,5 @@ declare const IntrospectionReportSchema: z.ZodObject<{
|
|
|
19
20
|
* An agent specialized in answering questions about Gemini CLI itself,
|
|
20
21
|
* using its own documentation and runtime state.
|
|
21
22
|
*/
|
|
22
|
-
export declare const
|
|
23
|
+
export declare const CliHelpAgent: (config: Config) => AgentDefinition<typeof CliHelpReportSchema>;
|
|
23
24
|
export {};
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { GET_INTERNAL_DOCS_TOOL_NAME } from '../tools/tool-names.js';
|
|
7
6
|
import { GEMINI_MODEL_ALIAS_FLASH } from '../config/models.js';
|
|
8
7
|
import { z } from 'zod';
|
|
9
|
-
|
|
8
|
+
import { GetInternalDocsTool } from '../tools/get-internal-docs.js';
|
|
9
|
+
const CliHelpReportSchema = z.object({
|
|
10
10
|
answer: z
|
|
11
11
|
.string()
|
|
12
12
|
.describe('The detailed answer to the user question about Gemini CLI.'),
|
|
@@ -18,11 +18,11 @@ const IntrospectionReportSchema = z.object({
|
|
|
18
18
|
* An agent specialized in answering questions about Gemini CLI itself,
|
|
19
19
|
* using its own documentation and runtime state.
|
|
20
20
|
*/
|
|
21
|
-
export const
|
|
22
|
-
name: '
|
|
21
|
+
export const CliHelpAgent = (config) => ({
|
|
22
|
+
name: 'cli_help',
|
|
23
23
|
kind: 'local',
|
|
24
|
-
displayName: '
|
|
25
|
-
description: 'Specialized in answering questions about
|
|
24
|
+
displayName: 'CLI Help Agent',
|
|
25
|
+
description: 'Specialized in answering questions about how users use you, (Gemini CLI): features, documentation, and current runtime configuration.',
|
|
26
26
|
inputConfig: {
|
|
27
27
|
inputs: {
|
|
28
28
|
question: {
|
|
@@ -35,7 +35,7 @@ export const IntrospectionAgent = {
|
|
|
35
35
|
outputConfig: {
|
|
36
36
|
outputName: 'report',
|
|
37
37
|
description: 'The final answer and sources as a JSON object.',
|
|
38
|
-
schema:
|
|
38
|
+
schema: CliHelpReportSchema,
|
|
39
39
|
},
|
|
40
40
|
processOutput: (output) => JSON.stringify(output, null, 2),
|
|
41
41
|
modelConfig: {
|
|
@@ -49,18 +49,24 @@ export const IntrospectionAgent = {
|
|
|
49
49
|
max_turns: 10,
|
|
50
50
|
},
|
|
51
51
|
toolConfig: {
|
|
52
|
-
tools: [
|
|
52
|
+
tools: [new GetInternalDocsTool(config.getMessageBus())],
|
|
53
53
|
},
|
|
54
54
|
promptConfig: {
|
|
55
55
|
query: 'Your task is to answer the following question about Gemini CLI:\n' +
|
|
56
56
|
'<question>\n' +
|
|
57
57
|
'${question}\n' +
|
|
58
58
|
'</question>',
|
|
59
|
-
systemPrompt: "You are **
|
|
59
|
+
systemPrompt: "You are **CLI Help Agent**, an expert on Gemini CLI. Your purpose is to provide accurate information about Gemini CLI's features, configuration, and current state.\n\n" +
|
|
60
60
|
'### Runtime Context\n' +
|
|
61
61
|
'- **CLI Version:** ${cliVersion}\n' +
|
|
62
62
|
'- **Active Model:** ${activeModel}\n' +
|
|
63
63
|
"- **Today's Date:** ${today}\n\n" +
|
|
64
|
+
(config.isAgentsEnabled()
|
|
65
|
+
? '### Sub-Agents (Local & Remote)\n' +
|
|
66
|
+
'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' +
|
|
67
|
+
'- **Local Agent:** `kind = "local"`, `name`, `description`, `prompts.system_prompt`, and optional `tools`, `model`, `run`.\n' +
|
|
68
|
+
'- **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'
|
|
69
|
+
: '') +
|
|
64
70
|
'### Instructions\n' +
|
|
65
71
|
"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" +
|
|
66
72
|
'2. **Be Precise**: Use the provided runtime context and documentation to give exact answers.\n' +
|
|
@@ -68,5 +74,5 @@ export const IntrospectionAgent = {
|
|
|
68
74
|
'4. **Non-Interactive**: You operate in a loop and cannot ask the user for more info. If the question is ambiguous, answer as best as you can with the information available.\n\n' +
|
|
69
75
|
'You MUST call `complete_task` with a JSON report containing your `answer` and the `sources` you used.',
|
|
70
76
|
},
|
|
71
|
-
};
|
|
72
|
-
//# sourceMappingURL=
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=cli-help-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-help-agent.js","sourceRoot":"","sources":["../../../src/agents/cli-help-agent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEpE,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,QAAQ,CAAC,4DAA4D,CAAC;IACzE,OAAO,EAAE,CAAC;SACP,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,CAAC,sDAAsD,CAAC;CACpE,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,MAAc,EAC+B,EAAE,CAAC,CAAC;IACjD,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,gBAAgB;IAC7B,WAAW,EACT,uIAAuI;IACzI,WAAW,EAAE;QACX,MAAM,EAAE;YACN,QAAQ,EAAE;gBACR,WAAW,EAAE,yCAAyC;gBACtD,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI;aACf;SACF;KACF;IACD,YAAY,EAAE;QACZ,UAAU,EAAE,QAAQ;QACpB,WAAW,EAAE,gDAAgD;QAC7D,MAAM,EAAE,mBAAmB;KAC5B;IAED,aAAa,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1D,WAAW,EAAE;QACX,KAAK,EAAE,wBAAwB;QAC/B,IAAI,EAAE,GAAG;QACT,KAAK,EAAE,IAAI;QACX,cAAc,EAAE,CAAC,CAAC;KACnB;IAED,SAAS,EAAE;QACT,gBAAgB,EAAE,CAAC;QACnB,SAAS,EAAE,EAAE;KACd;IAED,UAAU,EAAE;QACV,KAAK,EAAE,CAAC,IAAI,mBAAmB,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;KACzD;IAED,YAAY,EAAE;QACZ,KAAK,EACH,mEAAmE;YACnE,cAAc;YACd,eAAe;YACf,aAAa;QACf,YAAY,EACV,yKAAyK;YACzK,uBAAuB;YACvB,oCAAoC;YACpC,sCAAsC;YACtC,kCAAkC;YAClC,CAAC,MAAM,CAAC,eAAe,EAAE;gBACvB,CAAC,CAAC,mCAAmC;oBACnC,kRAAkR;oBAClR,8HAA8H;oBAC9H,gSAAgS;gBAClS,CAAC,CAAC,EAAE,CAAC;YACP,oBAAoB;YACpB,yNAAyN;YACzN,gGAAgG;YAChG,uGAAuG;YACvG,kLAAkL;YAClL,uGAAuG;KAC1G;CACF,CAAC,CAAC"}
|
|
@@ -4,15 +4,19 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { describe, it, expect } from 'vitest';
|
|
7
|
-
import {
|
|
7
|
+
import { CliHelpAgent } from './cli-help-agent.js';
|
|
8
8
|
import { GET_INTERNAL_DOCS_TOOL_NAME } from '../tools/tool-names.js';
|
|
9
9
|
import { GEMINI_MODEL_ALIAS_FLASH } from '../config/models.js';
|
|
10
|
-
describe('
|
|
11
|
-
const
|
|
10
|
+
describe('CliHelpAgent', () => {
|
|
11
|
+
const fakeConfig = {
|
|
12
|
+
getMessageBus: () => ({}),
|
|
13
|
+
isAgentsEnabled: () => false,
|
|
14
|
+
};
|
|
15
|
+
const localAgent = CliHelpAgent(fakeConfig);
|
|
12
16
|
it('should have the correct agent definition metadata', () => {
|
|
13
|
-
expect(localAgent.name).toBe('
|
|
17
|
+
expect(localAgent.name).toBe('cli_help');
|
|
14
18
|
expect(localAgent.kind).toBe('local');
|
|
15
|
-
expect(localAgent.displayName).toBe('
|
|
19
|
+
expect(localAgent.displayName).toBe('CLI Help Agent');
|
|
16
20
|
expect(localAgent.description).toContain('Gemini CLI');
|
|
17
21
|
});
|
|
18
22
|
it('should have correctly configured inputs and outputs', () => {
|
|
@@ -24,7 +28,7 @@ describe('IntrospectionAgent', () => {
|
|
|
24
28
|
it('should use the correct model and tools', () => {
|
|
25
29
|
expect(localAgent.modelConfig?.model).toBe(GEMINI_MODEL_ALIAS_FLASH);
|
|
26
30
|
const tools = localAgent.toolConfig?.tools || [];
|
|
27
|
-
const hasInternalDocsTool = tools.
|
|
31
|
+
const hasInternalDocsTool = tools.some((t) => typeof t !== 'string' && t.name === GET_INTERNAL_DOCS_TOOL_NAME);
|
|
28
32
|
expect(hasInternalDocsTool).toBe(true);
|
|
29
33
|
});
|
|
30
34
|
it('should have expected prompt placeholders', () => {
|
|
@@ -35,6 +39,20 @@ describe('IntrospectionAgent', () => {
|
|
|
35
39
|
const query = localAgent.promptConfig.query || '';
|
|
36
40
|
expect(query).toContain('${question}');
|
|
37
41
|
});
|
|
42
|
+
it('should include sub-agent information when agents are enabled', () => {
|
|
43
|
+
const enabledConfig = {
|
|
44
|
+
getMessageBus: () => ({}),
|
|
45
|
+
isAgentsEnabled: () => true,
|
|
46
|
+
getAgentRegistry: () => ({
|
|
47
|
+
getDirectoryContext: () => 'Mock Agent Directory',
|
|
48
|
+
}),
|
|
49
|
+
};
|
|
50
|
+
const agent = CliHelpAgent(enabledConfig);
|
|
51
|
+
const systemPrompt = agent.promptConfig.systemPrompt || '';
|
|
52
|
+
expect(systemPrompt).toContain('### Sub-Agents (Local & Remote)');
|
|
53
|
+
expect(systemPrompt).toContain('Remote Agent (A2A)');
|
|
54
|
+
expect(systemPrompt).toContain('Agent2Agent functionality');
|
|
55
|
+
});
|
|
38
56
|
it('should process output to a formatted JSON string', () => {
|
|
39
57
|
const mockOutput = {
|
|
40
58
|
answer: 'This is the answer.',
|
|
@@ -44,4 +62,4 @@ describe('IntrospectionAgent', () => {
|
|
|
44
62
|
expect(processed).toBe(JSON.stringify(mockOutput, null, 2));
|
|
45
63
|
});
|
|
46
64
|
});
|
|
47
|
-
//# sourceMappingURL=
|
|
65
|
+
//# sourceMappingURL=cli-help-agent.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-help-agent.test.js","sourceRoot":"","sources":["../../../src/agents/cli-help-agent.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAI/D,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,MAAM,UAAU,GAAG;QACjB,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;QACzB,eAAe,EAAE,GAAG,EAAE,CAAC,KAAK;KACR,CAAC;IACvB,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,CAAyB,CAAC;IAEpE,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACtD,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAChE,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEtE,MAAM,CAAC,UAAU,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3D,MAAM,CAAC,UAAU,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAErE,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC;QACjD,MAAM,mBAAmB,GAAG,KAAK,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,2BAA2B,CACvE,CAAC;QACF,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,YAAY,GAAG,UAAU,CAAC,YAAY,CAAC,YAAY,IAAI,EAAE,CAAC;QAChE,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAChD,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QACjD,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAE3C,MAAM,KAAK,GAAG,UAAU,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,aAAa,GAAG;YACpB,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;YACzB,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI;YAC3B,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;gBACvB,mBAAmB,EAAE,GAAG,EAAE,CAAC,sBAAsB;aAClD,CAAC;SACkB,CAAC;QACvB,MAAM,KAAK,GAAG,YAAY,CAAC,aAAa,CAAyB,CAAC;QAClE,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC,YAAY,IAAI,EAAE,CAAC;QAE3D,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAC;QAClE,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QACrD,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,UAAU,GAAG;YACjB,MAAM,EAAE,qBAAqB;YAC7B,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;SAClC,CAAC;QACF,MAAM,SAAS,GAAG,UAAU,CAAC,aAAa,EAAE,CAAC,UAAU,CAAC,CAAC;QACzD,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -95,21 +95,28 @@ class DelegateInvocation extends BaseToolInvocation {
|
|
|
95
95
|
getDescription() {
|
|
96
96
|
return `Delegating to agent '${this.params.agent_name}'`;
|
|
97
97
|
}
|
|
98
|
+
async shouldConfirmExecute(abortSignal) {
|
|
99
|
+
const definition = this.registry.getDefinition(this.params.agent_name);
|
|
100
|
+
if (!definition || definition.kind !== 'remote') {
|
|
101
|
+
// Local agents should execute without confirmation. Inner tool calls will bubble up their own confirmations to the user.
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
const { agent_name: _agent_name, ...agentArgs } = this.params;
|
|
105
|
+
const invocation = this.buildSubInvocation(definition, agentArgs);
|
|
106
|
+
return invocation.shouldConfirmExecute(abortSignal);
|
|
107
|
+
}
|
|
98
108
|
async execute(signal, updateOutput) {
|
|
99
109
|
const definition = this.registry.getDefinition(this.params.agent_name);
|
|
100
110
|
if (!definition) {
|
|
101
|
-
throw new Error(`Agent '${this.params.agent_name}'
|
|
111
|
+
throw new Error(`Agent '${this.params.agent_name}' not found in registry.`);
|
|
102
112
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const { agent_name, ...agentArgs } = this.params;
|
|
106
|
-
// Delegate the creation of the specific invocation (Local or Remote) to the wrapper.
|
|
107
|
-
// This centralizes the logic and ensures consistent handling.
|
|
108
|
-
const wrapper = new SubagentToolWrapper(definition, this.config, this.messageBus);
|
|
109
|
-
// We could skip extra validation here if we trust the Registry's schema,
|
|
110
|
-
// but build() will do a safety check anyway.
|
|
111
|
-
const invocation = wrapper.build(agentArgs);
|
|
113
|
+
const { agent_name: _agent_name, ...agentArgs } = this.params;
|
|
114
|
+
const invocation = this.buildSubInvocation(definition, agentArgs);
|
|
112
115
|
return invocation.execute(signal, updateOutput);
|
|
113
116
|
}
|
|
117
|
+
buildSubInvocation(definition, agentArgs) {
|
|
118
|
+
const wrapper = new SubagentToolWrapper(definition, this.config, this.messageBus);
|
|
119
|
+
return wrapper.build(agentArgs);
|
|
120
|
+
}
|
|
114
121
|
}
|
|
115
122
|
//# sourceMappingURL=delegate-to-agent-tool.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegate-to-agent-tool.js","sourceRoot":"","sources":["../../../src/agents/delegate-to-agent-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,mBAAmB,EACnB,IAAI,EAGJ,kBAAkB,
|
|
1
|
+
{"version":3,"file":"delegate-to-agent-tool.js","sourceRoot":"","sources":["../../../src/agents/delegate-to-agent-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,7 @@ vi.mock('./local-invocation.js', () => ({
|
|
|
16
16
|
execute: vi
|
|
17
17
|
.fn()
|
|
18
18
|
.mockResolvedValue({ content: [{ type: 'text', text: 'Success' }] }),
|
|
19
|
+
shouldConfirmExecute: vi.fn().mockResolvedValue(false),
|
|
19
20
|
})),
|
|
20
21
|
}));
|
|
21
22
|
vi.mock('./remote-invocation.js', () => ({
|
|
@@ -23,7 +24,12 @@ vi.mock('./remote-invocation.js', () => ({
|
|
|
23
24
|
execute: vi.fn().mockResolvedValue({
|
|
24
25
|
content: [{ type: 'text', text: 'Remote Success' }],
|
|
25
26
|
}),
|
|
26
|
-
shouldConfirmExecute: vi.fn().mockResolvedValue(
|
|
27
|
+
shouldConfirmExecute: vi.fn().mockResolvedValue({
|
|
28
|
+
type: 'info',
|
|
29
|
+
title: 'Remote Confirmation',
|
|
30
|
+
prompt: 'Confirm remote call',
|
|
31
|
+
onConfirm: vi.fn(),
|
|
32
|
+
}),
|
|
27
33
|
})),
|
|
28
34
|
}));
|
|
29
35
|
describe('DelegateToAgentTool', () => {
|
|
@@ -135,20 +141,20 @@ describe('DelegateToAgentTool', () => {
|
|
|
135
141
|
registry.agents.set(invalidAgentDef.name, invalidAgentDef);
|
|
136
142
|
expect(() => new DelegateToAgentTool(registry, config, messageBus)).toThrow("Agent 'invalid_agent' cannot have an input parameter named 'agent_name' as it is a reserved parameter for delegation.");
|
|
137
143
|
});
|
|
138
|
-
it('should
|
|
144
|
+
it('should execute local agents silently without requesting confirmation', async () => {
|
|
139
145
|
const invocation = tool.build({
|
|
140
146
|
agent_name: 'test_agent',
|
|
141
147
|
arg1: 'valid',
|
|
142
148
|
});
|
|
143
149
|
// Trigger confirmation check
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
const result = await invocation.shouldConfirmExecute(new AbortController().signal);
|
|
151
|
+
expect(result).toBe(false);
|
|
152
|
+
// Verify it did NOT call messageBus.publish with 'delegate_to_agent'
|
|
153
|
+
const delegateToAgentPublish = vi
|
|
154
|
+
.mocked(messageBus.publish)
|
|
155
|
+
.mock.calls.find((call) => call[0].type === MessageBusType.TOOL_CONFIRMATION_REQUEST &&
|
|
156
|
+
call[0].toolCall.name === DELEGATE_TO_AGENT_TOOL_NAME);
|
|
157
|
+
expect(delegateToAgentPublish).toBeUndefined();
|
|
152
158
|
});
|
|
153
159
|
it('should delegate to remote agent correctly', async () => {
|
|
154
160
|
const invocation = tool.build({
|
|
@@ -161,5 +167,41 @@ describe('DelegateToAgentTool', () => {
|
|
|
161
167
|
});
|
|
162
168
|
expect(RemoteAgentInvocation).toHaveBeenCalledWith(mockRemoteAgentDef, { query: 'hello remote' }, messageBus, 'remote_agent', 'remote_agent');
|
|
163
169
|
});
|
|
170
|
+
describe('Confirmation', () => {
|
|
171
|
+
it('should return false for local agents (silent execution)', async () => {
|
|
172
|
+
const invocation = tool.build({
|
|
173
|
+
agent_name: 'test_agent',
|
|
174
|
+
arg1: 'valid',
|
|
175
|
+
});
|
|
176
|
+
// Local agents should now return false directly, bypassing policy check
|
|
177
|
+
const result = await invocation.shouldConfirmExecute(new AbortController().signal);
|
|
178
|
+
expect(result).toBe(false);
|
|
179
|
+
const delegateToAgentPublish = vi
|
|
180
|
+
.mocked(messageBus.publish)
|
|
181
|
+
.mock.calls.find((call) => call[0].type === MessageBusType.TOOL_CONFIRMATION_REQUEST &&
|
|
182
|
+
call[0].toolCall.name === DELEGATE_TO_AGENT_TOOL_NAME);
|
|
183
|
+
expect(delegateToAgentPublish).toBeUndefined();
|
|
184
|
+
});
|
|
185
|
+
it('should forward to remote agent confirmation logic', async () => {
|
|
186
|
+
const invocation = tool.build({
|
|
187
|
+
agent_name: 'remote_agent',
|
|
188
|
+
query: 'hello remote',
|
|
189
|
+
});
|
|
190
|
+
const result = await invocation.shouldConfirmExecute(new AbortController().signal);
|
|
191
|
+
// Verify it returns the mock confirmation from RemoteAgentInvocation
|
|
192
|
+
expect(result).toMatchObject({
|
|
193
|
+
type: 'info',
|
|
194
|
+
title: 'Remote Confirmation',
|
|
195
|
+
});
|
|
196
|
+
// Verify it did NOT call messageBus.publish with 'delegate_to_agent'
|
|
197
|
+
// directly from DelegateInvocation, but instead went into RemoteAgentInvocation.
|
|
198
|
+
// RemoteAgentInvocation (the mock) doesn't call publish in its mock implementation.
|
|
199
|
+
const delegateToAgentPublish = vi
|
|
200
|
+
.mocked(messageBus.publish)
|
|
201
|
+
.mock.calls.find((call) => call[0].type === MessageBusType.TOOL_CONFIRMATION_REQUEST &&
|
|
202
|
+
call[0].toolCall.name === DELEGATE_TO_AGENT_TOOL_NAME);
|
|
203
|
+
expect(delegateToAgentPublish).toBeUndefined();
|
|
204
|
+
});
|
|
205
|
+
});
|
|
164
206
|
});
|
|
165
207
|
//# sourceMappingURL=delegate-to-agent-tool.test.js.map
|