refactor(core): rename task tool to agent

- Update tool name aliases to map 'task' to 'agent' as legacy alias
- Add proper 'agent' tool name aliases (Agent, AgentTool)
- Update canonical-to-rule display mapping from 'task' to 'Agent'
- Update tests to expect 'agent' instead of 'task'
- Fix debug log message from [TaskTool] to [Agent]

This completes the tool renaming from "task" to "agent" for clarity,
as "agent" better describes the tool's purpose of delegating to
subagents.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
tanzhenxin 2026-03-20 15:50:06 +08:00
parent 9824e395a8
commit 19ed08098b
4 changed files with 29 additions and 20 deletions

View file

@ -305,7 +305,7 @@ OTHER AGENTS CANNOT:
if (isSDKAssistantMessage(message)) {
// Check for task tool use in content blocks (main agent calling subagent)
const taskToolBlocks = findToolUseBlocks(message, 'task');
const taskToolBlocks = findToolUseBlocks(message, 'agent');
if (taskToolBlocks.length > 0) {
foundTaskTool = true;
taskToolUseId = taskToolBlocks[0].id;
@ -399,7 +399,7 @@ OTHER AGENTS CANNOT:
// Check for task tool use (main agent delegating to subagent)
const toolUseBlock = message.message.content.find(
(block: ContentBlock): block is ToolUseBlock =>
block.type === 'tool_use' && block.name === 'task',
block.type === 'tool_use' && block.name === 'agent',
);
if (toolUseBlock) {
foundTaskTool = true;

View file

@ -49,7 +49,15 @@ describe('resolveToolName', () => {
});
it('resolves Agent category', () => {
expect(resolveToolName('Agent')).toBe('task');
expect(resolveToolName('Agent')).toBe('agent');
expect(resolveToolName('agent')).toBe('agent');
expect(resolveToolName('AgentTool')).toBe('agent');
});
it('resolves legacy task aliases to agent', () => {
expect(resolveToolName('task')).toBe('agent');
expect(resolveToolName('Task')).toBe('agent');
expect(resolveToolName('TaskTool')).toBe('agent');
});
it('returns unknown names unchanged', () => {
@ -158,7 +166,7 @@ describe('parseRule', () => {
it('parses Agent with literal specifier', () => {
const r = parseRule('Agent(Explore)');
expect(r.toolName).toBe('task');
expect(r.toolName).toBe('agent');
expect(r.specifier).toBe('Explore');
expect(r.specifierKind).toBe('literal');
});
@ -798,7 +806,7 @@ describe('PermissionManager', () => {
it('returns default for unmatched tool', () => {
// Note: 'glob' is covered by ReadFileTool via Read meta-category,
// so use a tool not in any rule or meta-category
expect(pm.evaluate({ toolName: 'task' })).toBe('default');
expect(pm.evaluate({ toolName: 'agent' })).toBe('default');
});
it('deny takes precedence over ask and allow', () => {
@ -1294,8 +1302,8 @@ describe('getRuleDisplayName', () => {
expect(getRuleDisplayName('web_fetch')).toBe('WebFetch');
});
it('maps task to "Task" and skill to "Skill"', () => {
expect(getRuleDisplayName('task')).toBe('Task');
it('maps agent to "Agent" and skill to "Skill"', () => {
expect(getRuleDisplayName('agent')).toBe('Agent');
expect(getRuleDisplayName('skill')).toBe('Skill');
});
@ -1488,12 +1496,12 @@ describe('buildPermissionRules', () => {
expect(rules).toEqual(['Skill(Explore)']);
});
it('generates Task rule with specifier', () => {
it('generates Agent rule with specifier', () => {
const rules = buildPermissionRules({
toolName: 'task',
toolName: 'agent',
specifier: 'research',
});
expect(rules).toEqual(['Task(research)']);
expect(rules).toEqual(['Agent(research)']);
});
it('falls back to bare display name when no specifier', () => {

View file

@ -99,10 +99,15 @@ export const TOOL_NAME_ALIASES: Readonly<Record<string, string>> = {
WebSearch: 'web_search',
WebSearchTool: 'web_search',
// Task tool
task: 'task',
Task: 'task',
TaskTool: 'task',
// Agent (subagent) tool
agent: 'agent',
Agent: 'agent',
AgentTool: 'agent',
// Legacy aliases for the agent tool (renamed from "task")
task: 'agent',
Task: 'agent',
TaskTool: 'agent',
// Skill tool
skill: 'skill',
@ -121,10 +126,6 @@ export const TOOL_NAME_ALIASES: Readonly<Record<string, string>> = {
// Legacy edit tool name
replace: 'edit',
// Agent (subagent) rules — "Agent" is a user-friendly alias for the Task tool.
// "Agent(Explore)" is parsed with toolName = "task" and specifier = "Explore"
Agent: 'task',
};
/**
@ -301,7 +302,7 @@ const CANONICAL_TO_RULE_DISPLAY: Readonly<Record<string, string>> = {
web_fetch: 'WebFetch',
web_search: 'WebSearch',
// Agent / Skill
task: 'Task',
agent: 'Agent',
skill: 'Skill',
// Others
save_memory: 'SaveMemory',

View file

@ -534,7 +534,7 @@ class AgentToolInvocation extends BaseToolInvocation<AgentParams, ToolResult> {
}
} catch (hookError) {
debugLogger.warn(
`[TaskTool] SubagentStart hook failed, continuing execution: ${hookError}`,
`[Agent] SubagentStart hook failed, continuing execution: ${hookError}`,
);
}
}