修复Agent对话真实回复可见性

主窗口单 Agent 对话改为调用真实 Agent 回复

开发聊天入口在回复失败时把错误显示到对话区

更新单 Agent 对话回归测试
This commit is contained in:
AIGameCreator App
2026-07-08 22:58:49 +08:00
parent c0ff9edf97
commit 46fbcdf78a
2 changed files with 108 additions and 37 deletions
+41 -17
View File
@@ -2938,12 +2938,20 @@ export function WorkspaceLauncher({
return;
}
if (savedUserResult) {
setAgentChatMessages(savedUserResult.messages);
setAgentChatStatus(
`已保存用户消息;Agent 回复失败:${
error instanceof Error ? error.message : String(error)
}`,
);
const message = `已保存用户消息;Agent 回复失败:${
error instanceof Error ? error.message : String(error)
}`;
setAgentChatMessages([
...savedUserResult.messages,
{
schemaVersion: 'game-creator-conversation.v1',
role: 'assistant',
content: message,
agentId: null,
updatedAt: Date.now(),
},
]);
setAgentChatStatus(message);
} else {
setAgentChatInput(content);
setAgentChatStatus(error instanceof Error ? error.message : String(error));
@@ -10552,10 +10560,6 @@ function summarizeAgentRunHistoryReadDrafts(
: 'Run 历史读取命令:暂无已加载 run';
}
function localAgentConversationReceipt(agent: Pick<AgentStatusCard, 'title'>) {
return `已记录给 ${agent.title}。下一次生成会把这条对话作为该 agent 的上下文读取。`;
}
function summarizeLlmConversation(trace: GameCreationAgentRunTrace) {
const llmSteps = trace.steps.filter((step) =>
step.toolCalls.some((toolCall) => toolCall.toolId.startsWith('llm.')),
@@ -12159,6 +12163,18 @@ export function App() {
return;
}
setAgentConversationMessages(savedUserResult.messages);
setAgentConversationStatus('Agent 正在思考');
const reply = await invoke<GameCreatorChatAgentReply>(
'chat_with_game_creator_role_agent',
{
projectPath: nextProjectPath,
agentId: agent.id,
prompt: content,
},
);
if (agentConversationLoadVersionRef.current !== saveVersion) {
return;
}
const assistantResult = await invoke<LocalConversationResult>(
'append_local_conversation_message',
{
@@ -12166,7 +12182,7 @@ export function App() {
agentId: agent.id,
message: {
role: 'assistant',
content: localAgentConversationReceipt(agent),
content: reply.replyText,
agentId: null,
},
},
@@ -12184,12 +12200,20 @@ export function App() {
return;
}
if (savedUserResult) {
setAgentConversationMessages(savedUserResult.messages);
setAgentConversationStatus(
`已保存用户消息;Agent 回执失败:${
error instanceof Error ? error.message : String(error)
}`,
);
const message = `已保存用户消息;Agent 回复失败:${
error instanceof Error ? error.message : String(error)
}`;
setAgentConversationMessages([
...savedUserResult.messages,
{
schemaVersion: 'game-creator-conversation.v1',
role: 'assistant',
content: message,
agentId: null,
updatedAt: Date.now(),
},
]);
setAgentConversationStatus(message);
} else {
setAgentConversationInput(content);
setAgentConversationStatus(
@@ -908,6 +908,11 @@ describe('AI 游戏创作 App 界面边界', () => {
})),
};
}
if (command === 'chat_with_game_creator_role_agent') {
return {
replyText: `Agent 真回复:${String(args?.prompt ?? '')}`,
};
}
if (command === 'append_local_conversation_message') {
const message = args?.message as {
role: 'user' | 'assistant' | 'tool';
@@ -925,11 +930,6 @@ describe('AI 游戏创作 App 界面边界', () => {
})),
};
}
if (command === 'chat_with_game_creator_role_agent') {
return {
replyText: `Agent 回复:${String(args?.prompt ?? '')}`,
};
}
throw new Error(`unexpected invoke ${command}`);
},
);
@@ -959,7 +959,7 @@ describe('AI 游戏创作 App 界面边界', () => {
).not.toBeNull();
expect(
await screen.findByText(
'Agent 回复:请单独评估这个角色设定流程',
'Agent 回复:请单独评估这个角色设定流程',
),
).not.toBeNull();
expect(invoke).toHaveBeenCalledWith('append_local_conversation_message', {
@@ -976,7 +976,7 @@ describe('AI 游戏创作 App 界面边界', () => {
agentId: 'design-director',
message: {
role: 'assistant',
content: 'Agent 回复:请单独评估这个角色设定流程',
content: 'Agent 回复:请单独评估这个角色设定流程',
agentId: null,
},
});
@@ -1215,6 +1215,11 @@ describe('AI 游戏创作 App 界面边界', () => {
manifestPath: '/tmp/home-created-game/.agent/manifest.json',
};
}
if (command === 'chat_with_game_creator_role_agent') {
return {
replyText: `Agent 真回复:${String(args?.prompt ?? '')}`,
};
}
if (command === 'append_local_conversation_message') {
return {
path: '.agent/conversations/project.jsonl',
@@ -2278,6 +2283,11 @@ describe('AI 游戏创作 App 界面边界', () => {
messages: [],
};
}
if (command === 'chat_with_game_creator_role_agent') {
return {
replyText: `Agent 真回复:${String(args?.prompt ?? '')}`,
};
}
if (command === 'append_local_conversation_message') {
return {
path: '/tmp/authorized-game/.agent/conversations/project.jsonl',
@@ -10637,6 +10647,11 @@ describe('AI 游戏创作 App 界面边界', () => {
if (command === 'list_local_project_files') {
return { projectPath: String(args?.projectPath ?? ''), files: [] };
}
if (command === 'chat_with_game_creator_role_agent') {
return {
replyText: `Agent 真回复:${String(args?.prompt ?? '')}`,
};
}
if (command === 'append_local_conversation_message') {
appendAttempts += 1;
const message = args?.message as { content: string };
@@ -11099,6 +11114,11 @@ describe('AI 游戏创作 App 界面边界', () => {
],
};
}
if (command === 'chat_with_game_creator_role_agent') {
return {
replyText: `Agent 真回复:${String(args?.prompt ?? '')}`,
};
}
if (command === 'append_local_conversation_message') {
const message = args?.message as {
role: 'user' | 'assistant';
@@ -11157,7 +11177,7 @@ describe('AI 游戏创作 App 界面边界', () => {
).not.toBeNull();
expect(
screen.getByText(
'已记录给 拆解创作方向。下一次生成会把这条对话作为该 agent 的上下文读取。',
'Agent 真回复:优先保留轻量像素风',
),
).not.toBeNull();
expect(invoke).toHaveBeenCalledWith('read_local_conversation', {
@@ -11198,11 +11218,15 @@ describe('AI 游戏创作 App 界面边界', () => {
agentId: 'design-director',
message: {
role: 'assistant',
content:
'已记录给 拆解创作方向。下一次生成会把这条对话作为该 agent 的上下文读取。',
content: 'Agent 真回复:优先保留轻量像素风',
agentId: null,
},
});
expect(invoke).toHaveBeenCalledWith('chat_with_game_creator_role_agent', {
projectPath: '/tmp/authorized-game',
agentId: 'design-director',
prompt: '优先保留轻量像素风',
});
fireEvent.change(screen.getByLabelText('Agent 对话内容'), {
target: { value: '稳定结论:锅铲音效要跟随连击节奏' },
});
@@ -11551,6 +11575,11 @@ describe('AI 游戏创作 App 界面边界', () => {
exists: false,
};
}
if (command === 'chat_with_game_creator_role_agent') {
return {
replyText: `Agent 真回复:${String(args?.prompt ?? '')}`,
};
}
if (command === 'append_local_conversation_message') {
const message = args?.message as {
role: 'user' | 'assistant';
@@ -11608,7 +11637,7 @@ describe('AI 游戏创作 App 界面边界', () => {
expect(screen.getByText('先记住这个方向')).not.toBeNull();
expect(
screen.getByText(
'已记录给 拆解创作方向。下一次生成会把这条对话作为该 agent 的上下文读取。',
'Agent 真回复:先记住这个方向',
),
).not.toBeNull();
expect(invoke).toHaveBeenCalledWith('append_local_conversation_message', {
@@ -11625,11 +11654,15 @@ describe('AI 游戏创作 App 界面边界', () => {
agentId: 'design-director',
message: {
role: 'assistant',
content:
'已记录给 拆解创作方向。下一次生成会把这条对话作为该 agent 的上下文读取。',
content: 'Agent 真回复:先记住这个方向',
agentId: null,
},
});
expect(invoke).toHaveBeenCalledWith('chat_with_game_creator_role_agent', {
projectPath: '/tmp/authorized-game',
agentId: 'design-director',
prompt: '先记住这个方向',
});
});
it('shows agent conversation history in recent batches', async () => {
@@ -11761,6 +11794,11 @@ describe('AI 游戏创作 App 界面边界', () => {
exists: false,
};
}
if (command === 'chat_with_game_creator_role_agent') {
return {
replyText: `Agent 真回复:${String(args?.prompt ?? '')}`,
};
}
if (command === 'append_local_conversation_message') {
const message = args?.message as {
role: 'user' | 'assistant';
@@ -11940,15 +11978,15 @@ describe('AI 游戏创作 App 界面边界', () => {
exists: false,
};
}
if (command === 'chat_with_game_creator_role_agent') {
throw new Error('Agent LLM 未配置');
}
if (command === 'append_local_conversation_message') {
const message = args?.message as {
role: 'user' | 'assistant';
content: string;
agentId: string | null;
};
if (message.role === 'assistant') {
throw new Error('保存 Agent 回执失败');
}
agentMessages.push({
schemaVersion: 'game-creator-conversation.v1',
role: message.role,
@@ -11983,12 +12021,16 @@ describe('AI 游戏创作 App 界面边界', () => {
fireEvent.submit(input.closest('form') as HTMLFormElement);
expect(
await screen.findByText(/已保存用户消息;Agent 回执失败/),
).not.toBeNull();
(
await screen.findAllByText(
/已保存用户消息;Agent 回复失败:Agent LLM 未配置/,
)
).length,
).toBeGreaterThan(0);
expect(screen.getByText('先保留这个方向')).not.toBeNull();
expect(
screen.queryByText(
'已记录给 拆解创作方向。下一次生成会把这条对话作为该 agent 的上下文读取。',
'Agent 真回复:先保留这个方向',
),
).toBeNull();
expect(screen.getByLabelText('Agent 对话内容')).toHaveProperty('value', '');
@@ -12098,6 +12140,11 @@ describe('AI 游戏创作 App 界面边界', () => {
exists: false,
};
}
if (command === 'chat_with_game_creator_role_agent') {
return {
replyText: `Agent 真回复:${String(args?.prompt ?? '')}`,
};
}
if (command === 'append_local_conversation_message') {
const message = args?.message as {
role: 'user' | 'assistant';
@@ -12141,7 +12188,7 @@ describe('AI 游戏创作 App 界面边界', () => {
expect(screen.getByText('先记住这个方向')).not.toBeNull();
expect(
screen.getByText(
'已记录给 拆解创作方向。下一次生成会把这条对话作为该 agent 的上下文读取。',
'Agent 真回复:先记住这个方向',
),
).not.toBeNull();
expect(screen.getByLabelText('Agent 对话内容')).toHaveProperty('value', '');