From 93543cf0b3d18006ddeab43cd5b03910b283ef4e Mon Sep 17 00:00:00 2001 From: Fini Date: Sat, 9 May 2026 20:59:29 +0800 Subject: [PATCH] fix(ai): route workspace/console fallback prompts to desktop-screen, not landing-page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Why: Codex stop-time review #6 — C6 added workspace / console / 工作台 / 工作区 to the component DISQUALIFIER, but the dashboard detector regex still only matched dashboard|admin|管理|后台|控制台. So "design a workspace with side panel" skipped component (correct) AND skipped dashboard (regex miss) and fell through to landing-page (1200×0, 4-section), which is the wrong shape for a workspace UI — the user wants a 3-section desktop-screen with header/main/actions. What: dashboard detector regex extended in lockstep with the disqualifier — dashboard|admin|workspace|console|管理|后台|控制台| 工作台|工作区. Comment makes the "keep in sync" invariant explicit. Tests: 4 new positive cases (Latin workspace + console, zh-Hans 工作台 + 工作区 with 卡片) assert the plan returns 1200×800 with the 3- section ['Header','Main Content','Actions'] layout, not the 4-section landing-page default. 1066 / 1066 AI tests pass (was 1062; +4). --- .../orchestrator-prompt-optimizer.test.ts | 21 +++++++++++++++++++ .../src/services/ai/design-type-presets.ts | 11 +++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/apps/web/src/services/ai/__tests__/orchestrator-prompt-optimizer.test.ts b/apps/web/src/services/ai/__tests__/orchestrator-prompt-optimizer.test.ts index 4e6cdcae8..586ef1dd9 100644 --- a/apps/web/src/services/ai/__tests__/orchestrator-prompt-optimizer.test.ts +++ b/apps/web/src/services/ai/__tests__/orchestrator-prompt-optimizer.test.ts @@ -208,6 +208,27 @@ describe('buildFallbackPlanFromPrompt', () => { expect(plan.rootFrame.width).not.toBe(400); }); + // Codex review #6: keywords disqualifying a component fallback MUST + // also route the prompt to the right non-component preset. Otherwise + // "design a workspace with side panel" skipped component AND skipped + // dashboard (the regex only matched dashboard|admin|管理|后台|控制台) + // and fell through to landing-page (1200×0), which is the wrong shape + // for a workspace UI. + it.each([ + ['design a workspace with side panel and metrics'], + ['design a console with charts and live metrics'], + ['设计一个工作台 with charts'], + ['设计一个工作区 with 卡片'], + ])('classifies "%s" as desktop-screen (1200×800), not landing-page', (prompt) => { + const plan = buildFallbackPlanFromPrompt(prompt); + expect(plan.rootFrame.width).toBe(1200); + expect(plan.rootFrame.height).toBe(800); // desktop-screen preset has rootHeight=800 + // 3 default sections (Header / Main Content / Actions) — not the + // 4 sections of landing-page (Header / Main / Supporting / Footer). + expect(plan.subtasks).toHaveLength(3); + expect(plan.subtasks.map((st) => st.label)).toEqual(['Header', 'Main Content', 'Actions']); + }); + it('uses design.md background and style-guide name when designMd is present', () => { const designMd: DesignMdSpec = { raw: '# Test', diff --git a/apps/web/src/services/ai/design-type-presets.ts b/apps/web/src/services/ai/design-type-presets.ts index da6ee278f..40afba8ba 100644 --- a/apps/web/src/services/ai/design-type-presets.ts +++ b/apps/web/src/services/ai/design-type-presets.ts @@ -45,7 +45,7 @@ const COMPONENT_TRIGGER_CJK_RE = /(卡片|徽章|标签|按钮|开关|对话框| // the prompt also names a tile/panel/chart/metric inside it // ("admin dashboard with metric tiles" must not become a Type 0 tile). const COMPONENT_DISQUALIFIER_RE = - /\b(screen|page|app|home|onboarding|flow|mobile|phone|ios|android|dashboard|admin|workspace|console)\b|网页|页面|屏幕|手机|移动端|管理|后台|控制台/i; + /\b(screen|page|app|home|onboarding|flow|mobile|phone|ios|android|dashboard|admin|workspace|console)\b|网页|页面|屏幕|手机|移动端|管理|后台|控制台|工作台|工作区/i; /** * Minimal fallback design type detection. @@ -87,8 +87,13 @@ export function detectDesignType(prompt: string): DesignTypePreset { }; } - // Fixed-height desktop screens - if (/dashboard|admin|管理|后台|控制台/i.test(prompt)) { + // Fixed-height desktop screens. Keep in sync with the workspace markers + // in COMPONENT_DISQUALIFIER_RE — every keyword that disqualifies a + // component fallback for "workspace context" MUST also be detected here, + // otherwise the prompt skips component AND skips dashboard and falls + // through to landing-page (1200×0) which is wrong for "design a workspace + // with side panel" / "design a console with metrics" (Codex review #6). + if (/dashboard|admin|workspace|console|管理|后台|控制台|工作台|工作区/i.test(prompt)) { return { type: 'desktop-screen', width: 1200,