mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-05-01 21:20:44 +00:00
feat(review): add model attribution to PR review summary
Add {{model}} template variable support in BundledSkillLoader. When a
skill body contains {{model}}, it is replaced with the runtime model ID
from config.getModel(). Only skills that use the variable are affected.
The /review skill now appends a model attribution footer to PR review
summaries: "Reviewed by {model} via Qwen Code /review"
This enables cross-model review workflows (e.g., develop with model A,
review with model B) with accurate attribution in PR comments.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fe3d596d72
commit
fab4dc5949
3 changed files with 72 additions and 6 deletions
|
|
@ -127,6 +127,65 @@ describe('BundledSkillLoader', () => {
|
|||
expect(commands.map((c) => c.name)).toEqual(['review', 'deploy']);
|
||||
});
|
||||
|
||||
it('should resolve {{model}} template variable in skill body', async () => {
|
||||
const skill = makeSkill({
|
||||
body: 'Review by {{model}} via Qwen Code',
|
||||
});
|
||||
mockSkillManager.listSkills.mockResolvedValue([skill]);
|
||||
(mockConfig as Record<string, unknown>).getModel = vi
|
||||
.fn()
|
||||
.mockReturnValue('qwen3-coder');
|
||||
|
||||
const loader = new BundledSkillLoader(mockConfig);
|
||||
const commands = await loader.loadCommands(signal);
|
||||
const result = await commands[0].action!(
|
||||
{ invocation: { raw: '/review', args: '' } } as never,
|
||||
'',
|
||||
);
|
||||
|
||||
expect(result).toEqual({
|
||||
type: 'submit_prompt',
|
||||
content: [{ text: 'Review by qwen3-coder via Qwen Code' }],
|
||||
});
|
||||
});
|
||||
|
||||
it('should use "unknown" when model is not available for {{model}}', async () => {
|
||||
const skill = makeSkill({
|
||||
body: 'Review by {{model}}',
|
||||
});
|
||||
mockSkillManager.listSkills.mockResolvedValue([skill]);
|
||||
// No getModel on config
|
||||
|
||||
const loader = new BundledSkillLoader(mockConfig);
|
||||
const commands = await loader.loadCommands(signal);
|
||||
const result = await commands[0].action!(
|
||||
{ invocation: { raw: '/review', args: '' } } as never,
|
||||
'',
|
||||
);
|
||||
|
||||
expect(result).toEqual({
|
||||
type: 'submit_prompt',
|
||||
content: [{ text: 'Review by unknown' }],
|
||||
});
|
||||
});
|
||||
|
||||
it('should not modify skill body without {{model}} template', async () => {
|
||||
const skill = makeSkill({ body: 'No template here' });
|
||||
mockSkillManager.listSkills.mockResolvedValue([skill]);
|
||||
|
||||
const loader = new BundledSkillLoader(mockConfig);
|
||||
const commands = await loader.loadCommands(signal);
|
||||
const result = await commands[0].action!(
|
||||
{ invocation: { raw: '/review', args: '' } } as never,
|
||||
'',
|
||||
);
|
||||
|
||||
expect(result).toEqual({
|
||||
type: 'submit_prompt',
|
||||
content: [{ text: 'No template here' }],
|
||||
});
|
||||
});
|
||||
|
||||
it('should hide skills with cron allowedTools when cron is disabled', async () => {
|
||||
const skills = [
|
||||
makeSkill({ name: 'review', description: 'Review code' }),
|
||||
|
|
|
|||
|
|
@ -59,12 +59,19 @@ export class BundledSkillLoader implements ICommandLoader {
|
|||
description: skill.description,
|
||||
kind: CommandKind.SKILL,
|
||||
action: async (context, _args): Promise<SlashCommandActionReturn> => {
|
||||
// Resolve template variables in skill body (e.g., {{model}})
|
||||
let body = skill.body;
|
||||
if (body.includes('{{model}}')) {
|
||||
const modelId =
|
||||
(typeof this.config?.getModel === 'function'
|
||||
? this.config.getModel()
|
||||
: undefined) ?? 'unknown';
|
||||
body = body.replaceAll('{{model}}', modelId);
|
||||
}
|
||||
|
||||
const content = context.invocation?.args
|
||||
? appendToLastTextPart(
|
||||
[{ text: skill.body }],
|
||||
context.invocation.raw,
|
||||
)
|
||||
: [{ text: skill.body }];
|
||||
? appendToLastTextPart([{ text: body }], context.invocation.raw)
|
||||
: [{ text: body }];
|
||||
|
||||
return {
|
||||
type: 'submit_prompt',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue