refactor(core): 统一模板引擎到 src/template/ 目录
- 将 agent/prompt-template/ 目录合并到 src/template/
- 新增通用模板函数 renderTemplate、render
- 新增 Agent 特定函数 renderPromptTemplate、renderPrompt
- 新增 createToolDescriptionContext 支持工具描述模板变量
- 支持 ${GREP_TOOL_NAME} 等 Claude Code 风格变量
- 更新所有相关导入路径
This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import {
|
||||
renderTemplate,
|
||||
renderPromptTemplate,
|
||||
createDefaultContext,
|
||||
createPlanContext,
|
||||
createToolDescriptionContext,
|
||||
DEFAULT_TOOL_NAMES,
|
||||
} from '../../../src/agent/prompt-template/index.js';
|
||||
import type { PromptContext } from '../../../src/agent/prompt-template/types.js';
|
||||
} from '../../../src/template/index.js';
|
||||
import type { PromptContext } from '../../../src/template/types.js';
|
||||
|
||||
// Alias for backward compatibility in tests
|
||||
const renderTemplate = renderPromptTemplate;
|
||||
|
||||
describe('Prompt Template System', () => {
|
||||
let context: PromptContext;
|
||||
@@ -178,4 +182,74 @@ describe('Prompt Template System', () => {
|
||||
expect(result).toBe('primary');
|
||||
});
|
||||
});
|
||||
|
||||
describe('createToolDescriptionContext', () => {
|
||||
it('should create context with uppercase tool name variables', () => {
|
||||
const ctx = createToolDescriptionContext();
|
||||
// Check that uppercase tool names are available in custom
|
||||
expect(ctx.custom).toBeDefined();
|
||||
expect(ctx.custom!['GLOB_TOOL_NAME']).toBe('glob');
|
||||
expect(ctx.custom!['GREP_TOOL_NAME']).toBe('grep');
|
||||
expect(ctx.custom!['BASH_TOOL_NAME']).toBe('bash');
|
||||
expect(ctx.custom!['READ_TOOL_NAME']).toBe('read_file');
|
||||
expect(ctx.custom!['WRITE_TOOL_NAME']).toBe('write_file');
|
||||
expect(ctx.custom!['EDIT_TOOL_NAME']).toBe('edit_file');
|
||||
expect(ctx.custom!['TASK_TOOL_NAME']).toBe('task');
|
||||
});
|
||||
|
||||
it('should convert camelCase to UPPER_SNAKE_CASE correctly', () => {
|
||||
const ctx = createToolDescriptionContext();
|
||||
// askUserQuestion -> ASK_USER_QUESTION_TOOL_NAME
|
||||
expect(ctx.custom!['ASK_USER_QUESTION_TOOL_NAME']).toBe('ask_user_question');
|
||||
// exitPlanMode -> EXIT_PLAN_MODE_TOOL_NAME
|
||||
expect(ctx.custom!['EXIT_PLAN_MODE_TOOL_NAME']).toBe('exit_plan_mode');
|
||||
// webSearch -> WEB_SEARCH_TOOL_NAME
|
||||
expect(ctx.custom!['WEB_SEARCH_TOOL_NAME']).toBe('web_search');
|
||||
});
|
||||
|
||||
it('should support rendering with uppercase tool name variables', () => {
|
||||
const ctx = createToolDescriptionContext();
|
||||
const template = 'Use ${GREP_TOOL_NAME} for search. Never use ${BASH_TOOL_NAME} grep.';
|
||||
const result = renderTemplate(template, ctx);
|
||||
expect(result).toBe('Use grep for search. Never use bash grep.');
|
||||
});
|
||||
|
||||
it('should support both lowercase and uppercase variable styles', () => {
|
||||
const ctx = createToolDescriptionContext();
|
||||
const template = 'Tools: ${tools.grep} or ${GREP_TOOL_NAME}';
|
||||
const result = renderTemplate(template, ctx);
|
||||
expect(result).toBe('Tools: grep or grep');
|
||||
});
|
||||
|
||||
it('should preserve overrides', () => {
|
||||
const ctx = createToolDescriptionContext({
|
||||
agent: {
|
||||
name: 'custom-agent',
|
||||
mode: 'subagent',
|
||||
isSubagent: true,
|
||||
},
|
||||
});
|
||||
expect(ctx.agent.name).toBe('custom-agent');
|
||||
expect(ctx.agent.mode).toBe('subagent');
|
||||
expect(ctx.agent.isSubagent).toBe(true);
|
||||
// Uppercase tool names should still be available
|
||||
expect(ctx.custom!['GREP_TOOL_NAME']).toBe('grep');
|
||||
});
|
||||
|
||||
it('should render Claude Code style tool description template', () => {
|
||||
const ctx = createToolDescriptionContext();
|
||||
// Example from Claude Code official prompt
|
||||
const template = `A powerful search tool built on ripgrep
|
||||
|
||||
Usage:
|
||||
- ALWAYS use \${GREP_TOOL_NAME} for search tasks. NEVER invoke \`grep\` or \`rg\` as a \${BASH_TOOL_NAME} command.
|
||||
- Use \${TASK_TOOL_NAME} tool for open-ended searches requiring multiple rounds`;
|
||||
|
||||
const result = renderTemplate(template, ctx);
|
||||
|
||||
expect(result).toContain('ALWAYS use grep for search tasks');
|
||||
expect(result).toContain('NEVER invoke `grep` or `rg` as a bash command');
|
||||
expect(result).toContain('Use task tool for open-ended searches');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user