对齐策划入口测试到新设计 Agent
新建策划入口走设计会话命令,已有 V2 会话仍走原链路 补审批与澄清卡界面用例
This commit is contained in:
@@ -2,7 +2,6 @@ use super::*;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use uuid::Uuid;
|
||||
use serde_json::Value;
|
||||
@@ -301,6 +300,7 @@ pub(crate) fn reject_design_phase(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::fs;
|
||||
|
||||
#[test]
|
||||
fn phase_artifact_check_includes_previous_phases() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** @vitest-environment jsdom */
|
||||
import { registerAgentRuntimeCommandTests } from './appSurface/agent-runtime.suite';
|
||||
import { registerAuthTests } from './appSurface/auth.suite';
|
||||
import { registerDesignAgentSurfaceTests } from './appSurface/design-agent.suite';
|
||||
import {
|
||||
registerDeveloperAgentWindowTests,
|
||||
registerDeveloperToolsTests,
|
||||
@@ -56,4 +57,5 @@ describe('AI 游戏创作 App 界面边界', () => {
|
||||
registerAgentRuntimeCommandTests();
|
||||
registerCanvasAssetTests();
|
||||
registerPlanGddApprovalTests();
|
||||
registerDesignAgentSurfaceTests();
|
||||
});
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
App,
|
||||
createProjectSupervisorRuntimeHarness,
|
||||
expect,
|
||||
fireEvent,
|
||||
it,
|
||||
React,
|
||||
render,
|
||||
screen,
|
||||
waitFor,
|
||||
} from './harness';
|
||||
|
||||
function designApprovalView() {
|
||||
return {
|
||||
session: {
|
||||
sessionId: 'design-session-1',
|
||||
projectId: 'local-project-draft',
|
||||
currentPhase: 'concept',
|
||||
approvedPhases: [],
|
||||
pendingApproval: {
|
||||
requestId: 'approval-1',
|
||||
phase: 'concept',
|
||||
submittedAt: 1,
|
||||
},
|
||||
pendingClarification: null,
|
||||
turnIndex: 2,
|
||||
lastError: null,
|
||||
},
|
||||
messages: [{ id: 'a1', role: 'assistant', text: '概念稿已写好。' }],
|
||||
running: false,
|
||||
canRetry: false,
|
||||
};
|
||||
}
|
||||
|
||||
export function registerDesignAgentSurfaceTests() {
|
||||
it('hydrates an existing design session and decides approval through design commands', async () => {
|
||||
const harness = createProjectSupervisorRuntimeHarness({
|
||||
designAgentView: designApprovalView(),
|
||||
});
|
||||
window.__TAURI__ = {
|
||||
core: { invoke: harness.invoke },
|
||||
event: { listen: harness.listen },
|
||||
};
|
||||
window.history.pushState({}, '', '/');
|
||||
render(
|
||||
React.createElement(App, {
|
||||
initialProjectPath: harness.projectPath,
|
||||
orchestrationMode: 'single-supervisor',
|
||||
planningStartMode: true,
|
||||
projectSupervisorOnly: true,
|
||||
}),
|
||||
);
|
||||
|
||||
await screen.findByLabelText('批准');
|
||||
expect(
|
||||
harness.invoke.mock.calls.some(
|
||||
([command]) => command === 'hydrate_design_agent_session',
|
||||
),
|
||||
).toBe(true);
|
||||
expect(screen.getByLabelText('项目需求')).toHaveProperty('disabled', true);
|
||||
fireEvent.click(screen.getByRole('button', { name: '批准' }));
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
harness.invoke.mock.calls.some(
|
||||
([command]) => command === 'decide_design_phase',
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -462,6 +462,9 @@ function createProjectSupervisorRuntimeHarness({
|
||||
expectedRunProfile = 'autonomous-game-build',
|
||||
planningV2Result = null,
|
||||
planningV2StartResult = null,
|
||||
designAgentView = null,
|
||||
designAgentContinueView = null,
|
||||
designWorkspaceFiles = [],
|
||||
}: {
|
||||
projectPath?: string;
|
||||
sessionId?: string;
|
||||
@@ -475,6 +478,9 @@ function createProjectSupervisorRuntimeHarness({
|
||||
expectedRunProfile?: 'standard' | 'autonomous-game-build';
|
||||
planningV2Result?: Record<string, unknown> | null;
|
||||
planningV2StartResult?: Record<string, unknown> | null;
|
||||
designAgentView?: Record<string, unknown> | null;
|
||||
designAgentContinueView?: Record<string, unknown> | null;
|
||||
designWorkspaceFiles?: Array<Record<string, unknown>>;
|
||||
} = {}) {
|
||||
const manifest = createGameCreationAppManifest(
|
||||
'local-project-draft',
|
||||
@@ -522,6 +528,9 @@ function createProjectSupervisorRuntimeHarness({
|
||||
// 默认不配置策划状态:hydrate 与接入本 harness 之前一样抛出,既有用例行为不变。
|
||||
let currentPlanningV2Result = planningV2Result;
|
||||
let currentPlanningV2StartResult = planningV2StartResult;
|
||||
let currentDesignAgentView = designAgentView;
|
||||
const currentDesignContinueView = designAgentContinueView;
|
||||
const currentDesignWorkspaceFiles = [...designWorkspaceFiles];
|
||||
let planningV2DecisionError: string | null = null;
|
||||
const planningV2DecisionCalls: Array<Record<string, unknown>> = [];
|
||||
let runtimeUpdateHandler:
|
||||
@@ -841,6 +850,29 @@ function createProjectSupervisorRuntimeHarness({
|
||||
});
|
||||
return runtimeResult();
|
||||
}
|
||||
if (command === 'hydrate_design_agent_session') {
|
||||
return currentDesignAgentView;
|
||||
}
|
||||
if (command === 'continue_design_agent_session') {
|
||||
const next = currentDesignContinueView ?? currentDesignAgentView;
|
||||
if (!next) {
|
||||
throw new Error('DESIGN_AGENT_VIEW_NOT_CONFIGURED');
|
||||
}
|
||||
currentDesignAgentView = next;
|
||||
return next;
|
||||
}
|
||||
if (command === 'decide_design_phase') {
|
||||
if (!currentDesignAgentView) {
|
||||
throw new Error('DESIGN_AGENT_VIEW_NOT_CONFIGURED');
|
||||
}
|
||||
return currentDesignAgentView;
|
||||
}
|
||||
if (command === 'list_design_workspace') {
|
||||
return currentDesignWorkspaceFiles;
|
||||
}
|
||||
if (command === 'read_design_workspace_file') {
|
||||
return '';
|
||||
}
|
||||
if (command === 'hydrate_planning_session_v2') {
|
||||
return currentPlanningV2Result;
|
||||
}
|
||||
|
||||
@@ -745,9 +745,39 @@ export function registerPlanGddApprovalTests() {
|
||||
});
|
||||
});
|
||||
|
||||
it('starts a new V2 planning session and renders its question card', async () => {
|
||||
it('starts a new planning entry through the design agent', async () => {
|
||||
const harness = createProjectSupervisorRuntimeHarness({
|
||||
planningV2StartResult: planningV2QuestionResult(),
|
||||
designAgentContinueView: {
|
||||
session: {
|
||||
sessionId: 'design-session-1',
|
||||
projectId: 'local-project-draft',
|
||||
currentPhase: 'concept',
|
||||
approvedPhases: [],
|
||||
pendingApproval: null,
|
||||
pendingClarification: {
|
||||
requestId: 'clarify-1',
|
||||
question: '玩家在一局中主要反复做什么?',
|
||||
options: ['持续闪避', '站桩输出'],
|
||||
createdAt: 1,
|
||||
},
|
||||
turnIndex: 1,
|
||||
lastError: null,
|
||||
},
|
||||
messages: [
|
||||
{
|
||||
id: 'u1',
|
||||
role: 'user',
|
||||
text: '做一个2D弹幕射击游戏',
|
||||
},
|
||||
{
|
||||
id: 'a1',
|
||||
role: 'assistant',
|
||||
text: '先确认核心循环。',
|
||||
},
|
||||
],
|
||||
running: false,
|
||||
canRetry: false,
|
||||
},
|
||||
});
|
||||
window.__TAURI__ = {
|
||||
core: { invoke: harness.invoke },
|
||||
@@ -764,21 +794,28 @@ export function registerPlanGddApprovalTests() {
|
||||
}),
|
||||
);
|
||||
|
||||
await screen.findByLabelText('Needs input');
|
||||
await screen.findByText('玩家在一局中主要反复做什么?');
|
||||
expect(
|
||||
harness.invoke.mock.calls.some(
|
||||
([command]) => command === 'hydrate_design_agent_session',
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
harness.invoke.mock.calls.some(
|
||||
([command]) => command === 'start_planning_session_v2',
|
||||
),
|
||||
).toBe(true);
|
||||
expect(screen.getByText('玩家在一局中主要反复做什么?')).not.toBeNull();
|
||||
).toBe(false);
|
||||
expect(screen.queryByText(/agent\.delegate/)).toBeNull();
|
||||
fireEvent.click(screen.getByRole('button', { name: /持续闪避/ }));
|
||||
fireEvent.click(screen.getByRole('button', { name: '提交回答' }));
|
||||
fireEvent.click(screen.getByRole('button', { name: '持续闪避' }));
|
||||
await waitFor(() => {
|
||||
expect(harness.invoke).toHaveBeenCalledWith(
|
||||
'continue_planning_session_v2',
|
||||
'continue_design_agent_session',
|
||||
expect.objectContaining({
|
||||
input: { text: '持续闪避', questionId: 'core_loop' },
|
||||
input: expect.objectContaining({
|
||||
type: 'clarification',
|
||||
requestId: 'clarify-1',
|
||||
optionIndex: 0,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user