feat: complete Aider Page Data review workflow

This commit is contained in:
john
2026-07-25 09:47:25 +08:00
parent be9c25f1d0
commit 104fb4e370
15 changed files with 914 additions and 30 deletions
+121
View File
@@ -158,6 +158,83 @@ test('selected Aider development skill forces code mode, task type, and Aider ex
assert.equal(created[0].payload.userMessage.metadata.memindRun.executor, 'aider');
});
test('selected Aider development skill rejects a template-only task before creating a run', async () => {
let created = false;
const handler = createPostAgentRunsHandler({
userAuth: {
async getUserSkills() {
return { skills: { 'aider-development': true } };
},
},
agentRunGateway: {
async createRun() {
created = true;
return { id: 'must-not-run' };
},
},
codeRunsEnabled: true,
});
const res = createResponseRecorder();
const template =
'请使用 aider-development 技能:本轮必须由 Aider code run 在当前用户工作区执行开发、修复和验证;Aider 或 Tool Gateway 不可用时直接失败,禁止回退到 Goose、OpenHands 或普通聊天冒充执行。我的开发任务是:';
await handler(
{
currentUser: { id: 'user-1' },
body: {
request_id: 'req-aider-empty',
user_message: {
role: 'user',
content: [{ type: 'text', text: template }],
metadata: {
displayText: template,
memindRun: { selectedChatSkill: 'aider-development' },
},
},
},
},
res,
);
assert.equal(res.statusCode, 400);
assert.match(res.body.message, /具体开发任务/);
assert.equal(created, false);
});
test('Aider development routes Page Data creation through Agent then requires Aider review', () => {
const template =
'请使用 aider-development 技能:本轮必须由 Aider code run 在当前用户工作区执行开发、修复和验证;Aider 或 Tool Gateway 不可用时直接失败,禁止回退到 Goose、OpenHands 或普通聊天冒充执行。我的开发任务是:';
const task = '帮我设计一个简单下单系统,不要支付,可以有简单后台管理订单';
const enforced = enforceSelectedSkillRuntime(
{
role: 'user',
content: [
{ type: 'text', text: `${template}${task}` },
{
type: 'text',
text: '[Memind code-run validation]\nBefore finishing, create the receipt.',
},
],
metadata: {
displayText: `${template}${task}`,
memindRun: { selectedChatSkill: 'aider-development', executor: 'openhands' },
},
},
{ rawToolMode: 'code', taskType: 'h5_chat_code_task' },
);
assert.equal(enforced.rawToolMode, 'chat');
assert.equal(enforced.taskType, null);
assert.equal(enforced.requiredExecutor, null);
assert.equal(enforced.requiredReviewExecutor, 'aider');
assert.equal(enforced.userMessage.metadata.memindRun.executor, undefined);
assert.equal(enforced.userMessage.metadata.memindRun.reviewExecutor, 'aider');
assert.equal(enforced.userMessage.metadata.memindRun.pageDataAiderWorkflow, true);
assert.match(enforced.userMessage.content[0].text, /private_data_execute/);
assert.match(enforced.userMessage.content[0].text, /强制 Aider 审查/);
assert.match(enforced.userMessage.content[0].text, /简单下单系统/);
assert.equal(enforced.userMessage.content.length, 1);
});
test('selected Aider development skill fails closed when code runs are disabled', async () => {
const handler = createPostAgentRunsHandler({
userAuth: {
@@ -197,6 +274,50 @@ test('selected Aider development skill fails closed when code runs are disabled'
assert.match(res.body.message, /代码任务灰度未开启/);
});
test('Page Data plus Aider review also respects the code-run policy gate', async () => {
const template =
'请使用 aider-development 技能:本轮必须由 Aider code run 在当前用户工作区执行开发、修复和验证;Aider 或 Tool Gateway 不可用时直接失败,禁止回退到 Goose、OpenHands 或普通聊天冒充执行。我的开发任务是:';
const task = '创建下单系统并在后台管理订单';
const handler = createPostAgentRunsHandler({
userAuth: {
async getUserSkills() {
return { skills: { 'aider-development': true } };
},
},
agentRunGateway: {
async createRun() {
assert.fail('disabled review policy must not create a run');
},
},
codeRunsEnabled: false,
});
const res = createResponseRecorder();
await handler(
{
currentUser: { id: 'user-1' },
body: {
request_id: 'req-page-data-aider-disabled',
user_message: {
role: 'user',
content: [{ type: 'text', text: `${template}${task}` }],
metadata: {
displayText: `${template}${task}`,
memindRun: {
selectedChatSkill: 'aider-development',
validation: {
expectedFile: '.memind/agent-runs/req-page-data-aider-disabled.json',
},
},
},
},
},
},
res,
);
assert.equal(res.statusCode, 403);
assert.match(res.body.message, /代码任务灰度未开启/);
});
test('POST /agent/runs forwards deep reasoning flag to the run gateway', async () => {
const created = [];
const handler = createPostAgentRunsHandler({