feat: add guarded image generation controls

This commit is contained in:
john
2026-07-20 07:37:43 +08:00
parent 72ed4dde83
commit 105a72c1f1
19 changed files with 482 additions and 23 deletions
+48
View File
@@ -23,10 +23,58 @@ import {
isRealtimeInfoQuestion,
isRichChannelPageIntent,
isRichPublishableContentIntent,
IMAGE_GENERATION_MODE,
resolveImageGenerationDecision,
coerceRealtimeWebSkill,
resolveChatIntentRouterPolicy,
} from './chat-intent-router.mjs';
test('image generation intent requires a real image for explicit background requests', () => {
const decision = resolveImageGenerationDecision({
text: '帮我生成一首唐诗页面,背景是大唐盛景图片,页面要精美',
});
assert.equal(decision.mode, IMAGE_GENERATION_MODE.REQUIRED);
assert.equal(decision.source, 'intent');
});
test('image generation user override can force or disable image generation', () => {
assert.equal(resolveImageGenerationDecision({
text: '做一个纯文字页面',
requestedMode: 'required',
}).mode, IMAGE_GENERATION_MODE.REQUIRED);
assert.equal(resolveImageGenerationDecision({
text: '生成一个带背景图的页面',
requestedMode: 'disabled',
}).mode, IMAGE_GENERATION_MODE.DISABLED);
});
test('router injects a fail-closed generate_image contract for required visual pages', async () => {
const router = createChatIntentRouter();
const text = '帮我生成一个精美唐诗页面,背景是大唐盛景图片';
const userMessage = {
role: 'user',
content: [{ type: 'text', text }],
metadata: {
displayText: text,
memindRun: { imageGenerationMode: 'auto' },
},
};
const classification = await router.classify({
userMessage,
grantedSkills: ['static-page-publish'],
});
assert.equal(classification.imageGeneration.mode, IMAGE_GENERATION_MODE.REQUIRED);
const enriched = router.applyAgentOrchestration(userMessage, classification, {
grantedSkills: ['static-page-publish'],
});
assert.match(enriched.content[0].text, /sandbox-fs__generate_image/);
assert.match(enriched.content[0].text, /当前这一次执行中发起新的 generate_image/);
assert.match(enriched.content[0].text, /历史对话中的成功或失败都不能作为本轮结果/);
assert.match(enriched.content[0].text, /hero 成功后必须复用该资产/);
assert.match(enriched.content[0].text, /禁止再调用 card_cover 或 feed_cover/);
assert.match(enriched.content[0].text, /不得用 SVG/);
});
test('classifyWithRules routes greetings to direct chat', () => {
const result = classifyWithRules({
text: '你好',